예제 #1
0
        /// <summary>
        /// Add a list of songs to the playlist
        /// </summary>
        /// <param name="playlist"></param>
        /// <param name="songs"></param>
        public void AddSongs(IEnumerable <Song> songs)
        {
            List <SongPlaylistItem> songPlaylistItems = new();

            // For each song create a PlayListItem and add to the PlayList
            foreach (Song song in songs)
            {
                song.Artist = Artists.GetArtistById(ArtistAlbums.GetArtistAlbumById(song.ArtistAlbumId).ArtistId);

                SongPlaylistItem itemToAdd = new()
                {
                    Artist     = song.Artist,
                    PlaylistId = Id,
                    Song       = song,
                    SongId     = song.Id,
                    Index      = PlaylistItems.Count
                };

                songPlaylistItems.Add(itemToAdd);
                PlaylistItems.Add(itemToAdd);
            }

            // No need to wait for this
            DbAccess.InsertAllAsync(songPlaylistItems);
        }
예제 #2
0
        /// <summary>
        /// Read all the managed collections and then tell any registered listeners
        /// </summary>
        private static async void ReadManagedCollections()
        {
            await Songs.GetDataAsync();

            await Albums.GetDataAsync();

            await Sources.GetDataAsync();

            await Artists.GetDataAsync();

            await ArtistAlbums.GetDataAsync();

            await Libraries.GetDataAsync();

            await Playback.GetDataAsync();

            await Playlists.GetDataAsync();

            await Autoplays.GetDataAsync();

            await Tags.GetDataAsync();

            await TaggedAlbums.GetDataAsync();

            await GenrePopulations.GetDataAsync();

            // Carry out some one-off data linking
            await PopulateArtistsAsync();

            await FilterManagementController.FormGenreTagsAsync();

            DataAvailable = true;
            new StorageDataAvailableMessage().Send();
        }
예제 #3
0
        /// <summary>
        /// Get an existing or new ArtistAlbum entry to hold the songs associated with a particular Artist
        /// </summary>
        /// <param name="songArtist"></param>
        /// <param name="songAlbum"></param>
        /// <returns></returns>
        private async Task <ArtistAlbum> GetArtistAlbumToHoldSongsAsync(Artist songArtist, Album songAlbum)
        {
            ArtistAlbum songArtistAlbum = null;

            // Find an existing or create a new ArtistAlbum entry
            songArtistAlbum = songArtist.ArtistAlbums.SingleOrDefault(p => (p.Name.ToUpper() == songAlbum.Name.ToUpper()));

            Logger.Log(string.Format("ArtistAlbum: {0} {1}", songAlbum.Name, (songArtistAlbum != null) ? "found" : "not found creating in db"));

            if (songArtistAlbum == null)
            {
                // Create a new ArtistAlbum and add it to the database and the Artist
                songArtistAlbum = new ArtistAlbum()
                {
                    Name   = songAlbum.Name, Album = songAlbum, Songs = new List <Song>(), ArtistId = songArtist.Id,
                    Artist = songArtist, AlbumId = songAlbum.Id
                };
                await ArtistAlbums.AddArtistAlbumAsync(songArtistAlbum);

                songArtist.ArtistAlbums.Add(songArtistAlbum);
            }
            else
            {
                // Get the children of the existing ArtistAlbum
                if (songArtistAlbum.Songs == null)
                {
                    songArtistAlbum.Songs = Songs.GetArtistAlbumSongs(songArtistAlbum.Id);
                }
            }

            return(songArtistAlbum);
        }
예제 #4
0
        /// <summary>
        /// Duplicate the SongPlaylist in the specified library
        /// </summary>
        /// <param name="playlistToDuplicate"></param>
        /// <returns></returns>
        private static async void DuplicateSongPlaylistAsync(SongPlaylist playlistToDuplicate, int libraryId)
        {
            // Attempt to find matching songs for each SongPlaylistItem in the SongPlaylist
            // Need to access the songs via the Sources associated with the Library
            List <Source> sources = Sources.GetSourcesForLibrary(libraryId);

            // Keep track of the matching songs
            List <Song> songsToAdd = new();

            foreach (SongPlaylistItem item in playlistToDuplicate.PlaylistItems)
            {
                Song matchingSong = null;
                int  sourceIndex  = 0;

                while ((matchingSong == null) && (sourceIndex < sources.Count))
                {
                    // Get a list of all the songs with matching Titles in the source
                    List <Song> matchingTitles = Songs.GetSourceSongsWithName(sources[sourceIndex++].Id, item.Song.Title);

                    // Now for each song access the associated artist
                    int titleIndex = 0;
                    while ((matchingSong == null) && (titleIndex < matchingTitles.Count))
                    {
                        Artist nameCheck = Artists.GetArtistById(ArtistAlbums.GetArtistAlbumById(matchingTitles[titleIndex].ArtistAlbumId).ArtistId);

                        // Correct name?
                        if (nameCheck.Name == item.Artist.Name)
                        {
                            matchingSong = matchingTitles[titleIndex];
                            songsToAdd.Add(matchingSong);

                            // Make sure that the Artist is stored with the song
                            matchingSong.Artist = nameCheck;
                        }

                        titleIndex++;
                    }
                }
            }

            // Only create the playlist if at least one of the songs was found
            if (songsToAdd.Count > 0)
            {
                SongPlaylist duplicatedPlaylist = new() { Name = playlistToDuplicate.Name, LibraryId = libraryId };

                // Wait for the playlist to be added as we're going to use its id
                await Playlists.AddPlaylistAsync(duplicatedPlaylist);

                // Add the songs to the new SongPlaylist.
                duplicatedPlaylist.AddSongs(songsToAdd);
            }
        }
