コード例 #1
0
ファイル: LabelService.cs プロジェクト: liamdawson/roadie
        public async Task <OperationResult <bool> > UpdateLabel(User user, Label model)
        {
            var sw = new Stopwatch();

            sw.Start();
            var errors = new List <Exception>();
            var label  = this.DbContext.Labels.FirstOrDefault(x => x.RoadieId == model.Id);

            if (label == null)
            {
                return(new OperationResult <bool>(true, string.Format("Label Not Found [{0}]", model.Id)));
            }
            try
            {
                var now = DateTime.UtcNow;
                label.AlternateNames = model.AlternateNamesList.ToDelimitedList();
                label.BeginDate      = model.BeginDate;
                label.DiscogsId      = model.DiscogsId;
                label.EndDate        = model.EndDate;
                label.IsLocked       = model.IsLocked;
                label.MusicBrainzId  = model.MusicBrainzId;
                label.Name           = model.Name;
                label.Profile        = model.Profile;
                label.SortName       = model.SortName;
                label.Status         = SafeParser.ToEnum <Statuses>(model.Status);
                label.Tags           = model.TagsList.ToDelimitedList();
                label.URLs           = model.URLsList.ToDelimitedList();

                var labelImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
                if (labelImage != null)
                {
                    // Ensure is jpeg first
                    label.Thumbnail = ImageHelper.ConvertToJpegFormat(labelImage);

                    // Resize to store in database as thumbnail
                    label.Thumbnail = ImageHelper.ResizeImage(label.Thumbnail, this.Configuration.MediumImageSize.Width, this.Configuration.MediumImageSize.Height);
                }
                label.LastUpdated = now;
                await this.DbContext.SaveChangesAsync();

                this.CacheManager.ClearRegion(label.CacheRegion);
                this.Logger.LogInformation($"UpdateLabel `{ label }` By User `{ user }`");
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex);
                errors.Add(ex);
            }
            sw.Stop();

            return(new OperationResult <bool>
            {
                IsSuccess = !errors.Any(),
                Data = !errors.Any(),
                OperationTime = sw.ElapsedMilliseconds,
                Errors = errors
            });
        }
コード例 #2
0
        public async Task <OperationResult <bool> > UpdatePlaylist(User user, Playlist model)
        {
            var sw = new Stopwatch();

            sw.Start();
            var errors   = new List <Exception>();
            var playlist = DbContext.Playlists.FirstOrDefault(x => x.RoadieId == model.Id);

            if (playlist == null)
            {
                return(new OperationResult <bool>(true, string.Format("Label Not Found [{0}]", model.Id)));
            }
            try
            {
                var now = DateTime.UtcNow;
                playlist.AlternateNames = model.AlternateNamesList.ToDelimitedList();
                playlist.Description    = model.Description;
                playlist.IsLocked       = model.IsLocked;
                playlist.IsPublic       = model.IsPublic;
                playlist.Name           = model.Name;
                playlist.Status         = SafeParser.ToEnum <Statuses>(model.Status);
                playlist.Tags           = model.TagsList.ToDelimitedList();
                playlist.URLs           = model.URLsList.ToDelimitedList();

                var playlistImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
                if (playlistImage != null)
                {
                    // Ensure is jpeg first
                    playlist.Thumbnail = ImageHelper.ConvertToJpegFormat(playlistImage);

                    // Resize to store in database as thumbnail
                    playlist.Thumbnail = ImageHelper.ResizeImage(playlist.Thumbnail,
                                                                 Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height);
                }

                playlist.LastUpdated = now;
                await DbContext.SaveChangesAsync();

                CacheManager.ClearRegion(playlist.CacheRegion);
                Logger.LogInformation($"UpdatePlaylist `{playlist}` By User `{user}`");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                errors.Add(ex);
            }

            sw.Stop();

            return(new OperationResult <bool>
            {
                IsSuccess = !errors.Any(),
                Data = !errors.Any(),
                OperationTime = sw.ElapsedMilliseconds,
                Errors = errors
            });
        }
コード例 #3
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
            });
        }
