Example #1
0
 /// <summary>
 /// Perform any operations to the given folder and the plugin results after processing
 /// </summary>
 private async Task <bool> PostProcessFolder(DirectoryInfo inboundFolder, IEnumerable <PluginResultInfo> pluginResults, bool doJustInfo)
 {
     SimpleContract.Requires <ArgumentNullException>(inboundFolder != null, "Invalid InboundFolder");
     if (pluginResults != null)
     {
         foreach (var releasesInfo in pluginResults.GroupBy(x => x.ReleaseId).Select(x => x.First()))
         {
             await this.ReleaseFactory.ScanReleaseFolder(releasesInfo.ReleaseId, this.DestinationRoot, doJustInfo);
         }
     }
     if (!doJustInfo)
     {
         var fileExtensionsToDelete = this.Configuration.FileExtensionsToDelete ?? new string[0];
         if (fileExtensionsToDelete.Any())
         {
             foreach (var fileInFolder in inboundFolder.GetFiles("*.*", SearchOption.AllDirectories))
             {
                 if (fileExtensionsToDelete.Any(x => x.Equals(fileInFolder.Extension, StringComparison.OrdinalIgnoreCase)))
                 {
                     if (!doJustInfo)
                     {
                         fileInFolder.Delete();
                         this.Logger.LogInformation("x Deleted File [{0}], Was foud in in FileExtensionsToDelete", fileInFolder.Name);
                     }
                 }
             }
         }
         FolderProcessor.DeleteEmptyFolders(inboundFolder, this.Logger);
     }
     return(true);
 }
Example #2
0
        /// <summary>
        /// Get image data from all sources for either fileanme or MetaData
        /// </summary>
        /// <param name="filename">Name of the File (ie a CUE file)</param>
        /// <param name="metaData">Populated MetaData</param>
        /// <returns></returns>
        public AudioMetaDataImage GetPictureForMetaData(string filename, AudioMetaData metaData)
        {
            SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(filename), "Invalid Filename");
            SimpleContract.Requires <ArgumentException>(metaData != null, "Invalid MetaData");

            return(this.ImageForFilename(filename));
        }
Example #3
0
        /// <summary>
        ///     Get image data from all sources for either fileanme or MetaData
        /// </summary>
        /// <param name="filename">Name of the File (ie a CUE file)</param>
        /// <param name="metaData">Populated MetaData</param>
        /// <returns></returns>
        public static AudioMetaDataImage GetPictureForMetaData(IRoadieSettings configuration, string filename, AudioMetaData metaData)
        {
            SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(filename), "Invalid Filename");
            SimpleContract.Requires <ArgumentException>(metaData != null, "Invalid MetaData");

            return(ImageForFilename(configuration, filename));
        }
Example #4
0
        public async Task <OperationResult <Label> > PerformMetaDataProvidersLabelSearch(string LabelName)
        {
            SimpleContract.Requires <ArgumentNullException>(LabelName != null, "Invalid Label Name");

            var sw = new Stopwatch();

            sw.Start();
            var result = new Label
            {
                Name = LabelName.ToTitleCase()
            };
            var resultsExceptions = new List <Exception>();

            if (DiscogsLabelSearchEngine.IsEnabled)
            {
                var discogsResult = await DiscogsLabelSearchEngine.PerformLabelSearch(result.Name, 1).ConfigureAwait(false);

                if (discogsResult.IsSuccess)
                {
                    var d = discogsResult.Data.First();
                    if (d.Urls != null)
                    {
                        result.URLs = result.URLs.AddToDelimitedList(d.Urls);
                    }
                    if (d.AlternateNames != null)
                    {
                        result.AlternateNames = result.AlternateNames.AddToDelimitedList(d.AlternateNames);
                    }
                    if (!string.IsNullOrEmpty(d.LabelName) &&
                        !d.LabelName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
                    {
                        result.AlternateNames.AddToDelimitedList(new[] { d.LabelName });
                    }
                    result.CopyTo(new Label
                    {
                        Profile   = HttpEncoder.HtmlEncode(d.Profile),
                        DiscogsId = d.DiscogsId,
                        Name      = result.Name ?? d.LabelName.ToTitleCase()
                    });
                }

                if (discogsResult.Errors != null)
                {
                    resultsExceptions.AddRange(discogsResult.Errors);
                }
            }

            sw.Stop();
            return(new OperationResult <Label>
            {
                Data = result,
                IsSuccess = result != null,
                Errors = resultsExceptions,
                OperationTime = sw.ElapsedMilliseconds
            });
        }
Example #5
0
        /// <summary>
        /// Check if exists if not make given folder
        /// </summary>
        /// <param name="folder">Folder To Check</param>
        /// <returns>False if Exists, True if Made</returns>
        public static bool CheckMakeFolder(string folder)
        {
            SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(folder), "Invalid Folder");

            if (!Directory.Exists(folder))
            {
                Directory.CreateDirectory(folder);
                return(true);
            }
            return(false);
        }
Example #6
0
 /// <summary>
 /// Perform any operations to the given folder and the plugin results after processing
 /// </summary>
 private async Task <bool> PostProcessFolder(DirectoryInfo inboundFolder, IEnumerable <PluginResultInfo> pluginResults, bool doJustInfo)
 {
     SimpleContract.Requires <ArgumentNullException>(inboundFolder != null, "Invalid InboundFolder");
     if (!doJustInfo)
     {
         FolderProcessor.DeleteEmptyFolders(inboundFolder, this.Logger);
     }
     if (pluginResults != null)
     {
         foreach (var releasesInfo in pluginResults.GroupBy(x => x.ReleaseId).Select(x => x.First()))
         {
             await this.ReleaseFactory.ScanReleaseFolder(releasesInfo.ReleaseId, this.DestinationRoot, doJustInfo);
         }
     }
     return(true);
 }
Example #7
0
        public async Task <OperationResult <Label> > Add(Label label)
        {
            SimpleContract.Requires <ArgumentNullException>(label != null, "Invalid Label");

            try
            {
                var now = DateTime.UtcNow;
                label.AlternateNames = label.AlternateNames.AddToDelimitedList(new[] { label.Name.ToAlphanumericName() });
                if (!label.IsValid)
                {
                    return(new OperationResult <Label>
                    {
                        Errors = new Exception[1] {
                            new Exception("Label is Invalid")
                        }
                    });
                }
                DbContext.Labels.Add(label);
                var inserted = 0;
                try
                {
                    inserted = await DbContext.SaveChangesAsync().ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex);
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
            }

            return(new OperationResult <Label>
            {
                IsSuccess = label.Id > 0,
                Data = label
            });
        }
Example #8
0
        /// <summary>
        ///     Perform any operations to the given folder and the plugin results after processing
        /// </summary>
        private async Task <bool> PostProcessFolder(User user, DirectoryInfo inboundFolder, IEnumerable <PluginResultInfo> pluginResults, bool doJustInfo, bool doDeleteFiles = true)
        {
            SimpleContract.Requires <ArgumentNullException>(inboundFolder != null, "Invalid InboundFolder");
            if (pluginResults != null)
            {
                foreach (var releasesInfo in pluginResults.GroupBy(x => x.ReleaseId).Select(x => x.First()))
                {
                    await ReleaseService.ScanReleaseFolder(user, releasesInfo.ReleaseId, doJustInfo);

                    _addedTrackIds.AddRange(ReleaseService.AddedTrackIds);
                }
            }
            if (!doJustInfo && doDeleteFiles)
            {
                var fileExtensionsToDelete = Configuration.FileExtensionsToDelete ?? new string[0];
                if (fileExtensionsToDelete.Any())
                {
                    foreach (var fileInFolder in inboundFolder.GetFiles("*.*", SearchOption.AllDirectories))
                    {
                        if (fileExtensionsToDelete.Any(x => x.Equals(fileInFolder.Extension, StringComparison.OrdinalIgnoreCase)))
                        {
                            if (!doJustInfo)
                            {
                                fileInFolder.Delete();
                                Logger.LogTrace("Deleted File [{0}], Was found in in FileExtensionsToDelete",
                                                fileInFolder.Name);
                            }
                        }
                    }
                }

                DeleteEmptyFolders(inboundFolder, Logger);
            }

            return(true);
        }