예제 #5
0
        /// <summary>
        /// Get the PlaylistItems and associated songs for this playlist
        /// </summary>
        /// <param name="playlistItems"></param>
        public void GetContents(IEnumerable <SongPlaylistItem> playlistItems)
        {
            // Get all the SongPlaylistItem entries associated with this SongPlaylist and then the Song entries for each of them
            PlaylistItems.AddRange(playlistItems.Where(item => item.PlaylistId == Id));

            foreach (SongPlaylistItem playlistItem in PlaylistItems)
            {
                playlistItem.Song        = Songs.GetSongById(playlistItem.SongId);
                playlistItem.Artist      = Artists.GetArtistById(ArtistAlbums.GetArtistAlbumById(playlistItem.Song.ArtistAlbumId).ArtistId);
                playlistItem.Song.Artist = playlistItem.Artist;
            }

            PlaylistItems.Sort((a, b) => a.Index.CompareTo(b.Index));
        }
예제 #6
0
        /// <summary>
        /// Called to handle the command.
        /// </summary>
        /// <param name="commandIdentity"></param>
        public override void HandleCommand(int commandIdentity)
        {
            List <string> selectedGenres = new List <string>();

            // If an Artist has been selected then the starting point for generation will be the albums associated with the Artist.
            // If an Album has been selected then that album will be the starting point.
            // If a Song has been selected then that song will be the starting point.
            if (selectedObjects.Artists.Count > 0)
            {
                // Get all the genres associated with all the selected artists
                foreach (Artist selectedArtist in selectedObjects.Artists)
                {
                    foreach (ArtistAlbum artistAlbum in selectedArtist.ArtistAlbums)
                    {
                        selectedGenres.AddRange(artistAlbum.Album.Genre.Split(';').ToList());
                    }
                }
            }
            else if (selectedObjects.ArtistAlbums.Count > 0)
            {
                // Get all the genres associated with the albums from all the selected artistalbums
                foreach (ArtistAlbum selectedArtistAlbum in selectedObjects.ArtistAlbums)
                {
                    selectedGenres.AddRange(selectedArtistAlbum.Album.Genre.Split(';').ToList());
                }
            }
            else if (selectedObjects.Albums.Count > 0)
            {
                // Get all the genres associated with the albums from all the selected albums
                foreach (Album selectedAlbum in selectedObjects.Albums)
                {
                    selectedGenres.AddRange(selectedAlbum.Genre.Split(';').ToList());
                }
            }
            else if (selectedObjects.Songs.Count > 0)
            {
                foreach (Song selectedSong in selectedObjects.Songs)
                {
                    selectedGenres.AddRange(ArtistAlbums.GetArtistAlbumById(selectedSong.ArtistAlbumId).Album.Genre.Split(';').ToList());
                }
            }

            // Make genre list unique
            selectedGenres = selectedGenres.Distinct().ToList();

            AutoplayController.StartAutoplay(selectedObjects.Songs, selectedGenres, commandIdentity == Resource.Id.auto_play);

            commandCallback.PerformAction();
        }
