diff --git a/api/responses/responses.go b/api/responses/responses.go index 6f53b1fe3..c6bf9e4a8 100644 --- a/api/responses/responses.go +++ b/api/responses/responses.go @@ -95,8 +95,6 @@ type Playlist struct { - - diff --git a/scanner/importer.go b/scanner/importer.go index 5645cce9e..69e39aec5 100644 --- a/scanner/importer.go +++ b/scanner/importer.go @@ -19,6 +19,7 @@ type Scanner interface { MediaFiles() map[string]*domain.MediaFile Albums() map[string]*domain.Album Artists() map[string]*domain.Artist + Playlists() map[string]*domain.Playlist } type tempIndex map[string]domain.ArtistInfo @@ -32,6 +33,7 @@ func StartImport() { albumRepo: persistence.NewAlbumRepository(), artistRepo: persistence.NewArtistRepository(), idxRepo: persistence.NewArtistIndexRepository(), + plsRepo: persistence.NewPlaylistRepository(), propertyRepo: persistence.NewPropertyRepository(), } i.Run() @@ -46,6 +48,7 @@ type Importer struct { albumRepo domain.AlbumRepository artistRepo domain.ArtistRepository idxRepo domain.ArtistIndexRepository + plsRepo domain.PlaylistRepository propertyRepo engine.PropertyRepository lastScan time.Time } @@ -59,7 +62,8 @@ func (i *Importer) Run() { beego.Debug("Found", total, "tracks,", len(i.scanner.MediaFiles()), "songs,", len(i.scanner.Albums()), "albums,", - len(i.scanner.Artists()), "artists") + len(i.scanner.Artists()), "artists", + len(i.scanner.Playlists()), "playlists") } if err := i.importLibrary(); err != nil { beego.Error("Error persisting data:", err) @@ -83,6 +87,7 @@ func (i *Importer) importLibrary() (err error) { mfs := make(domain.MediaFiles, len(i.scanner.MediaFiles())) als := make(domain.Albums, len(i.scanner.Albums())) ars := make(domain.Artists, len(i.scanner.Artists())) + pls := make(domain.Playlists, len(i.scanner.Playlists())) beego.Debug("Saving updated data") j := 0 @@ -119,6 +124,15 @@ func (i *Importer) importLibrary() (err error) { i.collectIndex(indexGroups, ar, artistIndex) } + j = 0 + for _, pl := range i.scanner.Playlists() { + pls[j] = *pl + j++ + if err := i.plsRepo.Put(pl); err != nil { + beego.Error(err) + } + } + if err = i.saveIndex(artistIndex); err != nil { beego.Error(err) } @@ -133,6 +147,9 @@ func (i *Importer) importLibrary() (err error) { if err := i.artistRepo.PurgeInactive(&ars); err != nil { beego.Error(err) } + if err := i.plsRepo.PurgeInactive(&pls); err != nil { + beego.Error(err) + } c, _ := i.artistRepo.CountAll() beego.Info("Total Artists in database:", c) @@ -140,6 +157,8 @@ func (i *Importer) importLibrary() (err error) { beego.Info("Total Albums in database:", c) c, _ = i.mfRepo.CountAll() beego.Info("Total MediaFiles in database:", c) + c, _ = i.plsRepo.CountAll() + beego.Info("Total Playlists in database:", c) if err == nil { millis := time.Now().UnixNano() / int64(time.Millisecond) diff --git a/scanner/itunes_scanner.go b/scanner/itunes_scanner.go index e1b7a3d89..039c36671 100644 --- a/scanner/itunes_scanner.go +++ b/scanner/itunes_scanner.go @@ -22,6 +22,7 @@ type ItunesScanner struct { mediaFiles map[string]*domain.MediaFile albums map[string]*domain.Album artists map[string]*domain.Artist + playlists map[string]*domain.Playlist lastModifiedSince time.Time } @@ -39,6 +40,7 @@ func (s *ItunesScanner) ScanLibrary(lastModifiedSince time.Time, path string) (i s.mediaFiles = make(map[string]*domain.MediaFile) s.albums = make(map[string]*domain.Album) s.artists = make(map[string]*domain.Artist) + s.playlists = make(map[string]*domain.Playlist) i := 0 for _, t := range l.Tracks { @@ -52,6 +54,12 @@ func (s *ItunesScanner) ScanLibrary(lastModifiedSince time.Time, path string) (i beego.Debug("Processed", i, "tracks.", len(s.artists), "artists,", len(s.albums), "albums", len(s.mediaFiles), "songs") } } + + for _, p := range l.Playlists { + s.collectPlaylists(&p) + } + beego.Debug("Processed", len(l.Playlists), "playlists.") + return len(l.Tracks), nil } @@ -64,6 +72,28 @@ func (s *ItunesScanner) Albums() map[string]*domain.Album { func (s *ItunesScanner) Artists() map[string]*domain.Artist { return s.artists } +func (s *ItunesScanner) Playlists() map[string]*domain.Playlist { + return s.playlists +} + +func (s *ItunesScanner) collectPlaylists(p *itl.Playlist) { + if p.Master || p.Music { + return + } + pl := &domain.Playlist{} + pl.Id = strconv.Itoa(p.PlaylistID) + pl.Name = p.Name + pl.Tracks = make([]string, 0, len(p.PlaylistItems)) + for _, item := range p.PlaylistItems { + id := strconv.Itoa(item.TrackID) + if _, found := s.mediaFiles[id]; found { + pl.Tracks = append(pl.Tracks, id) + } + } + if len(pl.Tracks) > 0 { + s.playlists[pl.Id] = pl + } +} func (s *ItunesScanner) collectMediaFiles(t *itl.Track) *domain.MediaFile { mf := &domain.MediaFile{}