Example #9
0
        public async Task <OperationResult <Data.Release> > Add(Data.Release release, bool doAddTracksInDatabase = false)
        {
            SimpleContract.Requires <ArgumentNullException>(release != null, "Invalid Release");

            try
            {
                var releaseGenreTables = release.Genres;
                var releaseImages      = release.Images;
                var releaseMedias      = release.Medias;
                var releaseLabels      = release.Labels;
                var now = DateTime.UtcNow;
                release.AlternateNames = release.AlternateNames.AddToDelimitedList(new string[] { release.Title.ToAlphanumericName() });
                release.Images         = null;
                release.Labels         = null;
                release.Medias         = null;
                release.Genres         = null;
                release.LibraryStatus  = LibraryStatus.Incomplete;
                release.Status         = Statuses.New;
                if (!release.IsValid)
                {
                    return(new OperationResult <Data.Release>
                    {
                        Errors = new Exception[1] {
                            new Exception("Release is Invalid")
                        }
                    });
                }
                this.DbContext.Releases.Add(release);
                int inserted = 0;
                try
                {
                    inserted = await this.DbContext.SaveChangesAsync();
                }
                catch (Exception ex)
                {
                    this.Logger.LogError(ex, ex.Serialize());
                }
                if (inserted > 0 && release.Id > 0)
                {
                    this._addedReleaseIds.Add(release.Id);
                    if (releaseGenreTables != null && releaseGenreTables.Any(x => x.GenreId == null))
                    {
                        foreach (var releaseGenreTable in releaseGenreTables)
                        {
                            var genreName = releaseGenreTable.Genre.Name.ToLower().Trim();
                            if (string.IsNullOrEmpty(genreName))
                            {
                                continue;
                            }
                            var genre = this.DbContext.Genres.FirstOrDefault(x => x.Name.ToLower().Trim() == genreName);
                            if (genre == null)
                            {
                                genre = new Genre
                                {
                                    Name = releaseGenreTable.Genre.Name
                                };
                                this.DbContext.Genres.Add(genre);
                                await this.DbContext.SaveChangesAsync();
                            }
                            if (genre != null && genre.Id > 0)
                            {
                                string sql = null;
                                try
                                {
                                    await this.DbContext.Database.ExecuteSqlCommandAsync("INSERT INTO `releaseGenreTable` (releaseId, genreId) VALUES ({0}, {1});", release.Id, genre.Id);
                                }
                                catch (Exception ex)
                                {
                                    this.Logger.LogError(ex, "Sql [" + sql + "]");
                                }
                            }
                        }
                    }
                    if (releaseImages != null && releaseImages.Any(x => x.Status == Statuses.New))
                    {
                        foreach (var releaseImage in releaseImages)
                        {
                            this.DbContext.Images.Add(new Data.Image
                            {
                                ReleaseId = release.Id,
                                Url       = releaseImage.Url,
                                Signature = releaseImage.Signature,
                                Bytes     = releaseImage.Bytes
                            });
                        }
                        try
                        {
                            await this.DbContext.SaveChangesAsync();
                        }
                        catch (Exception ex)
                        {
                            this.Logger.LogError(ex);
                        }
                    }

                    if (releaseLabels != null && releaseLabels.Any(x => x.Status == Statuses.New))
                    {
                        foreach (var neweleaseLabel in releaseLabels.Where(x => x.Status == Statuses.New))
                        {
                            var labelFetch = await this.LabelLookupEngine.GetByName(neweleaseLabel.Label.Name, true);

                            if (labelFetch.IsSuccess)
                            {
                                this.DbContext.ReleaseLabels.Add(new Data.ReleaseLabel
                                {
                                    CatalogNumber = neweleaseLabel.CatalogNumber,
                                    BeginDate     = neweleaseLabel.BeginDate,
                                    EndDate       = neweleaseLabel.EndDate,
                                    ReleaseId     = release.Id,
                                    LabelId       = labelFetch.Data.Id
                                });
                            }
                        }
                        try
                        {
                            await this.DbContext.SaveChangesAsync();
                        }
                        catch (Exception ex)
                        {
                            this.Logger.LogError(ex);
                        }
                    }
                    if (doAddTracksInDatabase)
                    {
                        if (releaseMedias != null && releaseMedias.Any(x => x.Status == Statuses.New))
                        {
                            foreach (var newReleaseMedia in releaseMedias.Where(x => x.Status == Statuses.New))
                            {
                                var releasemedia = new Data.ReleaseMedia
                                {
                                    Status      = Statuses.Incomplete,
                                    MediaNumber = newReleaseMedia.MediaNumber,
                                    SubTitle    = newReleaseMedia.SubTitle,
                                    TrackCount  = newReleaseMedia.TrackCount,
                                    ReleaseId   = release.Id
                                };
                                var releasemediatracks = new List <Data.Track>();
                                foreach (var newTrack in newReleaseMedia.Tracks)
                                {
                                    int?   trackArtistId = null;
                                    string partTitles    = null;
                                    if (newTrack.TrackArtist != null)
                                    {
                                        if (!release.IsCastRecording)
                                        {
                                            var trackArtistData = await this.ArtistLookupEngine.GetByName(new AudioMetaData { Artist = newTrack.TrackArtist.Name }, true);

                                            if (trackArtistData.IsSuccess)
                                            {
                                                trackArtistId = trackArtistData.Data.Id;
                                            }
                                        }
                                        else if (newTrack.TrackArtists != null && newTrack.TrackArtists.Any())
                                        {
                                            partTitles = string.Join("/", newTrack.TrackArtists);
                                        }
                                        else
                                        {
                                            partTitles = newTrack.TrackArtist.Name;
                                        }
                                    }
                                    releasemediatracks.Add(new Data.Track
                                    {
                                        ArtistId       = trackArtistId,
                                        PartTitles     = partTitles,
                                        Status         = Statuses.Incomplete,
                                        TrackNumber    = newTrack.TrackNumber,
                                        MusicBrainzId  = newTrack.MusicBrainzId,
                                        SpotifyId      = newTrack.SpotifyId,
                                        AmgId          = newTrack.AmgId,
                                        Title          = newTrack.Title,
                                        AlternateNames = newTrack.AlternateNames,
                                        Duration       = newTrack.Duration,
                                        Tags           = newTrack.Tags,
                                        ISRC           = newTrack.ISRC,
                                        LastFMId       = newTrack.LastFMId
                                    });
                                }
                                releasemedia.Tracks = releasemediatracks;
                                this.DbContext.ReleaseMedias.Add(releasemedia);
                                this._addedTrackIds.AddRange(releasemedia.Tracks.Select(x => x.Id));
                            }
                            try
                            {
                                await this.DbContext.SaveChangesAsync();
                            }
                            catch (Exception ex)
                            {
                                this.Logger.LogError(ex);
                            }
                        }
                    }

                    this.Logger.LogInformation("Added New Release: `{0}`", release.ToString());
                }
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex, ex.Serialize());
            }
            return(new OperationResult <Data.Release>
            {
                IsSuccess = release.Id > 0,
                Data = release
            });
        }
Example #10
0
        public async Task <OperationResult <Artist> > Update(Artist Artist, IEnumerable <Image> ArtistImages, string destinationFolder = null)
        {
            SimpleContract.Requires <ArgumentNullException>(Artist != null, "Invalid Artist");

            var sw = new Stopwatch();

            sw.Start();

            var artistGenreTables = Artist.Genres.Select(x => new ArtistGenre {
                ArtistId = Artist.Id, GenreId = x.GenreId
            }).ToList();
            var artistAssociatedWith = Artist.AssociatedArtists.Select(x => new ArtistAssociation {
                ArtistId = Artist.Id, AssociatedArtistId = x.AssociatedArtistId
            }).ToList();
            var similarArtists = Artist.SimilarArtists.Select(x => new ArtistSimilar {
                ArtistId = Artist.Id, SimilarArtistId = x.SimilarArtistId
            }).ToList();
            var result = true;

            var now = DateTime.UtcNow;
            var originalArtistFolder = Artist.ArtistFileFolder(this.Configuration, destinationFolder ?? this.Configuration.LibraryFolder);
            var originalName         = Artist.Name;
            var originalSortName     = Artist.SortName;

            Artist.LastUpdated = now;
            await this.DbContext.SaveChangesAsync();

            this.DbContext.ArtistGenres.RemoveRange((from at in this.DbContext.ArtistGenres
                                                     where at.ArtistId == Artist.Id
                                                     select at));
            Artist.Genres = artistGenreTables;
            this.DbContext.ArtistAssociations.RemoveRange((from at in this.DbContext.ArtistAssociations
                                                           where at.ArtistId == Artist.Id
                                                           select at));
            Artist.AssociatedArtists = artistAssociatedWith;
            Artist.SimilarArtists    = similarArtists;
            await this.DbContext.SaveChangesAsync();

            var existingImageIds = (from ai in ArtistImages
                                    where ai.Status != Statuses.New
                                    select ai.RoadieId).ToArray();

            this.DbContext.Images.RemoveRange((from i in this.DbContext.Images
                                               where i.ArtistId == Artist.Id
                                               where !(from x in existingImageIds select x).Contains(i.RoadieId)
                                               select i));
            await this.DbContext.SaveChangesAsync();

            if (ArtistImages != null && ArtistImages.Any(x => x.Status == Statuses.New))
            {
                foreach (var ArtistImage in ArtistImages.Where(x => x.Status == Statuses.New))
                {
                    this.DbContext.Images.Add(ArtistImage);
                }
                try
                {
                    await this.DbContext.SaveChangesAsync();
                }
                catch (Exception ex)
                {
                    this.Logger.LogError(ex, ex.Serialize());
                }
            }

            var newArtistFolder = Artist.ArtistFileFolder(this.Configuration, destinationFolder ?? this.Configuration.LibraryFolder);

            if (!originalArtistFolder.Equals(newArtistFolder, StringComparison.OrdinalIgnoreCase))
            {
                this.Logger.LogTrace("Moving Artist From Folder [{0}] To  [{1}]", originalArtistFolder, newArtistFolder);
                //  Directory.Move(originalArtistFolder, Artist.ArtistFileFolder(destinationFolder ?? SettingsHelper.Instance.LibraryFolder));
                // TODO if name changed then update Artist track files to have new Artist name
            }
            this.CacheManager.ClearRegion(Artist.CacheRegion);
            sw.Stop();

            return(new OperationResult <Artist>
            {
                Data = Artist,
                IsSuccess = result,
                OperationTime = sw.ElapsedMilliseconds
            });
        }
Example #11
0
        public async Task <OperationResult <bool> > ScanArtistReleasesFolders(Guid artistId, string destinationFolder, bool doJustInfo)
        {
            SimpleContract.Requires <ArgumentOutOfRangeException>(artistId != Guid.Empty, "Invalid ArtistId");

            var result       = true;
            var resultErrors = new List <Exception>();
            var sw           = new Stopwatch();

            sw.Start();
            try
            {
                var artist = this.DbContext.Artists
                             .Include("Releases")
                             .Include("Releases.Labels")
                             .FirstOrDefault(x => x.RoadieId == artistId);
                if (artist == null)
                {
                    this.Logger.LogWarning("Unable To Find Artist [{0}]", artistId);
                    return(new OperationResult <bool>());
                }
                var releaseScannedCount  = 0;
                var artistFolder         = artist.ArtistFileFolder(this.Configuration, destinationFolder);
                var scannedArtistFolders = new List <string>();
                // Scan known releases for changes
                if (artist.Releases != null)
                {
                    foreach (var release in artist.Releases)
                    {
                        try
                        {
                            result = result && (await this.ReleaseFactory.ScanReleaseFolder(Guid.Empty, destinationFolder, doJustInfo, release)).Data;
                            releaseScannedCount++;
                            scannedArtistFolders.Add(release.ReleaseFileFolder(artistFolder));
                        }
                        catch (Exception ex)
                        {
                            this.Logger.LogError(ex, ex.Serialize());
                        }
                    }
                }
                // Any folder found in Artist folder not already scanned scan
                var folderProcessor   = new FolderProcessor(this.Configuration, this.HttpEncoder, destinationFolder, this.DbContext, this.CacheManager, this.Logger, this.ArtistLookupEngine, this, this.ReleaseFactory, this.ImageFactory, this.ReleaseLookupEngine, this.AudioMetaDataHelper);
                var nonReleaseFolders = (from d in Directory.EnumerateDirectories(artistFolder)
                                         where !(from r in scannedArtistFolders select r).Contains(d)
                                         orderby d
                                         select d);
                foreach (var folder in nonReleaseFolders)
                {
                    await folderProcessor.Process(new DirectoryInfo(folder), doJustInfo);
                }
                if (!doJustInfo)
                {
                    FolderProcessor.DeleteEmptyFolders(new DirectoryInfo(artistFolder), this.Logger);
                }

                // Always update artist image if artist image is found on an artist rescan
                var imageFiles = ImageHelper.ImageFilesInFolder(artistFolder, SearchOption.AllDirectories);
                if (imageFiles != null && imageFiles.Any())
                {
                    var imageFile     = imageFiles.First();
                    var i             = new FileInfo(imageFile);
                    var iName         = i.Name.ToLower().Trim();
                    var isArtistImage = iName.Contains("artist") || iName.Contains(artist.Name.ToLower());
                    if (isArtistImage)
                    {
                        // Read image and convert to jpeg
                        artist.Thumbnail = File.ReadAllBytes(i.FullName);
                        artist.Thumbnail = ImageHelper.ResizeImage(artist.Thumbnail, this.Configuration.MediumImageSize.Width, this.Configuration.MediumImageSize.Height);
                        artist.Thumbnail = ImageHelper.ConvertToJpegFormat(artist.Thumbnail);
                        if (artist.Thumbnail.Length >= ImageHelper.MaximumThumbnailByteSize)
                        {
                            Logger.LogWarning($"Artist Thumbnail larger than maximum size after resizing to [{ this.Configuration.ThumbnailImageSize.Width }x{ this.Configuration.ThumbnailImageSize.Height}] Thumbnail Size [{ artist.Thumbnail.Length }]");
                            artist.Thumbnail = null;
                        }
                        artist.LastUpdated = DateTime.UtcNow;
                        await this.DbContext.SaveChangesAsync();

                        this.CacheManager.ClearRegion(artist.CacheRegion);
                        this.Logger.LogInformation("Update Thumbnail using Artist File [{0}]", iName);
                    }
                }

                sw.Stop();
                this.CacheManager.ClearRegion(artist.CacheRegion);
                this.Logger.LogInformation("Scanned Artist [{0}], Releases Scanned [{1}], OperationTime [{2}]", artist.ToString(), releaseScannedCount, sw.ElapsedMilliseconds);
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex, ex.Serialize());
                resultErrors.Add(ex);
            }
            return(new OperationResult <bool>
            {
                Data = result,
                IsSuccess = result,
                Errors = resultErrors,
                OperationTime = sw.ElapsedMilliseconds
            });
        }