コード例 #4
0
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }
            var queryDictionary = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(bindingContext.HttpContext.Request.QueryString.ToString());

            // Create a dictionary of all the properties to populate on the result model
            var modelDictionary = new Dictionary <string, object>(StringComparer.InvariantCultureIgnoreCase)
            {
                { "albumCount", null },
                { "albumOffset", null },
                { "artist", null },
                { "artistCount", null },
                { "artistOffset", null },
                { "c", null },
                { "callback", null },
                { "f", null },
                { "fromYear", null },
                { "genre", null },
                { "id", null },
                { "musicFolderId", null },
                { "offset", null },
                { "p", null },
                { "message", null },
                { "query", null },
                { "s", null },
                { "size", null },
                { "songCount", null },
                { "songOffset", null },
                { "t", null },
                { "toYear", null },
                { "type", null },
                { "u", null },
                { "v", null }
            };

            // Setup model dictionary from Query Parameters
            modelDictionary["albumCount"]    = queryDictionary.ContainsKey("albumCount") ? SafeParser.ToNumber <int?>(queryDictionary["albumCount"].First()) : null;
            modelDictionary["albumOffset"]   = queryDictionary.ContainsKey("albumOffset") ? SafeParser.ToNumber <int?>(queryDictionary["albumOffset"].First()) : null;
            modelDictionary["artist"]        = queryDictionary.ContainsKey("artist") ? queryDictionary["artist"].First() : null;
            modelDictionary["artistCount"]   = queryDictionary.ContainsKey("artistCount") ? SafeParser.ToNumber <int?>(queryDictionary["artistCount"].First()) : null;
            modelDictionary["artistOffset"]  = queryDictionary.ContainsKey("artistOffset") ? SafeParser.ToNumber <int?>(queryDictionary["artistOffset"].First()) : null;
            modelDictionary["c"]             = queryDictionary.ContainsKey("c") ? queryDictionary["c"].First() : null;
            modelDictionary["callback"]      = queryDictionary.ContainsKey("callback") ? queryDictionary["callback"].First() : null;
            modelDictionary["f"]             = queryDictionary.ContainsKey("f") ? queryDictionary["f"].First() : null;
            modelDictionary["fromYear"]      = queryDictionary.ContainsKey("fromYear") ? SafeParser.ToNumber <int?>(queryDictionary["fromYear"].First()) : null;
            modelDictionary["genre"]         = queryDictionary.ContainsKey("genre") ? queryDictionary["genre"].First() : null;
            modelDictionary["id"]            = queryDictionary.ContainsKey("id") ? queryDictionary["id"].First() : null;
            modelDictionary["musicFolderId"] = queryDictionary.ContainsKey("musicFolderId") ? SafeParser.ToNumber <int?>(queryDictionary["musicFolderId"].First()) : null;
            modelDictionary["offset"]        = queryDictionary.ContainsKey("offset") ? SafeParser.ToNumber <int?>(queryDictionary["offset"].First()) : null;
            modelDictionary["p"]             = queryDictionary.ContainsKey("p") ? queryDictionary["p"].First() : null;
            modelDictionary["query"]         = queryDictionary.ContainsKey("query") ? queryDictionary["query"].First() : null;
            modelDictionary["s"]             = queryDictionary.ContainsKey("s") ? queryDictionary["s"].First() : null;
            var size  = queryDictionary.ContainsKey("size") ? SafeParser.ToNumber <int?>(queryDictionary["size"].First()) : null;
            var count = queryDictionary.ContainsKey("count") ? SafeParser.ToNumber <int?>(queryDictionary["count"].First()) : null;

            modelDictionary["size"]       = size ?? count ?? 20;
            modelDictionary["songCount"]  = queryDictionary.ContainsKey("songCount") ? SafeParser.ToNumber <int?>(queryDictionary["songCount"].First()) : null;
            modelDictionary["songOffset"] = queryDictionary.ContainsKey("songOffset") ? SafeParser.ToNumber <int?>(queryDictionary["songOffset"].First()) : null;
            modelDictionary["t"]          = queryDictionary.ContainsKey("t") ? queryDictionary["t"].First() : null;
            modelDictionary["toYear"]     = queryDictionary.ContainsKey("toYear") ? SafeParser.ToNumber <int?>(queryDictionary["toYear"].First()) : null;
            modelDictionary["type"]       = queryDictionary.ContainsKey("type") ? SafeParser.ToEnum <ListType>(queryDictionary["type"].First()) : ListType.AlphabeticalByName;
            modelDictionary["u"]          = queryDictionary.ContainsKey("u") ? queryDictionary["u"].First() : null;
            modelDictionary["v"]          = queryDictionary.ContainsKey("v") ? queryDictionary["v"].First() : null;
            modelDictionary["message"]    = queryDictionary.ContainsKey("message") ? queryDictionary["message"].First() : null;


            // Setup model dictionary from Posted Body values
            var postedIds = new List <string>();

            if (!bindingContext.HttpContext.Request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(bindingContext.HttpContext.Request.ContentType))
            {
                var formCollection = bindingContext.HttpContext.Request.Form;
                if (formCollection != null && formCollection.Any())
                {
                    foreach (var form in formCollection)
                    {
                        if (modelDictionary.ContainsKey(form.Key))
                        {
                            modelDictionary[form.Key] = form.Value.FirstOrDefault();
                        }
                        else
                        {
                            modelDictionary.Add(form.Key, form.Value.FirstOrDefault());
                        }
                        if (form.Key == "id")
                        {
                            postedIds.AddRange(form.Value.ToArray());
                        }
                    }
                }
            }

            var model = new SubsonicRequest
            {
                AlbumCount    = SafeParser.ToNumber <short?>(modelDictionary["albumCount"]) ?? 20,
                AlbumOffset   = SafeParser.ToNumber <int?>(modelDictionary["albumOffset"]),
                ArtistCount   = SafeParser.ToNumber <short?>(modelDictionary["artistCount"]) ?? 20,
                ArtistName    = SafeParser.ToString(modelDictionary["artist"]),
                ArtistOffset  = SafeParser.ToNumber <int?>(modelDictionary["artistOffset"]),
                c             = SafeParser.ToString(modelDictionary["c"]),
                callback      = SafeParser.ToString(modelDictionary["callback"]),
                f             = SafeParser.ToString(modelDictionary["f"]),
                FromYear      = SafeParser.ToNumber <int?>(modelDictionary["fromYear"]),
                Genre         = SafeParser.ToString(modelDictionary["genre"]),
                id            = SafeParser.ToString(modelDictionary["id"]),
                ids           = postedIds?.ToArray(),
                MusicFolderId = SafeParser.ToNumber <int?>(modelDictionary["musicFolderId"]),
                Message       = SafeParser.ToString(modelDictionary["message"]),
                Offset        = SafeParser.ToNumber <int?>(modelDictionary["offset"]),
                p             = SafeParser.ToString(modelDictionary["p"]),
                Query         = SafeParser.ToString(modelDictionary["query"]),
                s             = SafeParser.ToString(modelDictionary["s"]),
                Size          = SafeParser.ToNumber <short?>(modelDictionary["size"]),
                SongCount     = SafeParser.ToNumber <short?>(modelDictionary["songCount"]) ?? 20,
                SongOffset    = SafeParser.ToNumber <int?>(modelDictionary["songOffset"]),
                t             = SafeParser.ToString(modelDictionary["t"]),
                ToYear        = SafeParser.ToNumber <int?>(modelDictionary["toYear"]),
                Type          = SafeParser.ToEnum <ListType>(modelDictionary["type"]),
                u             = SafeParser.ToString(modelDictionary["u"]),
                v             = SafeParser.ToString(modelDictionary["v"])
            };

            bindingContext.Result = ModelBindingResult.Success(model);

            return(Task.CompletedTask);
        }
