/// <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); } }
/// <summary> /// Clear the data held by this model /// </summary> public static void ClearModel() { Artists.Clear(); UnfilteredArtists.Clear(); ArtistsAndAlbums.Clear(); LibraryId = -1; FilterSelector.CurrentFilter = null; FilteredAlbumsIds.Clear(); BaseModel.SortSelector.SetActiveSortOrder(SortSelector.SortType.alphabetic); // This also sets the sort order to alphabetic ascending FastScrollSections = null; FastScrollSectionLookup = null; BaseModel.Clear(); }
/// <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)); }
/// <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; } }
/// <summary> /// Get an existing Artist or create a new one. /// </summary> /// <param name="artistName"></param> /// <returns></returns> private async Task <Artist> GetArtistToHoldSongsAsync(string artistName) { // Find the Artist for this song. The 'scanLibrary' can be used for this search as it is already fully populated with the // artists Artist songArtist = artistsInLibrary.GetValueOrDefault(artistName.ToUpper()); Logger.Log(string.Format("Artist: {0} {1}", artistName, (songArtist != null) ? "found" : "not found creating in db")); if (songArtist == null) { // Create a new Artist and add it to the database songArtist = new Artist() { Name = artistName, ArtistAlbums = new List <ArtistAlbum>(), LibraryId = scanLibrary }; await Artists.AddArtistAsync(songArtist); // Add it to the collection for this library only artistsInLibrary[songArtist.Name.ToUpper()] = songArtist; } return(songArtist); }
/// <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); }