Example #12
0
        /// <summary>
        /// Perform a Metadata Provider search and then merge the results into the given Artist
        /// </summary>
        /// <param name="ArtistId">Given Artist RoadieId</param>
        /// <returns>Operation Result</returns>
        public async Task <OperationResult <bool> > RefreshArtistMetadata(Guid ArtistId)
        {
            SimpleContract.Requires <ArgumentOutOfRangeException>(ArtistId != Guid.Empty, "Invalid ArtistId");

            var result       = true;
            var resultErrors = new List <Exception>();
            var sw           = new Stopwatch();

            sw.Start();
            try
            {
                var Artist = this.DbContext.Artists.FirstOrDefault(x => x.RoadieId == ArtistId);
                if (Artist == null)
                {
                    this.Logger.LogWarning("Unable To Find Artist [{0}]", ArtistId);
                    return(new OperationResult <bool>());
                }

                OperationResult <Artist> ArtistSearch = null;
                try
                {
                    ArtistSearch = await this.ArtistLookupEngine.PerformMetaDataProvidersArtistSearch(new AudioMetaData
                    {
                        Artist = Artist.Name
                    });
                }
                catch (Exception ex)
                {
                    this.Logger.LogError(ex, ex.Serialize());
                }
                if (ArtistSearch.IsSuccess)
                {
                    // Do metadata search for Artist like if new Artist then set some overides and merge
                    var mergeResult = await this.MergeArtists(ArtistSearch.Data, Artist);

                    if (mergeResult.IsSuccess)
                    {
                        Artist = mergeResult.Data;
                        await this.DbContext.SaveChangesAsync();

                        sw.Stop();
                        this.CacheManager.ClearRegion(Artist.CacheRegion);
                        this.Logger.LogInformation("Scanned RefreshArtistMetadata [{0}], OperationTime [{1}]", Artist.ToString(), sw.ElapsedMilliseconds);
                    }
                    else
                    {
                        sw.Stop();
                    }
                }
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex, ex.Serialize());
                resultErrors.Add(ex);
            }
            return(new OperationResult <bool>
            {
                Data = result,
                IsSuccess = result,
                Errors = resultErrors,
                OperationTime = sw.ElapsedMilliseconds
            });
        }
Example #13
0
        /// <summary>
        /// Merge one Artist into another one
        /// </summary>
        /// <param name="ArtistToMerge">The Artist to be merged</param>
        /// <param name="artistToMergeInto">The Artist to merge into</param>
        /// <returns></returns>
        public async Task <OperationResult <Artist> > MergeArtists(Artist ArtistToMerge, Artist artistToMergeInto, bool doDbUpdates = false)
        {
            SimpleContract.Requires <ArgumentNullException>(ArtistToMerge != null, "Invalid Artist");
            SimpleContract.Requires <ArgumentNullException>(artistToMergeInto != null, "Invalid Artist");

            var result = false;
            var now    = DateTime.UtcNow;

            var sw = new Stopwatch();

            sw.Start();

            artistToMergeInto.RealName      = ArtistToMerge.RealName ?? artistToMergeInto.RealName;
            artistToMergeInto.MusicBrainzId = ArtistToMerge.MusicBrainzId ?? artistToMergeInto.MusicBrainzId;
            artistToMergeInto.ITunesId      = ArtistToMerge.ITunesId ?? artistToMergeInto.ITunesId;
            artistToMergeInto.AmgId         = ArtistToMerge.AmgId ?? artistToMergeInto.AmgId;
            artistToMergeInto.SpotifyId     = ArtistToMerge.SpotifyId ?? artistToMergeInto.SpotifyId;
            artistToMergeInto.Thumbnail     = ArtistToMerge.Thumbnail ?? artistToMergeInto.Thumbnail;
            artistToMergeInto.Profile       = ArtistToMerge.Profile ?? artistToMergeInto.Profile;
            artistToMergeInto.BirthDate     = ArtistToMerge.BirthDate ?? artistToMergeInto.BirthDate;
            artistToMergeInto.BeginDate     = ArtistToMerge.BeginDate ?? artistToMergeInto.BeginDate;
            artistToMergeInto.EndDate       = ArtistToMerge.EndDate ?? artistToMergeInto.EndDate;
            if (!string.IsNullOrEmpty(ArtistToMerge.ArtistType) && !ArtistToMerge.ArtistType.Equals("Other", StringComparison.OrdinalIgnoreCase))
            {
                artistToMergeInto.ArtistType = ArtistToMerge.ArtistType;
            }
            artistToMergeInto.BioContext = ArtistToMerge.BioContext ?? artistToMergeInto.BioContext;
            artistToMergeInto.DiscogsId  = ArtistToMerge.DiscogsId ?? artistToMergeInto.DiscogsId;

            artistToMergeInto.Tags = artistToMergeInto.Tags.AddToDelimitedList(ArtistToMerge.Tags.ToListFromDelimited());
            var altNames = ArtistToMerge.AlternateNames.ToListFromDelimited().ToList();

            altNames.Add(ArtistToMerge.Name);
            altNames.Add(ArtistToMerge.SortName);
            artistToMergeInto.AlternateNames = artistToMergeInto.AlternateNames.AddToDelimitedList(altNames);
            artistToMergeInto.URLs           = artistToMergeInto.URLs.AddToDelimitedList(ArtistToMerge.URLs.ToListFromDelimited());
            artistToMergeInto.ISNI           = artistToMergeInto.ISNI.AddToDelimitedList(ArtistToMerge.ISNI.ToListFromDelimited());
            artistToMergeInto.LastUpdated    = now;

            if (doDbUpdates)
            {
                string sql = null;

                sql = "UPDATE `artistGenreTable` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
                await this.DbContext.Database.ExecuteSqlCommandAsync(sql);

                sql = "UPDATE `image` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
                await this.DbContext.Database.ExecuteSqlCommandAsync(sql);

                sql = "UPDATE `userartist` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
                await this.DbContext.Database.ExecuteSqlCommandAsync(sql);

                sql = "UPDATE `track` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
                await this.DbContext.Database.ExecuteSqlCommandAsync(sql);

                try
                {
                    sql = "UPDATE `release` set artistId = " + artistToMergeInto.Id + " WHERE artistId = " + ArtistToMerge.Id + ";";
                    await this.DbContext.Database.ExecuteSqlCommandAsync(sql);
                }
                catch (Exception ex)
                {
                    this.Logger.LogWarning(ex.ToString());
                }
                var artistFolder = ArtistToMerge.ArtistFileFolder(this.Configuration, this.Configuration.LibraryFolder);
                foreach (var release in this.DbContext.Releases.Include("Artist").Where(x => x.ArtistId == ArtistToMerge.Id).ToArray())
                {
                    var originalReleaseFolder = release.ReleaseFileFolder(artistFolder);
                    await this.ReleaseFactory.Update(release, null, originalReleaseFolder);
                }

                await this.Delete(ArtistToMerge);
            }

            result = true;

            sw.Stop();
            return(new OperationResult <Artist>
            {
                Data = artistToMergeInto,
                IsSuccess = result,
                OperationTime = sw.ElapsedMilliseconds
            });
        }