コード例 #5
0
        public async Task <OperationResult <bool> > UpdateGenre(Library.Models.Users.User user, Genre model)
        {
            var sw = new Stopwatch();

            sw.Start();
            var errors = new List <Exception>();
            var genre  = DbContext.Genres.FirstOrDefault(x => x.RoadieId == model.Id);

            if (genre == null)
            {
                return(new OperationResult <bool>(true, string.Format("Genre Not Found [{0}]", model.Id)));
            }
            // If genre is being renamed, see if genre already exists with new model supplied name
            var genreName      = genre.SortNameValue;
            var genreModelName = genre.SortNameValue;
            var didChangeName  = !genreName.ToAlphanumericName().Equals(genreModelName.ToAlphanumericName(), StringComparison.OrdinalIgnoreCase);

            if (didChangeName)
            {
                var existingGenre = DbContext.Genres.FirstOrDefault(x => x.Name == model.Name || x.SortName == model.SortName);
                if (existingGenre != null)
                {
                    return(new OperationResult <bool>($"Genre already exists `{ existingGenre }` with name [{ genreModelName }]."));
                }
            }
            try
            {
                var now = DateTime.UtcNow;
                var specialGenreName = model.Name.ToAlphanumericName();
                var alt = new List <string>(model.AlternateNamesList);
                if (!model.AlternateNamesList.Contains(specialGenreName, StringComparer.OrdinalIgnoreCase))
                {
                    alt.Add(specialGenreName);
                }
                genre.AlternateNames = alt.ToDelimitedList();
                genre.Description    = model.Description;
                genre.IsLocked       = model.IsLocked;
                var oldPathToImage = genre.PathToImage(Configuration);
                genre.Name           = model.Name;
                genre.NormalizedName = model.NormalizedName;
                genre.SortName       = model.SortName;
                genre.Status         = SafeParser.ToEnum <Statuses>(model.Status);
                genre.Tags           = model.TagsList.ToDelimitedList();

                if (didChangeName)
                {
                    if (File.Exists(oldPathToImage))
                    {
                        File.Move(oldPathToImage, genre.PathToImage(Configuration));
                    }
                }
                var genreImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
                if (genreImage != null)
                {
                    // Save unaltered genre image
                    File.WriteAllBytes(genre.PathToImage(Configuration), ImageHelper.ConvertToJpegFormat(genreImage));
                }
                genre.LastUpdated = now;
                await DbContext.SaveChangesAsync();

                CacheManager.ClearRegion(genre.CacheRegion);
                Logger.LogInformation($"UpdateGenre `{genre}` By User `{user}`");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                errors.Add(ex);
            }

            sw.Stop();

            return(new OperationResult <bool>
            {
                IsSuccess = !errors.Any(),
                Data = !errors.Any(),
                OperationTime = sw.ElapsedMilliseconds,
                Errors = errors
            });
        }
