Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Delete the specified ArtistAlbum from the storage and the collections
 /// </summary>
 /// <param name="artistAlbumToDelete"></param>
 /// <returns></returns>
 public static void DeleteArtistAlbum(ArtistAlbum artistAlbumToDelete)
 {
     // No need to wait for the ArtistAlbum to be deleted from storage
     DbAccess.DeleteAsync(artistAlbumToDelete);
     ArtistAlbumCollection.Remove(artistAlbumToDelete);
     IdLookup.Remove(artistAlbumToDelete.Id);
 }
Exemplo n.º 3
0
 public void GetArtistAlbumSongs(ArtistAlbum artistAlbum)
 {
     if (artistAlbum.Songs == null)
     {
         artistAlbum.Songs = Songs.GetArtistAlbumSongs(artistAlbum.Id);
         artistAlbum.Songs.Sort((a, b) => a.Track.CompareTo(b.Track));
     }
 }
Exemplo n.º 4
0
        /// <summary>
        /// Add a new ArtistAlbum to the storage and the local collections
        /// </summary>
        /// <param name="artistAlbumToAdd"></param>
        public static async Task AddArtistAlbumAsync(ArtistAlbum artistAlbumToAdd)
        {
            ArtistAlbumCollection.Add(artistAlbumToAdd);

            // Need to wait for the ArtistAlbum to be added as that will set its ID
            await DbAccess.InsertAsync(artistAlbumToAdd);

            IdLookup[artistAlbumToAdd.Id] = artistAlbumToAdd;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Either find an existing album or create a new album to hold the songs.
        /// If all songs are from the same artist then check is there is an existing album of the same name associated with that artist.
        /// If the songs are from different artists then check in the "Various Artists" artist.
        /// These artists may not exist at this stage
        /// </summary>
        /// <returns></returns>
        private async Task <Album> GetAlbumToHoldSongsAsync(ScannedAlbum album)
        {
            Album songAlbum = null;

            string artistName = (album.SingleArtist == true) ? album.Songs[0].ArtistName : VariousArtistsString;

            // Check if the artist already exists in the library.
            Artist songArtist = artistsInLibrary.GetValueOrDefault(artistName.ToUpper());

            // If the artist exists then check for existing album. The artist will hold ArtistAlbum entries rather than Album entries, but the ArtistAlbum entries
            // have the same name as the albums. Cannot just use the album name as that may not be unique.
            if (songArtist != null)
            {
                ArtistAlbum songArtistAlbum = songArtist.ArtistAlbums.SingleOrDefault(p => (p.Name.ToUpper() == album.Songs[0].Tags.Album.ToUpper()));
                if (songArtistAlbum != null)
                {
                    songAlbum = songArtistAlbum.Album;

                    // The rest of the code expects the Album to have its songs populated, so check here
                    songAlbum.GetSongs();
                }
            }

            Logger.Log(string.Format("Album: {0} {1} for artist {2}", album.Name, (songAlbum != null) ? "found" : "not found", artistName));

            // If no existing album create a new one
            if (songAlbum == null)
            {
                songAlbum = new Album()
                {
                    Name = album.Name, Songs = new List <Song>(), LibraryId = scanLibrary
                };
                await Albums.AddAlbumAsync(songAlbum);
            }

            return(songAlbum);
        }
Exemplo n.º 6
0
            public void DisplayAlbum(ArtistAlbum artistAlbum, bool actionMode)
            {
                // Save the default colour if not already done so
                if (albumNameColour == Color.Fuchsia)
                {
                    albumNameColour = new Color(AlbumName.CurrentTextColor);
                }

                AlbumName.Text = artistAlbum.Name;
                AlbumName.SetTextColor((artistAlbum.Album.Played == true) ? Color.Black : albumNameColour);

                // A very nasty workaround here. If action mode is in effect then remove the AlignParentLeft from the album name.
                // When the Checkbox is being shown then the album name can be positioned between the checkbox and the album year,
                // but when there is no checkbox this does not work and the name has to be aligned with the parent.
                // This seems to be too complicated for static layout
                ((RelativeLayout.LayoutParams)AlbumName.LayoutParameters).AddRule(LayoutRules.AlignParentLeft, (actionMode == true) ? 0 : 1);

                // Set the year text
                Year.Text = (artistAlbum.Album.Year > 0) ? artistAlbum.Album.Year.ToString() : " ";

                // Display the genres. Replace any spaces in the genres with non-breaking space characters. This prevents a long genres string with a
                // space near the start being broken at the start, It just looks funny.
                Genre.Text = artistAlbum.Album.Genre.Replace(' ', '\u00a0');
            }
Exemplo n.º 7
0
 /// <summary>
 /// Get the contents for the specified ArtistAlbum
 /// </summary>
 /// <param name="artistAlbum"></param>
 /// <returns></returns>
 public static void GetArtistAlbumContents(ArtistAlbum artistAlbum) => artistAlbum.Artist.GetArtistAlbumSongs(artistAlbum);
Exemplo n.º 8
0
        /// <summary>
        /// Called to process a group of songs belonging to the same album name ( but not necessarily the same artist )
        /// </summary>
        /// <param name="album"></param>
        private async Task StoreAlbumAsync(ScannedAlbum album)
        {
            // Set the modified flag
            LibraryModified = true;

            Logger.Log(string.Format("Album: {0} Single artist: {1}", album.Name, album.SingleArtist));

            // Get an existing or new Album entry for the songs
            Album songAlbum = await GetAlbumToHoldSongsAsync(album);

            // Keep track of Artist and ArtistAlbum entries in case they can be reused for different artists
            ArtistAlbum songArtistAlbum = null;
            Artist      songArtist      = null;

            // Add all the songs in the album
            foreach (ScannedSong songScanned in album.Songs)
            {
                // If there is no existing Artist entry or the current one if for the wrong Artist name then get or create a new one
                if ((songArtist == null) || (songArtist.Name != songScanned.ArtistName))
                {
                    // As this is a new Artist the ArtistAlbum needs to be re-initialised.
                    if (songArtistAlbum != null)
                    {
                        songArtistAlbum.Songs.Sort((a, b) => a.Track.CompareTo(b.Track));
                    }

                    songArtistAlbum = null;

                    // Find the Artist for this song
                    songArtist = await GetArtistToHoldSongsAsync(songScanned.ArtistName);
                }

                // If there is an existing ArtistAlbum then use it as it will be for the correct Artist, i.e. not cleared above
                if (songArtistAlbum == null)
                {
                    // Find an existing or create a new ArtistAlbum entry
                    songArtistAlbum = await GetArtistAlbumToHoldSongsAsync(songArtist, songAlbum);
                }

                // Add the song to the database, the album and the album artist
                Song songToAdd = new() {
                    Title        = songScanned.Tags.Title, Track = songScanned.Track, Path = songScanned.SourcePath,
                    ModifiedTime = songScanned.Modified, Length = songScanned.Length, AlbumId = songAlbum.Id, ArtistAlbumId = songArtistAlbum.Id,
                    SourceId     = sourceBeingScanned.Id
                };

                // No need to wait for this
                Songs.AddSongAsync(songToAdd);

                Logger.Log(string.Format("Artist: {0} Title: {1} Track: {2} Modified: {3} Length {4} Year {5}", songScanned.Tags.Artist, songScanned.Tags.Title,
                                         songScanned.Tags.Track, songScanned.Modified, songScanned.Length, songScanned.Year));

                // Add to the Album
                songAlbum.Songs.Add(songToAdd);

                // Keep track whether or not to update the album
                bool updateAlbum = false;

                // Store the artist name with the album
                if ((songAlbum.ArtistName == null) || (songAlbum.ArtistName.Length == 0))
                {
                    songAlbum.ArtistName = songArtist.Name;
                    updateAlbum          = true;
                }
                else
                {
                    // The artist has already been stored - check if it is the same artist
                    if (songAlbum.ArtistName != songArtist.Name)
                    {
                        songAlbum.ArtistName = VariousArtistsString;
                        updateAlbum          = true;
                    }
                }

                // Update the album year if not already set and this song has a year set
                if ((songAlbum.Year != songScanned.Year) && (songAlbum.Year == 0))
                {
                    songAlbum.Year = songScanned.Year;
                    updateAlbum    = true;
                }

                // Update the album genre.
                // Only try updating if a genre is defined for the song
                // If the album does not have a genre then get one for the song and store it in the album
                if ((songScanned.Tags.Genre.Length > 0) && (songAlbum.Genre.Length == 0))
                {
                    songAlbum.Genre = songScanned.Tags.Genre;
                    updateAlbum     = true;
                }

                if (updateAlbum == true)
                {
                    await ConnectionDetailsModel.AsynchConnection.UpdateAsync(songAlbum);
                }

                // Add to the source
                sourceBeingScanned.Songs.Add(songToAdd);

                // Add to the ArtistAlbum
                songArtistAlbum.Songs.Add(songToAdd);
            }

            if (songArtistAlbum != null)
            {
                songArtistAlbum.Songs.Sort((a, b) => a.Track.CompareTo(b.Track));
            }
        }
Exemplo n.º 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);
        }