Example #14
0
        public override async Task <OperationResult <bool> > Process(FileInfo fileInfo, bool doJustInfo, int?submissionId)
        {
            Logger.LogTrace($">> Audio: Process FileInfo [{fileInfo}], doJustInfo [{doJustInfo}], submissionId [{submissionId}]", fileInfo, doJustInfo, submissionId);
            var sw     = Stopwatch.StartNew();
            var result = new OperationResult <bool>();

            try
            {
                string destinationName = null;

                var metaData = await AudioMetaDataHelper.GetInfo(fileInfo, doJustInfo).ConfigureAwait(false);

                if (!metaData.IsValid)
                {
                    var minWeight = MinWeightToDelete;
                    if (metaData.ValidWeight < minWeight && minWeight > 0)
                    {
                        Logger.LogTrace(
                            "Invalid File{3}: ValidWeight [{0}], Under MinWeightToDelete [{1}]. Deleting File [{2}]",
                            metaData.ValidWeight, minWeight, fileInfo.FullName,
                            doJustInfo ? " [Read Only Mode] " : string.Empty);
                        if (!doJustInfo)
                        {
                            fileInfo.Delete();
                        }
                    }

                    return(result);
                }

                var artist      = metaData.Artist.CleanString(Configuration);
                var album       = metaData.Release.CleanString(Configuration);
                var title       = metaData.Title.CleanString(Configuration).ToTitleCase(false);
                var year        = metaData.Year;
                var trackNumber = metaData.TrackNumber ?? 0;
                var discNumber  = metaData.Disc ?? 0;

                SimpleContract.Requires(metaData.IsValid, "Track MetaData Invalid");
                SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(artist), "Missing Track Artist");
                SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(album), "Missing Track Album");
                SimpleContract.Requires <ArgumentException>(!string.IsNullOrEmpty(title), "Missing Track Title");
                SimpleContract.Requires <ArgumentException>(year > 0, string.Format("Invalid Track Year [{0}]", year));
                SimpleContract.Requires <ArgumentException>(trackNumber > 0, "Missing Track Number");

                var artistFolder = await DetermineArtistFolder(metaData, doJustInfo).ConfigureAwait(false);

                if (string.IsNullOrEmpty(artistFolder))
                {
                    Logger.LogWarning("Unable To Find ArtistFolder [{0}] For MetaData [{1}]", artistFolder,
                                      metaData.ToString());
                    return(new OperationResult <bool>("Unable To Find Artist Folder"));
                }

                var releaseFolder = await DetermineReleaseFolder(artistFolder, metaData, doJustInfo, submissionId).ConfigureAwait(false);

                if (string.IsNullOrEmpty(releaseFolder))
                {
                    Logger.LogWarning("Unable To Find ReleaseFolder For MetaData [{0}]", metaData.ToString());
                    return(new OperationResult <bool>("Unable To Find Release Folder"));
                }

                destinationName = FolderPathHelper.TrackFullPath(Configuration, metaData, artistFolder, releaseFolder);
                Logger.LogTrace("Info: FileInfo [{0}], Artist Folder [{1}], Release Folder [{1}], Destination Name [{3}]", fileInfo.FullName, artistFolder, releaseFolder, destinationName);
                if (doJustInfo)
                {
                    result.IsSuccess = metaData.IsValid;
                    return(result);
                }

                if (CheckMakeFolder(artistFolder))
                {
                    Logger.LogTrace("Created ArtistFolder [{0}]", artistFolder);
                }
                if (CheckMakeFolder(releaseFolder))
                {
                    Logger.LogTrace("Created ReleaseFolder [{0}]", releaseFolder);
                }

                try
                {
                    // See if file folder parent folder (likely file is in release folder) has primary artist image if so then move to artist folder
                    var artistImages = new List <FileInfo>();
                    artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, ImageType.Artist));
                    artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory.Parent, ImageType.Artist));
                    if (artistImages.Count > 0)
                    {
                        var artistImage         = artistImages[0];
                        var artistImageFilename = Path.Combine(artistFolder, ImageHelper.ArtistImageFilename);
                        if (artistImageFilename != artistImage.FullName)
                        {
                            // Read image and convert to jpeg
                            var imageBytes = File.ReadAllBytes(artistImage.FullName);
                            imageBytes = ImageHelper.ConvertToJpegFormat(imageBytes);

                            // Move artist image to artist folder
                            if (!doJustInfo)
                            {
                                File.WriteAllBytes(artistImageFilename, imageBytes);
                                artistImage.Delete();
                            }

                            Logger.LogDebug("Found Artist Image File [{0}], Moved to artist folder.", artistImage.Name);
                        }
                    }

                    // See if any secondary artist images if so then move to artist folder
                    artistImages.Clear();
                    artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, ImageType.ArtistSecondary));
                    artistImages.AddRange(ImageHelper.FindImageTypeInDirectory(fileInfo.Directory.Parent, ImageType.Artist));
                    if (artistImages.Count > 0)
                    {
                        var looper = 0;
                        foreach (var artistImage in artistImages)
                        {
                            looper++;
                            var artistImageFilename = Path.Combine(artistFolder,
                                                                   string.Format(ImageHelper.ArtistSecondaryImageFilename, looper.ToString("00")));
                            if (artistImageFilename != artistImage.FullName)
                            {
                                // Read image and convert to jpeg
                                var imageBytes = File.ReadAllBytes(artistImage.FullName);
                                imageBytes = ImageHelper.ConvertToJpegFormat(imageBytes);

                                // Move artist image to artist folder
                                if (!doJustInfo)
                                {
                                    while (File.Exists(artistImageFilename))
                                    {
                                        looper++;
                                        artistImageFilename = Path.Combine(artistFolder,
                                                                           string.Format(ImageHelper.ArtistSecondaryImageFilename,
                                                                                         looper.ToString("00")));
                                    }

                                    File.WriteAllBytes(artistImageFilename, imageBytes);
                                    artistImage.Delete();
                                }

                                Logger.LogDebug(
                                    "Found Artist Secondary Image File [{0}], Moved to artist folder [{1}].",
                                    artistImage.Name, artistImageFilename);
                            }
                        }
                    }

                    // See if file folder has release image if so then move to release folder
                    var releaseImages = ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, ImageType.Release);
                    if (releaseImages.Any())
                    {
                        var releaseImage  = releaseImages.First();
                        var coverFileName = Path.Combine(releaseFolder, ImageHelper.ReleaseCoverFilename);
                        if (coverFileName != releaseImage.FullName)
                        {
                            // Read image and convert to jpeg
                            var imageBytes = File.ReadAllBytes(releaseImage.FullName);
                            imageBytes = ImageHelper.ConvertToJpegFormat(imageBytes);

                            // Move cover to release folder
                            if (!doJustInfo)
                            {
                                File.WriteAllBytes(coverFileName, imageBytes);
                                releaseImage.Delete();
                            }

                            Logger.LogTrace("Found Release Image File [{0}], Moved to release folder", releaseImage.Name);
                        }
                    }

                    // See if folder has secondary release image if so then move to release folder
                    releaseImages = ImageHelper.FindImageTypeInDirectory(fileInfo.Directory, ImageType.ReleaseSecondary);
                    if (releaseImages.Any())
                    {
                        var looper = 0;
                        foreach (var releaseImage in releaseImages)
                        {
                            looper++;
                            var releaseImageFilename = Path.Combine(releaseFolder,
                                                                    string.Format(ImageHelper.ReleaseSecondaryImageFilename, looper.ToString("00")));
                            if (releaseImageFilename != releaseImage.FullName)
                            {
                                // Read image and convert to jpeg
                                var imageBytes = File.ReadAllBytes(releaseImage.FullName);
                                imageBytes = ImageHelper.ConvertToJpegFormat(imageBytes);

                                // Move cover to release folder
                                if (!doJustInfo)
                                {
                                    File.WriteAllBytes(releaseImageFilename, imageBytes);
                                    releaseImage.Delete();
                                }

                                Logger.LogTrace("Found Release Image File [{0}], Moved to release folder [{1}]", releaseImage.Name, releaseImageFilename);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(ex, "Error with Managing Images For [{0}]", fileInfo.FullName);
                }

                var doesFileExistsForTrack = File.Exists(destinationName);
                if (doesFileExistsForTrack)
                {
                    var existing = new FileInfo(destinationName);

                    // If Exists determine which is better - if same do nothing
                    var existingMetaData = await AudioMetaDataHelper.GetInfo(existing, doJustInfo).ConfigureAwait(false);

                    var areSameFile = existing.FullName.Replace("\\", "").Replace("/", "")
                                      .Equals(fileInfo.FullName.Replace("\\", "").Replace("/", ""),
                                              StringComparison.OrdinalIgnoreCase);
                    var currentBitRate  = metaData.AudioBitrate;
                    var existingBitRate = existingMetaData.AudioBitrate;

                    if (!areSameFile)
                    {
                        if (!existingMetaData.IsValid || currentBitRate > existingBitRate)
                        {
                            Logger.LogTrace("Newer Is Better: Deleting Existing File [{0}]", existing);
                            if (!doJustInfo)
                            {
                                existing.Delete();
                                fileInfo.MoveTo(destinationName);
                            }
                        }
                        else
                        {
                            Logger.LogTrace("Existing [{0}] Is Better or Equal: Deleting Found File [{1}]", existing,
                                            fileInfo.FullName);
                            if (!doJustInfo)
                            {
                                fileInfo.Delete();
                            }
                        }
                    }
                }
                else
                {
                    Logger.LogTrace("Moving File To [{0}]", destinationName);
                    if (!doJustInfo)
                    {
                        try
                        {
                            fileInfo.MoveTo(destinationName);
                        }
                        catch (Exception ex)
                        {
                            Logger.LogError(ex, "Error Moving File [{0}}", destinationName);
                        }
                    }
                }

                result.AdditionalData.Add(PluginResultInfo.AdditionalDataKeyPluginResultInfo, new PluginResultInfo
                {
                    ArtistFolder  = artistFolder,
                    ArtistId      = _artistId,
                    ReleaseFolder = releaseFolder,
                    ReleaseId     = _releaseId,
                    Filename      = fileInfo.FullName,
                    TrackNumber   = metaData.TrackNumber,
                    TrackTitle    = metaData.Title
                });
                result.IsSuccess = true;
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Error Processing File [{0}}", fileInfo);
            }

            sw.Stop();
            Logger.LogTrace("<< Audio: Process Complete. Result `{0}`, ElapsedTime [{1}]",
                            JsonConvert.SerializeObject(result), sw.ElapsedMilliseconds);
            return(result);
        }