コード例 #6
0
ファイル: TrackService.cs プロジェクト: liamdawson/roadie
        public async Task <OperationResult <bool> > UpdateTrack(User user, Track model)
        {
            var didChangeTrack     = false;
            var didChangeThumbnail = false;
            var sw = new Stopwatch();

            sw.Start();
            var errors = new List <Exception>();
            var track  = this.DbContext.Tracks
                         .Include(x => x.ReleaseMedia)
                         .Include(x => x.ReleaseMedia.Release)
                         .Include(x => x.ReleaseMedia.Release.Artist)
                         .FirstOrDefault(x => x.RoadieId == model.Id);

            if (track == null)
            {
                return(new OperationResult <bool>(true, string.Format("Track Not Found [{0}]", model.Id)));
            }
            try
            {
                var now = DateTime.UtcNow;
                track.IsLocked       = model.IsLocked;
                track.Status         = SafeParser.ToEnum <Statuses>(model.Status);
                track.Title          = model.Title;
                track.AlternateNames = model.AlternateNamesList.ToDelimitedList();
                track.Rating         = model.Rating;
                track.AmgId          = model.AmgId;
                track.LastFMId       = model.LastFMId;
                track.MusicBrainzId  = model.MusicBrainzId;
                track.SpotifyId      = model.SpotifyId;
                track.Tags           = model.TagsList.ToDelimitedList();
                track.PartTitles     = model.PartTitlesList == null || !model.PartTitlesList.Any() ? null : string.Join("\n", model.PartTitlesList);

                if (model.TrackArtistToken != null)
                {
                    var artistId = SafeParser.ToGuid(model.TrackArtistToken.Value);
                    if (artistId.HasValue)
                    {
                        var artist = this.GetArtist(artistId.Value);
                        if (artist != null)
                        {
                            track.ArtistId = artist.Id;
                        }
                    }
                }
                else
                {
                    track.ArtistId = null;
                }

                var trackImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
                if (trackImage != null)
                {
                    // Ensure is jpeg first
                    track.Thumbnail = ImageHelper.ConvertToJpegFormat(trackImage);

                    // Save unaltered image to cover file
                    var trackThumbnailName = track.PathToTrackThumbnail(this.Configuration, this.Configuration.LibraryFolder);
                    File.WriteAllBytes(trackThumbnailName, track.Thumbnail);

                    // Resize to store in database as thumbnail
                    track.Thumbnail    = ImageHelper.ResizeImage(track.Thumbnail, this.Configuration.MediumImageSize.Width, this.Configuration.MediumImageSize.Height);
                    didChangeThumbnail = true;
                }
                track.LastUpdated = now;
                await this.DbContext.SaveChangesAsync();

                this.CacheManager.ClearRegion(track.CacheRegion);
                this.Logger.LogInformation($"UpdateTrack `{ track }` By User `{ user }`: Edited Track [{ didChangeTrack }], Uploaded new image [{ didChangeThumbnail }]");
            }
            catch (Exception ex)
            {
                this.Logger.LogError(ex);
                errors.Add(ex);
            }
            sw.Stop();

            return(new OperationResult <bool>
            {
                IsSuccess = !errors.Any(),
                Data = !errors.Any(),
                OperationTime = sw.ElapsedMilliseconds,
                Errors = errors
            });
        }
