diff --git a/backend/mediaprovider/jellyfin/jellyfinmediaprovider.go b/backend/mediaprovider/jellyfin/jellyfinmediaprovider.go index 002fe80..dd862d9 100644 --- a/backend/mediaprovider/jellyfin/jellyfinmediaprovider.go +++ b/backend/mediaprovider/jellyfin/jellyfinmediaprovider.go @@ -440,6 +440,7 @@ func fillAlbum(a *jellyfin.Album, album *mediaprovider.Album) { album.TrackCount = a.ChildCount album.Genres = a.Genres album.Favorite = a.UserData.IsFavorite + album.ReleaseTypes = mediaprovider.ReleaseTypeAlbum } func (j *jellyfinMediaProvider) toPlaylist(p *jellyfin.Playlist) *mediaprovider.Playlist { diff --git a/backend/mediaprovider/model.go b/backend/mediaprovider/model.go index 9e10253..2c1aa81 100644 --- a/backend/mediaprovider/model.go +++ b/backend/mediaprovider/model.go @@ -1,16 +1,47 @@ package mediaprovider +// Bit field flag for the ReleaseTypes property +type ReleaseType = int32 + +// Bit field of release types +type ReleaseTypes = int32 + +// Set of possible release types +// Taken from Picard: +// +// (a) https://picard-docs.musicbrainz.org/en/config/options_releases.html +// (b) https://musicbrainz.org/doc/Release_Group/Type +const ( + ReleaseTypeAlbum ReleaseType = 0x0001 + ReleaseTypeAudiobook ReleaseType = 0x0002 + ReleaseTypeAudioDrama ReleaseType = 0x0004 + ReleaseTypeBroadcast ReleaseType = 0x0008 + ReleaseTypeCompilation ReleaseType = 0x0010 + ReleaseTypeDemo ReleaseType = 0x0020 + ReleaseTypeDJMix ReleaseType = 0x0040 + ReleaseTypeEP ReleaseType = 0x0080 + ReleaseTypeFieldRecording ReleaseType = 0x0100 + ReleaseTypeInterview ReleaseType = 0x0200 + ReleaseTypeLive ReleaseType = 0x0400 + ReleaseTypeMixtape ReleaseType = 0x0800 + ReleaseTypeRemix ReleaseType = 0x1000 + ReleaseTypeSingle ReleaseType = 0x2000 + ReleaseTypeSoundtrack ReleaseType = 0x4000 + ReleaseTypeSpokenWord ReleaseType = 0x8000 +) + type Album struct { - ID string - CoverArtID string - Name string - Duration int - ArtistIDs []string - ArtistNames []string - Year int - Genres []string - TrackCount int - Favorite bool + ID string + CoverArtID string + Name string + Duration int + ArtistIDs []string + ArtistNames []string + Year int + Genres []string + TrackCount int + Favorite bool + ReleaseTypes ReleaseTypes } type AlbumWithTracks struct { diff --git a/backend/mediaprovider/subsonic/subsonicmediaprovider.go b/backend/mediaprovider/subsonic/subsonicmediaprovider.go index 44b51d2..c43a058 100644 --- a/backend/mediaprovider/subsonic/subsonicmediaprovider.go +++ b/backend/mediaprovider/subsonic/subsonicmediaprovider.go @@ -6,6 +6,7 @@ import ( "io" "math" "strconv" + "strings" "sync" "time" @@ -404,6 +405,54 @@ func fillAlbum(subAlbum *subsonic.AlbumID3, album *mediaprovider.Album) { album.TrackCount = subAlbum.SongCount album.Genres = genres album.Favorite = !subAlbum.Starred.IsZero() + album.ReleaseTypes = normalizeReleaseTypes(subAlbum.ReleaseTypes) + if subAlbum.IsCompilation { + album.ReleaseTypes |= mediaprovider.ReleaseTypeCompilation + } +} + +func normalizeReleaseTypes(releaseTypes []string) mediaprovider.ReleaseTypes { + var mpReleaseTypes mediaprovider.ReleaseTypes + for _, t := range releaseTypes { + switch strings.ToLower(strings.ReplaceAll(t, " ", "")) { + case "album": + mpReleaseTypes |= mediaprovider.ReleaseTypeAlbum + case "audiobook": + mpReleaseTypes |= mediaprovider.ReleaseTypeAudiobook + case "audiodrama": + mpReleaseTypes |= mediaprovider.ReleaseTypeAudioDrama + case "broadcast": + mpReleaseTypes |= mediaprovider.ReleaseTypeBroadcast + case "compilation": + mpReleaseTypes |= mediaprovider.ReleaseTypeCompilation + case "demo": + mpReleaseTypes |= mediaprovider.ReleaseTypeDemo + case "djmix": + mpReleaseTypes |= mediaprovider.ReleaseTypeDJMix + case "ep": + mpReleaseTypes |= mediaprovider.ReleaseTypeEP + case "fieldrecording": + mpReleaseTypes |= mediaprovider.ReleaseTypeFieldRecording + case "interview": + mpReleaseTypes |= mediaprovider.ReleaseTypeInterview + case "live": + mpReleaseTypes |= mediaprovider.ReleaseTypeLive + case "mixtape": + mpReleaseTypes |= mediaprovider.ReleaseTypeMixtape + case "remix": + mpReleaseTypes |= mediaprovider.ReleaseTypeRemix + case "single": + mpReleaseTypes |= mediaprovider.ReleaseTypeSingle + case "soundtrack": + mpReleaseTypes |= mediaprovider.ReleaseTypeSoundtrack + case "spokenword": + mpReleaseTypes |= mediaprovider.ReleaseTypeSpokenWord + } + } + if mpReleaseTypes == 0 { + return mediaprovider.ReleaseTypeAlbum + } + return mpReleaseTypes } func toArtistFromID3(ar *subsonic.ArtistID3) *mediaprovider.Artist { diff --git a/go.mod b/go.mod index 543e82e..0f7f008 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1 github.com/dweymouth/go-jellyfin v0.0.0-20231116161116-e800860bdacc github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee - github.com/dweymouth/go-subsonic v0.0.0-20231216015633-3797c9b3d94d + github.com/dweymouth/go-subsonic v0.0.0-20231216190641-c537a36d520c github.com/fsnotify/fsnotify v1.6.0 github.com/godbus/dbus/v5 v5.1.0 github.com/google/uuid v1.3.0 diff --git a/go.sum b/go.sum index 9625e37..35e169d 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,8 @@ github.com/dweymouth/go-jellyfin v0.0.0-20231116161116-e800860bdacc h1:wJy4U12Ys github.com/dweymouth/go-jellyfin v0.0.0-20231116161116-e800860bdacc/go.mod h1:BMwS4vdjEYf1gmjPGSKCzWP/I6YlI6fkefJ9nsjBjaU= github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee h1:ZGyJ6wp7CAfT31BugypcF/TPKEy2RrGR9JFq1JOjOpY= github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee/go.mod h1:Ov0ieN90M7i+0k3OxhA/g1dozGs+UcPHDsMKqPgRDk0= -github.com/dweymouth/go-subsonic v0.0.0-20231216015633-3797c9b3d94d h1:E9heA09mvlF+i+fH8Cow7NgRpQ+cbJQkdFL0OtFo624= -github.com/dweymouth/go-subsonic v0.0.0-20231216015633-3797c9b3d94d/go.mod h1:OWtcumdQsan8uM6wmx6PqKhldaCthH10CQ+vb+94kzo= +github.com/dweymouth/go-subsonic v0.0.0-20231216190641-c537a36d520c h1:48xbtXN53Rrru1Y3Ywd/FIVohH4NoRMzvxEY4aY1s0M= +github.com/dweymouth/go-subsonic v0.0.0-20231216190641-c537a36d520c/go.mod h1:OWtcumdQsan8uM6wmx6PqKhldaCthH10CQ+vb+94kzo= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=