Example #15
0
        public async Task <OperationResult <Data.Release> > PerformMetaDataProvidersReleaseSearch(AudioMetaData metaData, string artistFolder = null, int?submissionId = null)
        {
            SimpleContract.Requires <ArgumentNullException>(metaData != null, "Invalid MetaData");

            var sw = new Stopwatch();

            sw.Start();

            var result = new Data.Release
            {
                Title        = metaData.Release.ToTitleCase(false),
                TrackCount   = (short)(metaData.TotalTrackNumbers ?? 0),
                ReleaseDate  = SafeParser.ToDateTime(metaData.Year),
                SubmissionId = submissionId
            };
            var resultsExceptions = new List <Exception>();
            var releaseGenres     = new List <string>();

            // Add any Genre found in the given MetaData
            if (metaData.Genres != null)
            {
                releaseGenres.AddRange(metaData.Genres);
            }
            var releaseLabels    = new List <ReleaseLabelSearchResult>();
            var releaseMedias    = new List <ReleaseMediaSearchResult>();
            var releaseImageUrls = new List <string>();

            var dontDoMetaDataProvidersSearchArtists = this.Configuration.DontDoMetaDataProvidersSearchArtists;

            if (!dontDoMetaDataProvidersSearchArtists.Any(x => x.Equals(metaData.Artist, StringComparison.OrdinalIgnoreCase)))
            {
                try
                {
                    #region ITunes

                    if (this.ITunesReleaseSearchEngine.IsEnabled)
                    {
                        this.Logger.LogTrace("ITunesReleaseSearchEngine Release Search for ArtistName [{0}], ReleaseTitle [{1}]", metaData.Artist, result.Title);
                        var iTunesResult = await this.ITunesReleaseSearchEngine.PerformReleaseSearch(metaData.Artist, result.Title, 1);

                        if (iTunesResult.IsSuccess)
                        {
                            var i = iTunesResult.Data.First();
                            if (i.AlternateNames != null)
                            {
                                result.AlternateNames = result.AlternateNames.AddToDelimitedList(i.AlternateNames);
                            }
                            if (i.Tags != null)
                            {
                                result.Tags = result.Tags.AddToDelimitedList(i.Tags);
                            }
                            if (i.Urls != null)
                            {
                                result.URLs = result.URLs.AddToDelimitedList(i.Urls);
                            }
                            if (i.ImageUrls != null)
                            {
                                releaseImageUrls.AddRange(i.ImageUrls);
                            }
                            if (i.ReleaseGenres != null)
                            {
                                releaseGenres.AddRange(i.ReleaseGenres);
                            }
                            result.CopyTo(new Data.Release
                            {
                                ReleaseDate = result.ReleaseDate ?? i.ReleaseDate,
                                AmgId       = i.AmgId,
                                Profile     = i.Profile,
                                ITunesId    = i.iTunesId,
                                Title       = result.Title ?? i.ReleaseTitle,
                                Thumbnail   = i.ReleaseThumbnailUrl != null ? WebHelper.BytesForImageUrl(i.ReleaseThumbnailUrl) : null,
                                ReleaseType = result.ReleaseType == ReleaseType.Unknown ? SafeParser.ToEnum <ReleaseType>(i.ReleaseType) : result.ReleaseType
                            });
                            if (i.ReleaseLabel != null)
                            {
                                releaseLabels.AddRange(i.ReleaseLabel);
                            }
                            if (i.ReleaseMedia != null)
                            {
                                releaseMedias.AddRange(i.ReleaseMedia);
                            }
                        }
                        if (iTunesResult.Errors != null)
                        {
                            resultsExceptions.AddRange(iTunesResult.Errors);
                        }
                    }

                    #endregion ITunes

                    #region MusicBrainz

                    if (this.MusicBrainzReleaseSearchEngine.IsEnabled)
                    {
                        this.Logger.LogTrace("MusicBrainzReleaseSearchEngine Release Search for ArtistName [{0}], ReleaseTitle [{1}]", metaData.Artist, result.Title);
                        var mbResult = await this.MusicBrainzReleaseSearchEngine.PerformReleaseSearch(metaData.Artist, result.Title, 1);

                        if (mbResult.IsSuccess)
                        {
                            var mb = mbResult.Data.First();
                            if (mb.AlternateNames != null)
                            {
                                result.AlternateNames = result.AlternateNames.AddToDelimitedList(mb.AlternateNames);
                            }
                            if (mb.Tags != null)
                            {
                                result.Tags = result.Tags.AddToDelimitedList(mb.Tags);
                            }
                            if (mb.Urls != null)
                            {
                                result.URLs = result.URLs.AddToDelimitedList(mb.Urls);
                            }
                            if (mb.ImageUrls != null)
                            {
                                releaseImageUrls.AddRange(mb.ImageUrls);
                            }
                            if (mb.ReleaseGenres != null)
                            {
                                releaseGenres.AddRange(mb.ReleaseGenres);
                            }
                            if (!string.IsNullOrEmpty(mb.ReleaseTitle) && !mb.ReleaseTitle.Equals(result.Title, StringComparison.OrdinalIgnoreCase))
                            {
                                result.AlternateNames.AddToDelimitedList(new string[] { mb.ReleaseTitle });
                            }
                            result.CopyTo(new Data.Release
                            {
                                ReleaseDate   = result.ReleaseDate ?? mb.ReleaseDate,
                                AmgId         = mb.AmgId,
                                Profile       = mb.Profile,
                                TrackCount    = mb.ReleaseMedia != null ? (short)mb.ReleaseMedia.Sum(x => x.TrackCount) : (short)0,
                                MusicBrainzId = mb.MusicBrainzId,
                                ITunesId      = mb.iTunesId,
                                Title         = result.Title ?? mb.ReleaseTitle,
                                Thumbnail     = mb.ReleaseThumbnailUrl != null ? WebHelper.BytesForImageUrl(mb.ReleaseThumbnailUrl) : null,
                                ReleaseType   = result.ReleaseType == ReleaseType.Unknown ? SafeParser.ToEnum <ReleaseType>(mb.ReleaseType) : result.ReleaseType
                            });
                            if (mb.ReleaseLabel != null)
                            {
                                releaseLabels.AddRange(mb.ReleaseLabel);
                            }
                            if (mb.ReleaseMedia != null)
                            {
                                releaseMedias.AddRange(mb.ReleaseMedia);
                            }
                        }
                        if (mbResult.Errors != null)
                        {
                            resultsExceptions.AddRange(mbResult.Errors);
                        }
                    }

                    #endregion MusicBrainz

                    #region LastFm

                    if (this.LastFmReleaseSearchEngine.IsEnabled)
                    {
                        this.Logger.LogTrace("LastFmReleaseSearchEngine Release Search for ArtistName [{0}], ReleaseTitle [{1}]", metaData.Artist, result.Title);
                        var lastFmResult = await this.LastFmReleaseSearchEngine.PerformReleaseSearch(metaData.Artist, result.Title, 1);

                        if (lastFmResult.IsSuccess)
                        {
                            var l = lastFmResult.Data.First();
                            if (l.AlternateNames != null)
                            {
                                result.AlternateNames = result.AlternateNames.AddToDelimitedList(l.AlternateNames);
                            }
                            if (l.Tags != null)
                            {
                                result.Tags = result.Tags.AddToDelimitedList(l.Tags);
                            }
                            if (l.Urls != null)
                            {
                                result.URLs = result.URLs.AddToDelimitedList(l.Urls);
                            }
                            if (l.ImageUrls != null)
                            {
                                releaseImageUrls.AddRange(l.ImageUrls);
                            }
                            if (l.ReleaseGenres != null)
                            {
                                releaseGenres.AddRange(l.ReleaseGenres);
                            }
                            if (!string.IsNullOrEmpty(l.ReleaseTitle) && !l.ReleaseTitle.Equals(result.Title, StringComparison.OrdinalIgnoreCase))
                            {
                                result.AlternateNames.AddToDelimitedList(new string[] { l.ReleaseTitle });
                            }
                            result.CopyTo(new Data.Release
                            {
                                ReleaseDate   = result.ReleaseDate ?? l.ReleaseDate,
                                AmgId         = l.AmgId,
                                Profile       = l.Profile,
                                LastFMId      = l.LastFMId,
                                LastFMSummary = l.LastFMSummary,
                                MusicBrainzId = l.MusicBrainzId,
                                ITunesId      = l.iTunesId,
                                Title         = result.Title ?? l.ReleaseTitle,
                                Thumbnail     = l.ReleaseThumbnailUrl != null ? WebHelper.BytesForImageUrl(l.ReleaseThumbnailUrl) : null,
                                ReleaseType   = result.ReleaseType == ReleaseType.Unknown ? SafeParser.ToEnum <ReleaseType>(l.ReleaseType) : result.ReleaseType
                            });
                            if (l.ReleaseLabel != null)
                            {
                                releaseLabels.AddRange(l.ReleaseLabel);
                            }
                            if (l.ReleaseMedia != null)
                            {
                                releaseMedias.AddRange(l.ReleaseMedia);
                            }
                        }
                        if (lastFmResult.Errors != null)
                        {
                            resultsExceptions.AddRange(lastFmResult.Errors);
                        }
                    }

                    #endregion LastFm

                    #region Spotify

                    if (this.SpotifyReleaseSearchEngine.IsEnabled)
                    {
                        this.Logger.LogTrace("SpotifyReleaseSearchEngine Release Search for ArtistName [{0}], ReleaseTitle [{1}]", metaData.Artist, result.Title);
                        var spotifyResult = await this.SpotifyReleaseSearchEngine.PerformReleaseSearch(metaData.Artist, result.Title, 1);

                        if (spotifyResult.IsSuccess)
                        {
                            var s = spotifyResult.Data.First();
                            if (s.Tags != null)
                            {
                                result.Tags = result.Tags.AddToDelimitedList(s.Tags);
                            }
                            if (s.Urls != null)
                            {
                                result.URLs = result.URLs.AddToDelimitedList(s.Urls);
                            }
                            if (s.ImageUrls != null)
                            {
                                releaseImageUrls.AddRange(s.ImageUrls);
                            }
                            if (s.ReleaseGenres != null)
                            {
                                releaseGenres.AddRange(s.ReleaseGenres);
                            }
                            if (!string.IsNullOrEmpty(s.ReleaseTitle) && !s.ReleaseTitle.Equals(result.Title, StringComparison.OrdinalIgnoreCase))
                            {
                                result.AlternateNames.AddToDelimitedList(new string[] { s.ReleaseTitle });
                            }
                            result.CopyTo(new Data.Release
                            {
                                ReleaseDate   = result.ReleaseDate ?? s.ReleaseDate,
                                AmgId         = s.AmgId,
                                Profile       = this.HttpEncoder.HtmlEncode(s.Profile),
                                SpotifyId     = s.SpotifyId,
                                MusicBrainzId = s.MusicBrainzId,
                                ITunesId      = s.iTunesId,
                                Title         = result.Title ?? s.ReleaseTitle,
                                Thumbnail     = s.ReleaseThumbnailUrl != null ? WebHelper.BytesForImageUrl(s.ReleaseThumbnailUrl) : null,
                                ReleaseType   = result.ReleaseType == ReleaseType.Unknown ? SafeParser.ToEnum <ReleaseType>(s.ReleaseType) : result.ReleaseType
                            });
                            if (s.ReleaseLabel != null)
                            {
                                releaseLabels.AddRange(s.ReleaseLabel);
                            }
                            if (s.ReleaseMedia != null)
                            {
                                releaseMedias.AddRange(s.ReleaseMedia);
                            }
                        }
                        if (spotifyResult.Errors != null)
                        {
                            resultsExceptions.AddRange(spotifyResult.Errors);
                        }
                    }

                    #endregion Spotify

                    #region Discogs

                    if (this.DiscogsReleaseSearchEngine.IsEnabled)
                    {
                        this.Logger.LogTrace("DiscogsReleaseSearchEngine Release Search for ArtistName [{0}], ReleaseTitle [{1}]", metaData.Artist, result.Title);
                        var discogsResult = await this.DiscogsReleaseSearchEngine.PerformReleaseSearch(metaData.Artist, result.Title, 1);

                        if (discogsResult.IsSuccess)
                        {
                            var d = discogsResult.Data.First();
                            if (d.Urls != null)
                            {
                                result.URLs = result.URLs.AddToDelimitedList(d.Urls);
                            }
                            if (d.ImageUrls != null)
                            {
                                releaseImageUrls.AddRange(d.ImageUrls);
                            }
                            if (d.AlternateNames != null)
                            {
                                result.AlternateNames = result.AlternateNames.AddToDelimitedList(d.AlternateNames);
                            }
                            if (!string.IsNullOrEmpty(d.ReleaseTitle) && !d.ReleaseTitle.Equals(result.Title, StringComparison.OrdinalIgnoreCase))
                            {
                                result.AlternateNames.AddToDelimitedList(new string[] { d.ReleaseTitle });
                            }
                            result.CopyTo(new Data.Release
                            {
                                Profile     = this.HttpEncoder.HtmlEncode(d.Profile),
                                DiscogsId   = d.DiscogsId,
                                Title       = result.Title ?? d.ReleaseTitle,
                                Thumbnail   = d.ReleaseThumbnailUrl != null ? WebHelper.BytesForImageUrl(d.ReleaseThumbnailUrl) : null,
                                ReleaseType = result.ReleaseType == ReleaseType.Unknown ? SafeParser.ToEnum <ReleaseType>(d.ReleaseType) : result.ReleaseType
                            });
                            if (d.ReleaseLabel != null)
                            {
                                releaseLabels.AddRange(d.ReleaseLabel);
                            }
                            if (d.ReleaseMedia != null)
                            {
                                releaseMedias.AddRange(d.ReleaseMedia);
                            }
                        }
                        if (discogsResult.Errors != null)
                        {
                            resultsExceptions.AddRange(discogsResult.Errors);
                        }
                    }

                    #endregion Discogs
                }
                catch (Exception ex)
                {
                    this.Logger.LogError(ex);
                }

                this.Logger.LogTrace("Metadata Providers Search Complete. [{0}]", sw.ElapsedMilliseconds);
            }
            else
            {
                this.Logger.LogTrace("Skipped Metadata Providers Search, DontDoMetaDataProvidersSearchArtists set for Artist [{0}].", metaData.Artist);
            }

            if (result.AlternateNames != null)
            {
                result.AlternateNames = string.Join("|", result.AlternateNames.ToListFromDelimited().Distinct().OrderBy(x => x));
            }
            if (result.URLs != null)
            {
                result.URLs = string.Join("|", result.URLs.ToListFromDelimited().Distinct().OrderBy(x => x));
            }
            if (result.Tags != null)
            {
                result.Tags = string.Join("|", result.Tags.ToListFromDelimited().Distinct().OrderBy(x => x));
            }
            if (releaseGenres.Any())
            {
                result.Genres = new List <ReleaseGenre>();
                foreach (var releaseGenre in releaseGenres.Where(x => !string.IsNullOrEmpty(x)).GroupBy(x => x).Select(x => x.First()))
                {
                    var rg = releaseGenre.Trim();
                    if (!string.IsNullOrEmpty(rg))
                    {
                        result.Genres.Add(new Data.ReleaseGenre
                        {
                            Genre = (this.DbContext.Genres.Where(x => x.Name.ToLower() == rg.ToLower()).FirstOrDefault() ?? new Data.Genre {
                                Name = rg
                            })
                        });
                    }
                }
                ;
            }
            if (releaseImageUrls.Any())
            {
                var imageBag = new ConcurrentBag <Data.Image>();
                var i        = releaseImageUrls.Select(async url =>
                {
                    imageBag.Add(await WebHelper.GetImageFromUrlAsync(url));
                });
                await Task.WhenAll(i);

                // If the release has images merge any fetched images
                var existingImages = result.Images != null?result.Images.ToList() : new List <Data.Image>();

                existingImages.AddRange(imageBag.ToList());
                // Now set release images to be unique image based on image hash
                result.Images = existingImages.Where(x => x != null && x.Bytes != null).GroupBy(x => x.Signature).Select(x => x.First()).Take(this.Configuration.Processing.MaximumReleaseImagesToAdd).ToList();
                if (result.Thumbnail == null && result.Images != null)
                {
                    result.Thumbnail = result.Images.First().Bytes;
                }
            }

            if (releaseLabels.Any())
            {
                result.Labels = releaseLabels.GroupBy(x => x.CatalogNumber).Select(x => x.First()).Select(x => new Data.ReleaseLabel
                {
                    CatalogNumber = x.CatalogNumber,
                    BeginDate     = x.BeginDate,
                    EndDate       = x.EndDate,
                    Status        = Statuses.New,
                    Label         = new Data.Label
                    {
                        Name           = x.Label.LabelName,
                        SortName       = x.Label.LabelSortName,
                        MusicBrainzId  = x.Label.MusicBrainzId,
                        BeginDate      = x.Label.StartDate,
                        EndDate        = x.Label.EndDate,
                        ImageUrl       = x.Label.LabelImageUrl,
                        AlternateNames = x.Label.AlternateNames.ToDelimitedList(),
                        URLs           = x.Label.Urls.ToDelimitedList(),
                        Status         = Statuses.New
                    }
                }).ToList();
            }

            if (releaseMedias.Any())
            {
                var resultReleaseMedias = new List <Data.ReleaseMedia>();
                foreach (var releaseMedia in releaseMedias.GroupBy(x => x.ReleaseMediaNumber).Select(x => x.First()))
                {
                    var rm = new Data.ReleaseMedia
                    {
                        MediaNumber = releaseMedia.ReleaseMediaNumber ?? 0,
                        SubTitle    = releaseMedia.ReleaseMediaSubTitle,
                        TrackCount  = releaseMedia.TrackCount ?? 0,
                        Status      = Statuses.New
                    };
                    var rmTracks = new List <Data.Track>();
                    foreach (var releaseTrack in releaseMedias.Where(x => x.ReleaseMediaNumber == releaseMedia.ReleaseMediaNumber)
                             .SelectMany(x => x.Tracks)
                             .Where(x => x.TrackNumber.HasValue)
                             .OrderBy(x => x.TrackNumber))
                    {
                        var foundTrack = true;
                        var rmTrack    = rmTracks.FirstOrDefault(x => x.TrackNumber == releaseTrack.TrackNumber.Value);
                        if (rmTrack == null)
                        {
                            Data.Artist trackArtist = null;
                            if (releaseTrack.Artist != null)
                            {
                                trackArtist = new Data.Artist
                                {
                                    Name       = releaseTrack.Artist.ArtistName,
                                    SpotifyId  = releaseTrack.Artist.SpotifyId,
                                    ArtistType = releaseTrack.Artist.ArtistType
                                };
                            }
                            rmTrack = new Data.Track
                            {
                                TrackArtist    = trackArtist,
                                TrackArtists   = releaseTrack.Artists,
                                TrackNumber    = releaseTrack.TrackNumber.Value,
                                MusicBrainzId  = releaseTrack.MusicBrainzId,
                                SpotifyId      = releaseTrack.SpotifyId,
                                AmgId          = releaseTrack.AmgId,
                                Title          = releaseTrack.Title,
                                AlternateNames = releaseTrack.AlternateNames.ToDelimitedList(),
                                Duration       = releaseTrack.Duration,
                                Tags           = releaseTrack.Tags.ToDelimitedList(),
                                ISRC           = releaseTrack.ISRC,
                                LastFMId       = releaseTrack.LastFMId,
                                Status         = Statuses.New
                            };
                            foundTrack = false;
                        }
                        rmTrack.Duration      = rmTrack.Duration ?? releaseTrack.Duration;
                        rmTrack.MusicBrainzId = rmTrack.MusicBrainzId ?? releaseTrack.MusicBrainzId;
                        rmTrack.SpotifyId     = rmTrack.SpotifyId ?? releaseTrack.SpotifyId;
                        rmTrack.AmgId         = rmTrack.AmgId ?? releaseTrack.AmgId;
                        rmTrack.Title         = rmTrack.Title ?? releaseTrack.Title;
                        rmTrack.Duration      = releaseTrack.Duration;
                        rmTrack.Tags          = rmTrack.Tags == null?releaseTrack.Tags.ToDelimitedList() : rmTrack.Tags.AddToDelimitedList(releaseTrack.Tags);

                        rmTrack.AlternateNames = rmTrack.AlternateNames == null?releaseTrack.AlternateNames.ToDelimitedList() : rmTrack.AlternateNames.AddToDelimitedList(releaseTrack.AlternateNames);

                        rmTrack.ISRC     = rmTrack.ISRC ?? releaseTrack.ISRC;
                        rmTrack.LastFMId = rmTrack.LastFMId ?? releaseTrack.LastFMId;
                        if (!foundTrack)
                        {
                            rmTracks.Add(rmTrack);
                        }
                    }
                    rm.Tracks     = rmTracks;
                    rm.TrackCount = (short)rmTracks.Count();
                    resultReleaseMedias.Add(rm);
                }
                result.Medias     = resultReleaseMedias;
                result.TrackCount = (short)releaseMedias.SelectMany(x => x.Tracks).Count();
            }

            if (metaData.Images != null && metaData.Images.Any())
            {
                var image = metaData.Images.FirstOrDefault(x => x.Type == AudioMetaDataImageType.FrontCover);
                if (image == null)
                {
                    image = metaData.Images.FirstOrDefault();
                }
                // If there is an image on the metadata file itself then that over-rides metadata providers.
                if (image != null)
                {
                    result.Thumbnail = image.Data;
                }
            }
            if (!string.IsNullOrEmpty(artistFolder))
            {
                // If any file exist for cover that over-rides whatever if found in metadata providers.
                var releaseFolder = new DirectoryInfo(result.ReleaseFileFolder(artistFolder));
                if (releaseFolder.Exists)
                {
                    var cover = ImageHelper.FindImageTypeInDirectory(releaseFolder, ImageType.Release);
                    if (cover.Any())
                    {
                        // Read image and convert to jpeg
                        var coverFileName = cover.First().FullName;
                        result.Thumbnail = File.ReadAllBytes(coverFileName);
                        this.Logger.LogDebug("Using Release Cover File [{0}]", coverFileName);
                    }
                }
            }

            if (result.Thumbnail != null)
            {
                result.Thumbnail = ImageHelper.ResizeImage(result.Thumbnail, this.Configuration.ThumbnailImageSize.Width, this.Configuration.ThumbnailImageSize.Height);
                result.Thumbnail = ImageHelper.ConvertToJpegFormat(result.Thumbnail);
            }
            sw.Stop();
            return(new OperationResult <Data.Release>
            {
                Data = result,
                IsSuccess = result != null,
                Errors = resultsExceptions,
                OperationTime = sw.ElapsedMilliseconds
            });
        }