コード例 #7
0
        /// <summary>
        /// Updates (or Adds) Collection
        /// </summary>
        public async Task <OperationResult <bool> > UpdateCollection(User user, Collection model)
        {
            var isNew = model.Id == Guid.Empty;
            var now   = DateTime.UtcNow;

            var sw = new Stopwatch();

            sw.Start();
            var errors = new List <Exception>();

            data.Collection collection = new data.Collection();

            if (!isNew)
            {
                collection = this.DbContext.Collections.FirstOrDefault(x => x.RoadieId == model.Id);
                if (collection == null)
                {
                    return(new OperationResult <bool>(true, string.Format("Collection Not Found [{0}]", model.Id)));
                }
            }
            collection.IsLocked        = model.IsLocked;
            collection.Name            = model.Name;
            collection.SortName        = model.SortName;
            collection.Edition         = model.Edition;
            collection.ListInCSVFormat = model.ListInCSVFormat;
            collection.ListInCSV       = model.ListInCSV;
            collection.Description     = model.Description;
            collection.URLs            = model.URLs;
            collection.Status          = SafeParser.ToEnum <Statuses>(model.Status);
            collection.CollectionType  = SafeParser.ToEnum <CollectionType>(model.CollectionType);
            collection.Tags            = model.TagsList.ToDelimitedList();
            collection.URLs            = model.URLsList.ToDelimitedList();
            collection.AlternateNames  = model.AlternateNamesList.ToDelimitedList();
            collection.CollectionCount = model.CollectionCount;

            var collectionImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);

            if (collectionImage != null)
            {
                // Ensure is jpeg first
                collection.Thumbnail = ImageHelper.ConvertToJpegFormat(collectionImage);

                // Resize to store in database as thumbnail
                collection.Thumbnail = ImageHelper.ResizeImage(collection.Thumbnail, this.Configuration.MediumImageSize.Width, this.Configuration.MediumImageSize.Height);
            }

            if (model.Maintainer?.Value != null)
            {
                var maintainer = this.DbContext.Users.FirstOrDefault(x => x.RoadieId == SafeParser.ToGuid(model.Maintainer.Value));
                if (maintainer != null)
                {
                    collection.MaintainerId = maintainer.Id;
                }
            }
            collection.LastUpdated = now;

            if (isNew)
            {
                await this.DbContext.Collections.AddAsync(collection);
            }
            await this.DbContext.SaveChangesAsync();

            this.CacheManager.ClearRegion(collection.CacheRegion);
            this.Logger.LogInformation($"UpdateArtist `{ collection }` By User `{ user }`");
            return(new OperationResult <bool>
            {
                IsSuccess = !errors.Any(),
                Data = !errors.Any(),
                OperationTime = sw.ElapsedMilliseconds,
                Errors = errors
            });
        }
