public async Task <OperationResult <LibraryStats> > LibraryStatistics() { LibraryStats result = null; var sw = new Stopwatch(); sw.Start(); try { using (var conn = new MySqlConnection(this.Configuration.ConnectionString)) { conn.Open(); var sql = @"SELECT rm.releaseMediaCount AS releaseMediaCount, COUNT(r.roadieId) AS releaseCount, ts.trackCount, ts.trackDuration as TotalTrackDuration, ts.trackSize as TotalTrackSize, ac.artistCount, lc.labelCount, pc.playedCount, uc.userCount, cc.collectionCount, pl.playlistCount FROM `release` r INNER JOIN ( SELECT COUNT(1) AS trackCount, SUM(t.duration) AS trackDuration, SUM(t.fileSize) AS trackSize FROM `track` t JOIN `releasemedia` rm ON rm.id = t.releaseMediaId JOIN `release` r ON r.id = rm.releaseId JOIN `artist` a ON a.id = r.artistId WHERE t.hash IS NOT NULL) ts INNER JOIN ( SELECT COUNT(1) AS artistCount FROM `artist`) ac INNER JOIN ( SELECT COUNT(1) AS labelCount FROM `label`) lc INNER JOIN ( SELECT SUM(playedCount) as playedCount FROM `usertrack`) pc INNER JOIN ( SELECT COUNT(1) as releaseMediaCount FROM `releasemedia`) rm INNER JOIN ( SELECT COUNT(1) as userCount FROM `user`) uc INNER JOIN ( SELECT COUNT(1) as collectionCount FROM `collection`) cc INNER JOIN ( SELECT COUNT(1) as playlistCount FROM `playlist`) pl;" ; using (var cmd = new MySqlCommand(sql, conn)) { try { using (var rdr = await cmd.ExecuteReaderAsync()) { if (rdr.HasRows) { while (rdr.Read()) { result = new LibraryStats { UserCount = SafeParser.ToNumber <int?>(rdr["UserCount"]), CollectionCount = SafeParser.ToNumber <int?>(rdr["CollectionCount"]), PlaylistCount = SafeParser.ToNumber <int?>(rdr["PlaylistCount"]), ArtistCount = SafeParser.ToNumber <int?>(rdr["ArtistCount"]), LabelCount = SafeParser.ToNumber <int?>(rdr["LabelCount"]), ReleaseCount = SafeParser.ToNumber <int?>(rdr["ReleaseCount"]), ReleaseMediaCount = SafeParser.ToNumber <int?>(rdr["ReleaseMediaCount"]), PlayedCount = SafeParser.ToNumber <int?>(rdr["PlayedCount"]), TrackCount = SafeParser.ToNumber <int?>(rdr["TrackCount"]), TotalTrackDuration = SafeParser.ToNumber <long?>(rdr["TotalTrackDuration"]), TotalTrackSize = SafeParser.ToNumber <long?>(rdr["TotalTrackSize"]) }; } } } } catch (Exception ex) { this.Logger.LogError(ex); } finally { conn.Close(); } } } var lastScan = this.DbContext.ScanHistories.OrderByDescending(x => x.CreatedDate).FirstOrDefault(); if (lastScan != null) { result.LastScan = lastScan.CreatedDate; } sw.Stop(); } catch (Exception ex) { this.Logger.LogError(ex); } return(new OperationResult <LibraryStats> { IsSuccess = result != null, OperationTime = sw.ElapsedMilliseconds, Data = result }); }
public async Task <OperationResult <IEnumerable <ReleaseSearchResult> > > PerformReleaseSearch(string artistName, string query, int resultsCount) { ReleaseSearchResult result = null; try { var releaseInfosForArtist = await this.ReleasesForArtist(artistName); if (releaseInfosForArtist != null) { var releaseInfo = releaseInfosForArtist.FirstOrDefault(x => x.title.Equals(query, StringComparison.OrdinalIgnoreCase)); if (releaseInfo != null) { var mbRelease = await this.MusicBrainzReleaseById(releaseInfo.id); if (mbRelease != null) { result = new ReleaseSearchResult { ReleaseDate = mbRelease.releasegroup != null?SafeParser.ToDateTime(mbRelease.releasegroup.firstreleasedate) : null, ReleaseTitle = mbRelease.title, MusicBrainzId = mbRelease.id, ReleaseType = mbRelease.releasegroup != null ? mbRelease.releasegroup.primarytype : null, }; if (mbRelease.labelinfo != null) { var releaseLabels = new List <ReleaseLabelSearchResult>(); foreach (var mbLabel in mbRelease.labelinfo) { releaseLabels.Add(new ReleaseLabelSearchResult { CatalogNumber = mbLabel.catalognumber, Label = new LabelSearchResult { LabelName = mbLabel.label.name, MusicBrainzId = mbLabel.label.id, LabelSortName = mbLabel.label.sortname, AlternateNames = mbLabel.label.aliases.Select(x => x.name).ToList() } }); } result.ReleaseLabel = releaseLabels; } if (mbRelease.media != null) { var releaseMedia = new List <ReleaseMediaSearchResult>(); foreach (var mbMedia in mbRelease.media.OrderBy(x => x.position)) { var mediaTracks = new List <TrackSearchResult>(); short trackLooper = 0; foreach (var mbTrack in mbMedia.tracks.OrderBy(x => x.position)) { trackLooper++; mediaTracks.Add(new TrackSearchResult { Title = mbTrack.title, TrackNumber = trackLooper, Duration = mbTrack.length, MusicBrainzId = mbTrack.id, AlternateNames = mbTrack.recording != null && mbTrack.recording.aliases != null ? mbTrack.recording.aliases.Select(x => x.name).ToList() : null }); } releaseMedia.Add(new ReleaseMediaSearchResult { ReleaseMediaNumber = SafeParser.ToNumber <short?>(mbMedia.position), ReleaseMediaSubTitle = mbMedia.title, TrackCount = SafeParser.ToNumber <short?>(mbMedia.trackcount), Tracks = mediaTracks }); } result.ReleaseMedia = releaseMedia; } } } } } catch (Exception ex) { this.Logger.LogError(ex, ex.Serialize()); } if (result == null) { this.Logger.LogWarning("MusicBrainzArtist: ArtistName [{0}], ReleaseTitle [{0}], No MusicBrainz Release Found", artistName, query); } else { this.Logger.LogTrace("MusicBrainzArtist: Result [{0}]", query, result.ToString()); } return(new OperationResult <IEnumerable <ReleaseSearchResult> > { IsSuccess = result != null, Data = new ReleaseSearchResult[] { result } }); }
public async Task <IEnumerable <AudioMetaData> > MusicBrainzReleaseTracks(string artistName, string releaseTitle) { try { if (string.IsNullOrEmpty(artistName) && string.IsNullOrEmpty(releaseTitle)) { return(null); } // Find the Artist var artistCacheKey = string.Format("uri:musicbrainz:artist:{0}", artistName); var artistSearch = await this.PerformArtistSearch(artistName, 1); if (!artistSearch.IsSuccess) { return(null); } var artist = artistSearch.Data.First(); if (artist == null) { return(null); } var ReleaseCacheKey = string.Format("uri:musicbrainz:release:{0}", releaseTitle); var release = this.CacheManager.Get <Release>(ReleaseCacheKey); if (release == null) { // Now Get Artist Details including Releases var ReleaseResult = artist.Releases.FirstOrDefault(x => x.ReleaseTitle.Equals(releaseTitle, StringComparison.InvariantCultureIgnoreCase)); if (ReleaseResult == null) { ReleaseResult = artist.Releases.FirstOrDefault(x => x.ReleaseTitle.EndsWith(releaseTitle, StringComparison.InvariantCultureIgnoreCase)); if (ReleaseResult == null) { ReleaseResult = artist.Releases.FirstOrDefault(x => x.ReleaseTitle.StartsWith(releaseTitle, StringComparison.InvariantCultureIgnoreCase)); if (ReleaseResult == null) { return(null); } } } // Now get The Release Details release = await MusicBrainzRequestHelper.GetAsync <Release>(MusicBrainzRequestHelper.CreateLookupUrl("release", ReleaseResult.MusicBrainzId, "recordings")); if (release == null) { return(null); } this.CacheManager.Add(ReleaseCacheKey, release); } var result = new List <AudioMetaData>(); foreach (var media in release.media) { foreach (var track in media.tracks) { int date = 0; if (!string.IsNullOrEmpty(release.date)) { if (release.date.Length > 4) { DateTime ReleaseDate = DateTime.MinValue; if (DateTime.TryParse(release.date, out ReleaseDate)) { date = ReleaseDate.Year; } } else { int.TryParse(release.date, out date); } } result.Add(new AudioMetaData { ReleaseMusicBrainzId = release.id, MusicBrainzId = track.id, Artist = artist.ArtistName, Release = release.title, Title = track.title, Time = track.length.HasValue ? (TimeSpan?)TimeSpan.FromMilliseconds(track.length.Value) : null, TrackNumber = SafeParser.ToNumber <short?>(track.position ?? track.number) ?? 0, Disc = media.position, Year = date > 0 ? (int?)date : null, TotalTrackNumbers = media.trackcount, //tagFile.Tag.Pictures.Select(x => new AudoMetaDataImage //{ // Data = x.Data.Data, // Description = x.Description, // MimeType = x.MimeType, // Type = (AudioMetaDataImageType)x.Type //}).ToArray() }); } } return(result); } catch (Exception) { } return(null); }
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 = 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 = 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(Configuration, Configuration.LibraryFolder); File.WriteAllBytes(trackThumbnailName, track.Thumbnail); // Resize to store in database as thumbnail track.Thumbnail = ImageHelper.ResizeImage(track.Thumbnail, Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height); didChangeThumbnail = true; } track.LastUpdated = now; await DbContext.SaveChangesAsync(); CacheManager.ClearRegion(track.CacheRegion); Logger.LogInformation( $"UpdateTrack `{track}` By User `{user}`: Edited Track [{didChangeTrack}], Uploaded new image [{didChangeThumbnail}]"); } 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 }); }
public void Parse_Boolean_ShouldBeTrue(string input) { var parsed = SafeParser.ToBoolean(input); Assert.True(parsed); }
public void ParseBooleanShouldBeFalse(string input) { var parsed = SafeParser.ToBoolean(input); Assert.False(parsed); }
public async Task <OperationResult <IEnumerable <ReleaseSearchResult> > > PerformReleaseSearch(string artistName, string query, int resultsCount) { ReleaseSearchResult data = null; try { var cacheKey = $"uri:discogs:releasesearch:{ artistName.ToAlphanumericName() }:{ query.ToAlphanumericName() }"; data = await CacheManager.GetAsync <ReleaseSearchResult>(cacheKey, async() => { var request = BuildSearchRequest(query, 10, "release", artistName); var client = new RestClient("https://api.discogs.com/database") { UserAgent = WebHelper.UserAgent, ReadWriteTimeout = SafeParser.ToNumber <int>(Configuration.Integrations.DiscogsReadWriteTimeout), Timeout = SafeParser.ToNumber <int>(Configuration.Integrations.DiscogsTimeout) }; var response = await client.ExecuteAsync <DiscogsReleaseSearchResult>(request); if (response?.ResponseStatus == null || response.ResponseStatus == ResponseStatus.Error) { if (response.StatusCode == HttpStatusCode.Unauthorized) { throw new AuthenticationException("Unauthorized"); } throw new Exception($"Request Error Message: {response?.ErrorMessage}. Content: {response?.Content}."); } var responseData = response?.Data?.results?.OrderBy(x => x.year).FirstOrDefault(); if (responseData?.id != null) { request = BuildReleaseRequest(responseData.id); var c2 = new RestClient("https://api.discogs.com/") { UserAgent = WebHelper.UserAgent }; var releaseResult = await c2.ExecuteTaskAsync <DiscogReleaseDetail>(request); var release = releaseResult?.Data; if (release != null) { var urls = new List <string>(); var images = new List <string>(); string releaseThumbnailUrl = null; urls.Add(release.uri); if (release.images != null) { images.AddRange(release.images.Where(x => x.type != "primary").Select(x => x.uri)); var primaryImage = release.images.FirstOrDefault(x => x.type == "primary"); if (primaryImage != null) { releaseThumbnailUrl = primaryImage.uri; } if (string.IsNullOrEmpty(releaseThumbnailUrl)) { releaseThumbnailUrl = release.images.First(x => !string.IsNullOrEmpty(x.uri)).uri; } } data = new ReleaseSearchResult { DiscogsId = release.id.ToString(), ReleaseType = responseData.type, ReleaseDate = SafeParser.ToDateTime(release.released), Profile = release.notes, ReleaseThumbnailUrl = releaseThumbnailUrl, Urls = urls, ImageUrls = images }; if (release.genres != null) { data.ReleaseGenres = release.genres.ToList(); } if (release.labels != null) { data.ReleaseLabel = release.labels.Select(x => new ReleaseLabelSearchResult { CatalogNumber = x.catno, Label = new LabelSearchResult { LabelName = x.name, DiscogsId = x.id.ToString() } }).ToList(); } if (release.tracklist != null) { var releaseMediaCount = 1; var releaseMedias = new List <ReleaseMediaSearchResult>(); for (short?i = 1; i <= releaseMediaCount; i++) { var releaseTracks = new List <TrackSearchResult>(); short?looper = 0; foreach (var dTrack in release.tracklist.OrderBy(x => x.position)) { looper++; releaseTracks.Add(new TrackSearchResult { TrackNumber = looper, Title = dTrack.title, Duration = dTrack.duration.ToTrackDuration(), TrackType = dTrack.type_ }); } releaseMedias.Add(new ReleaseMediaSearchResult { ReleaseMediaNumber = i, TrackCount = (short)releaseTracks.Count(), Tracks = releaseTracks }); } data.ReleaseMedia = releaseMedias; } if (release.identifiers != null) { var barcode = release.identifiers.FirstOrDefault(x => (x.type ?? string.Empty) == "Barcode"); if (barcode?.value != null) { data.Tags = new[] { "barcode:" + barcode.value }; } } } } return(null); }, "uri:metadata"); } catch (Exception ex) { Logger.LogError(ex, $"DiscogsHelper: Error in PerformReleaseSearch artistname [{ artistName }], query [{ query }], resultsCount [{ resultsCount }]"); } return(new OperationResult <IEnumerable <ReleaseSearchResult> > { IsSuccess = data != null, Data = new[] { data } }); }
private IMediaItem TrackDetail(string id, bool isFileRequest) { lock (lockObject) { var releaseId = SafeParser.ToNumber <int>(id.Replace("r:t:tk:", "").Split(':')[0]); var trackId = SafeParser.ToNumber <int>(id.Replace("r:t:tk:", "").Split(':')[1]); var trackToken = id.Replace("r:t:tk:", "").Split(':')[2]; var track = TracksForRelease(releaseId).First(x => x.Id == trackId); byte[] trackbytes = null; if (isFileRequest) { trackbytes = AsyncHelper.RunSync(() => TrackBytesAndMarkPlayed(releaseId, track, trackToken)); } return(new Track($"r:t:tk:{releaseId}:{trackId}:{ Guid.NewGuid() }", track.ReleaseMedia.Release.Artist.Name, track.ReleaseMedia.Release.Title, track.ReleaseMedia.MediaNumber, track.Title, track.ReleaseMedia.Release.Genres.Select(x => x.Genre.Name).ToCSV(), track.TrackArtist?.Name, track.TrackNumber, track.ReleaseMedia.Release.ReleaseYear, TimeSpan.FromMilliseconds(SafeParser.ToNumber <double>(track.Duration)), track.PartTitles, track.LastUpdated ?? track.CreatedDate, ReleaseCoverArt(track.ReleaseMedia.Release.RoadieId), trackbytes)); } }
private IMediaItem TracksForRelease(string id) { var releaseId = SafeParser.ToNumber <int>(id.Replace("vf:release:", "")); var release = DbContext.Releases.FirstOrDefault(x => x.Id == releaseId); var result = new VirtualFolder() { Name = release.Title, Id = id }; foreach (var releaseTrack in TracksForRelease(release.Id)) { var t = new Track($"r:t:tk:{release.Id}:{releaseTrack.Id}:{Guid.NewGuid()}", releaseTrack.ReleaseMedia.Release.Artist.Name, releaseTrack.ReleaseMedia.Release.Title, releaseTrack.ReleaseMedia.MediaNumber, releaseTrack.Title, releaseTrack.ReleaseMedia.Release.Genres.Select(x => x.Genre.Name).ToCSV(), releaseTrack.TrackArtist?.Name, releaseTrack.TrackNumber, releaseTrack.ReleaseMedia.Release.ReleaseYear, TimeSpan.FromMilliseconds(SafeParser.ToNumber <double>(releaseTrack.Duration)), releaseTrack.PartTitles, releaseTrack.LastUpdated ?? releaseTrack.CreatedDate, ReleaseCoverArt(release.RoadieId)); result.AddResource(t); } return(result); }
/// <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 }); }
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)) { foreach (var g in ID3TagsHelper.SplitGenre(rg)) { result.Genres.Add(new Data.ReleaseGenre { Genre = (this.DbContext.Genres.Where(x => x.Name.ToLower() == g.ToLower()).FirstOrDefault() ?? new Data.Genre { Name = g }) }); } } } ; } 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) { string coverFileName = null; var cover = ImageHelper.FindImageTypeInDirectory(releaseFolder, ImageType.Release); if (!cover.Any()) { // See if cover exist by filename var imageFilesInFolder = ImageHelper.ImageFilesInFolder(releaseFolder.FullName, SearchOption.AllDirectories); if (imageFilesInFolder != null && imageFilesInFolder.Any()) { var imageCoverByReleaseName = imageFilesInFolder.FirstOrDefault(x => x == result.Title || x == result.Title.ToFileNameFriendly()); if (imageCoverByReleaseName != null) { coverFileName = imageCoverByReleaseName; } } } else if (cover.Any()) { coverFileName = cover.First().FullName; } if (!string.IsNullOrEmpty(coverFileName)) { // Read image and convert to jpeg 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); if (result.Thumbnail.Length >= ImageHelper.MaximumThumbnailByteSize) { Logger.LogWarning($"Release Thumbnail larger than maximum size after resizing to [{ this.Configuration.ThumbnailImageSize.Width }x{ this.Configuration.ThumbnailImageSize.Height}] Thumbnail Size [{ result.Thumbnail.Length }]"); result.Thumbnail = null; } } sw.Stop(); return(new OperationResult <Data.Release> { Data = result, IsSuccess = result != null, Errors = resultsExceptions, OperationTime = sw.ElapsedMilliseconds }); }
public static T GetParsedValue <T>(IDictionary <string, string> dictionary, string key, SafeParser <T> parser, T defaultValue = default(T)) { T parsed; return(dictionary.ContainsKey(key) && parser(dictionary[key], out parsed) ? parsed : defaultValue); }
/// <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))); } } 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, Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height); } 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; } } collection.LastUpdated = now; if (isNew) { await DbContext.Collections.AddAsync(collection); } await DbContext.SaveChangesAsync(); CacheManager.ClearRegion(collection.CacheRegion); Logger.LogInformation($"UpdateArtist `{collection}` By User `{user}`"); return(new OperationResult <bool> { IsSuccess = !errors.Any(), Data = !errors.Any(), OperationTime = sw.ElapsedMilliseconds, Errors = errors }); }
public void Parse_Int_ShouldBeOne(string input) { var parsed = SafeParser.ToNumber <int>(input); Assert.Equal(1, parsed); }
public void ParseDatetimeShouldBe2004(string input) { var parsed = SafeParser.ToDateTime(input); Assert.NotNull(parsed); }
public async Task <OperationResult <IEnumerable <ReleaseSearchResult> > > PerformReleaseSearch(string artistName, string query, int resultsCount) { var artistResult = await this.PerformArtistSearch(artistName, resultsCount); if (!artistResult.IsSuccess) { return(new OperationResult <IEnumerable <ReleaseSearchResult> >()); } try { var tcs = new TaskCompletionSource <OperationResult <IEnumerable <ReleaseSearchResult> > >(); var request = new RestRequest(Method.GET); ReleaseSearchResult result = null; var response = await this.AlbumsForArtist(artistResult.Data.First().SpotifyId); if (response != null && response.items != null) { string foundByAlternateName = null; var spotifyAlbum = response.items.FirstOrDefault(x => x.name.Trim().Equals(query.Trim(), StringComparison.OrdinalIgnoreCase)); if (spotifyAlbum == null) { // No Exact match see if one starts with and use the first one spotifyAlbum = response.items.FirstOrDefault(x => x.name.Trim().StartsWith(query.Trim(), StringComparison.OrdinalIgnoreCase)); if (spotifyAlbum == null) { return(new OperationResult <IEnumerable <ReleaseSearchResult> >()); } foundByAlternateName = spotifyAlbum.name; } var client = new RestClient(string.Format("http://api.spotify.com/v1/albums/{0}", spotifyAlbum.id)); var albumResult = await client.ExecuteTaskAsync <AlbumResult>(request); if (albumResult != null && albumResult.Data != null) { var sa = albumResult.Data; var resultTags = new List <string>(); var resultUrls = new List <string>(); if (sa.external_ids != null) { resultTags.Add("upc:" + sa.external_ids.upc); } result = new ReleaseSearchResult { ReleaseTitle = !string.IsNullOrEmpty(foundByAlternateName) ? query.ToTitleCase(false) : sa.name, ReleaseDate = SafeParser.ToDateTime(sa.release_date), ReleaseType = sa.album_type, SpotifyId = sa.id, Tags = resultTags, AlternateNames = !string.IsNullOrEmpty(foundByAlternateName) ? new string[] { foundByAlternateName } : null }; if (sa.artists != null && sa.artists.FirstOrDefault() != null) { var saArtist = sa.artists.First(); result.Artist = new ArtistSearchResult { ArtistName = saArtist.name, ArtistType = saArtist.type, SpotifyId = saArtist.id }; } if (sa.genres != null) { result.ReleaseGenres = sa.genres.ToList(); } if (sa.external_urls != null) { resultUrls.Add(sa.external_urls.spotify); } if (sa.images != null) { result.ImageUrls = sa.images.OrderBy(x => x.width).Take(1).Select(x => x.url).ToList(); } if (sa.tracks != null) { var releaseMediaCount = sa.tracks.items.Max(x => x.disc_number ?? 0); var releaseMedias = new List <ReleaseMediaSearchResult>(); for (short?i = 1; i <= releaseMediaCount; i++) { var releaseTracks = new List <TrackSearchResult>(); foreach (var saTrack in sa.tracks.items) { ArtistSearchResult trackArtist = null; if (saTrack.artists != null && saTrack.artists.FirstOrDefault() != null) { var saTrackArtist = saTrack.artists.First(); trackArtist = new ArtistSearchResult { ArtistName = saTrackArtist.name, SpotifyId = saTrackArtist.id, ArtistType = saTrackArtist.type }; } releaseTracks.Add(new TrackSearchResult { Artist = !trackArtist.SpotifyId.Equals(trackArtist.SpotifyId) ? trackArtist : null, TrackNumber = saTrack.track_number, Title = saTrack.name, SpotifyId = saTrack.id, Urls = new List <string> { saTrack.external_urls.spotify, saTrack.preview_url }, Duration = saTrack.duration_ms, TrackType = saTrack.type }); } releaseMedias.Add(new ReleaseMediaSearchResult { ReleaseMediaNumber = i, TrackCount = (short)sa.tracks.items.Count(x => x.disc_number == i), Tracks = releaseTracks }); } result.ReleaseMedia = releaseMedias; } result.Urls = resultUrls; } } return(new OperationResult <IEnumerable <ReleaseSearchResult> > { IsSuccess = result != null, Data = new List <ReleaseSearchResult> { result } }); } catch (Exception ex) { this.Logger.LogError(ex, ex.Serialize()); } return(new OperationResult <IEnumerable <ReleaseSearchResult> >()); }
public void ParseGuid(string input) { var parsed = SafeParser.ToGuid(input); Assert.NotNull(parsed); }
public async Task <OperationResult <IEnumerable <ReleaseSearchResult> > > PerformReleaseSearch(string artistName, string query, int resultsCount) { ReleaseSearchResult data = null; try { var request = this.BuildSearchRequest(query, 10, "release", artistName); var client = new RestClient("https://api.discogs.com/database") { UserAgent = WebHelper.UserAgent, ReadWriteTimeout = (int)this.Configuration.Integrations.DiscogsReadWriteTimeout, Timeout = (int)this.Configuration.Integrations.DiscogsTimeout }; var response = await client.ExecuteTaskAsync <DiscogsReleaseSearchResult>(request); if (response.ResponseStatus == ResponseStatus.Error) { if (response.StatusCode == HttpStatusCode.Unauthorized) { throw new AuthenticationException("Unauthorized"); } throw new Exception(string.Format("Request Error Message: {0}. Content: {1}.", response.ErrorMessage, response.Content)); } var responseData = response.Data != null && response.Data.results.Any() ? response.Data.results.OrderBy(x => x.year).First() : null; if (responseData != null) { request = this.BuildReleaseRequest(responseData.id); var c2 = new RestClient("https://api.discogs.com/"); c2.UserAgent = WebHelper.UserAgent; var releaseResult = await c2.ExecuteTaskAsync <DiscogReleaseDetail>(request); var release = releaseResult != null && releaseResult.Data != null ? releaseResult.Data : null; if (release != null) { var urls = new List <string>(); var images = new List <string>(); string releaseThumbnailUrl = null; urls.Add(release.uri); if (release.images != null) { images.AddRange(release.images.Where(x => x.type != "primary").Select(x => x.uri)); var primaryImage = release.images.FirstOrDefault(x => x.type == "primary"); if (primaryImage != null) { releaseThumbnailUrl = primaryImage.uri; } if (string.IsNullOrEmpty(releaseThumbnailUrl)) { releaseThumbnailUrl = release.images.First(x => !string.IsNullOrEmpty(x.uri)).uri; } } data = new ReleaseSearchResult { DiscogsId = release.id.ToString(), ReleaseType = responseData.type, ReleaseDate = SafeParser.ToDateTime(release.released), Profile = release.notes, ReleaseThumbnailUrl = releaseThumbnailUrl, Urls = urls, ImageUrls = images }; if (release.genres != null) { data.ReleaseGenres = release.genres.ToList(); } if (release.labels != null) { data.ReleaseLabel = release.labels.Select(x => new ReleaseLabelSearchResult { CatalogNumber = x.catno, Label = new LabelSearchResult { LabelName = x.name, DiscogsId = x.id.ToString() } }).ToList(); } if (release.tracklist != null) { var releaseMediaCount = 1; var releaseMedias = new List <ReleaseMediaSearchResult>(); for (short?i = 1; i <= releaseMediaCount; i++) { var releaseTracks = new List <TrackSearchResult>(); short?looper = 0; foreach (var dTrack in release.tracklist.OrderBy(x => x.position)) { looper++; releaseTracks.Add(new TrackSearchResult { TrackNumber = looper, Title = dTrack.title, Duration = dTrack.duration.ToTrackDuration(), TrackType = dTrack.type_ }); } releaseMedias.Add(new ReleaseMediaSearchResult { ReleaseMediaNumber = i, TrackCount = (short)releaseTracks.Count(), Tracks = releaseTracks }); } data.ReleaseMedia = releaseMedias; } if (release.identifiers != null) { var barcode = release.identifiers.FirstOrDefault(x => x.type == "Barcode"); if (barcode != null && !string.IsNullOrEmpty(barcode.value)) { data.Tags = new string[] { "barcode:" + barcode.value }; } } } } } catch (Exception ex) { this.Logger.LogError(ex); } return(new OperationResult <IEnumerable <ReleaseSearchResult> > { IsSuccess = data != null, Data = new ReleaseSearchResult[] { data } }); }
public void ParseIntShouldBeZero(string input) { var parsed = SafeParser.ToNumber <int>(input); Assert.Equal(0, parsed); }
public async Task <OperationResult <bool> > UpdateLabel(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))); } 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, Configuration.MediumImageSize.Width, Configuration.MediumImageSize.Height); } 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 }); }
private OperationResult <AudioMetaData> MetaDataForFileFromIdSharp(string fileName) { var sw = new Stopwatch(); sw.Start(); var result = new AudioMetaData(); string message = null; var isSuccess = false; try { result.Filename = fileName; var audioFile = AudioFile.Create(fileName, true); if (ID3v2Tag.DoesTagExist(fileName)) { IID3v2Tag id3v2 = new ID3v2Tag(fileName); result.Artist = id3v2.AlbumArtist ?? id3v2.Artist; result.ArtistRaw = id3v2.AlbumArtist ?? id3v2.Artist; result.AudioBitrate = (int?)audioFile.Bitrate; result.AudioChannels = audioFile.Channels; result.AudioSampleRate = (int)audioFile.Bitrate; result.Comments = id3v2.CommentsList != null ? string.Join("|", id3v2.CommentsList?.Select(x => x.Value)) : null; result.Disc = ParseDiscNumber(id3v2.DiscNumber); result.DiscSubTitle = id3v2.SetSubtitle; result.Genres = SplitGenre(id3v2.Genre); result.Release = id3v2.Album; result.TrackArtist = id3v2.OriginalArtist ?? id3v2.Artist ?? id3v2.AlbumArtist; result.TrackArtistRaw = id3v2.OriginalArtist ?? id3v2.Artist ?? id3v2.AlbumArtist; result.Images = id3v2.PictureList?.Select(x => new AudioMetaDataImage { Data = x.PictureData, Description = x.Description, MimeType = x.MimeType, Type = (AudioMetaDataImageType)x.PictureType }).ToArray(); result.Time = audioFile.TotalSeconds > 0 ? ((decimal?)audioFile.TotalSeconds).ToTimeSpan() : null; result.Title = id3v2.Title.ToTitleCase(false); result.TrackNumber = ParseTrackNumber(id3v2.TrackNumber); result.TotalTrackNumbers = ParseTotalTrackNumber(id3v2.TrackNumber); var year = id3v2.Year ?? id3v2.RecordingTimestamp ?? id3v2.ReleaseTimestamp ?? id3v2.OriginalReleaseTimestamp; result.Year = ParseYear(year); isSuccess = result.IsValid; } if (!isSuccess) { if (ID3v1Tag.DoesTagExist(fileName)) { IID3v1Tag id3v1 = new ID3v1Tag(fileName); result.Release = id3v1.Album; result.Artist = id3v1.Artist; result.ArtistRaw = id3v1.Artist; result.AudioBitrate = (int?)audioFile.Bitrate; result.AudioChannels = audioFile.Channels; result.AudioSampleRate = (int)audioFile.Bitrate; result.Time = audioFile.TotalSeconds > 0 ? ((decimal?)audioFile.TotalSeconds).ToTimeSpan() : null; result.Title = id3v1.Title.ToTitleCase(false); result.TrackNumber = SafeParser.ToNumber <short?>(id3v1.TrackNumber); var date = SafeParser.ToDateTime(id3v1.Year); result.Year = date?.Year ?? SafeParser.ToNumber <int?>(id3v1.Year); isSuccess = result.IsValid; } } } catch (Exception ex) { message = ex.ToString(); Logger.LogError(ex, "MetaDataForFileFromTagLib Filename [" + fileName + "] Error [" + ex.Serialize() + "]"); } sw.Stop(); return(new OperationResult <AudioMetaData>(message) { IsSuccess = isSuccess, OperationTime = sw.ElapsedMilliseconds, Data = result }); }
public async Task <OperationResult <IEnumerable <ArtistSearchResult> > > PerformArtistSearch(string query, int resultsCount) { ArtistSearchResult result = null; try { this.Logger.LogTrace("MusicBrainzProvider:PerformArtistSearch:{0}", query); // Find the Artist var artistCacheKey = string.Format("uri:musicbrainz:ArtistSearchResult:{0}", query); result = this.CacheManager.Get <ArtistSearchResult>(artistCacheKey); if (result == null) { ArtistResult artistResult = null; try { artistResult = await MusicBrainzRequestHelper.GetAsync <ArtistResult>(MusicBrainzRequestHelper.CreateSearchTemplate("artist", query, resultsCount, 0)); } catch (Exception ex) { this.Logger.LogError(ex); } if (artistResult == null || artistResult.artists == null || artistResult.count < 1) { return(new OperationResult <IEnumerable <ArtistSearchResult> >()); } var a = artistResult.artists.First(); var mbArtist = await MusicBrainzRequestHelper.GetAsync <Artist>(MusicBrainzRequestHelper.CreateLookupUrl("artist", artistResult.artists.First().id, "releases")); if (mbArtist == null) { return(new OperationResult <IEnumerable <ArtistSearchResult> >()); } result = new ArtistSearchResult { ArtistName = mbArtist.name, ArtistSortName = mbArtist.sortname, MusicBrainzId = mbArtist.id, ArtistType = mbArtist.type, IPIs = mbArtist.ipis, ISNIs = mbArtist.isnis }; if (mbArtist.lifespan != null) { result.BeginDate = SafeParser.ToDateTime(mbArtist.lifespan.begin); result.EndDate = SafeParser.ToDateTime(mbArtist.lifespan.end); } if (a.aliases != null) { result.AlternateNames = a.aliases.Select(x => x.name).Distinct().ToArray(); } if (a.tags != null) { result.Tags = a.tags.Select(x => x.name).Distinct().ToArray(); } var mbFilteredReleases = new List <Release>(); var filteredPlaces = new List <string> { "US", "WORLDWIDE", "XW", "GB" }; foreach (var release in mbArtist.releases) { if (filteredPlaces.Contains((release.country ?? string.Empty).ToUpper())) { mbFilteredReleases.Add(release); } } result.Releases = new List <ReleaseSearchResult>(); var bag = new ConcurrentBag <Release>(); var filteredReleaseDetails = mbFilteredReleases.Select(async release => { bag.Add(await this.MusicBrainzReleaseById(release.id)); }); await Task.WhenAll(filteredReleaseDetails); foreach (var mbRelease in bag.Where(x => x != null)) { var release = new ReleaseSearchResult { MusicBrainzId = mbRelease.id, ReleaseTitle = mbRelease.title, ReleaseThumbnailUrl = mbRelease.coverThumbnailUrl }; if (mbRelease.imageUrls != null) { release.ImageUrls = mbRelease.imageUrls; } if (mbRelease.releaseevents != null) { release.ReleaseDate = SafeParser.ToDateTime(mbRelease.releaseevents.First().date); } // Labels if (mbRelease.media != null) { var releaseMedias = new List <ReleaseMediaSearchResult>(); foreach (var mbMedia in mbRelease.media) { var releaseMedia = new ReleaseMediaSearchResult { ReleaseMediaNumber = SafeParser.ToNumber <short?>(mbMedia.position), TrackCount = mbMedia.trackcount }; if (mbMedia.tracks != null) { var releaseTracks = new List <TrackSearchResult>(); foreach (var mbTrack in mbMedia.tracks) { releaseTracks.Add(new TrackSearchResult { MusicBrainzId = mbTrack.id, TrackNumber = SafeParser.ToNumber <short?>(mbTrack.number), Title = mbTrack.title, Duration = mbTrack.length }); } releaseMedia.Tracks = releaseTracks; } releaseMedias.Add(releaseMedia); } release.ReleaseMedia = releaseMedias; } result.Releases.Add(release); } ; this.CacheManager.Add(artistCacheKey, result); } } catch (HttpRequestException) { } catch (Exception ex) { this.Logger.LogError(ex); } if (result == null) { this.Logger.LogWarning("MusicBrainzArtist: ArtistName [{0}], No MusicBrainz Artist Found", query); } else { this.Logger.LogTrace("MusicBrainzArtist: Result [{0}]", query, result.ToString()); } return(new OperationResult <IEnumerable <ArtistSearchResult> > { IsSuccess = result != null, Data = new ArtistSearchResult[] { result } }); }
public AudioMetaData MetaDataFromFilename(string rawFilename) { var filename = CleanString(rawFilename); if (IsTalbTyerTalbTrckTit2(filename)) { // GUID~TPE1 - [TYER] - TALB~TRCK. TIT2 var parts = filename.Split('~'); var firstParts = parts[1].Split('-'); var artist = firstParts[0]; var year = firstParts[1].Replace("[", "").Replace("]", ""); var Release = firstParts[2]; var trck = parts[2].Substring(0, 2); var title = parts[2].Substring(3, parts[2].Length - 3); return(new AudioMetaData { Artist = CleanString(artist), Year = SafeParser.ToNumber <int?>(CleanString(year)), Release = CleanString(Release), TrackNumber = SafeParser.ToNumber <short?>(CleanString(trck)), Title = CleanString(title) }); } else if (IsTpe1TalbTyerTrckTpe1Tit2(filename)) { // GUID~TPE1-TALB-TYER~TRCK-TPE1-TIT2 var parts = filename.Split('~'); var firstParts = parts[1].Split('-'); var secondParts = parts[2].Split('-'); var artist = firstParts[0]; var Release = firstParts[1]; var year = firstParts[2]; var trck = secondParts[0].Substring(0, 2); var title = secondParts[1]; return(new AudioMetaData { Artist = CleanString(artist), Year = SafeParser.ToNumber <int?>(CleanString(year)), Release = CleanString(Release), TrackNumber = SafeParser.ToNumber <short?>(CleanString(trck)), Title = CleanString(title) }); } else if (IsTpe1TalbTyerTrckTit2(filename)) { // GUID~TPE1-TALB (TYER)~TRCK-TIT2 var parts = filename.Split('~'); var firstParts = parts[1].Split('-'); var secondParts = parts[2].Split('-'); var artist = firstParts[0]; var year = firstParts[1].Substring(firstParts[1].Length - 6, 6).Replace("(", "").Replace(")", ""); var Release = firstParts[1].Substring(0, firstParts[1].Length - 6); var trck = secondParts[1]; var title = secondParts[2]; return(new AudioMetaData { Artist = CleanString(artist), Year = SafeParser.ToNumber <int?>(CleanString(year)), Release = CleanString(Release), TrackNumber = SafeParser.ToNumber <short?>(CleanString(trck)), Title = CleanString(title) }); } else if (IsTalbTposTpe1TrckTit2(filename)) { // GUID~TALB~TPOS TPE1 - TRCK - TIT2 var parts = filename.Split('~'); var Release = parts[1]; var secondParts = parts[2].Split('-'); var tpos = secondParts[0].Substring(0, 2); var artist = secondParts[0].Substring(2, secondParts[0].Length - 2); var trck = secondParts[1]; var title = secondParts[2]; return(new AudioMetaData { Artist = CleanString(artist), Disk = SafeParser.ToNumber <int?>(CleanString(tpos)), Release = CleanString(Release), TrackNumber = SafeParser.ToNumber <short?>(CleanString(trck)), Title = CleanString(title) }); } else if (IsTyerTalbTrckTit2(filename)) { // GUID~[TYER] TALB~TRCK - TIT2 var parts = filename.Split('~'); var year = parts[1].Split(' ').First().Replace("[", "").Replace("]", "").Replace("(", "").Replace(")", ""); var Release = string.Join(" ", parts[1].Split(' ').Skip(1)); var secondParts = parts[2]; if (secondParts.StartsWith("-")) { secondParts = secondParts.Substring(1, secondParts.Length - 1); } var track = secondParts.Split('-').First(); var title = string.Join(" ", secondParts.Split('-').Skip(1)); return(new AudioMetaData { Year = SafeParser.ToNumber <int?>(CleanString(year)), Release = CleanString(Release), TrackNumber = SafeParser.ToNumber <short?>(CleanString(track)), Title = CleanString(title) }); } else if (IsTyerTalbTpe1Tit2(filename)) { // GUID~TYER - TALB~TPE1 - TIT2 var parts = filename.Split('~'); var secondParts = parts[1].Split('-'); var year = secondParts[0]; var Release = secondParts[1]; var thirdParts = parts[2].Split('-'); var artist = thirdParts[0]; var title = thirdParts[1]; return(new AudioMetaData { Year = SafeParser.ToNumber <int?>(CleanString(year)), Artist = CleanString(artist), Release = CleanString(Release), Title = CleanString(title) }); } else if (IsTpe1TrckTit2(filename)) { // GUID~TPE1~TRCK TIT2 var parts = filename.Split('~'); var track = parts[2].Split(' ').First(); var title = string.Join(" ", parts[2].Split(' ').Skip(1)); return(new AudioMetaData { Artist = CleanString(parts[1]), TrackNumber = SafeParser.ToNumber <short?>(CleanString(track)), Title = CleanString(title) }); } else if (IsTpe1Tit2(filename)) { var parts = filename.Split('~'); return(new AudioMetaData { Artist = CleanString(parts[1]), Title = CleanString(parts[2]) }); } return(new AudioMetaData()); }
public override OperationResult <string> Process(DirectoryInfo directory) { var result = new OperationResult <string>(); var data = string.Empty; var found = 0; var modified = 0; var metaDatasForFilesInFolder = GetAudioMetaDatasForDirectory(directory); if (metaDatasForFilesInFolder.Any()) { found = metaDatasForFilesInFolder.Count(); var firstMetaData = metaDatasForFilesInFolder.OrderBy(x => x.Filename ?? string.Empty).ThenBy(x => SafeParser.ToNumber <short>(x.TrackNumber)).FirstOrDefault(); if (firstMetaData == null) { return(new OperationResult <string>("Error Getting First MetaData") { Data = $"Unable to read Metadatas for Directory [{ directory.FullName }]" }); } var artist = firstMetaData.Artist; foreach (var metaData in metaDatasForFilesInFolder.Where(x => x.Artist != artist)) { modified++; Console.WriteLine($"╟ Setting Artist to [{ artist }], was [{ metaData.Artist }] on file [{ metaData.FileInfo.Name}"); metaData.Artist = artist; if (!Configuration.Inspector.IsInReadOnlyMode) { TagsHelper.WriteTags(metaData, metaData.Filename); } } data = $"Found [{ found }] files, Modified [{ modified }] files"; } result.Data = data; result.IsSuccess = true; return(result); }