editing playlist metadata is working now
This commit is contained in:
@@ -10,7 +10,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/dweymouth/go-jellyfin"
|
"github.com/dweymouth/go-jellyfin"
|
||||||
jellyfinCli "github.com/dweymouth/go-jellyfin"
|
|
||||||
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
"github.com/dweymouth/supersonic/backend/mediaprovider"
|
||||||
"github.com/dweymouth/supersonic/sharedutil"
|
"github.com/dweymouth/supersonic/sharedutil"
|
||||||
)
|
)
|
||||||
@@ -18,7 +17,7 @@ import (
|
|||||||
const cacheValidDurationSeconds = 60
|
const cacheValidDurationSeconds = 60
|
||||||
|
|
||||||
type JellyfinServer struct {
|
type JellyfinServer struct {
|
||||||
jellyfinCli.Client
|
jellyfin.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *JellyfinServer) MediaProvider() mediaprovider.MediaProvider {
|
func (j *JellyfinServer) MediaProvider() mediaprovider.MediaProvider {
|
||||||
@@ -54,8 +53,12 @@ func (j *jellyfinMediaProvider) DeletePlaylist(id string) error {
|
|||||||
return j.client.DeletePlaylist(id)
|
return j.client.DeletePlaylist(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *jellyfinMediaProvider) EditPlaylist(id, name, description string, public bool) error {
|
func (j *jellyfinMediaProvider) CanMakePublicPlaylist() bool {
|
||||||
return errors.New("unimplemented")
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (j *jellyfinMediaProvider) EditPlaylist(id, name, description string, public bool) error {
|
||||||
|
return j.client.UpdatePlaylistMetadata(id, name, description)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *jellyfinMediaProvider) AddPlaylistTracks(id string, trackIDsToAdd []string) error {
|
func (j *jellyfinMediaProvider) AddPlaylistTracks(id string, trackIDsToAdd []string) error {
|
||||||
@@ -271,7 +274,7 @@ func (j *jellyfinMediaProvider) GetPlaylists() ([]*mediaprovider.Playlist, error
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return sharedutil.MapSlice(pl, toPlaylist), nil
|
return sharedutil.MapSlice(pl, j.toPlaylist), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *jellyfinMediaProvider) GetPlaylist(playlistID string) (*mediaprovider.PlaylistWithTracks, error) {
|
func (j *jellyfinMediaProvider) GetPlaylist(playlistID string) (*mediaprovider.PlaylistWithTracks, error) {
|
||||||
@@ -287,7 +290,7 @@ func (j *jellyfinMediaProvider) GetPlaylist(playlistID string) (*mediaprovider.P
|
|||||||
playlist := &mediaprovider.PlaylistWithTracks{
|
playlist := &mediaprovider.PlaylistWithTracks{
|
||||||
Tracks: sharedutil.MapSlice(tr, toTrack),
|
Tracks: sharedutil.MapSlice(tr, toTrack),
|
||||||
}
|
}
|
||||||
fillPlaylist(pl, &playlist.Playlist)
|
j.fillPlaylist(pl, &playlist.Playlist)
|
||||||
return playlist, nil
|
return playlist, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,8 +348,8 @@ func (j *jellyfinMediaProvider) Scrobble(trackID string, submission bool) error
|
|||||||
return errors.New("unimplemented")
|
return errors.New("unimplemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *jellyfinMediaProvider) RescanLibrary() error {
|
func (j *jellyfinMediaProvider) RescanLibrary() error {
|
||||||
return errors.New("unimplemented")
|
return j.client.RefreshLibrary()
|
||||||
}
|
}
|
||||||
|
|
||||||
func toTrack(ch *jellyfin.Song) *mediaprovider.Track {
|
func toTrack(ch *jellyfin.Song) *mediaprovider.Track {
|
||||||
@@ -359,9 +362,14 @@ func toTrack(ch *jellyfin.Song) *mediaprovider.Track {
|
|||||||
artistNames = append(artistNames, a.Name)
|
artistNames = append(artistNames, a.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coverArtID := ch.AlbumID
|
||||||
|
if ch.ImageTags.Primary != "" {
|
||||||
|
coverArtID = ch.Id
|
||||||
|
}
|
||||||
|
|
||||||
t := &mediaprovider.Track{
|
t := &mediaprovider.Track{
|
||||||
ID: ch.Id,
|
ID: ch.Id,
|
||||||
//CoverArtID: ch.CoverArt,
|
CoverArtID: coverArtID,
|
||||||
ParentID: ch.AlbumID,
|
ParentID: ch.AlbumID,
|
||||||
Name: ch.Name,
|
Name: ch.Name,
|
||||||
Duration: int(ch.RunTimeTicks / 10_000_000),
|
Duration: int(ch.RunTimeTicks / 10_000_000),
|
||||||
@@ -424,19 +432,20 @@ func fillAlbum(a *jellyfin.Album, album *mediaprovider.Album) {
|
|||||||
album.Favorite = a.UserData.IsFavorite
|
album.Favorite = a.UserData.IsFavorite
|
||||||
}
|
}
|
||||||
|
|
||||||
func toPlaylist(p *jellyfin.Playlist) *mediaprovider.Playlist {
|
func (j *jellyfinMediaProvider) toPlaylist(p *jellyfin.Playlist) *mediaprovider.Playlist {
|
||||||
pl := &mediaprovider.Playlist{}
|
pl := &mediaprovider.Playlist{}
|
||||||
fillPlaylist(p, pl)
|
j.fillPlaylist(p, pl)
|
||||||
return pl
|
return pl
|
||||||
}
|
}
|
||||||
|
|
||||||
func fillPlaylist(p *jellyfin.Playlist, pl *mediaprovider.Playlist) {
|
func (j *jellyfinMediaProvider) fillPlaylist(p *jellyfin.Playlist, pl *mediaprovider.Playlist) {
|
||||||
pl.Name = p.Name
|
pl.Name = p.Name
|
||||||
pl.ID = p.ID
|
pl.ID = p.ID
|
||||||
pl.CoverArtID = p.ID
|
pl.CoverArtID = p.ID
|
||||||
pl.Description = p.Overview
|
pl.Description = p.Overview
|
||||||
//Owner = pl.Owner
|
|
||||||
//Public = pl.Public
|
|
||||||
pl.TrackCount = p.SongCount
|
pl.TrackCount = p.SongCount
|
||||||
pl.Duration = int(p.RunTimeTicks / 1_000_000)
|
pl.Duration = int(p.RunTimeTicks / 1_000_000)
|
||||||
|
// Jellyfin does not have public playlists
|
||||||
|
pl.Owner = j.client.LoggedInUser()
|
||||||
|
pl.Public = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ type MediaProvider interface {
|
|||||||
|
|
||||||
CreatePlaylist(name string, trackIDs []string) error
|
CreatePlaylist(name string, trackIDs []string) error
|
||||||
|
|
||||||
|
CanMakePublicPlaylist() bool
|
||||||
|
|
||||||
EditPlaylist(id, name, description string, public bool) error
|
EditPlaylist(id, name, description string, public bool) error
|
||||||
|
|
||||||
AddPlaylistTracks(id string, trackIDsToAdd []string) error
|
AddPlaylistTracks(id string, trackIDsToAdd []string) error
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ func (s *subsonicMediaProvider) DeletePlaylist(id string) error {
|
|||||||
return s.client.DeletePlaylist(id)
|
return s.client.DeletePlaylist(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *subsonicMediaProvider) CanMakePublicPlaylist() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (s *subsonicMediaProvider) EditPlaylist(id, name, description string, public bool) error {
|
func (s *subsonicMediaProvider) EditPlaylist(id, name, description string, public bool) error {
|
||||||
return s.client.UpdatePlaylist(id, map[string]string{
|
return s.client.UpdatePlaylist(id, map[string]string{
|
||||||
"name": name,
|
"name": name,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ require (
|
|||||||
fyne.io/fyne/v2 v2.4.1
|
fyne.io/fyne/v2 v2.4.1
|
||||||
github.com/20after4/configdir v0.1.1
|
github.com/20after4/configdir v0.1.1
|
||||||
github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1
|
github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1
|
||||||
github.com/dweymouth/go-jellyfin v0.0.0-20231113023851-8cce8cd32c59
|
github.com/dweymouth/go-jellyfin v0.0.0-20231113161404-7697fc026881
|
||||||
github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee
|
github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee
|
||||||
github.com/dweymouth/go-subsonic v0.0.0-20231105161622-54b5aec28363
|
github.com/dweymouth/go-subsonic v0.0.0-20231105161622-54b5aec28363
|
||||||
github.com/fsnotify/fsnotify v1.6.0
|
github.com/fsnotify/fsnotify v1.6.0
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1 h1:mGvOb3zxl4vCLv+
|
|||||||
github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1/go.mod h1:ZNCLJfehvEf34B7BbLKjgpsL9lyW7q938w/GY1XgV4E=
|
github.com/deluan/sanitize v0.0.0-20230310221930-6e18967d9fc1/go.mod h1:ZNCLJfehvEf34B7BbLKjgpsL9lyW7q938w/GY1XgV4E=
|
||||||
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231110162149-a0e470497555 h1:8S+d0LuwdTUEipEzFeXp8rNwTQD47dBdDOg9+FI1+Vw=
|
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231110162149-a0e470497555 h1:8S+d0LuwdTUEipEzFeXp8rNwTQD47dBdDOg9+FI1+Vw=
|
||||||
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231110162149-a0e470497555/go.mod h1:AWM1iPM2YfliduZ4u/kQzP9E6ARIWm0gg+57GpYzWro=
|
github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231110162149-a0e470497555/go.mod h1:AWM1iPM2YfliduZ4u/kQzP9E6ARIWm0gg+57GpYzWro=
|
||||||
github.com/dweymouth/go-jellyfin v0.0.0-20231113023851-8cce8cd32c59 h1:qpIwMxwEYlE+OEB99FVaaIxaZ7RO6VW3pvOU1WFL9f0=
|
github.com/dweymouth/go-jellyfin v0.0.0-20231113161404-7697fc026881 h1:CAbdL67fYdR3anSJB6VJDqXURAP1dpeUfS65h9Moq8g=
|
||||||
github.com/dweymouth/go-jellyfin v0.0.0-20231113023851-8cce8cd32c59/go.mod h1:BMwS4vdjEYf1gmjPGSKCzWP/I6YlI6fkefJ9nsjBjaU=
|
github.com/dweymouth/go-jellyfin v0.0.0-20231113161404-7697fc026881/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 h1:ZGyJ6wp7CAfT31BugypcF/TPKEy2RrGR9JFq1JOjOpY=
|
||||||
github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee/go.mod h1:Ov0ieN90M7i+0k3OxhA/g1dozGs+UcPHDsMKqPgRDk0=
|
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-20231105161622-54b5aec28363 h1:MIH7MAWWPPVRKEKxz+RJubn+ycyQPimHn1Zvoxs1KRI=
|
github.com/dweymouth/go-subsonic v0.0.0-20231105161622-54b5aec28363 h1:MIH7MAWWPPVRKEKxz+RJubn+ycyQPimHn1Zvoxs1KRI=
|
||||||
|
|||||||
@@ -279,7 +279,8 @@ func (m *Controller) DoAddTracksToPlaylistWorkflow(trackIDs []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Controller) DoEditPlaylistWorkflow(playlist *mediaprovider.Playlist) {
|
func (m *Controller) DoEditPlaylistWorkflow(playlist *mediaprovider.Playlist) {
|
||||||
dlg := dialogs.NewEditPlaylistDialog(playlist)
|
canMakePublic := m.App.ServerManager.Server.CanMakePublicPlaylist()
|
||||||
|
dlg := dialogs.NewEditPlaylistDialog(playlist, canMakePublic)
|
||||||
pop := widget.NewModalPopUp(dlg, m.MainWindow.Canvas())
|
pop := widget.NewModalPopUp(dlg, m.MainWindow.Canvas())
|
||||||
m.ClosePopUpOnEscape(pop)
|
m.ClosePopUpOnEscape(pop)
|
||||||
dlg.OnCanceled = func() {
|
dlg.OnCanceled = func() {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ type EditPlaylistDialog struct {
|
|||||||
container *fyne.Container
|
container *fyne.Container
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEditPlaylistDialog(playlist *mediaprovider.Playlist) *EditPlaylistDialog {
|
func NewEditPlaylistDialog(playlist *mediaprovider.Playlist, showPublicCheck bool) *EditPlaylistDialog {
|
||||||
e := &EditPlaylistDialog{
|
e := &EditPlaylistDialog{
|
||||||
IsPublic: playlist.Public,
|
IsPublic: playlist.Public,
|
||||||
Name: playlist.Name,
|
Name: playlist.Name,
|
||||||
@@ -32,6 +32,7 @@ func NewEditPlaylistDialog(playlist *mediaprovider.Playlist) *EditPlaylistDialog
|
|||||||
e.ExtendBaseWidget(e)
|
e.ExtendBaseWidget(e)
|
||||||
|
|
||||||
isPublicCheck := widget.NewCheckWithData("Public", binding.BindBool(&e.IsPublic))
|
isPublicCheck := widget.NewCheckWithData("Public", binding.BindBool(&e.IsPublic))
|
||||||
|
isPublicCheck.Hidden = !showPublicCheck
|
||||||
nameEntry := widget.NewEntryWithData(binding.BindString(&e.Name))
|
nameEntry := widget.NewEntryWithData(binding.BindString(&e.Name))
|
||||||
descriptionEntry := widget.NewEntryWithData(binding.BindString(&e.Description))
|
descriptionEntry := widget.NewEntryWithData(binding.BindString(&e.Description))
|
||||||
deleteBtn := widget.NewButton("Delete Playlist", func() {
|
deleteBtn := widget.NewButton("Delete Playlist", func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user