GoScrobble/internal/goscrobble/ingress_jellyfin.go

111 lines
3.8 KiB
Go
Raw Normal View History

2021-03-23 08:43:44 +00:00
package goscrobble
2021-03-28 08:52:34 +00:00
import (
"database/sql"
"errors"
"log"
"net"
"time"
2021-03-28 08:52:34 +00:00
)
type JellyfinRequest struct {
Album string `json:"Album"`
Artist string `json:"Artist"`
ClientName string `json:"ClientName"`
DeviceID string `json:"DeviceId"`
DeviceName string `json:"DeviceName"`
IsAutomated bool `json:"IsAutomated"`
IsPaused bool `json:"IsPaused"`
ItemID string `json:"ItemId"`
ItemType string `json:"ItemType"`
MediaSourceID string `json:"MediaSourceId"`
Name string `json:"Name"`
NotificationType string `json:"NotificationType"`
Overview string `json:"Overview"`
PlaybackPosition string `json:"PlaybackPosition"`
PlaybackPositionTicks int64 `json:"PlaybackPositionTicks"`
ProviderMusicbrainzalbum string `json:"Provider_musicbrainzalbum"`
ProviderMusicbrainzalbumartist string `json:"Provider_musicbrainzalbumartist"`
ProviderMusicbrainzartist string `json:"Provider_musicbrainzartist"`
ProviderMusicbrainzreleasegroup string `json:"Provider_musicbrainzreleasegroup"`
ProviderMusicbrainztrack string `json:"Provider_musicbrainztrack"`
RunTime string `json:"RunTime"`
RunTimeTicks int64 `json:"RunTimeTicks"`
ServerID string `json:"ServerId"`
ServerName string `json:"ServerName"`
ServerURL string `json:"ServerUrl"`
ServerVersion string `json:"ServerVersion"`
Timestamp string `json:"Timestamp"`
UserID string `json:"UserId"`
Username string `json:"Username"`
UtcTimestamp string `json:"UtcTimestamp"`
Year int64 `json:"Year"`
}
// ParseJellyfinInput - Transform API data into a common struct. Uses MusicBrainzID primarily
func ParseJellyfinInput(userUUID string, jf JellyfinRequest, ip net.IP, tx *sql.Tx) error {
// Debugging
// fmt.Printf("%+v", jf)
// Prevents scrobbling same song twice!
cacheKey := jf.UserID + ":" + jf.Name + ":" + jf.Artist + ":" + jf.Album + ":" + jf.ServerID
redisKey := getMd5(cacheKey + userUUID)
if getRedisKeyExists(redisKey) {
return nil
}
if jf.ItemType != "Audio" {
return errors.New("Media type not audio")
}
// Safety Checks
if jf.Artist == "" {
return errors.New("Missing artist data")
}
if jf.Album == "" {
return errors.New("Missing album data")
}
if jf.Name == "" {
return errors.New("Missing track data")
}
2021-03-28 08:52:34 +00:00
// Insert artist if not exist
artist, err := insertArtist(jf.Artist, jf.ProviderMusicbrainzartist, "", tx)
2021-03-28 08:52:34 +00:00
if err != nil {
log.Printf("%+v", err)
return errors.New("Failed to map artist")
}
// Insert album if not exist
artists := []string{artist.UUID}
album, err := insertAlbum(jf.Album, jf.ProviderMusicbrainzalbum, "", artists, tx)
2021-03-28 08:52:34 +00:00
if err != nil {
log.Printf("%+v", err)
return errors.New("Failed to map album")
}
// Insert track if not exist
length := timestampToSeconds(jf.RunTime)
track, err := insertTrack(jf.Name, length, jf.ProviderMusicbrainztrack, "", album.UUID, artists, tx)
2021-03-28 08:52:34 +00:00
if err != nil {
log.Printf("%+v", err)
return errors.New("Failed to map track")
}
// Insert scrobble if not exist
timestamp := time.Now()
err = insertScrobble(userUUID, track.UUID, "jellyfin", timestamp, ip, tx)
2021-03-28 08:52:34 +00:00
if err != nil {
log.Printf("%+v", err)
return errors.New("Failed to map track")
}
// Add cache key!
ttl := time.Duration(timestampToSeconds(jf.RunTime)) * time.Second
setRedisValTtl(redisKey, "1", ttl)
2021-03-28 08:52:34 +00:00
return nil
2021-03-23 08:43:44 +00:00
}