124 lines
2.7 KiB
Go
124 lines
2.7 KiB
Go
|
// Простой модуль для взаимодействия с API LastFM
|
|||
|
package models
|
|||
|
|
|||
|
import (
|
|||
|
"encoding/json"
|
|||
|
"errors"
|
|||
|
"fmt"
|
|||
|
"io"
|
|||
|
"net/http"
|
|||
|
)
|
|||
|
|
|||
|
type LFMWorker struct {
|
|||
|
Username string
|
|||
|
ApiKey string
|
|||
|
}
|
|||
|
|
|||
|
type Track struct {
|
|||
|
URL string
|
|||
|
Title string
|
|||
|
Artist string
|
|||
|
Album string
|
|||
|
Listening int
|
|||
|
}
|
|||
|
|
|||
|
type LastFMResponse struct {
|
|||
|
RecentTracks struct {
|
|||
|
Track []struct {
|
|||
|
Name string `json:"name"`
|
|||
|
Artist struct {
|
|||
|
Name string `json:"#text"`
|
|||
|
} `json:"artist"`
|
|||
|
Album struct {
|
|||
|
Name string `json:"#text"`
|
|||
|
} `json:"album"`
|
|||
|
Date struct {
|
|||
|
Unix string `json:"#text"`
|
|||
|
} `json:"date"`
|
|||
|
Image []struct {
|
|||
|
Size string `json:"size"`
|
|||
|
URL string `json:"#text"`
|
|||
|
} `json:"image"`
|
|||
|
} `json:"track"`
|
|||
|
} `json:"recenttracks"`
|
|||
|
}
|
|||
|
|
|||
|
func LFMNew(username, apikey string) *LFMWorker {
|
|||
|
return &LFMWorker{
|
|||
|
Username: username,
|
|||
|
ApiKey: apikey,
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
func (w *LFMWorker) LastTrack() (*Track, error) {
|
|||
|
url := fmt.Sprintf("https://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=%s&api_key=%s&format=json",
|
|||
|
w.Username, w.ApiKey)
|
|||
|
resp, err := http.Get(url)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
body, err := io.ReadAll(resp.Body)
|
|||
|
if err != nil {
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
|
|||
|
var lastFMResponse LastFMResponse
|
|||
|
var listening int
|
|||
|
json.Unmarshal(body, &lastFMResponse)
|
|||
|
resp.Body.Close()
|
|||
|
|
|||
|
// Получаем только последний трек (первый в списке)
|
|||
|
if len(lastFMResponse.RecentTracks.Track) == 0 {
|
|||
|
return nil, errors.New("no recent tracks")
|
|||
|
}
|
|||
|
lastTrack := lastFMResponse.RecentTracks.Track[0]
|
|||
|
|
|||
|
var imageURL string
|
|||
|
for _, img := range lastTrack.Image {
|
|||
|
if img.Size == "large" {
|
|||
|
imageURL = img.URL
|
|||
|
break
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if lastTrack.Date.Unix == "" {
|
|||
|
listening = 1
|
|||
|
} else {
|
|||
|
listening = 0
|
|||
|
}
|
|||
|
|
|||
|
return &Track{
|
|||
|
URL: imageURL,
|
|||
|
Title: lastTrack.Name,
|
|||
|
Artist: lastTrack.Artist.Name,
|
|||
|
Album: lastTrack.Album.Name,
|
|||
|
Listening: listening}, nil
|
|||
|
}
|
|||
|
|
|||
|
func (w *LFMWorker) TrackAjax(trackData *Track) string {
|
|||
|
style, subdescr := "display: none;", "Последнее, что слушал админ:"
|
|||
|
if trackData.Listening == 1 {
|
|||
|
style, subdescr = "display: block;", "Админ сейчас слушает:"
|
|||
|
}
|
|||
|
|
|||
|
if trackData.URL == "" {
|
|||
|
trackData.URL = "/assets/pic/noimage.webp"
|
|||
|
}
|
|||
|
|
|||
|
return fmt.Sprintf(`
|
|||
|
<img src="%s">
|
|||
|
<img src="/assets/pic/playing.gif" alt="overlay" class="overlay-image" style="%s">
|
|||
|
<div class="descr" title="Это можно скроллить если описание слишком большое">
|
|||
|
<div id="subdescr">%s</div>
|
|||
|
<div id="artist">%s</div>
|
|||
|
<div id="title">%s</div>
|
|||
|
</div>`,
|
|||
|
trackData.URL,
|
|||
|
style,
|
|||
|
subdescr,
|
|||
|
trackData.Artist,
|
|||
|
trackData.Title,
|
|||
|
)
|
|||
|
}
|