예제 #7
0
        /// <summary>
        /// Categorise the specified selected objects
        /// </summary>
        /// <param name="selectedObjects"></param>
        public GroupedSelection(IEnumerable <object> selectedObjects)
        {
            // Save the unprocessed objects.
            SelectedObjects = selectedObjects;

            // Group the objects into sets of Song, PlaylistItem, IPlaylist, Artist, ArtistAlbum, Album and Genre (string) items
            foreach (object selectedObject in selectedObjects)
            {
                if (selectedObject is Song song)
                {
                    Songs.Add(song);
                }
                else if (selectedObject is PlaylistItem playlistItem)
                {
                    PlaylistItems.Add(playlistItem);
                }
                else if (selectedObject is Playlist playlist)
                {
                    Playlists.Add(playlist);
                }
                else if (selectedObject is Artist artist)
                {
                    Artists.Add(artist);
                }
                else if (selectedObject is ArtistAlbum artistAlbum)
                {
                    ArtistAlbums.Add(artistAlbum);
                }
                else if (selectedObject is Album album)
                {
                    Albums.Add(album);
                }
                else if (selectedObject is string str)
                {
                    Genres.Add(str);
                }
            }

            // Determine if there is a parent playlist
            if (PlaylistItems.Count > 0)
            {
                ParentPlaylist = DBTest.Playlists.GetParentPlaylist(PlaylistItems[0]);
            }
        }
        /// <summary>
        /// Clear the contents of the specified library
        /// </summary>
        /// <param name="libraryToClear"></param>
        /// <returns></returns>
        public static void ClearLibrary(Library libraryToClear)
        {
            int libId = libraryToClear.Id;

            // Delete all the artists in the library and their associated ArtistAlbum entries
            List <Artist> artists = Artists.ArtistCollection.Where(art => art.LibraryId == libId).ToList();

            Artists.DeleteArtists(artists);

            ArtistAlbums.DeleteArtistAlbums(
                ArtistAlbums.ArtistAlbumCollection.Where(artAlb => artists.Any(art => art.Id == artAlb.ArtistId)).Distinct().ToList());

            // Delete all the albums in the library and any tags associated with them
            List <Album> albums = Albums.AlbumCollection.Where(alb => alb.LibraryId == libId).ToList();

            Albums.DeleteAlbums(albums);

            // We can use the FilterManagementController to carry out the Tag deletions.
            new AlbumsDeletedMessage()
            {
                DeletedAlbumIds = albums.Select(alb => alb.Id).ToList()
            }.Send();

            // Delete all the user playlists and thier contents
            Playlists.GetPlaylistsForLibrary(libId).ForEach(play => Playlists.DeletePlaylist(play));

            // Delete the contents of the NowPlayingList but keep the playlist itself
            Playlist nowPlaying = Playlists.GetNowPlayingPlaylist(libId);

            nowPlaying.Clear();
            nowPlaying.SongIndex = -1;

            // Delete all the songs in each of the sources associated with the library
            List <Source> sources = Sources.GetSourcesForLibrary(libId);

            foreach (Source source in sources)
            {
                Songs.DeleteSongs(Songs.GetSourceSongs(source.Id));
                source.Songs = null;
            }
        }
예제 #9
0
        /// <summary>
        /// Called to determine whether a song that has been scanned requires adding to the library, or just an existing entry updated
        /// </summary>
        /// <param name="song"></param>
        /// <returns></returns>
        private async Task <bool> DoesSongRequireAdding(ScannedSong song)
        {
            bool needsAdding = true;

            // Lookup the path of this song in the dictionary
            if ((songLookup.TryGetValue(song.SourcePath, out Song matchedSong) == true) && (matchedSong.ScanAction == Song.ScanActionType.Differ))
            {
                // The library is about to be changed in some way so set the modified flag
                LibraryModified = true;

                // Need to check whether the matched Artist or Album names have changed. If they have then treat this as a new song and mark
                // the matched song for deletion
                ArtistAlbum matchedArtistAlbum = ArtistAlbums.GetArtistAlbumById(matchedSong.ArtistAlbumId);
                Artist      matchedArtist      = Artists.GetArtistById(matchedArtistAlbum.ArtistId);

                // If the artist or album name has changed then treat this as a new song. Otherwise update the existing song in the library
                if ((matchedArtist.Name.ToUpper() != song.ArtistName.ToUpper()) || (matchedArtistAlbum.Name.ToUpper() != song.Tags.Album.ToUpper()))
                {
                    // The existing song needs to be deleted now.
                    // If the song is not deleted then there will be more than one associated with the same storage location.
                    // This is much less complicated than trying to move the existing song to a new Artist or Album
                    // If an Artist has been deleted due to this song deletion then remove it from the dictionary being used here
                    Artist deletedArtist = LibraryScanController.DeleteSong(matchedSong);
                    if (deletedArtist != null)
                    {
                        artistsInLibrary.Remove(deletedArtist.Name.ToUpper());
                    }

                    matchedSong.ScanAction = Song.ScanActionType.Matched;
                }
                else
                {
                    // No need to add a new song, update the existing one
                    needsAdding = false;

                    matchedSong.Length       = song.Length;
                    matchedSong.ModifiedTime = song.Modified;
                    matchedSong.Title        = song.Tags.Title;
                    matchedSong.Track        = song.Track;
                    await ConnectionDetailsModel.AsynchConnection.UpdateAsync(matchedSong);

                    // Check if the year or genre fields on the album needs updating
                    // Don't update the Album if it is a 'various artists' album as the these fields is not applicable
                    Album matchedAlbum = Albums.GetAlbumById(matchedArtistAlbum.AlbumId);

                    if (matchedAlbum.ArtistName != SongStorage.VariousArtistsString)
                    {
                        // Update the stored year if it is different to the artist year and the artist year is defined.
                        // Log when a valid year is overwritten by different year
                        if (matchedAlbum.Year != song.Year)
                        {
                            if (song.Year != 0)
                            {
                                matchedAlbum.Year = song.Year;
                                await ConnectionDetailsModel.AsynchConnection.UpdateAsync(matchedAlbum);
                            }
                        }

                        if (song.Tags.Genre.Length > 0)
                        {
                            // If this album does not already have a genre, or the genre has been changed then set it now
                            if ((matchedAlbum.Genre == null) || (matchedAlbum.Genre != song.Tags.Genre))
                            {
                                matchedAlbum.Genre = song.Tags.Genre;
                                await ConnectionDetailsModel.AsynchConnection.UpdateAsync(matchedAlbum);
                            }
                        }
                    }
                }
            }

            return(needsAdding);
        }