/// <summary> /// Transfer over enough of the file to extract the MP3 files tags /// </summary> /// <param name="fileItem"></param> /// <returns></returns> private async Task <ScannedSong> GetFileTags(FileInfo fileItem) { ScannedSong song = new ScannedSong(); await Task.Run(() => { try { song.Modified = fileItem.LastWriteTime; song.SourcePath = fileItem.FullName.TrimStart(rootDirectory); using (FileStream fs = File.OpenRead(fileItem.FullName)) { song.Tags = MP3TagExtractor.GetFileTags(fs); } } catch (Exception songProblem) { Logger.Error(string.Format("FTP exception reading song: {0} : {1}", fileItem.FullName, songProblem.Message)); } }); return(song); }
/// <summary> /// Transfer over enough of the file to extract the MP3 files tags /// </summary> /// <param name="fileItem"></param> /// <returns></returns> private async Task <ScannedSong> GetFileTags(DirectoryItem fileItem) { ScannedSong song = new ScannedSong(); try { song.Modified = fileItem.Created; song.SourcePath = fileItem.AbsolutePath; string requestName = ftpHeader + fileItem.AbsolutePath; // Get the length of the file FtpWebResponse lengthResponse = await new FtpRequest(requestName, WebRequestMethods.Ftp.GetFileSize, true).MakeRequestAsync(); long fileSize = lengthResponse.ContentLength; // Start downloading the file FtpRequest request = new FtpRequest(requestName, WebRequestMethods.Ftp.DownloadFile, true); FtpWebResponse response = await request.MakeRequestAsync(); // Read the file to get the MP3 tags. FTPStream wrappedStream = new FTPStream(response.GetResponseStream(), fileSize); song.Tags = MP3TagExtractor.GetFileTags(wrappedStream); // Read the FTP response and prevent stale data on the socket request.AbortRequest(); wrappedStream.Close(); response.Close(); } catch (Exception songProblem) { Logger.Error(string.Format("FTP exception reading song: {0} : {1}", fileItem.AbsolutePath, songProblem.Message)); } return(song); }
/// <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); }