コード例 #8
0
ファイル: LabelService.cs プロジェクト: jindal1979/roadie
        public async Task <OperationResult <bool> > UpdateLabel(Library.Models.Users.User user, Label model)
        {
            var sw = new Stopwatch();

            sw.Start();
            var errors = new List <Exception>();
            var label  = DbContext.Labels.FirstOrDefault(x => x.RoadieId == model.Id);

            if (label == null)
            {
                return(new OperationResult <bool>(true, string.Format("Label Not Found [{0}]", model.Id)));
            }
            // If label is being renamed, see if label already exists with new model supplied name
            var labelName      = label.SortNameValue;
            var labelModelName = model.SortNameValue;
            var oldPathToImage = label.PathToImage(Configuration);
            var didChangeName  = !labelName.ToAlphanumericName().Equals(labelModelName.ToAlphanumericName(), StringComparison.OrdinalIgnoreCase);

            if (didChangeName)
            {
                var existingLabel = DbContext.Labels.FirstOrDefault(x => x.Name == model.Name || x.SortName == model.SortName);
                if (existingLabel != null)
                {
                    return(new OperationResult <bool>($"Label already exists `{ existingLabel }` with name [{ labelModelName }]."));
                }
            }
            try
            {
                var now = DateTime.UtcNow;
                var specialLabelName = model.Name.ToAlphanumericName();
                var alt = new List <string>(model.AlternateNamesList);
                if (!model.AlternateNamesList.Contains(specialLabelName, StringComparer.OrdinalIgnoreCase))
                {
                    alt.Add(specialLabelName);
                }
                label.AlternateNames = alt.ToDelimitedList();
                label.BeginDate      = model.BeginDate;
                label.DiscogsId      = model.DiscogsId;
                label.EndDate        = model.EndDate;
                label.IsLocked       = model.IsLocked;
                label.MusicBrainzId  = model.MusicBrainzId;
                label.Name           = model.Name;
                label.Profile        = model.Profile;
                label.SortName       = model.SortName;
                label.Status         = SafeParser.ToEnum <Statuses>(model.Status);
                label.Tags           = model.TagsList.ToDelimitedList();
                label.URLs           = model.URLsList.ToDelimitedList();

                if (didChangeName)
                {
                    if (File.Exists(oldPathToImage))
                    {
                        File.Move(oldPathToImage, label.PathToImage(Configuration));
                    }
                }
                var labelImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
                if (labelImage != null)
                {
                    // Save unaltered label image
                    File.WriteAllBytes(label.PathToImage(Configuration, true), ImageHelper.ConvertToJpegFormat(labelImage));
                }
                label.LastUpdated = now;
                await DbContext.SaveChangesAsync();

                CacheManager.ClearRegion(label.CacheRegion);
                Logger.LogInformation($"UpdateLabel `{label}` By User `{user}`");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                errors.Add(ex);
            }

            sw.Stop();

            return(new OperationResult <bool>
            {
                IsSuccess = !errors.Any(),
                Data = !errors.Any(),
                OperationTime = sw.ElapsedMilliseconds,
                Errors = errors
            });
        }
コード例 #9
0
ファイル: PlaylistService.cs プロジェクト: jindal1979/roadie
        public async Task <OperationResult <bool> > UpdatePlaylist(User user, Playlist model)
        {
            var sw = new Stopwatch();

            sw.Start();
            var errors   = new List <Exception>();
            var playlist = DbContext.Playlists.FirstOrDefault(x => x.RoadieId == model.Id);

            if (playlist == null)
            {
                return(new OperationResult <bool>(true, string.Format("Playlist Not Found [{0}]", model.Id)));
            }
            if (!user.IsAdmin && user.Id != playlist.UserId)
            {
                Logger.LogWarning("User `{0}` attempted to update Playlist `{1}`", user, playlist);
                return(new OperationResult <bool>("Access Denied")
                {
                    IsAccessDeniedResult = true
                });
            }
            try
            {
                var now = DateTime.UtcNow;
                playlist.AlternateNames = model.AlternateNamesList.ToDelimitedList();
                playlist.Description    = model.Description;
                playlist.IsLocked       = model.IsLocked;
                playlist.IsPublic       = model.IsPublic;
                var oldPathToImage = playlist.PathToImage(Configuration);
                var didChangeName  = playlist.Name != model.Name;
                playlist.Name   = model.Name;
                playlist.Status = SafeParser.ToEnum <Statuses>(model.Status);
                playlist.Tags   = model.TagsList.ToDelimitedList();
                playlist.URLs   = model.URLsList.ToDelimitedList();

                if (didChangeName)
                {
                    if (File.Exists(oldPathToImage))
                    {
                        File.Move(oldPathToImage, playlist.PathToImage(Configuration));
                    }
                }

                var playlistImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);
                if (playlistImage != null)
                {
                    // Save unaltered playlist image
                    File.WriteAllBytes(playlist.PathToImage(Configuration, true), ImageHelper.ConvertToJpegFormat(playlistImage));
                }
                playlist.LastUpdated = now;
                await DbContext.SaveChangesAsync();

                CacheManager.ClearRegion(playlist.CacheRegion);
                Logger.LogInformation($"UpdatePlaylist `{playlist}` By User `{user}`");
            }
            catch (Exception ex)
            {
                Logger.LogError(ex);
                errors.Add(ex);
            }

            sw.Stop();

            return(new OperationResult <bool>
            {
                IsSuccess = !errors.Any(),
                Data = !errors.Any(),
                OperationTime = sw.ElapsedMilliseconds,
                Errors = errors
            });
        }