Example #16
0
        public async Task <OperationResult <Artist> > Add(Artist artist)
        {
            SimpleContract.Requires <ArgumentNullException>(artist != null, "Invalid Artist");

            try
            {
                var ArtistGenreTables = artist.Genres;
                var ArtistImages      = artist.Images;
                var now = DateTime.UtcNow;
                artist.AlternateNames = artist.AlternateNames.AddToDelimitedList(new string[] { artist.Name.ToAlphanumericName() });
                artist.Genres         = null;
                artist.Images         = null;
                if (artist.Thumbnail == null && ArtistImages != null)
                {
                    // Set the thumbnail to the first image
                    var firstImageWithNotNullBytes = ArtistImages.Where(x => x.Bytes != null).FirstOrDefault();
                    if (firstImageWithNotNullBytes != null)
                    {
                        artist.Thumbnail = firstImageWithNotNullBytes.Bytes;
                        if (artist.Thumbnail != null)
                        {
                            artist.Thumbnail = ImageHelper.ResizeImage(artist.Thumbnail, this.Configuration.ThumbnailImageSize.Width, this.Configuration.ThumbnailImageSize.Height);
                            artist.Thumbnail = ImageHelper.ConvertToJpegFormat(artist.Thumbnail);
                        }
                    }
                }
                if (!artist.IsValid)
                {
                    return(new OperationResult <Artist>
                    {
                        Errors = new Exception[1] {
                            new Exception("Artist is Invalid")
                        }
                    });
                }
                var addArtistResult = this.DbContext.Artists.Add(artist);
                int inserted        = 0;
                inserted = await this.DbContext.SaveChangesAsync();

                this._addedArtistIds.Add(artist.Id);
                if (artist.Id < 1 && addArtistResult.Entity.Id > 0)
                {
                    artist.Id = addArtistResult.Entity.Id;
                }
                if (inserted > 0 && artist.Id > 0)
                {
                    if (ArtistGenreTables != null && ArtistGenreTables.Any(x => x.GenreId == null))
                    {
                        string sql = null;
                        try
                        {
                            foreach (var ArtistGenreTable in ArtistGenreTables)
                            {
                                var genre = this.DbContext.Genres.FirstOrDefault(x => x.Name.ToLower().Trim() == ArtistGenreTable.Genre.Name.ToLower().Trim());
                                if (genre == null)
                                {
                                    genre = new Genre
                                    {
                                        Name = ArtistGenreTable.Genre.Name
                                    };
                                    this.DbContext.Genres.Add(genre);
                                    await this.DbContext.SaveChangesAsync();
                                }
                                if (genre != null && genre.Id > 0)
                                {
                                    await this.DbContext.Database.ExecuteSqlCommandAsync("INSERT INTO `artistGenreTable` (artistId, genreId) VALUES ({0}, {1});", artist.Id, genre.Id);
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            this.Logger.LogError(ex, "Sql [" + sql + "] Exception [" + ex.Serialize() + "]");
                        }
                    }
                    if (ArtistImages != null && ArtistImages.Any(x => x.Status == Statuses.New))
                    {
                        foreach (var ArtistImage in ArtistImages)
                        {
                            this.DbContext.Images.Add(new Image
                            {
                                ArtistId  = artist.Id,
                                Url       = ArtistImage.Url,
                                Signature = ArtistImage.Signature,
                                Bytes     = ArtistImage.Bytes
                            });
                        }
                        inserted = await this.DbContext.SaveChangesAsync();
                    }
                    this.Logger.LogInformation("Added New Artist: [{0}]", artist.ToString());
                }
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex, ex.Serialize());
            }
            return(new OperationResult <Artist>
            {
                IsSuccess = artist.Id > 0,
                Data = artist
            });
        }
Example #17
0
        public async Task <OperationResult <Artist> > Add(Artist artist)
        {
            var sw = Stopwatch.StartNew();

            SimpleContract.Requires <ArgumentNullException>(artist != null, "Invalid Artist");

            try
            {
                var artistGenreTables = artist.Genres;
                var artistImages      = artist.Images ?? new List <Image>();
                var now = DateTime.UtcNow;
                artist.AlternateNames = artist.AlternateNames.AddToDelimitedList(new[] { artist.Name.ToAlphanumericName() });
                artist.Genres         = null;
                artist.Images         = null;
                if (!artist.IsValid)
                {
                    return(new OperationResult <Artist>
                    {
                        Errors = new Exception[1] {
                            new Exception("Artist is Invalid")
                        }
                    });
                }
                var addArtistResult = DbContext.Artists.Add(artist);
                var inserted        = await DbContext.SaveChangesAsync().ConfigureAwait(false);

                _addedArtistIds.Add(artist.Id);
                if (artist.Id < 1 && addArtistResult.Entity.Id > 0)
                {
                    artist.Id = addArtistResult.Entity.Id;
                }
                if (inserted > 0 && artist.Id > 0)
                {
                    if (artistGenreTables != null)
                    {
                        foreach (var artistGenreTable in artistGenreTables.Where(x => x?.Genre?.Name != null).Select(x => x.Genre?.Name).Distinct())
                        {
                            var genreName      = artistGenreTable.ToAlphanumericName().ToTitleCase();
                            var normalizedName = genreName.ToUpper();
                            if (string.IsNullOrEmpty(genreName))
                            {
                                continue;
                            }
                            if (genreName.Length > 100)
                            {
                                var originalName = genreName;
                                genreName = genreName.Substring(0, 99);
                                Logger.LogWarning($"Genre Name Too long was [{originalName}] truncated to [{genreName}]");
                            }
                            var genre = DbContext.Genres.FirstOrDefault(x => x.NormalizedName == normalizedName);
                            if (genre == null)
                            {
                                genre = new Genre
                                {
                                    Name           = genreName,
                                    NormalizedName = normalizedName
                                };
                                DbContext.Genres.Add(genre);
                                await DbContext.SaveChangesAsync().ConfigureAwait(false);
                            }
                            DbContext.ArtistGenres.Add(new ArtistGenre
                            {
                                ArtistId = artist.Id,
                                GenreId  = genre.Id
                            });
                            await DbContext.SaveChangesAsync().ConfigureAwait(false);
                        }
                    }

                    if (artistImages.Any(x => x.Status == Statuses.New))
                    {
                        var    artistFolder = artist.ArtistFileFolder(Configuration, true);
                        var    looper       = -1;
                        string releaseImageFilename;
                        foreach (var artistImage in artistImages)
                        {
                            if (!(artistImage?.Bytes.Length > 0))
                            {
                                continue;
                            }
                            artistImage.Bytes = ImageHelper.ConvertToJpegFormat(artistImage.Bytes);
                            if (looper == -1)
                            {
                                releaseImageFilename = Path.Combine(artistFolder, ImageHelper.ArtistImageFilename);
                            }
                            else
                            {
                                releaseImageFilename = Path.Combine(artistFolder, string.Format(ImageHelper.ArtistSecondaryImageFilename, looper.ToString("00")));
                            }
                            while (File.Exists(releaseImageFilename))
                            {
                                looper++;
                                releaseImageFilename = Path.Combine(artistFolder, string.Format(ImageHelper.ArtistSecondaryImageFilename, looper.ToString("00")));
                            }
                            File.WriteAllBytes(releaseImageFilename, artistImage.Bytes);
                            looper++;
                        }
                    }
                    sw.Stop();
                    Logger.LogTrace($"Added New Artist: Elapsed Time [{ sw.ElapsedMilliseconds }], Artist `{ artist }`");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, $"Error Adding Artist `{ artist }`, Ex [{ ex.Serialize() }]");
            }
            return(new OperationResult <Artist>
            {
                IsSuccess = artist.Id > 0,
                Data = artist,
                OperationTime = sw.ElapsedMilliseconds
            });
        }
Example #18
0
        public async Task <OperationResult <Artist> > PerformMetaDataProvidersArtistSearch(AudioMetaData metaData)
        {
            SimpleContract.Requires <ArgumentNullException>(metaData != null, "Invalid MetaData");
            SimpleContract.Requires <ArgumentNullException>(!string.IsNullOrEmpty(metaData.Artist), "Invalid MetaData, Missing Artist");

            var sw = new Stopwatch();

            sw.Start();
            var result = new Artist
            {
                Name = metaData.Artist.ToTitleCase(false)
            };
            var resultsExceptions = new List <Exception>();
            var artistGenres      = new List <string>();
            var artistImageUrls   = new List <string>();
            var artistName        = metaData.Artist;

            try
            {
                if (ITunesArtistSearchEngine.IsEnabled)
                {
                    var sw2          = Stopwatch.StartNew();
                    var iTunesResult = await ITunesArtistSearchEngine.PerformArtistSearch(artistName, 1).ConfigureAwait(false);

                    if (iTunesResult.IsSuccess)
                    {
                        var i = iTunesResult.Data.First();
                        if (i.AlternateNames != null)
                        {
                            result.AlternateNames = result.AlternateNames.AddToDelimitedList(i.AlternateNames);
                        }
                        if (i.Tags != null)
                        {
                            result.Tags = result.Tags.AddToDelimitedList(i.Tags);
                        }
                        if (i.Urls != null)
                        {
                            result.URLs = result.URLs.AddToDelimitedList(i.Urls);
                        }
                        if (i.ISNIs != null)
                        {
                            result.ISNI = result.ISNI.AddToDelimitedList(i.ISNIs);
                        }
                        if (i.ImageUrls != null)
                        {
                            artistImageUrls.AddRange(i.ImageUrls);
                        }
                        if (i.ArtistGenres != null)
                        {
                            artistGenres.AddRange(i.ArtistGenres);
                        }
                        result.CopyTo(new Artist
                        {
                            EndDate    = i.EndDate,
                            BioContext = i.Bio,
                            Profile    = i.Profile,
                            ITunesId   = i.iTunesId,
                            BeginDate  = i.BeginDate,
                            Name       = result.Name ?? i.ArtistName,
                            SortName   = result.SortName ?? i.ArtistSortName,
                            ArtistType = result.ArtistType ?? i.ArtistType
                        });
                    }

                    if (iTunesResult.Errors != null)
                    {
                        resultsExceptions.AddRange(iTunesResult.Errors);
                    }

                    sw2.Stop();
                    Logger.LogTrace($"PerformMetaDataProvidersArtistSearch: ITunesArtistSearchEngine Complete [{ sw2.ElapsedMilliseconds }]");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "iTunesArtistSearch: " + ex.Serialize());
            }

            try
            {
                if (MusicBrainzArtistSearchEngine.IsEnabled)
                {
                    var sw2      = Stopwatch.StartNew();
                    var mbResult = await MusicBrainzArtistSearchEngine.PerformArtistSearch(result.Name, 1).ConfigureAwait(false);

                    if (mbResult.IsSuccess)
                    {
                        var mb = mbResult.Data.First();
                        if (mb.AlternateNames != null)
                        {
                            result.AlternateNames = result.AlternateNames.AddToDelimitedList(mb.AlternateNames);
                        }
                        if (mb.Tags != null)
                        {
                            result.Tags = result.Tags.AddToDelimitedList(mb.Tags);
                        }
                        if (mb.Urls != null)
                        {
                            result.URLs = result.URLs.AddToDelimitedList(mb.Urls);
                        }
                        if (mb.ISNIs != null)
                        {
                            result.ISNI = result.ISNI.AddToDelimitedList(mb.ISNIs);
                        }
                        if (mb.ImageUrls != null)
                        {
                            artistImageUrls.AddRange(mb.ImageUrls);
                        }
                        if (mb.ArtistGenres != null)
                        {
                            artistGenres.AddRange(mb.ArtistGenres);
                        }
                        if (!string.IsNullOrEmpty(mb.ArtistName) &&
                            !mb.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            result.AlternateNames.AddToDelimitedList(new[] { mb.ArtistName });
                        }
                        result.CopyTo(new Artist
                        {
                            EndDate       = mb.EndDate,
                            BioContext    = mb.Bio,
                            Profile       = mb.Profile,
                            MusicBrainzId = mb.MusicBrainzId,
                            DiscogsId     = mb.DiscogsId,
                            SpotifyId     = mb.SpotifyId,
                            ITunesId      = mb.iTunesId,
                            AmgId         = mb.AmgId,
                            BeginDate     = mb.BeginDate,
                            Name          = result.Name ?? mb.ArtistName,
                            SortName      = result.SortName ?? mb.ArtistSortName,
                            ArtistType    = mb.ArtistType
                        });
                    }

                    if (mbResult.Errors != null)
                    {
                        resultsExceptions.AddRange(mbResult.Errors);
                    }
                    sw2.Stop();
                    Logger.LogTrace($"PerformMetaDataProvidersArtistSearch: MusicBrainzArtistSearchEngine Complete [{ sw2.ElapsedMilliseconds }]");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "MusicBrainzArtistSearch: " + ex.Serialize());
            }

            try
            {
                if (LastFmArtistSearchEngine.IsEnabled)
                {
                    var sw2          = Stopwatch.StartNew();
                    var lastFmResult = await LastFmArtistSearchEngine.PerformArtistSearch(result.Name, 1).ConfigureAwait(false);

                    if (lastFmResult.IsSuccess)
                    {
                        var l = lastFmResult.Data.First();
                        if (l.AlternateNames != null)
                        {
                            result.AlternateNames = result.AlternateNames.AddToDelimitedList(l.AlternateNames);
                        }
                        if (l.Tags != null)
                        {
                            result.Tags = result.Tags.AddToDelimitedList(l.Tags);
                        }
                        if (l.Urls != null)
                        {
                            result.URLs = result.URLs.AddToDelimitedList(l.Urls);
                        }
                        if (l.ISNIs != null)
                        {
                            result.ISNI = result.ISNI.AddToDelimitedList(l.ISNIs);
                        }
                        if (l.ImageUrls != null)
                        {
                            artistImageUrls.AddRange(l.ImageUrls);
                        }
                        if (l.ArtistGenres != null)
                        {
                            artistGenres.AddRange(l.ArtistGenres);
                        }
                        if (!string.IsNullOrEmpty(l.ArtistName) &&
                            !l.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            result.AlternateNames.AddToDelimitedList(new[] { l.ArtistName });
                        }
                        result.CopyTo(new Artist
                        {
                            EndDate       = l.EndDate,
                            BioContext    = HttpEncoder.HtmlEncode(l.Bio),
                            Profile       = HttpEncoder.HtmlEncode(l.Profile),
                            MusicBrainzId = l.MusicBrainzId,
                            BeginDate     = l.BeginDate,
                            Name          = result.Name ?? l.ArtistName,
                            SortName      = result.SortName ?? l.ArtistSortName,
                            ArtistType    = result.ArtistType ?? l.ArtistType
                        });
                    }

                    if (lastFmResult.Errors != null)
                    {
                        resultsExceptions.AddRange(lastFmResult.Errors);
                    }
                    sw2.Stop();
                    Logger.LogTrace($"PerformMetaDataProvidersArtistSearch: LastFmArtistSearchEngine Complete [{ sw2.ElapsedMilliseconds }]");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "LastFMArtistSearch: " + ex.Serialize());
            }

            try
            {
                if (SpotifyArtistSearchEngine.IsEnabled)
                {
                    var sw2           = Stopwatch.StartNew();
                    var spotifyResult = await SpotifyArtistSearchEngine.PerformArtistSearch(result.Name, 1).ConfigureAwait(false);

                    if (spotifyResult.IsSuccess)
                    {
                        var s = spotifyResult.Data.First();
                        if (s.Tags != null)
                        {
                            result.Tags = result.Tags.AddToDelimitedList(s.Tags);
                        }
                        if (s.Urls != null)
                        {
                            result.URLs = result.URLs.AddToDelimitedList(s.Urls);
                        }
                        if (s.ImageUrls != null)
                        {
                            artistImageUrls.AddRange(s.ImageUrls);
                        }
                        if (s.ArtistGenres != null)
                        {
                            artistGenres.AddRange(s.ArtistGenres);
                        }
                        if (!string.IsNullOrEmpty(s.ArtistName) &&
                            !s.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            result.AlternateNames.AddToDelimitedList(new[] { s.ArtistName });
                        }
                        result.CopyTo(new Artist
                        {
                            EndDate       = s.EndDate,
                            BioContext    = s.Bio,
                            Profile       = HttpEncoder.HtmlEncode(s.Profile),
                            MusicBrainzId = s.MusicBrainzId,
                            SpotifyId     = s.SpotifyId,
                            BeginDate     = s.BeginDate,
                            Name          = result.Name ?? s.ArtistName,
                            SortName      = result.SortName ?? s.ArtistSortName,
                            ArtistType    = result.ArtistType ?? s.ArtistType
                        });
                    }

                    if (spotifyResult.Errors != null)
                    {
                        resultsExceptions.AddRange(spotifyResult.Errors);
                    }
                    sw2.Stop();
                    Logger.LogTrace($"PerformMetaDataProvidersArtistSearch: SpotifyArtistSearchEngine Complete [{ sw2.ElapsedMilliseconds }]");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "SpotifyArtistSearch: " + ex.Serialize());
            }

            try
            {
                if (DiscogsArtistSearchEngine.IsEnabled)
                {
                    var sw2           = Stopwatch.StartNew();
                    var discogsResult = await DiscogsArtistSearchEngine.PerformArtistSearch(result.Name, 1).ConfigureAwait(false);

                    if (discogsResult.IsSuccess)
                    {
                        var d = discogsResult?.Data?.FirstOrDefault();
                        if (d != null)
                        {
                            if (d.Urls != null)
                            {
                                result.URLs = result.URLs.AddToDelimitedList(d.Urls);
                            }
                            if (d.ImageUrls != null)
                            {
                                artistImageUrls.AddRange(d.ImageUrls);
                            }
                            if (d.AlternateNames != null)
                            {
                                result.AlternateNames = result.AlternateNames.AddToDelimitedList(d.AlternateNames);
                            }
                            if (!string.IsNullOrEmpty(d.ArtistName) &&
                                !d.ArtistName.Equals(result.Name, StringComparison.OrdinalIgnoreCase))
                            {
                                result.AlternateNames.AddToDelimitedList(new[] { d.ArtistName });
                            }
                            result.CopyTo(new Artist
                            {
                                Profile    = HttpEncoder.HtmlEncode(d.Profile),
                                DiscogsId  = d.DiscogsId,
                                Name       = result.Name ?? d.ArtistName,
                                RealName   = result.RealName ?? d.ArtistRealName,
                                ArtistType = result.ArtistType ?? d.ArtistType
                            });
                        }
                    }
                    if (discogsResult.Errors != null)
                    {
                        resultsExceptions.AddRange(discogsResult.Errors);
                    }
                    sw2.Stop();
                    Logger.LogTrace($"PerformMetaDataProvidersArtistSearch: DiscogsArtistSearchEngine Complete [{ sw2.ElapsedMilliseconds }]");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "DiscogsArtistSearch: " + ex.Serialize());
            }

            try
            {
                if (WikipediaArtistSearchEngine.IsEnabled)
                {
                    var sw2      = Stopwatch.StartNew();
                    var wikiName = result?.Name;
                    // Help get better results for bands with proper nouns (e.g. "Poison" vs "Poison Band")
                    if (!(result?.ArtistType ?? string.Empty).Equals("Person", StringComparison.OrdinalIgnoreCase))
                    {
                        wikiName += " band";
                    }
                    var wikipediaResult = await WikipediaArtistSearchEngine.PerformArtistSearch(wikiName, 1).ConfigureAwait(false);

                    if (wikipediaResult?.Data != null)
                    {
                        if (wikipediaResult.IsSuccess)
                        {
                            var w = wikipediaResult?.Data?.FirstOrDefault();
                            if (!string.IsNullOrEmpty(w?.Bio))
                            {
                                result.CopyTo(new Artist
                                {
                                    BioContext = HttpEncoder.HtmlEncode(w.Bio)
                                });
                            }
                        }

                        if (wikipediaResult.Errors != null)
                        {
                            resultsExceptions.AddRange(wikipediaResult.Errors);
                        }
                    }
                    sw2.Stop();
                    Logger.LogTrace($"PerformMetaDataProvidersArtistSearch: WikipediaArtistSearchEngine Complete [{ sw2.ElapsedMilliseconds }]");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "WikipediaArtistSearch: " + ex.Serialize());
            }

            try
            {
                if (result.AlternateNames != null)
                {
                    result.AlternateNames = string.Join("|", result.AlternateNames.ToListFromDelimited().Distinct().OrderBy(x => x));
                }
                if (result.URLs != null)
                {
                    result.URLs = string.Join("|", result.URLs.ToListFromDelimited().Distinct().OrderBy(x => x));
                }
                if (result.Tags != null)
                {
                    result.Tags = string.Join("|", result.Tags.ToListFromDelimited().Distinct().OrderBy(x => x));
                }
                if (artistGenres.Count > 0)
                {
                    var sw2        = Stopwatch.StartNew();
                    var genreInfos = from ag in artistGenres
                                     join g in DbContext.Genres on ag equals g.Name into gg
                                     from g in gg.DefaultIfEmpty()
                                     select new
                    {
                        newGenre      = ag.ToTitleCase(),
                        existingGenre = g
                    };
                    result.Genres = new List <ArtistGenre>();
                    foreach (var genreInfo in genreInfos)
                    {
                        var ag = new ArtistGenre
                        {
                            Genre = genreInfo.existingGenre ?? new Genre
                            {
                                Name           = genreInfo.newGenre,
                                NormalizedName = genreInfo.newGenre.ToAlphanumericName()
                            }
                        };
                        if (!result.Genres.Any(x => x.Genre.NormalizedName == ag.Genre.NormalizedName))
                        {
                            result.Genres.Add(ag);
                        }
                    }
                    sw2.Stop();
                    Logger.LogTrace($"PerformMetaDataProvidersArtistSearch: Artist Genre Processing Complete [{ sw2.ElapsedMilliseconds }]");
                }

                if (artistImageUrls.Count > 0)
                {
                    var sw2      = Stopwatch.StartNew();
                    var imageBag = new ConcurrentBag <IImage>();
                    var i        = artistImageUrls.Select(async url => imageBag.Add(await WebHelper.GetImageFromUrlAsync(url).ConfigureAwait(false)));
                    await Task.WhenAll(i).ConfigureAwait(false);

                    result.Images = imageBag.Where(x => x?.Bytes != null)
                                    .GroupBy(x => x.Signature)
                                    .Select(x => x.First())
                                    .Take(Configuration.Processing.MaximumArtistImagesToAdd)
                                    .ToList();
                    sw2.Stop();
                    Logger.LogTrace($"PerformMetaDataProvidersArtistSearch: Image Url Processing Complete [{ sw2.ElapsedMilliseconds }]");
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "CombiningResults: " + ex.Serialize());
            }

            result.SortName = result.SortName.ToTitleCase();
            if (!string.IsNullOrEmpty(result.ArtistType))
            {
                switch (result.ArtistType.ToLower().Replace('-', ' '))
                {
                case "artist":
                case "artists":
                case "one man band":
                case "one woman band":
                case "solo":
                case "person":
                    result.ArtistType = "Person";
                    break;

                case "band":
                case "big band":
                case "duet":
                case "jug band":
                case "quartet":
                case "quartette":
                case "sextet":
                case "trio":
                case "group":
                    result.ArtistType = "Group";
                    break;

                case "orchestra":
                    result.ArtistType = "Orchestra";
                    break;

                case "choir band":
                case "choir":
                    result.ArtistType = "Choir";
                    break;

                case "movie part":
                case "movie role":
                case "role":
                case "character":
                    result.ArtistType = "Character";
                    break;

                default:
                    Logger.LogWarning(string.Format("Unknown Artist Type [{0}]", result.ArtistType));
                    result.ArtistType = "Other";
                    break;
                }
            }

            sw.Stop();
            return(new OperationResult <Artist>
            {
                Data = result,
                IsSuccess = result != null,
                Errors = resultsExceptions,
                OperationTime = sw.ElapsedMilliseconds
            });
        }
Example #19
0
        public async Task <OperationResult <Data.Release> > GetByName(Data.Artist artist, AudioMetaData metaData, bool doFindIfNotInDatabase = false, bool doAddTracksInDatabase = false, int?submissionId = null)
        {
            SimpleContract.Requires <ArgumentNullException>(artist != null, "Invalid Artist");
            SimpleContract.Requires <ArgumentOutOfRangeException>(artist.Id > 0, "Invalid Artist Id");
            try
            {
                var sw = new Stopwatch();
                sw.Start();
                var cacheRegion   = (new Data.Release {
                    Artist = artist, Title = metaData.Release
                }).CacheRegion;
                var cacheKey      = string.Format("urn:release_by_artist_id_and_name:{0}:{1}", artist.Id, metaData.Release);
                var resultInCache = this.CacheManager.Get <Data.Release>(cacheKey, cacheRegion);
                if (resultInCache != null)
                {
                    sw.Stop();
                    return(new OperationResult <Data.Release>
                    {
                        IsSuccess = true,
                        OperationTime = sw.ElapsedMilliseconds,
                        Data = resultInCache
                    });
                }

                var searchName        = metaData.Release.NormalizeName().ToLower();
                var specialSearchName = metaData.Release.ToAlphanumericName();

                var altStart = $"{ searchName }|";
                var altIn    = $"|{ searchName }|";
                var altEnds  = $"|{ searchName }";

                var altStartSpecial = $"{ specialSearchName }|";
                var altInSpecial    = $"|{ specialSearchName }|";
                var altEndsSpecial  = $"|{ specialSearchName }";

                var release = (from r in this.DbContext.Releases
                               where (r.ArtistId == artist.Id)
                               where (r.Title.ToLower() == searchName ||
                                      r.AlternateNames.ToLower() == searchName ||
                                      r.AlternateNames.ToLower() == specialSearchName ||
                                      r.AlternateNames.ToLower().Contains(altStart) ||
                                      r.AlternateNames.ToLower().Contains(altIn) ||
                                      r.AlternateNames.ToLower().Contains(altEnds) ||
                                      r.AlternateNames.ToLower().Contains(altStartSpecial) ||
                                      r.AlternateNames.ToLower().Contains(altInSpecial) ||
                                      r.AlternateNames.ToLower().Contains(altEndsSpecial))
                               select r
                               ).FirstOrDefault();

                sw.Stop();
                if (release == null || !release.IsValid)
                {
                    this.Logger.LogInformation("ReleaseFactory: Release Not Found For Artist `{0}` MetaData [{1}]", artist.ToString(), metaData.ToString());
                    if (doFindIfNotInDatabase)
                    {
                        OperationResult <Data.Release> releaseSearch = new OperationResult <Data.Release>();
                        try
                        {
                            releaseSearch = await this.PerformMetaDataProvidersReleaseSearch(metaData, artist.ArtistFileFolder(this.Configuration, this.Configuration.LibraryFolder), submissionId);
                        }
                        catch (Exception ex)
                        {
                            sw.Stop();
                            this.Logger.LogError(ex);
                            return(new OperationResult <Data.Release>
                            {
                                OperationTime = sw.ElapsedMilliseconds,
                                Errors = new Exception[1] {
                                    ex
                                }
                            });
                        }
                        if (releaseSearch.IsSuccess)
                        {
                            release          = releaseSearch.Data;
                            release.ArtistId = artist.Id;
                            var addResult = await this.Add(release, doAddTracksInDatabase);

                            if (!addResult.IsSuccess)
                            {
                                sw.Stop();
                                return(new OperationResult <Data.Release>
                                {
                                    OperationTime = sw.ElapsedMilliseconds,
                                    Errors = addResult.Errors
                                });
                            }
                        }
                    }
                }
                if (release != null)
                {
                    this.CacheManager.Add(cacheKey, release);
                }
                return(new OperationResult <Data.Release>
                {
                    IsSuccess = release != null,
                    OperationTime = sw.ElapsedMilliseconds,
                    Data = release
                });
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex);
            }
            return(new OperationResult <Data.Release>());
        }
Example #20
0
 public FolderProcessor(IRoadieSettings configuration, IHttpEncoder httpEncoder, string destinationRoot, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine, IArtistFactory artistFactory, IReleaseFactory releaseFactory, IImageFactory imageFactory, IReleaseLookupEngine releaseLookupEngine, IAudioMetaDataHelper audioMetaDataHelper)
     : base(configuration, httpEncoder, destinationRoot, context, cacheManager, logger, artistLookupEngine, artistFactory, releaseFactory, imageFactory, releaseLookupEngine, audioMetaDataHelper)
 {
     SimpleContract.Requires <ArgumentNullException>(!string.IsNullOrEmpty(destinationRoot), "Invalid Destination Folder");
     this._fileProcessor = new FileProcessor(configuration, httpEncoder, destinationRoot, context, cacheManager, logger, artistLookupEngine, artistFactory, releaseFactory, imageFactory, releaseLookupEngine, audioMetaDataHelper);
 }