コード例 #10
0
        /// <summary>
        ///     Updates (or Adds) Collection
        /// </summary>
        public async Task <OperationResult <bool> > UpdateCollection(User user, Collection model)
        {
            var isNew = model.Id == Guid.Empty;
            var now   = DateTime.UtcNow;

            var sw = new Stopwatch();

            sw.Start();
            var errors = new List <Exception>();

            var collection = new data.Collection();

            if (!isNew)
            {
                collection = DbContext.Collections.FirstOrDefault(x => x.RoadieId == model.Id);
                if (collection == null)
                {
                    return(new OperationResult <bool>(true, string.Format("Collection Not Found [{0}]", model.Id)));
                }
                // If collection is being renamed, see if collection already exists with new model supplied name
                var collectionName      = collection.SortNameValue;
                var collectionModelName = model.SortNameValue;
                if (collectionName.ToAlphanumericName() != collectionModelName.ToAlphanumericName())
                {
                    var existingCollection = DbContext.Collections.FirstOrDefault(x => x.Name == model.Name || x.SortName == model.SortName);
                    if (existingCollection != null)
                    {
                        return(new OperationResult <bool>($"Collection already exists `{ collection }` with name [{ collectionModelName }]."));
                    }
                }
            }
            collection.IsLocked = model.IsLocked;
            var oldPathToImage = collection.PathToImage(Configuration);
            var didChangeName  = collection.Name != model.Name && !isNew;

            collection.Name            = model.Name;
            collection.SortName        = model.SortName;
            collection.Edition         = model.Edition;
            collection.ListInCSVFormat = model.ListInCSVFormat;
            collection.ListInCSV       = model.ListInCSV;
            collection.Description     = model.Description;
            collection.URLs            = model.URLs;
            collection.Status          = SafeParser.ToEnum <Statuses>(model.Status);
            collection.CollectionType  = SafeParser.ToEnum <CollectionType>(model.CollectionType);
            collection.Tags            = model.TagsList.ToDelimitedList();
            collection.URLs            = model.URLsList.ToDelimitedList();
            collection.AlternateNames  = model.AlternateNamesList.ToDelimitedList();
            collection.CollectionCount = model.CollectionCount;

            if (model.Maintainer?.Value != null)
            {
                var maintainer = DbContext.Users.FirstOrDefault(x => x.RoadieId == SafeParser.ToGuid(model.Maintainer.Value));
                if (maintainer != null)
                {
                    collection.MaintainerId = maintainer.Id;
                }
            }

            if (isNew)
            {
                await DbContext.Collections.AddAsync(collection);

                await DbContext.SaveChangesAsync();
            }

            if (didChangeName)
            {
                if (File.Exists(oldPathToImage))
                {
                    File.Move(oldPathToImage, collection.PathToImage(Configuration));
                }
            }

            var collectionImage = ImageHelper.ImageDataFromUrl(model.NewThumbnailData);

            if (collectionImage != null)
            {
                // Save unaltered collection image
                File.WriteAllBytes(collection.PathToImage(Configuration, true), ImageHelper.ConvertToJpegFormat(collectionImage));
            }

            collection.LastUpdated = now;
            await DbContext.SaveChangesAsync();

            CacheManager.ClearRegion(collection.CacheRegion);
            Logger.LogInformation($"UpdateCollection `{collection}` By User `{user}`");
            return(new OperationResult <bool>
            {
                IsSuccess = !errors.Any(),
                Data = !errors.Any(),
                OperationTime = sw.ElapsedMilliseconds,
                Errors = errors
            });
        }