From f556c28c29a45c0ead5e2a60d9ee3c4c20b3a797 Mon Sep 17 00:00:00 2001 From: Steven Hildreth Date: Sun, 21 Jun 2020 15:39:14 -0500 Subject: [PATCH] resolves #39, resolves #40 --- Inspector/Inspector.csproj | 2 +- .../ArtistLookupEngineTests.cs | 2 +- Roadie.Api.Library.Tests/ExtensionTests.cs | 17 + .../ID3TagsHelperTests.cs | 2 +- Roadie.Api.Library.Tests/InspectorTests.cs | 2 +- .../Roadie.Library.Tests.csproj | 2 +- Roadie.Api.Library.Tests/SearchEngineTests.cs | 2 +- .../Caching/CacheManagerBase.cs | 30 +- .../Caching/DictionaryCacheManager.cs | 4 +- .../Caching/ICacheSerializer.cs | 12 + .../Caching/MemoryCacheManager.cs | 4 +- .../Caching/NewtonsoftCacheSerializer.cs | 43 ++ .../Caching/RedisCacheManager.cs | 8 +- .../Caching/Utf8JsonCacheSerializer.cs | 52 ++ .../Configuration/Processing.cs | 3 + Roadie.Api.Library/Data/CollectionPartial.cs | 28 +- .../Engines/ArtistLookupEngine.cs | 4 +- .../Engines/ReleaseLookupEngine.cs | 389 +++++++---- Roadie.Api.Library/Extensions/DateTimeExt.cs | 1 - Roadie.Api.Library/Extensions/DecimalExt.cs | 9 +- .../Extensions/DictionaryExt.cs | 8 +- Roadie.Api.Library/Extensions/ExceptionExt.cs | 17 +- Roadie.Api.Library/Extensions/GenericExt.cs | 20 +- Roadie.Api.Library/Extensions/IntEx.cs | 6 +- Roadie.Api.Library/Extensions/ListExt.cs | 7 +- Roadie.Api.Library/Extensions/LongExt.cs | 6 +- Roadie.Api.Library/Extensions/ShortExt.cs | 18 +- Roadie.Api.Library/Extensions/StringExt.cs | 188 +++-- Roadie.Api.Library/Extensions/TimeSpanExt.cs | 6 +- Roadie.Api.Library/FilePlugins/Audio.cs | 32 +- Roadie.Api.Library/Imaging/ImageHelper.cs | 654 ++++++++++-------- Roadie.Api.Library/Inspect/Inspector.cs | 330 +++++---- .../Plugins/Directory/DeleteUnwantedFiles.cs | 6 +- .../Directory/EnsureArtistConsistent.cs | 8 +- .../Directory/EnsureReleaseConsistent.cs | 5 +- .../Plugins/Directory/EnsureYearConsistent.cs | 5 +- .../Directory/IInspectorDirectoryPlugin.cs | 3 + .../Inspect/Plugins/File/CleanUpArtists.cs | 29 +- .../Inspect/Plugins/File/CleanUpComments.cs | 5 + .../Plugins/File/CleanUpReleaseTitle.cs | 16 +- .../Inspect/Plugins/File/CleanUpTrackTitle.cs | 16 +- .../Plugins/File/EnsureFileWriteable.cs | 12 +- .../Plugins/File/IInspectorFilePlugin.cs | 2 + .../Inspect/Plugins/PluginBase.cs | 11 +- Roadie.Api.Library/Models/Artist.cs | 6 +- Roadie.Api.Library/Models/BookmarkList.cs | 4 +- .../Collections/CollectionReleaseList.cs | 16 +- Roadie.Api.Library/Models/DataToken.cs | 2 +- .../Models/EntityInfoModelBase.cs | 8 +- Roadie.Api.Library/Models/EntityModelBase.cs | 2 +- Roadie.Api.Library/Models/LabelList.cs | 7 +- Roadie.Api.Library/Models/PlayActivityList.cs | 23 +- .../Models/Player/PlayResult.cs | 11 +- .../Models/Releases/ReleaseLabelList.cs | 15 +- .../Models/Releases/ReleaseList.cs | 29 +- .../Models/ThirdPartyApi/Subsonic/Request.cs | 84 ++- Roadie.Api.Library/Models/Track.cs | 51 +- Roadie.Api.Library/Models/TrackList.cs | 150 ++-- Roadie.Api.Library/Models/Users/User.cs | 67 +- Roadie.Api.Library/OperationResult.cs | 57 +- Roadie.Api.Library/Roadie.Library.csproj | 17 +- .../RoadieProcessingException.cs | 23 + .../MetaData/Audio/AudioMetaData.cs | 153 ++-- .../MetaData/MusicBrainz/CoverArtEntities.cs | 1 - .../MetaData/MusicBrainz/Entities.cs | 123 +++- .../MusicBrainz/MusicBrainzProvider.cs | 2 +- .../MusicBrainz/MusicBrainzRequestHelper.cs | 13 +- .../MetaData/MusicBrainz/ResultEntities.cs | 200 ++++-- .../Roadie.Api.Services.csproj | 4 +- Roadie.Api.Services/ServiceBase.cs | 86 +-- Roadie.Api.Services/SubsonicService.cs | 428 ++++++++---- Roadie.Api.Services/TrackService.cs | 4 +- Roadie.Api.Services/UserService.cs | 4 +- .../Controllers/EntityControllerBase.cs | 4 +- Roadie.Api/Controllers/SubsonicController.cs | 6 +- Roadie.Api/Controllers/UserController.cs | 18 +- Roadie.Api/Program.cs | 23 +- Roadie.Api/Roadie.Api.csproj | 15 +- Roadie.Api/RoadieSerilogThemes.cs | 33 + Roadie.Api/Startup.cs | 16 +- Roadie.Api/appsettings.json | 4 +- .../Server/Handlers/MediaMount_SOAP.cs | 26 +- libraries/libwebp_x64.dll | Bin 0 -> 633344 bytes 83 files changed, 2451 insertions(+), 1310 deletions(-) create mode 100644 Roadie.Api.Library/Caching/ICacheSerializer.cs create mode 100644 Roadie.Api.Library/Caching/NewtonsoftCacheSerializer.cs create mode 100644 Roadie.Api.Library/Caching/Utf8JsonCacheSerializer.cs create mode 100644 Roadie.Api.Library/RoadieProcessingException.cs create mode 100644 Roadie.Api/RoadieSerilogThemes.cs create mode 100644 libraries/libwebp_x64.dll diff --git a/Inspector/Inspector.csproj b/Inspector/Inspector.csproj index 6706d76..e9beb22 100644 --- a/Inspector/Inspector.csproj +++ b/Inspector/Inspector.csproj @@ -22,7 +22,7 @@ - + diff --git a/Roadie.Api.Library.Tests/ArtistLookupEngineTests.cs b/Roadie.Api.Library.Tests/ArtistLookupEngineTests.cs index fe72721..3d58659 100644 --- a/Roadie.Api.Library.Tests/ArtistLookupEngineTests.cs +++ b/Roadie.Api.Library.Tests/ArtistLookupEngineTests.cs @@ -47,7 +47,7 @@ namespace Roadie.Library.Tests IConfiguration configuration = configurationBuilder.Build(); configuration.GetSection("RoadieSettings").Bind(settings); Configuration = settings; - CacheManager = new DictionaryCacheManager(Logger, new CachePolicy(TimeSpan.FromHours(4))); + CacheManager = new DictionaryCacheManager(Logger, new NewtonsoftCacheSerializer(Logger), new CachePolicy(TimeSpan.FromHours(4))); HttpEncoder = new Encoding.DummyHttpEncoder(); } diff --git a/Roadie.Api.Library.Tests/ExtensionTests.cs b/Roadie.Api.Library.Tests/ExtensionTests.cs index 15ac01e..723fe93 100644 --- a/Roadie.Api.Library.Tests/ExtensionTests.cs +++ b/Roadie.Api.Library.Tests/ExtensionTests.cs @@ -290,5 +290,22 @@ namespace Roadie.Library.Tests var d = input.ToSecondsFromMilliseconds(); Assert.Equal(shouldBe, d); } + + [Theory] + [InlineData("Song (ft. Joe)")] + [InlineData("Song (featuring Joe)")] + [InlineData("Song (feat. Joe)")] + public void StringHaveFeatureFragments(string input) + { + Assert.True(input.HasFeaturingFragments()); + } + + [Theory] + [InlineData("Future Feature")] + [InlineData("Feature Song")] + public void StringShouldNotHaveFeatureFragments(string input) + { + Assert.False(input.HasFeaturingFragments()); + } } } diff --git a/Roadie.Api.Library.Tests/ID3TagsHelperTests.cs b/Roadie.Api.Library.Tests/ID3TagsHelperTests.cs index 6ea698c..012a75b 100644 --- a/Roadie.Api.Library.Tests/ID3TagsHelperTests.cs +++ b/Roadie.Api.Library.Tests/ID3TagsHelperTests.cs @@ -42,7 +42,7 @@ namespace Roadie.Library.Tests configuration.GetSection("RoadieSettings").Bind(settings); settings.ConnectionString = configuration.GetConnectionString("RoadieDatabaseConnection"); Configuration = settings; - CacheManager = new DictionaryCacheManager(Logger, new CachePolicy(TimeSpan.FromHours(4))); + CacheManager = new DictionaryCacheManager(Logger, new NewtonsoftCacheSerializer(Logger), new CachePolicy(TimeSpan.FromHours(4))); var tagHelperLooper = new EventMessageLogger(); tagHelperLooper.Messages += MessageLoggerMessages; TagsHelper = new ID3TagsHelper(Configuration, CacheManager, tagHelperLooper); diff --git a/Roadie.Api.Library.Tests/InspectorTests.cs b/Roadie.Api.Library.Tests/InspectorTests.cs index ecf91f6..a3308dd 100644 --- a/Roadie.Api.Library.Tests/InspectorTests.cs +++ b/Roadie.Api.Library.Tests/InspectorTests.cs @@ -45,7 +45,7 @@ namespace Roadie.Library.Tests configuration.GetSection("RoadieSettings").Bind(settings); settings.ConnectionString = configuration.GetConnectionString("RoadieDatabaseConnection"); Configuration = settings; - CacheManager = new DictionaryCacheManager(Logger, new CachePolicy(TimeSpan.FromHours(4))); + CacheManager = new DictionaryCacheManager(Logger, new NewtonsoftCacheSerializer(Logger), new CachePolicy(TimeSpan.FromHours(4))); var tagHelperLooper = new EventMessageLogger(); tagHelperLooper.Messages += MessageLoggerMessages; TagsHelper = new ID3TagsHelper(Configuration, CacheManager, tagHelperLooper); diff --git a/Roadie.Api.Library.Tests/Roadie.Library.Tests.csproj b/Roadie.Api.Library.Tests/Roadie.Library.Tests.csproj index f891d84..1a5df5e 100644 --- a/Roadie.Api.Library.Tests/Roadie.Library.Tests.csproj +++ b/Roadie.Api.Library.Tests/Roadie.Library.Tests.csproj @@ -23,7 +23,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Roadie.Api.Library.Tests/SearchEngineTests.cs b/Roadie.Api.Library.Tests/SearchEngineTests.cs index 0a17146..47f18f3 100644 --- a/Roadie.Api.Library.Tests/SearchEngineTests.cs +++ b/Roadie.Api.Library.Tests/SearchEngineTests.cs @@ -35,7 +35,7 @@ namespace Roadie.Library.Tests IConfiguration configuration = configurationBuilder.Build(); configuration.GetSection("RoadieSettings").Bind(settings); Configuration = settings; - CacheManager = new DictionaryCacheManager(Logger, new CachePolicy(TimeSpan.FromHours(4))); + CacheManager = new DictionaryCacheManager(Logger, new NewtonsoftCacheSerializer(Logger), new CachePolicy(TimeSpan.FromHours(4))); HttpEncoder = new Encoding.DummyHttpEncoder(); } diff --git a/Roadie.Api.Library/Caching/CacheManagerBase.cs b/Roadie.Api.Library/Caching/CacheManagerBase.cs index 495cb4e..be231c2 100644 --- a/Roadie.Api.Library/Caching/CacheManagerBase.cs +++ b/Roadie.Api.Library/Caching/CacheManagerBase.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using System; using System.Threading.Tasks; @@ -10,19 +9,15 @@ namespace Roadie.Library.Caching public const string SystemCacheRegionUrn = "urn:system"; protected readonly CachePolicy _defaultPolicy; - protected readonly JsonSerializerSettings _serializerSettings; protected ILogger Logger { get; } + protected ICacheSerializer CacheSerializer { get; } - public CacheManagerBase(ILogger logger, CachePolicy defaultPolicy) + public CacheManagerBase(ILogger logger, ICacheSerializer cacheSerializer, CachePolicy defaultPolicy) { Logger = logger; + CacheSerializer = cacheSerializer; _defaultPolicy = defaultPolicy; - _serializerSettings = new JsonSerializerSettings - { - ContractResolver = new IgnoreJsonAttributesResolver(), - Formatting = Formatting.Indented - }; } public abstract bool Add(string key, TCacheValue value); @@ -55,24 +50,5 @@ namespace Roadie.Library.Caching public abstract bool Remove(string key, string region); - protected TOut Deserialize(string s) - { - if (string.IsNullOrEmpty(s)) return default(TOut); - try - { - return JsonConvert.DeserializeObject(s, _serializerSettings); - } - catch (Exception ex) - { - Logger.LogError(ex); - } - - return default(TOut); - } - - protected string Serialize(object o) - { - return JsonConvert.SerializeObject(o, _serializerSettings); - } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Caching/DictionaryCacheManager.cs b/Roadie.Api.Library/Caching/DictionaryCacheManager.cs index 88a0cbf..3fe99ec 100644 --- a/Roadie.Api.Library/Caching/DictionaryCacheManager.cs +++ b/Roadie.Api.Library/Caching/DictionaryCacheManager.cs @@ -11,8 +11,8 @@ namespace Roadie.Library.Caching private Dictionary Cache { get; } - public DictionaryCacheManager(ILogger logger, CachePolicy defaultPolicy) - : base(logger, defaultPolicy) + public DictionaryCacheManager(ILogger logger, ICacheSerializer cacheSerializer, CachePolicy defaultPolicy) + : base(logger, cacheSerializer, defaultPolicy) { Cache = new Dictionary(); } diff --git a/Roadie.Api.Library/Caching/ICacheSerializer.cs b/Roadie.Api.Library/Caching/ICacheSerializer.cs new file mode 100644 index 0000000..26ad043 --- /dev/null +++ b/Roadie.Api.Library/Caching/ICacheSerializer.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Roadie.Library.Caching +{ + public interface ICacheSerializer + { + string Serialize(object o); + TOut Deserialize(string s); + } +} diff --git a/Roadie.Api.Library/Caching/MemoryCacheManager.cs b/Roadie.Api.Library/Caching/MemoryCacheManager.cs index 78570ce..34c218d 100644 --- a/Roadie.Api.Library/Caching/MemoryCacheManager.cs +++ b/Roadie.Api.Library/Caching/MemoryCacheManager.cs @@ -9,8 +9,8 @@ namespace Roadie.Library.Caching { private MemoryCache _cache; - public MemoryCacheManager(ILogger logger, CachePolicy defaultPolicy) - : base(logger, defaultPolicy) + public MemoryCacheManager(ILogger logger, ICacheSerializer cacheSerializer, CachePolicy defaultPolicy) + : base(logger, cacheSerializer, defaultPolicy) { _cache = new MemoryCache(new MemoryCacheOptions()); } diff --git a/Roadie.Api.Library/Caching/NewtonsoftCacheSerializer.cs b/Roadie.Api.Library/Caching/NewtonsoftCacheSerializer.cs new file mode 100644 index 0000000..9831cb7 --- /dev/null +++ b/Roadie.Api.Library/Caching/NewtonsoftCacheSerializer.cs @@ -0,0 +1,43 @@ +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using System; + +namespace Roadie.Library.Caching +{ + public class NewtonsoftCacheSerializer : ICacheSerializer + { + protected ILogger Logger { get; } + + protected readonly JsonSerializerSettings _serializerSettings; + + public NewtonsoftCacheSerializer(ILogger logger) + { + Logger = logger; + _serializerSettings = new JsonSerializerSettings + { + ContractResolver = new IgnoreJsonAttributesResolver(), + ReferenceLoopHandling = ReferenceLoopHandling.Ignore, + Formatting = Formatting.Indented + }; + } + + public TOut Deserialize(string s) + { + if (string.IsNullOrEmpty(s)) + { + return default(TOut); + } + try + { + return JsonConvert.DeserializeObject(s, _serializerSettings); + } + catch (Exception ex) + { + Logger.LogError(ex); + } + return default(TOut); + } + + public string Serialize(object o) => JsonConvert.SerializeObject(o, _serializerSettings); + } +} \ No newline at end of file diff --git a/Roadie.Api.Library/Caching/RedisCacheManager.cs b/Roadie.Api.Library/Caching/RedisCacheManager.cs index ec4b43f..da31fc5 100644 --- a/Roadie.Api.Library/Caching/RedisCacheManager.cs +++ b/Roadie.Api.Library/Caching/RedisCacheManager.cs @@ -26,8 +26,8 @@ namespace Roadie.Library.Caching private IDatabase Redis => _redis ?? (_redis = Connection.GetDatabase()); - public RedisCacheManager(ILogger logger, CachePolicy defaultPolicy) - : base(logger, defaultPolicy) + public RedisCacheManager(ILogger logger, ICacheSerializer cacheSerializer, CachePolicy defaultPolicy) + : base(logger, cacheSerializer, defaultPolicy) { } @@ -49,7 +49,7 @@ namespace Roadie.Library.Caching public override bool Add(string key, TCacheValue value, string region, CachePolicy policy) { if (_doTraceLogging) Logger.LogTrace("Added [{0}], Region [{1}]", key, region); - return Redis.StringSet(key, Serialize(value)); + return Redis.StringSet(key, CacheSerializer.Serialize(value)); } public override void Clear() @@ -135,7 +135,7 @@ namespace Roadie.Library.Caching private TOut Get(string key, string region, CachePolicy policy) { - var result = Deserialize(Redis.StringGet(key)); + var result = CacheSerializer.Deserialize(Redis.StringGet(key)); if (result == null) { if (_doTraceLogging) Logger.LogTrace("Get Cache Miss Key [{0}], Region [{1}]", key, region); diff --git a/Roadie.Api.Library/Caching/Utf8JsonCacheSerializer.cs b/Roadie.Api.Library/Caching/Utf8JsonCacheSerializer.cs new file mode 100644 index 0000000..1083bfe --- /dev/null +++ b/Roadie.Api.Library/Caching/Utf8JsonCacheSerializer.cs @@ -0,0 +1,52 @@ +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Text; +using Utf8Json; + +namespace Roadie.Library.Caching +{ + public class Utf8JsonCacheSerializer : ICacheSerializer + { + protected ILogger Logger { get; } + + public Utf8JsonCacheSerializer(ILogger logger) + { + Logger = logger; + } + + public string Serialize(object o) + { + if(o == null) + { + return null; + } + try + { + return System.Text.Encoding.UTF8.GetString(JsonSerializer.Serialize(o)); + } + catch (Exception ex) + { + Logger.LogError(ex); + } + return null; + } + + public TOut Deserialize(string s) + { + if (string.IsNullOrEmpty(s)) + { + return default(TOut); + } + try + { + return JsonSerializer.Deserialize(s); + } + catch (Exception ex) + { + Logger.LogError(ex); + } + return default(TOut); + } + } +} diff --git a/Roadie.Api.Library/Configuration/Processing.cs b/Roadie.Api.Library/Configuration/Processing.cs index ad12ff4..e704253 100644 --- a/Roadie.Api.Library/Configuration/Processing.cs +++ b/Roadie.Api.Library/Configuration/Processing.cs @@ -46,6 +46,8 @@ namespace Roadie.Library.Configuration public string UnknownFolder { get; set; } + public bool DoDetectFeatureFragments { get; set; } + public Processing() { DoAudioCleanup = true; @@ -55,6 +57,7 @@ namespace Roadie.Library.Configuration DoParseFromLastFM = true; DoParseFromMusicBrainz = true; DoSaveEditsToTags = true; + DoDetectFeatureFragments = true; MaximumArtistImagesToAdd = 12; MaximumReleaseImagesToAdd = 12; diff --git a/Roadie.Api.Library/Data/CollectionPartial.cs b/Roadie.Api.Library/Data/CollectionPartial.cs index 84e2ab0..6eef9dd 100644 --- a/Roadie.Api.Library/Data/CollectionPartial.cs +++ b/Roadie.Api.Library/Data/CollectionPartial.cs @@ -1,7 +1,5 @@ using CsvHelper; -using Newtonsoft.Json; using Roadie.Library.Configuration; -using Roadie.Library.Enums; using Roadie.Library.Extensions; using Roadie.Library.Utility; using System; @@ -14,6 +12,10 @@ namespace Roadie.Library.Data { public partial class Collection { + public const string ArtistPosition = "artist"; + public const string PositionPosition = "position"; + public const string ReleasePosition = "release"; + /// /// If the given value in either Artist or Release starts with this then the next value is the database Id, example "1,~4,~19" /// @@ -35,7 +37,10 @@ namespace Roadie.Library.Data foreach (var pos in ListInCSVFormat.Split(',')) { looper++; - if (pos.ToLower().Equals("artist")) _artistColumn = looper; + if (String.Equals(pos, ArtistPosition, StringComparison.OrdinalIgnoreCase)) + { + _artistColumn = looper; + } } } @@ -70,7 +75,10 @@ namespace Roadie.Library.Data foreach (var pos in ListInCSVFormat.Split(',')) { looper++; - if (pos.ToLower().Equals("position")) _positionColumn = looper; + if (String.Equals(pos, PositionPosition, StringComparison.OrdinalIgnoreCase)) + { + _positionColumn = looper; + } } } @@ -88,7 +96,10 @@ namespace Roadie.Library.Data foreach (var pos in ListInCSVFormat.Split(',')) { looper++; - if (pos.ToLower().Equals("release")) _releaseColumn = looper; + if (String.Equals(pos, ReleasePosition, StringComparison.OrdinalIgnoreCase)) + { + _releaseColumn = looper; + } } } @@ -129,10 +140,7 @@ namespace Roadie.Library.Data MissingFieldFound = null, HasHeaderRecord = false }; - configuration.BadDataFound = context => - { - Trace.WriteLine($"PositionArtistReleases: Bad data found on row '{context.RawRow}'", "Warning"); - }; + configuration.BadDataFound = context => Trace.WriteLine($"PositionArtistReleases: Bad data found on row '{context.RawRow}'", "Warning"); using (var csv = new CsvReader(sr, configuration)) { while (csv.Read()) @@ -160,6 +168,4 @@ namespace Roadie.Library.Data return $"Id [{Id}], Name [{Name}], RoadieId [{RoadieId}]"; } } - - } \ No newline at end of file diff --git a/Roadie.Api.Library/Engines/ArtistLookupEngine.cs b/Roadie.Api.Library/Engines/ArtistLookupEngine.cs index 4d9df46..965eb99 100644 --- a/Roadie.Api.Library/Engines/ArtistLookupEngine.cs +++ b/Roadie.Api.Library/Engines/ArtistLookupEngine.cs @@ -1,6 +1,5 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Library.Caching; using Roadie.Library.Configuration; using Roadie.Library.Data; @@ -19,6 +18,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; using discogs = Roadie.Library.SearchEngines.MetaData.Discogs; using lastfm = Roadie.Library.MetaData.LastFm; @@ -251,7 +251,7 @@ namespace Roadie.Library.Engines } if (!string.IsNullOrEmpty(releaseRoadieDataFilename) && File.Exists(releaseRoadieDataFilename)) { - artist = JsonConvert.DeserializeObject(File.ReadAllText(releaseRoadieDataFilename)); + artist = JsonSerializer.Deserialize(File.ReadAllText(releaseRoadieDataFilename)); var addResult = await Add(artist).ConfigureAwait(false); if (!addResult.IsSuccess) { diff --git a/Roadie.Api.Library/Engines/ReleaseLookupEngine.cs b/Roadie.Api.Library/Engines/ReleaseLookupEngine.cs index 1d1e1d5..6ac56f1 100644 --- a/Roadie.Api.Library/Engines/ReleaseLookupEngine.cs +++ b/Roadie.Api.Library/Engines/ReleaseLookupEngine.cs @@ -30,7 +30,11 @@ namespace Roadie.Library.Engines { public class ReleaseLookupEngine : LookupEngineBase, IReleaseLookupEngine { + private IArtistLookupEngine ArtistLookupEngine { get; } + private ILabelLookupEngine LabelLookupEngine { get; } + public List _addedReleaseIds = new List(); + public List _addedTrackIds = new List(); public IEnumerable AddedReleaseIds => _addedReleaseIds; @@ -49,10 +53,6 @@ namespace Roadie.Library.Engines public IReleaseSearchEngine WikipediaReleaseSearchEngine { get; } - private IArtistLookupEngine ArtistLookupEngine { get; } - - private ILabelLookupEngine LabelLookupEngine { get; } - public ReleaseLookupEngine(IRoadieSettings configuration, IHttpEncoder httpEncoder, IRoadieDbContext context, ICacheManager cacheManager, ILogger logger, IArtistLookupEngine artistLookupEngine, ILabelLookupEngine labelLookupEngine, musicbrainz.IMusicBrainzProvider musicBrainzProvider, lastfm.ILastFmHelper lastFmHelper, @@ -117,7 +117,11 @@ namespace Roadie.Library.Engines { var genreName = releaseGenreTable.ToAlphanumericName().ToTitleCase(); var normalizedName = genreName.ToUpper(); - if (string.IsNullOrEmpty(genreName)) continue; + if (string.IsNullOrEmpty(genreName)) + { + continue; + } + if (genreName.Length > 100) { var originalName = genreName; @@ -204,76 +208,73 @@ namespace Roadie.Library.Engines } } - if (doAddTracksInDatabase) + if (doAddTracksInDatabase && releaseMedias?.Any(x => x.Status == Statuses.New) == true) { - if (releaseMedias?.Any(x => x.Status == Statuses.New) == true) + foreach (var newReleaseMedia in releaseMedias.Where(x => x.Status == Statuses.New)) { - foreach (var newReleaseMedia in releaseMedias.Where(x => x.Status == Statuses.New)) + var releasemedia = new ReleaseMedia { - var releasemedia = new ReleaseMedia + Status = Statuses.Incomplete, + MediaNumber = newReleaseMedia.MediaNumber, + SubTitle = newReleaseMedia.SubTitle, + TrackCount = newReleaseMedia.TrackCount, + ReleaseId = release.Id + }; + var releasemediatracks = new List(); + foreach (var newTrack in newReleaseMedia.Tracks) + { + int? trackArtistId = null; + string partTitles = null; + if (newTrack.TrackArtist != null) { - Status = Statuses.Incomplete, - MediaNumber = newReleaseMedia.MediaNumber, - SubTitle = newReleaseMedia.SubTitle, - TrackCount = newReleaseMedia.TrackCount, - ReleaseId = release.Id - }; - var releasemediatracks = new List(); - foreach (var newTrack in newReleaseMedia.Tracks) - { - int? trackArtistId = null; - string partTitles = null; - if (newTrack.TrackArtist != null) + if (!release.IsCastRecording) { - if (!release.IsCastRecording) + var trackArtistData = await ArtistLookupEngine.GetByName(new AudioMetaData { Artist = newTrack.TrackArtist.Name }, true).ConfigureAwait(false); + if (trackArtistData.IsSuccess) { - var trackArtistData = await ArtistLookupEngine.GetByName(new AudioMetaData { Artist = newTrack.TrackArtist.Name }, true).ConfigureAwait(false); - if (trackArtistData.IsSuccess) - { - trackArtistId = trackArtistData.Data.Id; - } - } - else if (newTrack.TrackArtists?.Any() == true) - { - partTitles = string.Join("/", newTrack.TrackArtists); - } - else - { - partTitles = newTrack.TrackArtist.Name; + trackArtistId = trackArtistData.Data.Id; } } - - releasemediatracks.Add(new Track + else if (newTrack.TrackArtists?.Any() == true) { - ArtistId = trackArtistId, - PartTitles = partTitles, - Status = Statuses.Incomplete, - TrackNumber = newTrack.TrackNumber, - MusicBrainzId = newTrack.MusicBrainzId, - SpotifyId = newTrack.SpotifyId, - AmgId = newTrack.AmgId, - Title = newTrack.Title, - AlternateNames = newTrack.AlternateNames, - Duration = newTrack.Duration, - Tags = newTrack.Tags, - ISRC = newTrack.ISRC, - LastFMId = newTrack.LastFMId - }); + partTitles = string.Join("/", newTrack.TrackArtists); + } + else + { + partTitles = newTrack.TrackArtist.Name; + } } - releasemedia.Tracks = releasemediatracks; - DbContext.ReleaseMedias.Add(releasemedia); - _addedTrackIds.AddRange(releasemedia.Tracks.Select(x => x.Id)); + releasemediatracks.Add(new Track + { + ArtistId = trackArtistId, + PartTitles = partTitles, + Status = Statuses.Incomplete, + TrackNumber = newTrack.TrackNumber, + MusicBrainzId = newTrack.MusicBrainzId, + SpotifyId = newTrack.SpotifyId, + AmgId = newTrack.AmgId, + Title = newTrack.Title, + AlternateNames = newTrack.AlternateNames, + Duration = newTrack.Duration, + Tags = newTrack.Tags, + ISRC = newTrack.ISRC, + LastFMId = newTrack.LastFMId + }); } - try - { - await DbContext.SaveChangesAsync().ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.LogError(ex); - } + releasemedia.Tracks = releasemediatracks; + DbContext.ReleaseMedias.Add(releasemedia); + _addedTrackIds.AddRange(releasemedia.Tracks.Select(x => x.Id)); + } + + try + { + await DbContext.SaveChangesAsync().ConfigureAwait(false); + } + catch (Exception ex) + { + Logger.LogError(ex); } } sw.Stop(); @@ -314,21 +315,21 @@ namespace Roadie.Library.Engines var specialSearchNameEnd = $"|{specialSearchName}"; return await (from a in DbContext.Releases - where a.ArtistId == artist.Id - where a.Title.ToLower() == searchName || - a.Title.ToLower() == specialSearchName || - a.SortTitle.ToLower() == searchName || - a.SortTitle.ToLower() == searchSortName || - a.SortTitle.ToLower() == specialSearchName || - a.AlternateNames.ToLower().Equals(searchName) || - a.AlternateNames.ToLower().StartsWith(searchNameStart) || - a.AlternateNames.ToLower().Contains(searchNameIn) || - a.AlternateNames.ToLower().EndsWith(searchNameEnd) || - a.AlternateNames.ToLower().Equals(specialSearchName) || - a.AlternateNames.ToLower().StartsWith(specialSearchNameStart) || - a.AlternateNames.ToLower().Contains(specialSearchNameIn) || - a.AlternateNames.ToLower().EndsWith(specialSearchNameEnd) - select a + where a.ArtistId == artist.Id + where a.Title.ToLower() == searchName || + a.Title.ToLower() == specialSearchName || + a.SortTitle.ToLower() == searchName || + a.SortTitle.ToLower() == searchSortName || + a.SortTitle.ToLower() == specialSearchName || + a.AlternateNames.ToLower().Equals(searchName) || + a.AlternateNames.ToLower().StartsWith(searchNameStart) || + a.AlternateNames.ToLower().Contains(searchNameIn) || + a.AlternateNames.ToLower().EndsWith(searchNameEnd) || + a.AlternateNames.ToLower().Equals(specialSearchName) || + a.AlternateNames.ToLower().StartsWith(specialSearchNameStart) || + a.AlternateNames.ToLower().Contains(specialSearchNameIn) || + a.AlternateNames.ToLower().EndsWith(specialSearchNameEnd) + select a ).FirstOrDefaultAsync().ConfigureAwait(false); } catch (Exception ex) @@ -348,7 +349,7 @@ namespace Roadie.Library.Engines var sw = new Stopwatch(); sw.Start(); var cacheRegion = new Release { Artist = artist, Title = metaData.Release }.CacheRegion; - var cacheKey = string.Format("urn:release_by_artist_id_and_name:{0}:{1}", artist.Id, metaData.Release); + var cacheKey = $"urn:release_by_artist_id_and_name:{artist.Id}:{metaData.Release}"; var resultInCache = CacheManager.Get(cacheKey, cacheRegion); if (resultInCache != null) { @@ -403,7 +404,11 @@ namespace Roadie.Library.Engines } } - if (release != null) CacheManager.Add(cacheKey, release); + if (release != null) + { + CacheManager.Add(cacheKey, release); + } + return new OperationResult { IsSuccess = release != null, @@ -437,7 +442,11 @@ namespace Roadie.Library.Engines var resultsExceptions = new List(); var releaseGenres = new List(); // Add any Genre found in the given MetaData - if (metaData.Genres != null) releaseGenres.AddRange(metaData.Genres); + if (metaData.Genres != null) + { + releaseGenres.AddRange(metaData.Genres); + } + var releaseLabels = new List(); var releaseMedias = new List(); var releaseImages = new List(); @@ -464,10 +473,26 @@ namespace Roadie.Library.Engines 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); + 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); + } + if (!string.IsNullOrEmpty(i.ReleaseThumbnailUrl)) { releaseImages.Add(new Imaging.Image() @@ -486,11 +511,22 @@ namespace Roadie.Library.Engines ? SafeParser.ToEnum(i.ReleaseType) : result.ReleaseType }); - if (i.ReleaseLabel != null) releaseLabels.AddRange(i.ReleaseLabel); - if (i.ReleaseMedia != null) releaseMedias.AddRange(i.ReleaseMedia); + if (i.ReleaseLabel != null) + { + releaseLabels.AddRange(i.ReleaseLabel); + } + + if (i.ReleaseMedia != null) + { + releaseMedias.AddRange(i.ReleaseMedia); + } + } + + if (iTunesResult.Errors != null) + { + resultsExceptions.AddRange(iTunesResult.Errors); } - if (iTunesResult.Errors != null) resultsExceptions.AddRange(iTunesResult.Errors); sw2.Stop(); Logger.LogTrace($"PerformMetaDataProvidersReleaseSearch: ITunesArtistSearchEngine Complete [{ sw2.ElapsedMilliseconds }]"); } @@ -508,13 +544,32 @@ namespace Roadie.Library.Engines { 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 (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)) + !mb.ReleaseTitle.Equals(result.Title, StringComparison.OrdinalIgnoreCase)) { result.AlternateNames.AddToDelimitedList(new[] { mb.ReleaseTitle }); } @@ -541,11 +596,22 @@ namespace Roadie.Library.Engines ? SafeParser.ToEnum(mb.ReleaseType) : result.ReleaseType }); - if (mb.ReleaseLabel != null) releaseLabels.AddRange(mb.ReleaseLabel); - if (mb.ReleaseMedia != null) releaseMedias.AddRange(mb.ReleaseMedia); + if (mb.ReleaseLabel != null) + { + releaseLabels.AddRange(mb.ReleaseLabel); + } + + if (mb.ReleaseMedia != null) + { + releaseMedias.AddRange(mb.ReleaseMedia); + } + } + + if (mbResult.Errors != null) + { + resultsExceptions.AddRange(mbResult.Errors); } - if (mbResult.Errors != null) resultsExceptions.AddRange(mbResult.Errors); sw2.Stop(); Logger.LogTrace($"PerformMetaDataProvidersReleaseSearch: MusicBrainzReleaseSearchEngine Complete [{ sw2.ElapsedMilliseconds }]"); } @@ -564,13 +630,32 @@ namespace Roadie.Library.Engines { 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 (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)) + !l.ReleaseTitle.Equals(result.Title, StringComparison.OrdinalIgnoreCase)) { result.AlternateNames.AddToDelimitedList(new[] { l.ReleaseTitle }); } @@ -596,11 +681,22 @@ namespace Roadie.Library.Engines ? SafeParser.ToEnum(l.ReleaseType) : result.ReleaseType }); - if (l.ReleaseLabel != null) releaseLabels.AddRange(l.ReleaseLabel); - if (l.ReleaseMedia != null) releaseMedias.AddRange(l.ReleaseMedia); + if (l.ReleaseLabel != null) + { + releaseLabels.AddRange(l.ReleaseLabel); + } + + if (l.ReleaseMedia != null) + { + releaseMedias.AddRange(l.ReleaseMedia); + } + } + + if (lastFmResult.Errors != null) + { + resultsExceptions.AddRange(lastFmResult.Errors); } - if (lastFmResult.Errors != null) resultsExceptions.AddRange(lastFmResult.Errors); sw2.Stop(); Logger.LogTrace($"PerformMetaDataProvidersReleaseSearch: LastFmReleaseSearchEngine Complete [{ sw2.ElapsedMilliseconds }]"); } @@ -617,12 +713,28 @@ namespace Roadie.Library.Engines 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 (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)) + !s.ReleaseTitle.Equals(result.Title, StringComparison.OrdinalIgnoreCase)) { result.AlternateNames.AddToDelimitedList(new[] { s.ReleaseTitle }); } @@ -647,11 +759,22 @@ namespace Roadie.Library.Engines ? SafeParser.ToEnum(s.ReleaseType) : result.ReleaseType }); - if (s.ReleaseLabel != null) releaseLabels.AddRange(s.ReleaseLabel); - if (s.ReleaseMedia != null) releaseMedias.AddRange(s.ReleaseMedia); + if (s.ReleaseLabel != null) + { + releaseLabels.AddRange(s.ReleaseLabel); + } + + if (s.ReleaseMedia != null) + { + releaseMedias.AddRange(s.ReleaseMedia); + } + } + + if (spotifyResult.Errors != null) + { + resultsExceptions.AddRange(spotifyResult.Errors); } - if (spotifyResult.Errors != null) resultsExceptions.AddRange(spotifyResult.Errors); sw2.Stop(); Logger.LogTrace($"PerformMetaDataProvidersReleaseSearch: SpotifyReleaseSearchEngine Complete [{ sw2.ElapsedMilliseconds }]"); } @@ -668,12 +791,23 @@ namespace Roadie.Library.Engines 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.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)) + !d.ReleaseTitle.Equals(result.Title, StringComparison.OrdinalIgnoreCase)) { result.AlternateNames.AddToDelimitedList(new[] { d.ReleaseTitle }); } @@ -694,11 +828,22 @@ namespace Roadie.Library.Engines ? SafeParser.ToEnum(d.ReleaseType) : result.ReleaseType }); - if (d.ReleaseLabel != null) releaseLabels.AddRange(d.ReleaseLabel); - if (d.ReleaseMedia != null) releaseMedias.AddRange(d.ReleaseMedia); + if (d.ReleaseLabel != null) + { + releaseLabels.AddRange(d.ReleaseLabel); + } + + if (d.ReleaseMedia != null) + { + releaseMedias.AddRange(d.ReleaseMedia); + } + } + + if (discogsResult.Errors != null) + { + resultsExceptions.AddRange(discogsResult.Errors); } - if (discogsResult.Errors != null) resultsExceptions.AddRange(discogsResult.Errors); sw2.Stop(); Logger.LogTrace($"PerformMetaDataProvidersReleaseSearch: DiscogsReleaseSearchEngine Complete [{ sw2.ElapsedMilliseconds }]"); } @@ -885,7 +1030,10 @@ namespace Roadie.Library.Engines : rmTrack.AlternateNames.AddToDelimitedList(releaseTrack.AlternateNames); rmTrack.ISRC ??= releaseTrack.ISRC; rmTrack.LastFMId ??= releaseTrack.LastFMId; - if (!foundTrack) rmTracks.Add(rmTrack); + if (!foundTrack) + { + rmTracks.Add(rmTrack); + } } rm.Tracks = rmTracks; @@ -916,7 +1064,10 @@ namespace Roadie.Library.Engines { var imageCoverByReleaseName = Array.Find(imageFilesInFolder, x => x == result.Title || x == result.Title.ToFileNameFriendly()); - if (imageCoverByReleaseName != null) coverFileName = imageCoverByReleaseName; + if (imageCoverByReleaseName != null) + { + coverFileName = imageCoverByReleaseName; + } } } else if (cover.Any()) diff --git a/Roadie.Api.Library/Extensions/DateTimeExt.cs b/Roadie.Api.Library/Extensions/DateTimeExt.cs index fb767a7..42d7fc3 100644 --- a/Roadie.Api.Library/Extensions/DateTimeExt.cs +++ b/Roadie.Api.Library/Extensions/DateTimeExt.cs @@ -15,6 +15,5 @@ namespace Roadie.Library.Extensions var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); return Convert.ToInt64((date - epoch).TotalSeconds); } - } } \ No newline at end of file diff --git a/Roadie.Api.Library/Extensions/DecimalExt.cs b/Roadie.Api.Library/Extensions/DecimalExt.cs index 2c1c06a..a90f33c 100644 --- a/Roadie.Api.Library/Extensions/DecimalExt.cs +++ b/Roadie.Api.Library/Extensions/DecimalExt.cs @@ -1,5 +1,4 @@ -using Roadie.Library.Utility; -using System; +using System; namespace Roadie.Library.Extensions { @@ -17,7 +16,11 @@ namespace Roadie.Library.Extensions public static TimeSpan? ToTimeSpan(this decimal? value) { - if (!value.HasValue) return null; + if (!value.HasValue) + { + return null; + } + return TimeSpan.FromSeconds((double)value); } } diff --git a/Roadie.Api.Library/Extensions/DictionaryExt.cs b/Roadie.Api.Library/Extensions/DictionaryExt.cs index d5ee31c..b7c4062 100644 --- a/Roadie.Api.Library/Extensions/DictionaryExt.cs +++ b/Roadie.Api.Library/Extensions/DictionaryExt.cs @@ -1,8 +1,6 @@ -using Roadie.Library.Utility; -using System; +using System; using System.Collections.Generic; using System.Linq; -using System.Text; namespace Roadie.Library.Extensions { @@ -10,7 +8,7 @@ namespace Roadie.Library.Extensions { public static string ToTimings(this IDictionary values) { - if(values == null || !values.Any()) + if (values == null || !values.Any()) { return null; } @@ -24,7 +22,5 @@ namespace Roadie.Library.Extensions } return string.Join(", ", timings); } - - } } diff --git a/Roadie.Api.Library/Extensions/ExceptionExt.cs b/Roadie.Api.Library/Extensions/ExceptionExt.cs index b407bdf..4818ee7 100644 --- a/Roadie.Api.Library/Extensions/ExceptionExt.cs +++ b/Roadie.Api.Library/Extensions/ExceptionExt.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using System; +using System; +using System.Text.Json; namespace Roadie.Library.Extensions { @@ -7,12 +7,15 @@ namespace Roadie.Library.Extensions { public static string Serialize(this Exception input) { - if (input == null) return null; - var settings = new JsonSerializerSettings + if (input == null) { - NullValueHandling = NullValueHandling.Ignore - }; - return JsonConvert.SerializeObject(input, Formatting.Indented, settings); + return null; + } + return JsonSerializer.Serialize(input, new JsonSerializerOptions + { + IgnoreNullValues = true, + WriteIndented = true + }); } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Extensions/GenericExt.cs b/Roadie.Api.Library/Extensions/GenericExt.cs index 72bb72f..e917608 100644 --- a/Roadie.Api.Library/Extensions/GenericExt.cs +++ b/Roadie.Api.Library/Extensions/GenericExt.cs @@ -18,10 +18,16 @@ namespace Roadie.Library.Extensions /// The copied object. public static T Clone(this T source) { - if (!typeof(T).IsSerializable) throw new ArgumentException("The type must be serializable.", "source"); + if (!typeof(T).IsSerializable) + { + throw new ArgumentException("The type must be serializable.", nameof(source)); + } // Don't serialize a null object, simply return the default for that object - if (ReferenceEquals(source, null)) return default(T); + if (ReferenceEquals(source, null)) + { + return default(T); + } IFormatter formatter = new BinaryFormatter(); using (Stream stream = new MemoryStream()) @@ -37,8 +43,12 @@ namespace Roadie.Library.Extensions var oProperties = OriginalEntity.GetType().GetProperties(); foreach (var CurrentProperty in oProperties.Where(p => p.CanWrite)) + { if (CurrentProperty.GetValue(NewEntity, null) != null) + { CurrentProperty.SetValue(OriginalEntity, CurrentProperty.GetValue(NewEntity, null), null); + } + } return OriginalEntity; } @@ -47,7 +57,11 @@ namespace Roadie.Library.Extensions { var fi = source.GetType().GetField(source.ToString()); var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); - if (attributes != null && attributes.Length > 0) return attributes[0].Description; + if (attributes != null && attributes.Length > 0) + { + return attributes[0].Description; + } + return source.ToString(); } } diff --git a/Roadie.Api.Library/Extensions/IntEx.cs b/Roadie.Api.Library/Extensions/IntEx.cs index c25dadf..8857e88 100644 --- a/Roadie.Api.Library/Extensions/IntEx.cs +++ b/Roadie.Api.Library/Extensions/IntEx.cs @@ -6,7 +6,11 @@ namespace Roadie.Library.Extensions { public static int? Or(this int? value, int? alternative) { - if (!value.HasValue && !alternative.HasValue) return null; + if (!value.HasValue && !alternative.HasValue) + { + return null; + } + return value.HasValue ? value : alternative; } diff --git a/Roadie.Api.Library/Extensions/ListExt.cs b/Roadie.Api.Library/Extensions/ListExt.cs index c078cf3..92c448c 100644 --- a/Roadie.Api.Library/Extensions/ListExt.cs +++ b/Roadie.Api.Library/Extensions/ListExt.cs @@ -31,7 +31,6 @@ namespace Roadie.Library.Extensions } } - public static string ToDelimitedList(this IList list, char delimiter = '|') { return ((ICollection)list).ToDelimitedList(delimiter); @@ -39,7 +38,11 @@ namespace Roadie.Library.Extensions public static string ToDelimitedList(this IEnumerable list, char delimiter = '|') { - if (list == null || !list.Any()) return null; + if (list == null || !list.Any()) + { + return null; + } + return string.Join(delimiter.ToString(), list); } } diff --git a/Roadie.Api.Library/Extensions/LongExt.cs b/Roadie.Api.Library/Extensions/LongExt.cs index 2b0584f..5522954 100644 --- a/Roadie.Api.Library/Extensions/LongExt.cs +++ b/Roadie.Api.Library/Extensions/LongExt.cs @@ -6,7 +6,11 @@ namespace Roadie.Library.Extensions { public static string ToFileSize(this long? l) { - if (!l.HasValue) return "0"; + if (!l.HasValue) + { + return "0"; + } + return string.Format(new FileSizeFormatProvider(), "{0:fs}", l); } } diff --git a/Roadie.Api.Library/Extensions/ShortExt.cs b/Roadie.Api.Library/Extensions/ShortExt.cs index bebab4f..7a800c6 100644 --- a/Roadie.Api.Library/Extensions/ShortExt.cs +++ b/Roadie.Api.Library/Extensions/ShortExt.cs @@ -4,14 +4,26 @@ { public static short? Or(this short? value, short? alternative) { - if (!value.HasValue && !alternative.HasValue) return null; + if (!value.HasValue && !alternative.HasValue) + { + return null; + } + return value.HasValue ? value : alternative; } public static short? TakeLarger(this short? value, short? alternative) { - if (!value.HasValue && !alternative.HasValue) return null; - if (!value.HasValue && alternative.HasValue) return alternative.Value; + if (!value.HasValue && !alternative.HasValue) + { + return null; + } + + if (!value.HasValue && alternative.HasValue) + { + return alternative.Value; + } + return value.Value > alternative.Value ? value.Value : alternative.Value; } } diff --git a/Roadie.Api.Library/Extensions/StringExt.cs b/Roadie.Api.Library/Extensions/StringExt.cs index d9a038d..75c3bc2 100644 --- a/Roadie.Api.Library/Extensions/StringExt.cs +++ b/Roadie.Api.Library/Extensions/StringExt.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; -using System.Web; namespace Roadie.Library.Extensions { @@ -88,7 +87,7 @@ namespace Roadie.Library.Extensions var rs = removeStringsRegex ?? settings.Processing.RemoveStringsRegex; if (!string.IsNullOrEmpty(rs)) { - result = Regex.Replace(result, rs, "", RegexOptions.IgnoreCase); + result = Regex.Replace(result, rs, string.Empty, RegexOptions.IgnoreCase); } if (result.Length > 5) { @@ -106,9 +105,25 @@ namespace Roadie.Library.Extensions return Regex.Replace(result, @"\s+", " ").Trim(); } + public static bool HasFeaturingFragments(this string input) + { + if (string.IsNullOrWhiteSpace(input)) + { + return false; + } + + return Regex.IsMatch(input, + @"\((ft.|feat.|featuring|feature)+", + RegexOptions.IgnoreCase); + } + public static bool DoesStartWithNumber(this string input) { - if (string.IsNullOrEmpty(input)) return false; + if (string.IsNullOrEmpty(input)) + { + return false; + } + var firstPart = input.Split(' ').First().SafeReplace("[").SafeReplace("]"); return SafeParser.ToNumber(firstPart) > 0; } @@ -116,32 +131,59 @@ namespace Roadie.Library.Extensions public static string FromHexString(this string hexString) { var bytes = new byte[hexString.Length / 2]; - for (var i = 0; i < bytes.Length; i++) bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + for (var i = 0; i < bytes.Length; i++) + { + bytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); + } return System.Text.Encoding.UTF8.GetString(bytes); // returns: "Hello world" for "48656C6C6F20776F726C64" } public static bool IsValidFilename(this string input) { - var containsABadCharacter = new Regex("[" + Regex.Escape(new string(Path.GetInvalidPathChars())) + "]"); - if (containsABadCharacter.IsMatch(input)) return false; - ; + var containsABadCharacter = new Regex($"[{Regex.Escape(new string(Path.GetInvalidPathChars()))}]"); + if (containsABadCharacter.IsMatch(input)) + { + return false; + }; return true; } public static bool IsValueInDelimitedList(this string input, string value, char delimiter = '|') { - if (string.IsNullOrEmpty(input)) return false; + if (string.IsNullOrEmpty(input)) + { + return false; + } + var p = input.Split(delimiter); return !p.Any() ? false : p.Any(x => x.Trim().Equals(value, StringComparison.OrdinalIgnoreCase)); } + public static string LastSegmentInUrl(this string input) + { + if (string.IsNullOrEmpty(input)) + { + return null; + } + var uri = new Uri(input); + return uri.Segments.Last(); + } + public static string NormalizeName(this string input) { - if (string.IsNullOrEmpty(input)) return input; + if (string.IsNullOrEmpty(input)) + { + return input; + } + input = input.ToLower(); var removeParts = new List { " ft. ", " ft ", " feat ", " feat. " }; - foreach (var removePart in removeParts) input = input.Replace(removePart, ""); + foreach (var removePart in removeParts) + { + input = input.Replace(removePart, string.Empty); + } + var cultInfo = new CultureInfo("en-US", false).TextInfo; return cultInfo.ToTitleCase(input).Trim(); } @@ -158,7 +200,10 @@ namespace Roadie.Library.Extensions for (var i = 0; i < normalizedString.Length; i++) { var c = normalizedString[i]; - if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) stringBuilder.Append(c); + if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark) + { + stringBuilder.Append(c); + } } return stringBuilder.ToString(); @@ -166,7 +211,11 @@ namespace Roadie.Library.Extensions public static string RemoveFirst(this string input, string remove = "") { - if (string.IsNullOrEmpty(input)) return input; + if (string.IsNullOrEmpty(input)) + { + return input; + } + var index = input.IndexOf(remove); return index < 0 ? input @@ -175,7 +224,11 @@ namespace Roadie.Library.Extensions public static string RemoveStartsWith(this string input, string remove = "") { - if (string.IsNullOrEmpty(input)) return input; + if (string.IsNullOrEmpty(input)) + { + return input; + } + var index = input.IndexOf(remove); var result = input; while (index == 0) @@ -194,7 +247,11 @@ namespace Roadie.Library.Extensions (sb, c) => { string r; - if (UnicodeAccents.TryGetValue(c, out r)) return sb.Append(r); + if (UnicodeAccents.TryGetValue(c, out r)) + { + return sb.Append(r); + } + return sb.Append(c); }).ToString(); } @@ -211,21 +268,33 @@ namespace Roadie.Library.Extensions public static string SafeReplace(this string input, string replace, string replaceWith = " ") { - if (string.IsNullOrEmpty(input)) return null; + if (string.IsNullOrEmpty(input)) + { + return null; + } + return input.Replace(replace, replaceWith); } public static string ScrubHtml(this string value) { - var step1 = Regex.Replace(value, @"<[^>]+>| ", "").Trim(); + var step1 = Regex.Replace(value, @"<[^>]+>| ", string.Empty).Trim(); var step2 = Regex.Replace(step1, @"\s{2,}", " "); return step2; } public static string StripStartingNumber(this string input) { - if (string.IsNullOrEmpty(input)) return null; - if (input.DoesStartWithNumber()) return string.Join(" ", input.Split(' ').Skip(1)); + if (string.IsNullOrEmpty(input)) + { + return null; + } + + if (input.DoesStartWithNumber()) + { + return string.Join(" ", input.Split(' ').Skip(1)); + } + return input; } @@ -240,23 +309,40 @@ namespace Roadie.Library.Extensions .Replace("%", "per"); input = WebUtility.HtmlDecode(input); input = input.ScrubHtml().ToLower() - .Replace("&", "and"); + .Replace("&", "and"); var arr = input.ToCharArray(); arr = Array.FindAll(arr, c => (c == ',' && !stripCommas) || (char.IsWhiteSpace(c) && !stripSpaces) || char.IsLetterOrDigit(c)); input = new string(arr).RemoveDiacritics().RemoveUnicodeAccents().Translit(); - input = Regex.Replace(input, $"[^A-Za-z0-9{ ( !stripSpaces ? @"\s" : "") }{ (!stripCommas ? "," : "")}]+", ""); + input = Regex.Replace(input, $"[^A-Za-z0-9{ (!stripSpaces ? @"\s" : string.Empty) }{ (!stripCommas ? "," : string.Empty)}]+", string.Empty); return input; } public static string ToContentDispositionFriendly(this string input) { - if (string.IsNullOrEmpty(input)) return null; + if (string.IsNullOrEmpty(input)) + { + return null; + } + return input.Replace(',', ' '); } + public static string ToCSV(this IEnumerable input) + { + if (input == null || !input.Any()) + { + return null; + } + return string.Join(",", input); + } + public static string ToFileNameFriendly(this string input) { - if (string.IsNullOrEmpty(input)) return null; + if (string.IsNullOrEmpty(input)) + { + return null; + } + return Regex.Replace(PathSanitizer.SanitizeFilename(input, ' '), @"\s+", " ").Trim(); } @@ -275,14 +361,21 @@ namespace Roadie.Library.Extensions var sb = new StringBuilder(); var bytes = System.Text.Encoding.UTF8.GetBytes(str); - foreach (var t in bytes) sb.Append(t.ToString("X2")); + foreach (var t in bytes) + { + sb.Append(t.ToString("X2")); + } return sb.ToString(); // returns: "48656C6C6F20776F726C64" for "Hello world" } public static IEnumerable ToListFromDelimited(this string input, char delimiter = '|') { - if (string.IsNullOrEmpty(input)) return new string[0]; + if (string.IsNullOrEmpty(input)) + { + return new string[0]; + } + return input.Split(delimiter); } @@ -300,7 +393,7 @@ namespace Roadie.Library.Extensions { if (r.StartsWith("The ")) { - r = r.Replace("The ", "") + ", The"; + r = $"{(r.Replace("The ", string.Empty))}, The"; } } return r.NameCase(); @@ -309,21 +402,36 @@ namespace Roadie.Library.Extensions public static int? ToTrackDuration(this string input) { - if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(input.Replace(":", ""))) return null; + if (string.IsNullOrEmpty(input) || string.IsNullOrEmpty(input.Replace(":", string.Empty))) + { + return null; + } + try { var parts = input.Contains(":") ? input.Split(':').ToList() : new List { input }; - while (parts.Count() < 3) parts.Insert(0, "00:"); + while (parts.Count() < 3) + { + parts.Insert(0, "00:"); + } + var tsRaw = string.Empty; foreach (var part in parts) { - if (tsRaw.Length > 0) tsRaw += ":"; + if (tsRaw.Length > 0) + { + tsRaw += ":"; + } + tsRaw += part.PadLeft(2, '0').Substring(0, 2); } var ts = TimeSpan.MinValue; var success = TimeSpan.TryParse(tsRaw, out ts); - if (success) return (int?)ts.TotalMilliseconds; + if (success) + { + return (int?)ts.TotalMilliseconds; + } } catch { @@ -366,27 +474,11 @@ namespace Roadie.Library.Extensions public static string TrimEnd(this string input, string suffixToRemove) { if (input != null && suffixToRemove != null && input.EndsWith(suffixToRemove)) + { return input.Substring(0, input.Length - suffixToRemove.Length); + } + return input; } - - public static string LastSegmentInUrl(this string input) - { - if(string.IsNullOrEmpty(input)) - { - return null; - } - var uri = new Uri(input); - return uri.Segments.Last(); - } - - public static string ToCSV(this IEnumerable input) - { - if(input == null || !input.Any()) - { - return null; - } - return string.Join(",", input); - } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Extensions/TimeSpanExt.cs b/Roadie.Api.Library/Extensions/TimeSpanExt.cs index 59f78f5..bb15b42 100644 --- a/Roadie.Api.Library/Extensions/TimeSpanExt.cs +++ b/Roadie.Api.Library/Extensions/TimeSpanExt.cs @@ -6,7 +6,11 @@ namespace Roadie.Library.Extensions { public static string ToDuration(this TimeSpan input) { - if (input == null || input.TotalMilliseconds == 0) return "--/--/--"; + if (input == null || input.TotalMilliseconds == 0) + { + return "--/--/--"; + } + return input.ToString(@"ddd\.hh\:mm\:ss"); } } diff --git a/Roadie.Api.Library/FilePlugins/Audio.cs b/Roadie.Api.Library/FilePlugins/Audio.cs index 6165033..28d897c 100644 --- a/Roadie.Api.Library/FilePlugins/Audio.cs +++ b/Roadie.Api.Library/FilePlugins/Audio.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Library.Caching; using Roadie.Library.Configuration; using Roadie.Library.Encoding; @@ -14,6 +13,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; namespace Roadie.Library.FilePlugins @@ -98,9 +98,16 @@ namespace Roadie.Library.FilePlugins return result; } - if (CheckMakeFolder(artistFolder)) Logger.LogTrace("Created ArtistFolder [{0}]", artistFolder); - if (CheckMakeFolder(releaseFolder)) Logger.LogTrace("Created ReleaseFolder [{0}]", releaseFolder); + if (CheckMakeFolder(artistFolder)) + { + Logger.LogTrace("Created ArtistFolder [{0}]", artistFolder); + } + if (CheckMakeFolder(releaseFolder)) + { + Logger.LogTrace("Created ReleaseFolder [{0}]", releaseFolder); + } + string imageFilename = null; try { // See if file folder parent folder (likely file is in release folder) has primary artist image if so then move to artist folder @@ -110,8 +117,8 @@ namespace Roadie.Library.FilePlugins if (artistImages.Count > 0) { var artistImage = artistImages[0]; - var artistImageFilename = Path.Combine(artistFolder, ImageHelper.ArtistImageFilename); - if (artistImageFilename != artistImage.FullName) + imageFilename = Path.Combine(artistFolder, ImageHelper.ArtistImageFilename); + if (imageFilename != artistImage.FullName) { // Read image and convert to jpeg var imageBytes = File.ReadAllBytes(artistImage.FullName); @@ -120,7 +127,7 @@ namespace Roadie.Library.FilePlugins // Move artist image to artist folder if (!doJustInfo) { - File.WriteAllBytes(artistImageFilename, imageBytes); + File.WriteAllBytes(imageFilename, imageBytes); artistImage.Delete(); } @@ -179,7 +186,10 @@ namespace Roadie.Library.FilePlugins // Read image and convert to jpeg var imageBytes = File.ReadAllBytes(releaseImage.FullName); imageBytes = ImageHelper.ConvertToJpegFormat(imageBytes); - + if(imageBytes == null) + { + Logger.LogWarning($"Unable to read image [{ releaseImage.FullName }]"); + } // Move cover to release folder if (!doJustInfo) { @@ -199,8 +209,7 @@ namespace Roadie.Library.FilePlugins foreach (var releaseImage in releaseImages) { looper++; - var releaseImageFilename = Path.Combine(releaseFolder, - string.Format(ImageHelper.ReleaseSecondaryImageFilename, looper.ToString("00"))); + var releaseImageFilename = Path.Combine(releaseFolder, string.Format(ImageHelper.ReleaseSecondaryImageFilename, looper.ToString("00"))); if (releaseImageFilename != releaseImage.FullName) { // Read image and convert to jpeg @@ -221,7 +230,7 @@ namespace Roadie.Library.FilePlugins } catch (Exception ex) { - Logger.LogError(ex, "Error with Managing Images For [{0}]", fileInfo.FullName); + Logger.LogError(ex, $"Error with Managing Images For [{fileInfo.FullName}], ImageFilename [{imageFilename }]"); } var doesFileExistsForTrack = File.Exists(destinationName); @@ -291,8 +300,7 @@ namespace Roadie.Library.FilePlugins } sw.Stop(); - Logger.LogTrace("<< Audio: Process Complete. Result `{0}`, ElapsedTime [{1}]", - JsonConvert.SerializeObject(result), sw.ElapsedMilliseconds); + Logger.LogTrace("<< Audio: Process Complete. Result `{0}`, ElapsedTime [{1}]", JsonSerializer.Serialize(result), sw.ElapsedMilliseconds); return result; } diff --git a/Roadie.Api.Library/Imaging/ImageHelper.cs b/Roadie.Api.Library/Imaging/ImageHelper.cs index 4e7347c..3c6dfaa 100644 --- a/Roadie.Api.Library/Imaging/ImageHelper.cs +++ b/Roadie.Api.Library/Imaging/ImageHelper.cs @@ -1,4 +1,5 @@ -using Roadie.Library.Configuration; +using ImageMagick; +using Roadie.Library.Configuration; using Roadie.Library.Enums; using Roadie.Library.Extensions; using Roadie.Library.MetaData.Audio; @@ -20,121 +21,123 @@ namespace Roadie.Library.Imaging public static class ImageHelper { public static string ArtistImageFilename = "artist.jpg"; + public static string ArtistSecondaryImageFilename = "artist {0}.jpg"; // Replace with counter of image + public static string ReleaseCoverFilename = "cover.jpg"; + public static string ReleaseSecondaryImageFilename = "release {0}.jpg"; // Replace with counter of image - public static byte[] ConvertToJpegFormat(byte[] imageBytes) - { - if(imageBytes?.Any() != true) - { - return null; - } - - try - { - using(var outStream = new MemoryStream()) - { - IImageFormat imageFormat = null; - using(var image = SixLabors.ImageSharp.Image.Load(imageBytes, out imageFormat)) - { - image.SaveAsJpeg(outStream); - } - return outStream.ToArray(); - } - } catch(Exception ex) - { - Trace.WriteLine($"Error Converting Image to Jpg [{ ex.Message }]", "Warning"); - } - return null; - } - /// /// Only user avatars are GIF to allow for animation. /// public static byte[] ConvertToGifFormat(byte[] imageBytes) { - if(imageBytes?.Any() != true) + if (imageBytes?.Any() != true) { return null; } try { - using(var outStream = new MemoryStream()) + using (var outStream = new MemoryStream()) { IImageFormat imageFormat = null; - using(var image = SixLabors.ImageSharp.Image.Load(imageBytes, out imageFormat)) + using (var image = SixLabors.ImageSharp.Image.Load(imageBytes, out imageFormat)) { image.SaveAsGif(outStream); } return outStream.ToArray(); } - } catch(Exception ex) + } + catch (Exception ex) { Trace.WriteLine($"Error Converting Image to Gif [{ ex.Message }]", "Warning"); } return null; } + public static byte[] ConvertToJpegFormat(byte[] imageBytes) + { + if (imageBytes?.Any() != true) + { + return null; + } + + try + { + return ConvertToJpegFormatViaSixLabors(imageBytes); + } + catch (Exception ex) + { + Trace.WriteLine($"Error Converting Image to Jpg via SixLabors [{ ex }]", "Warning"); + } + try + { + return ConvertToJpegFormatViaMagick(imageBytes); + } + catch (Exception ex) + { + Trace.WriteLine($"Error Converting Image to Jpg via Magick [{ ex }]", "Warning"); + } + return null; + } + + public static byte[] ConvertToJpegFormatViaSixLabors(byte[] imageBytes) + { + using (var outStream = new MemoryStream()) + { + IImageFormat imageFormat = null; + using (var image = SixLabors.ImageSharp.Image.Load(imageBytes, out imageFormat)) + { + image.SaveAsJpeg(outStream); + } + return outStream.ToArray(); + } + } + + public static byte[] ConvertToJpegFormatViaMagick(byte[] imageBytes) + { + using (var image = new MagickImage(imageBytes)) + { + image.Format = MagickFormat.Jpeg; + return image.ToByteArray(); + } + } + public static IEnumerable FindImagesByName(DirectoryInfo directory, string name, SearchOption folderSearchOptions = SearchOption.AllDirectories) { var result = new List(); - if(directory?.Exists != true || string.IsNullOrEmpty(name)) + if (directory?.Exists != true || string.IsNullOrEmpty(name)) + { return result; + } + var imageFilesInFolder = ImageFilesInFolder(directory.FullName, folderSearchOptions); - if(imageFilesInFolder?.Any() != true) + if (imageFilesInFolder?.Any() != true) + { return result; - if(imageFilesInFolder.Length > 0) + } + + if (imageFilesInFolder.Length > 0) { name = name.ToAlphanumericName(); - foreach(var imageFileInFolder in imageFilesInFolder) + foreach (var imageFileInFolder in imageFilesInFolder) { var image = new FileInfo(imageFileInFolder); var filenameWithoutExtension = Path.GetFileName(imageFileInFolder).ToAlphanumericName(); var imageName = image.Name.ToAlphanumericName(); - if(imageName.Equals(name) || filenameWithoutExtension.Equals(name)) + if (imageName.Equals(name) || filenameWithoutExtension.Equals(name)) + { result.Add(image); + } } } return result; } - public static bool IsImageBetterQuality(string image1, string compareToImage) - { - if(string.IsNullOrEmpty(compareToImage)) - { - return true; - } - try - { - if(string.IsNullOrEmpty(image1) || !File.Exists(image1)) - { - return File.Exists(compareToImage); - } - using(var imageComparing = SixLabors.ImageSharp.Image.Load(image1)) - { - using(var imageToCompare = SixLabors.ImageSharp.Image.Load(compareToImage)) - { - // Generally a larger image is the preferred image - var isBigger = imageToCompare.Height > imageComparing.Height && - imageToCompare.Width > imageComparing.Width; - if(isBigger) - { - return true; - } - } - } - } catch(Exception ex) - { - Trace.WriteLine($"Error IsImageBetterQuality Image Comparing [{ image1 }] to [{ compareToImage }], Error [{ ex }]", - "Warning"); - } - return false; - } - public static IEnumerable FindImageTypeInDirectory(DirectoryInfo directory, ImageType type, SearchOption folderSearchOptions = SearchOption.AllDirectories) @@ -149,10 +152,10 @@ namespace Roadie.Library.Imaging { return result; } - foreach(var imageFile in imageFilesInFolder) + foreach (var imageFile in imageFilesInFolder) { var image = new FileInfo(imageFile); - switch(type) + switch (type) { case ImageType.Artist: if (IsArtistImage(image)) @@ -197,174 +200,21 @@ namespace Roadie.Library.Imaging string[] patterns = null, SearchOption options = SearchOption.TopDirectoryOnly) { - if(!Directory.Exists(path)) + if (!Directory.Exists(path)) { return new string[0]; } - if(patterns == null || patterns.Length == 0) + if (patterns == null || patterns.Length == 0) { return Directory.GetFiles(path, "*", options); } - if(patterns.Length == 1) + if (patterns.Length == 1) { return Directory.GetFiles(path, patterns[0], options); } return patterns.SelectMany(pattern => Directory.GetFiles(path, pattern, options)).Distinct().ToArray(); } - public static byte[] ImageDataFromUrl(string imageUrl) - { - if(!string.IsNullOrEmpty(imageUrl) && !imageUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - { - var dataString = imageUrl.Trim() - .Replace('-', '+') - .Replace("data:image/jpeg;base64,", "") - .Replace("data:image/bmp;base64,", "") - .Replace("data:image/gif;base64,", "") - .Replace("data:image/png;base64,", ""); - return Convert.FromBase64String(dataString); - } - - return null; - } - - public static string[] ImageExtensions() - { return new string[6] { "*.bmp", "*.jpeg", "*.jpe", "*.jpg", "*.png", "*.gif" }; } - - public static string[] ImageFilesInFolder(string folder, SearchOption searchOption) - { return GetFiles(folder, ImageExtensions(), searchOption); } - - public static string[] ImageMimeTypes() - { return new string[4] { "image/bmp", "image/jpeg", "image/png", "image/gif" }; } - - public static ImageSearchResult ImageSearchResultForImageUrl(string imageUrl) - { - if(!WebHelper.IsStringUrl(imageUrl)) - return null; - var result = new ImageSearchResult(); - var imageBytes = WebHelper.BytesForImageUrl(imageUrl); - IImageFormat imageFormat = null; - using(var image = SixLabors.ImageSharp.Image.Load(imageBytes, out imageFormat)) - { - result.Height = image.Height.ToString(); - result.Width = image.Width.ToString(); - result.MediaUrl = imageUrl; - } - - return result; - } - - public static bool IsArtistImage(FileInfo fileinfo) - { - if(fileinfo == null) - return false; - return Regex.IsMatch(fileinfo.Name, - @"(band|artist|group|photo)\.(jpg|jpeg|png|bmp|gif)", - RegexOptions.IgnoreCase); - } - - public static bool IsArtistSecondaryImage(FileInfo fileinfo) - { - if(fileinfo == null) - return false; - return Regex.IsMatch(fileinfo.Name, - @"(artist_logo|logo|photo[-_\s]*[0-9]+|(artist[\s_-]+[0-9]+)|(band[\s_-]+[0-9]+))\.(jpg|jpeg|png|bmp|gif)", - RegexOptions.IgnoreCase); - } - - public static bool IsLabelImage(FileInfo fileinfo) - { - if(fileinfo == null) - return false; - return Regex.IsMatch(fileinfo.Name, - @"(label|recordlabel|record_label)\.(jpg|jpeg|png|bmp|gif)", - RegexOptions.IgnoreCase); - } - - public static bool IsReleaseImage(FileInfo fileinfo, string releaseName = null) - { - if(fileinfo == null) - return false; - return Regex.IsMatch(fileinfo.Name, - @"((f[-_\s]*[0-9]*)|00|art|big[art]*|cover|cvr|folder|release|front[-_\s]*)\.(jpg|jpeg|png|bmp|gif)", - RegexOptions.IgnoreCase); - } - - public static bool IsReleaseSecondaryImage(FileInfo fileinfo) - { - if(fileinfo == null) - return false; - return Regex.IsMatch(fileinfo.Name, - @"((img[\s-_]*[0-9]*[\s-_]*[0-9]*)|(book[let]*[#-_\s(]*[0-9]*-*[0-9]*(\))*)|(encartes[-_\s]*[(]*[0-9]*[)]*)|sc[an]*(.)?[0-9]*|matrix(.)?[0-9]*|(cover[\s_-]*[0-9]+)|back|traycard|jewel case|disc|(.*)[in]*side(.*)|in([side|lay|let|site])*[0-9]*|digipack.?\[?\(?([0-9]*)\]?\)?|cd.?\[?\(?([0-9]*)\]?\)?|(release[\s_-]+[0-9]+))\.(jpg|jpeg|png|bmp|gif)", - RegexOptions.IgnoreCase); - } - - public static byte[] ResizeImage(byte[] imageBytes, int width, int height) => ImageHelper.ResizeImage(imageBytes, - width, - height, - false) - .Item2; - - /// - /// Resize a given image to given dimensions if needed - /// - /// Image bytes to resize - /// Resize to width - /// Resize to height - /// Force resize - /// Tuple with bool for did resize and byte array of image - public static Tuple ResizeImage(byte[] imageBytes, - int width, - int height, - bool? forceResize = false) - { - if(imageBytes == null) - { - return null; - } - try - { - using(var outStream = new MemoryStream()) - { - var resized = false; - IImageFormat imageFormat = null; - using(var image = SixLabors.ImageSharp.Image.Load(imageBytes, out imageFormat)) - { - var doForce = forceResize ?? false; - if(doForce || image.Width > width || image.Height > height) - { - int newWidth, newHeight; - if(doForce) - { - newWidth = width; - newHeight = height; - } else - { - float aspect = image.Width / (float)image.Height; - if(aspect < 1) - { - newWidth = (int)(width * aspect); - newHeight = (int)(newWidth / aspect); - } else - { - newHeight = (int)(height / aspect); - newWidth = (int)(newHeight * aspect); - } - } - image.Mutate(ctx => ctx.Resize(newWidth, newHeight)); - resized = true; - } - image.Save(outStream, imageFormat); - } - return new Tuple(resized, outStream.ToArray()); - } - } catch(Exception ex) - { - Trace.WriteLine($"Error Resizing Image [{ex}]", "Warning"); - } - return null; - } - /// /// Get image data from all sources for either fileanme or MetaData /// @@ -380,6 +230,29 @@ namespace Roadie.Library.Imaging return ImageForFilename(configuration, filename); } + public static byte[] ImageDataFromUrl(string imageUrl) + { + if (!string.IsNullOrEmpty(imageUrl) && !imageUrl.StartsWith("http", StringComparison.OrdinalIgnoreCase)) + { + var dataString = imageUrl.Trim() + .Replace('-', '+') + .Replace("data:image/jpeg;base64,", string.Empty) + .Replace("data:image/bmp;base64,", string.Empty) + .Replace("data:image/gif;base64,", string.Empty) + .Replace("data:image/png;base64,", string.Empty) + .Replace("data:image/webp;base64,", string.Empty); + return Convert.FromBase64String(dataString); + } + + return null; + } + + public static string[] ImageExtensions() + { return new string[7] { "*.bmp", "*.jpeg", "*.jpe", "*.jpg", "*.png", "*.gif", "*.webp" }; } + + public static string[] ImageFilesInFolder(string folder, SearchOption searchOption) + { return GetFiles(folder, ImageExtensions(), searchOption); } + /// /// Does image exist with the same filename /// @@ -389,7 +262,7 @@ namespace Roadie.Library.Imaging { AudioMetaDataImage imageMetaData = null; - if(string.IsNullOrEmpty(filename)) + if (string.IsNullOrEmpty(filename)) { return imageMetaData; } @@ -397,9 +270,9 @@ namespace Roadie.Library.Imaging { var fileInfo = new FileInfo(filename); var ReleaseCover = Path.ChangeExtension(filename, "jpg"); - if(File.Exists(ReleaseCover)) + if (File.Exists(ReleaseCover)) { - using(var processor = new ImageProcessor(configuration)) + using (var processor = new ImageProcessor(configuration)) { imageMetaData = new AudioMetaDataImage { @@ -408,23 +281,31 @@ namespace Roadie.Library.Imaging MimeType = Library.Processors.FileProcessor.DetermineFileType(fileInfo) }; } - } else + } + else { // Is there a picture in filename folder (for the Release) var pictures = fileInfo.Directory.GetFiles("*.jpg"); var tagImages = new List(); - if(pictures?.Any() == true) + if (pictures?.Any() == true) { // See if there is a "cover" or "front" jpg file if so use it FileInfo picture = Array.Find(pictures, x => x.Name.Equals("cover", StringComparison.OrdinalIgnoreCase)); - if(picture == null) + if (picture == null) + { picture = Array.Find(pictures, - x => x.Name.Equals("front", StringComparison.OrdinalIgnoreCase)); - if(picture == null) + x => x.Name.Equals("front", StringComparison.OrdinalIgnoreCase)); + } + + if (picture == null) + { picture = pictures[0]; - if(picture != null) - using(var processor = new ImageProcessor(configuration)) + } + + if (picture != null) + { + using (var processor = new ImageProcessor(configuration)) { imageMetaData = new AudioMetaDataImage { @@ -433,11 +314,14 @@ namespace Roadie.Library.Imaging MimeType = Library.Processors.FileProcessor.DetermineFileType(picture) }; } + } } } - } catch(FileNotFoundException) + } + catch (FileNotFoundException) { - } catch(Exception ex) + } + catch (Exception ex) { Trace.WriteLine(ex, ex.Serialize()); } @@ -445,58 +329,132 @@ namespace Roadie.Library.Imaging return imageMetaData; } - public static models.Image MakeThumbnailImage(IRoadieSettings configuration, - IHttpContext httpContext, - Guid id, - string type, - int? width = null, - int? height = null, - bool includeCachebuster = false) + public static string[] ImageMimeTypes() + { return new string[4] { "image/bmp", "image/jpeg", "image/png", "image/gif" }; } + + public static ImageSearchResult ImageSearchResultForImageUrl(string imageUrl) { - return MakeImage(configuration, - httpContext, - id, - type, - width ?? configuration.ThumbnailImageSize.Width, - height ?? configuration.ThumbnailImageSize.Height, - null, - includeCachebuster); + if (!WebHelper.IsStringUrl(imageUrl)) + { + return null; + } + + var result = new ImageSearchResult(); + var imageBytes = WebHelper.BytesForImageUrl(imageUrl); + IImageFormat imageFormat = null; + using (var image = SixLabors.ImageSharp.Image.Load(imageBytes, out imageFormat)) + { + result.Height = image.Height.ToString(); + result.Width = image.Width.ToString(); + result.MediaUrl = imageUrl; + } + + return result; } - public static models.Image MakeNewImage(IHttpContext httpContext, string type) - { return new models.Image($"{httpContext.ImageBaseUrl}/{type}.jpg", null, null); } + public static bool IsArtistImage(FileInfo fileinfo) + { + if (fileinfo == null) + { + return false; + } - public static models.Image MakePlaylistThumbnailImage(IRoadieSettings configuration, - IHttpContext httpContext, - Guid id) - { return MakeThumbnailImage(configuration, httpContext, id, "playlist"); } + return Regex.IsMatch(fileinfo.Name, + @"(band|artist|group|photo)\.(jpg|jpeg|png|bmp|gif)", + RegexOptions.IgnoreCase); + } - public static models.Image MakeReleaseThumbnailImage(IRoadieSettings configuration, - IHttpContext httpContext, - Guid id) - { return MakeThumbnailImage(configuration, httpContext, id, "release"); } + public static bool IsArtistSecondaryImage(FileInfo fileinfo) + { + if (fileinfo == null) + { + return false; + } - public static models.Image MakeTrackThumbnailImage(IRoadieSettings configuration, - IHttpContext httpContext, - Guid id) - { return MakeThumbnailImage(configuration, httpContext, id, "track"); } + return Regex.IsMatch(fileinfo.Name, + @"(artist_logo|logo|photo[-_\s]*[0-9]+|(artist[\s_-]+[0-9]+)|(band[\s_-]+[0-9]+))\.(jpg|jpeg|png|bmp|gif)", + RegexOptions.IgnoreCase); + } - public static models.Image MakeUserThumbnailImage(IRoadieSettings configuration, - IHttpContext httpContext, - Guid id) - { return MakeThumbnailImage(configuration, httpContext, id, "user"); } + public static bool IsImageBetterQuality(string image1, string compareToImage) + { + if (string.IsNullOrEmpty(compareToImage)) + { + return true; + } + try + { + if (string.IsNullOrEmpty(image1) || !File.Exists(image1)) + { + return File.Exists(compareToImage); + } + using (var imageComparing = SixLabors.ImageSharp.Image.Load(image1)) + { + using (var imageToCompare = SixLabors.ImageSharp.Image.Load(compareToImage)) + { + // Generally a larger image is the preferred image + var isBigger = imageToCompare.Height > imageComparing.Height && + imageToCompare.Width > imageComparing.Width; + if (isBigger) + { + return true; + } + } + } + } + catch (Exception ex) + { + Trace.WriteLine($"Error IsImageBetterQuality Image Comparing [{ image1 }] to [{ compareToImage }], Error [{ ex }]", + "Warning"); + } + return false; + } - public static models.Image MakeLabelThumbnailImage(IRoadieSettings configuration, - IHttpContext httpContext, - Guid id) - { return MakeThumbnailImage(configuration, httpContext, id, "label"); } + public static bool IsLabelImage(FileInfo fileinfo) + { + if (fileinfo == null) + { + return false; + } + + return Regex.IsMatch(fileinfo.Name, + @"(label|recordlabel|record_label)\.(jpg|jpeg|png|bmp|gif)", + RegexOptions.IgnoreCase); + } + + public static bool IsReleaseImage(FileInfo fileinfo, string releaseName = null) + { + if (fileinfo == null) + { + return false; + } + + return Regex.IsMatch(fileinfo.Name, + @"((f[-_\s]*[0-9]*)|00|art|big[art]*|cover|cvr|folder|release|front[-_\s]*)\.(jpg|jpeg|png|bmp|gif)", + RegexOptions.IgnoreCase); + } + + public static bool IsReleaseSecondaryImage(FileInfo fileinfo) + { + if (fileinfo == null) + { + return false; + } + + return Regex.IsMatch(fileinfo.Name, + @"((img[\s-_]*[0-9]*[\s-_]*[0-9]*)|(book[let]*[#-_\s(]*[0-9]*-*[0-9]*(\))*)|(encartes[-_\s]*[(]*[0-9]*[)]*)|sc[an]*(.)?[0-9]*|matrix(.)?[0-9]*|(cover[\s_-]*[0-9]+)|back|traycard|jewel case|disc|(.*)[in]*side(.*)|in([side|lay|let|site])*[0-9]*|digipack.?\[?\(?([0-9]*)\]?\)?|cd.?\[?\(?([0-9]*)\]?\)?|(release[\s_-]+[0-9]+))\.(jpg|jpeg|png|bmp|gif)", + RegexOptions.IgnoreCase); + } public static models.Image MakeArtistThumbnailImage(IRoadieSettings configuration, IHttpContext httpContext, Guid? id) { - if(!id.HasValue) + if (!id.HasValue) + { return null; + } + return MakeThumbnailImage(configuration, httpContext, id.Value, "artist"); } @@ -522,7 +480,7 @@ namespace Roadie.Library.Imaging int imageId, string caption = null) { - if(type == ImageType.ArtistSecondary) + if (type == ImageType.ArtistSecondary) { return new models.Image($"{httpContext.ImageBaseUrl}/artist-secondary/{id}/{imageId}", caption, @@ -538,8 +496,12 @@ namespace Roadie.Library.Imaging Guid id) { return MakeThumbnailImage(configuration, httpContext, id, "genre"); } - public static models.Image MakeUnknownImage(IHttpContext httpContext, string unknownType = "unknown") - { return new models.Image($"{httpContext.ImageBaseUrl}/{ unknownType }.jpg"); } + public static models.Image MakeImage(IRoadieSettings configuration, + IHttpContext httpContext, + Guid id, + string type, + IImageSize imageSize) + { return MakeImage(configuration, httpContext, id, type, imageSize.Width, imageSize.Height); } public static models.Image MakeImage(IRoadieSettings configuration, IHttpContext httpContext, @@ -554,13 +516,6 @@ namespace Roadie.Library.Imaging $"{httpContext.ImageBaseUrl}/{id}/{configuration.SmallImageSize.Width}/{configuration.SmallImageSize.Height}"); } - public static models.Image MakeImage(IRoadieSettings configuration, - IHttpContext httpContext, - Guid id, - string type, - IImageSize imageSize) - { return MakeImage(configuration, httpContext, id, type, imageSize.Width, imageSize.Height); } - public static models.Image MakeImage(IRoadieSettings configuration, IHttpContext httpContext, Guid id, @@ -570,14 +525,135 @@ namespace Roadie.Library.Imaging string caption = null, bool includeCachebuster = false) { - if(width.HasValue && + if (width.HasValue && height.HasValue && (width.Value != configuration.ThumbnailImageSize.Width || height.Value != configuration.ThumbnailImageSize.Height)) + { return new models.Image($"{httpContext.ImageBaseUrl}/{type}/{id}/{width}/{height}/{(includeCachebuster ? DateTime.UtcNow.Ticks.ToString() : string.Empty)}", - caption, - $"{httpContext.ImageBaseUrl}/{type}/{id}/{configuration.ThumbnailImageSize.Width}/{configuration.ThumbnailImageSize.Height}"); + caption, + $"{httpContext.ImageBaseUrl}/{type}/{id}/{configuration.ThumbnailImageSize.Width}/{configuration.ThumbnailImageSize.Height}"); + } + return new models.Image($"{httpContext.ImageBaseUrl}/{type}/{id}", caption, null); } + + public static models.Image MakeLabelThumbnailImage(IRoadieSettings configuration, + IHttpContext httpContext, + Guid id) + { return MakeThumbnailImage(configuration, httpContext, id, "label"); } + + public static models.Image MakeNewImage(IHttpContext httpContext, string type) + { return new models.Image($"{httpContext.ImageBaseUrl}/{type}.jpg", null, null); } + + public static models.Image MakePlaylistThumbnailImage(IRoadieSettings configuration, + IHttpContext httpContext, + Guid id) + { return MakeThumbnailImage(configuration, httpContext, id, "playlist"); } + + public static models.Image MakeReleaseThumbnailImage(IRoadieSettings configuration, + IHttpContext httpContext, + Guid id) + { return MakeThumbnailImage(configuration, httpContext, id, "release"); } + + public static models.Image MakeThumbnailImage(IRoadieSettings configuration, + IHttpContext httpContext, + Guid id, + string type, + int? width = null, + int? height = null, + bool includeCachebuster = false) + { + return MakeImage(configuration, + httpContext, + id, + type, + width ?? configuration.ThumbnailImageSize.Width, + height ?? configuration.ThumbnailImageSize.Height, + null, + includeCachebuster); + } + + public static models.Image MakeTrackThumbnailImage(IRoadieSettings configuration, + IHttpContext httpContext, + Guid id) + { return MakeThumbnailImage(configuration, httpContext, id, "track"); } + + public static models.Image MakeUnknownImage(IHttpContext httpContext, string unknownType = "unknown") + { return new models.Image($"{httpContext.ImageBaseUrl}/{ unknownType }.jpg"); } + + public static models.Image MakeUserThumbnailImage(IRoadieSettings configuration, + IHttpContext httpContext, + Guid id) + { return MakeThumbnailImage(configuration, httpContext, id, "user"); } + + public static byte[] ResizeImage(byte[] imageBytes, int width, int height) => ImageHelper.ResizeImage(imageBytes, + width, + height, + false) + .Item2; + + /// + /// Resize a given image to given dimensions if needed + /// + /// Image bytes to resize + /// Resize to width + /// Resize to height + /// Force resize + /// Tuple with bool for did resize and byte array of image + public static Tuple ResizeImage(byte[] imageBytes, + int width, + int height, + bool? forceResize = false) + { + if (imageBytes == null) + { + return null; + } + try + { + using (var outStream = new MemoryStream()) + { + var resized = false; + IImageFormat imageFormat = null; + using (var image = SixLabors.ImageSharp.Image.Load(imageBytes, out imageFormat)) + { + var doForce = forceResize ?? false; + if (doForce || image.Width > width || image.Height > height) + { + int newWidth, newHeight; + if (doForce) + { + newWidth = width; + newHeight = height; + } + else + { + float aspect = image.Width / (float)image.Height; + if (aspect < 1) + { + newWidth = (int)(width * aspect); + newHeight = (int)(newWidth / aspect); + } + else + { + newHeight = (int)(height / aspect); + newWidth = (int)(newHeight * aspect); + } + } + image.Mutate(ctx => ctx.Resize(newWidth, newHeight)); + resized = true; + } + image.Save(outStream, imageFormat); + } + return new Tuple(resized, outStream.ToArray()); + } + } + catch (Exception ex) + { + Trace.WriteLine($"Error Resizing Image [{ex}]", "Warning"); + } + return null; + } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Inspect/Inspector.cs b/Roadie.Api.Library/Inspect/Inspector.cs index dcce8da..b77dfe0 100644 --- a/Roadie.Api.Library/Inspect/Inspector.cs +++ b/Roadie.Api.Library/Inspect/Inspector.cs @@ -3,7 +3,6 @@ using HashidsNet; using Mapster; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Library.Caching; using Roadie.Library.Configuration; using Roadie.Library.Enums; @@ -21,6 +20,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Management.Automation; +using System.Text.Json; namespace Roadie.Library.Inspect { @@ -28,7 +28,13 @@ namespace Roadie.Library.Inspect { private const string Salt = "6856F2EE-5965-4345-884B-2CCA457AAF59"; + private IRoadieSettings Configuration { get; } + private ILogger Logger => MessageLogger as ILogger; + private IEventMessageLogger MessageLogger { get; } + private ID3TagsHelper TagsHelper { get; } + private IEnumerable _directoryPlugins; + private IEnumerable _filePlugins; public DictionaryCacheManager CacheManager { get; } @@ -47,6 +53,7 @@ namespace Roadie.Library.Inspect .SelectMany(s => s.GetTypes()) .Where(p => type.IsAssignableFrom(p)); foreach (var t in types) + { if (t.GetInterface("IInspectorDirectoryPlugin") != null && !t.IsAbstract && !t.IsInterface) { var plugin = Activator.CreateInstance(t, Configuration, CacheManager, Logger, TagsHelper) as IInspectorDirectoryPlugin; @@ -59,6 +66,7 @@ namespace Roadie.Library.Inspect Console.WriteLine($"╠╣ Not Loading Disabled Plugin [{plugin.Description}]"); } } + } } catch (Exception ex) { @@ -113,18 +121,8 @@ namespace Roadie.Library.Inspect } } - private IRoadieSettings Configuration { get; } - - private ILogger Logger => MessageLogger as ILogger; - - private IEventMessageLogger MessageLogger { get; } - - private ID3TagsHelper TagsHelper { get; } - public Inspector() { - Console.WriteLine("Roadie Media Inspector"); - MessageLogger = new EventMessageLogger(); MessageLogger.Messages += MessageLogger_Messages; @@ -135,31 +133,141 @@ namespace Roadie.Library.Inspect configuration.GetSection("RoadieSettings").Bind(settings); settings.ConnectionString = configuration.GetConnectionString("RoadieDatabaseConnection"); Configuration = settings; - CacheManager = new DictionaryCacheManager(Logger, new CachePolicy(TimeSpan.FromHours(4))); + CacheManager = new DictionaryCacheManager(Logger, new NewtonsoftCacheSerializer(Logger), new CachePolicy(TimeSpan.FromHours(4))); var tagHelperLooper = new EventMessageLogger(); tagHelperLooper.Messages += MessageLogger_Messages; TagsHelper = new ID3TagsHelper(Configuration, CacheManager, tagHelperLooper); } - public static string ArtistInspectorToken(AudioMetaData metaData) => ToToken(metaData.Artist); - - public static string ReleaseInspectorToken(AudioMetaData metaData) => ToToken(metaData.Artist + metaData.Release); - - public static string ToToken(string input) + private void InspectImage(bool isReadOnly, bool doCopy, string dest, string subdirectory, FileInfo image) { - var hashids = new Hashids(Salt); - var numbers = 0; - var bytes = System.Text.Encoding.ASCII.GetBytes(input); - var looper = bytes.Length / 4; - for (var i = 0; i < looper; i++) + if (!image.Exists) { - numbers += BitConverter.ToInt32(bytes, i * 4); + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"╟ ■ InspectImage: Image Not Found [{image.FullName}]"); + Console.ResetColor(); + return; } - if (numbers < 0) numbers *= -1; - return hashids.Encode(numbers); + + Console.WriteLine($"╟─ Inspecting Image [{image.FullName}]"); + var newImageFolder = new DirectoryInfo(Path.Combine(dest, subdirectory)); + if (!newImageFolder.Exists) + { + newImageFolder.Create(); + } + + var newImagePath = Path.Combine(dest, subdirectory, image.Name); + + if (image.FullName != newImagePath) + { + var looper = 0; + while (File.Exists(newImagePath)) + { + looper++; + newImagePath = Path.Combine(dest, subdirectory, looper.ToString("00"), image.Name); + } + if (isReadOnly) + { + Console.WriteLine($"╟ 🔒 Read Only Mode: Would be [{(doCopy ? "Copied" : "Moved")}] to [{newImagePath}]"); + } + else + { + try + { + if (!doCopy) + { + image.MoveTo(newImagePath); + } + else + { + image.CopyTo(newImagePath, true); + } + Console.ForegroundColor = ConsoleColor.DarkYellow; + Console.WriteLine($"╠═ 🚛 {(doCopy ? "Copied" : "Moved")} Image File to [{newImagePath}]"); + } + catch (Exception ex) + { + Logger.LogError(ex); + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"📛 Error file [{image.FullName}], newImagePath [{newImagePath}], Exception: [{ex}]"); + } + } + } + + Console.ResetColor(); } + private void MessageLogger_Messages(object sender, EventMessage e) + { + Console.WriteLine($"Log Level [{e.Level}] Log Message [{e.Message}] "); + var message = e.Message; + switch (e.Level) + { + case LogLevel.Trace: + Logger.LogTrace(message); + break; + + case LogLevel.Debug: + Logger.LogDebug(message); + break; + + case LogLevel.Information: + Logger.LogInformation(message); + break; + + case LogLevel.Warning: + Logger.LogWarning(message); + break; + + case LogLevel.Critical: + Logger.LogCritical(message); + break; + } + } + + private string RunScript(string scriptFilename, bool doCopy, bool isReadOnly, string directoryToInspect, string dest) + { + if (string.IsNullOrEmpty(scriptFilename)) + { + return null; + } + + try + { + if (!File.Exists(scriptFilename)) + { + Console.WriteLine($"Script Not Found: [{ scriptFilename }]"); + return null; + } + + Console.WriteLine($"Running Script: [{ scriptFilename }]"); + var script = File.ReadAllText(scriptFilename); + using (var ps = PowerShell.Create()) + { + var r = string.Empty; + var results = ps.AddScript(script) + .AddParameter("DoCopy", doCopy) + .AddParameter("IsReadOnly", isReadOnly) + .AddParameter("DirectoryToInspect", directoryToInspect) + .AddParameter("Dest", dest) + .Invoke(); + foreach (var result in results) + { + r += result + Environment.NewLine; + } + return r; + } + } + catch (Exception ex) + { + Console.WriteLine($"📛 Error with Script File [{scriptFilename}], Error [{ex}] "); + } + return null; + } + + public static string ArtistInspectorToken(AudioMetaData metaData) => ToToken(metaData.Artist); + public void Inspect(bool doCopy, bool isReadOnly, string directoryToInspect, string destination, bool dontAppendSubFolder, bool dontDeleteEmptyFolders, bool dontRunPreScripts) { Configuration.Inspector.IsInReadOnlyMode = isReadOnly; @@ -171,13 +279,32 @@ namespace Roadie.Library.Inspect Trace.Listeners.Add(new LoggingTraceListener()); + Console.ForegroundColor = ConsoleColor.Blue; + Console.WriteLine(""); + Console.WriteLine(" ▄▄▄ ▄▄▄· ·▄▄▄▄ ▪ ▄▄▄ . • ▌ ▄ ·. ▄▄▄ .·▄▄▄▄ ▪ ▄▄▄· ▪ ▐ ▄ .▄▄ · ▄▄▄·▄▄▄ . ▄▄· ▄▄▄▄▄ ▄▄▄ "); + Console.WriteLine(" ▀▄ █·▪ ▐█ ▀█ ██▪ ██ ██ ▀▄.▀· ·██ ▐███▪▀▄.▀·██▪ ██ ██ ▐█ ▀█ ██ •█▌▐█▐█ ▀. ▐█ ▄█▀▄.▀·▐█ ▌▪•██ ▪ ▀▄ █·"); + Console.WriteLine(" ▐▀▀▄ ▄█▀▄ ▄█▀▀█ ▐█· ▐█▌▐█·▐▀▀▪▄ ▐█ ▌▐▌▐█·▐▀▀▪▄▐█· ▐█▌▐█·▄█▀▀█ ▐█·▐█▐▐▌▄▀▀▀█▄ ██▀·▐▀▀▪▄██ ▄▄ ▐█.▪ ▄█▀▄ ▐▀▀▄ "); + Console.WriteLine(" ▐█•█▌▐█▌.▐▌▐█ ▪▐▌██. ██ ▐█▌▐█▄▄▌ ██ ██▌▐█▌▐█▄▄▌██. ██ ▐█▌▐█ ▪▐▌ ▐█▌██▐█▌▐█▄▪▐█▐█▪·•▐█▄▄▌▐███▌ ▐█▌·▐█▌.▐▌▐█•█▌"); + Console.WriteLine(" .▀ ▀ ▀█▄▀▪ ▀ ▀ ▀▀▀▀▀• ▀▀▀ ▀▀▀ ▀▀ █▪▀▀▀ ▀▀▀ ▀▀▀▀▀• ▀▀▀ ▀ ▀ ▀▀▀▀▀ █▪ ▀▀▀▀ .▀ ▀▀▀ ·▀▀▀ ▀▀▀ ▀█▄▀▪.▀ ▀"); + Console.WriteLine(""); + Console.ResetColor(); + Console.BackgroundColor = ConsoleColor.White; Console.ForegroundColor = ConsoleColor.Blue; Console.WriteLine($"✨ Inspector Start, UTC [{DateTime.UtcNow.ToString("s")}]"); Console.ResetColor(); + if (!Directory.Exists(directoryToInspect)) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine($"📛 Folder To Inspect [{ directoryToInspect }] is not found."); + Console.ResetColor(); + return; + } + string scriptResult = null; // Run PreInspect script + dontRunPreScripts = File.Exists(Configuration.Processing.PreInspectScript) && dontRunPreScripts; if (dontRunPreScripts) { Console.BackgroundColor = ConsoleColor.Blue; @@ -198,7 +325,10 @@ namespace Roadie.Library.Inspect } // Create a new destination subfolder for each Inspector run by Current timestamp var dest = Path.Combine(destination, DateTime.UtcNow.ToString("yyyyMMddHHmm")); - if (isReadOnly || dontAppendSubFolder) dest = destination; + if (isReadOnly || dontAppendSubFolder) + { + dest = destination; + } // Get all the directorys in the directory var directoryDirectories = Directory.GetDirectories(directoryToInspect, "*.*", SearchOption.AllDirectories); var directories = new List @@ -239,7 +369,7 @@ namespace Roadie.Library.Inspect var pluginResult = plugin.Process(directoryInfo); if (!pluginResult.IsSuccess) { - Console.WriteLine($"📛 Plugin Failed: Error [{JsonConvert.SerializeObject(pluginResult)}]"); + Console.WriteLine($"📛 Plugin Failed: Error [{JsonSerializer.Serialize(pluginResult)}]"); return; } if (!string.IsNullOrEmpty(pluginResult.Data)) @@ -261,7 +391,11 @@ namespace Roadie.Library.Inspect Console.WriteLine($"╟─ 🎵 Inspecting [{fileInfo.FullName}]"); var tagLib = TagsHelper.MetaDataForFile(fileInfo.FullName, true); Console.ForegroundColor = ConsoleColor.Cyan; - if (!tagLib?.IsSuccess ?? false) Console.ForegroundColor = ConsoleColor.DarkYellow; + if (!tagLib?.IsSuccess ?? false) + { + Console.ForegroundColor = ConsoleColor.DarkYellow; + } + Console.WriteLine($"╟ (Pre ) : {tagLib.Data}"); Console.ResetColor(); tagLib.Data.Filename = fileInfo.FullName; @@ -270,7 +404,7 @@ namespace Roadie.Library.Inspect { Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine($"╟ ❗ INVALID: Missing: {ID3TagsHelper.DetermineMissingRequiredMetaData(originalMetaData)}"); - Console.WriteLine($"╟ [{JsonConvert.SerializeObject(tagLib, Newtonsoft.Json.Formatting.Indented)}]"); + Console.WriteLine($"╟ [{JsonSerializer.Serialize(tagLib, new JsonSerializerOptions { WriteIndented = true })}]"); Console.ResetColor(); } @@ -283,7 +417,7 @@ namespace Roadie.Library.Inspect if (!pluginResult.IsSuccess) { Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"📛 Plugin Failed: Error [{JsonConvert.SerializeObject(pluginResult)}]"); + Console.WriteLine($"📛 Plugin Failed: Error [{JsonSerializer.Serialize(pluginResult)}]"); Console.ResetColor(); return; } @@ -421,7 +555,11 @@ namespace Roadie.Library.Inspect { if (fileInfo.FullName != newPath) { - if (File.Exists(newPath)) File.Delete(newPath); + if (File.Exists(newPath)) + { + File.Delete(newPath); + } + fileInfo.MoveTo(newPath); } } @@ -453,12 +591,14 @@ namespace Roadie.Library.Inspect var pluginResult = plugin.Process(directoryInfo); if (!pluginResult.IsSuccess) { - Console.WriteLine($"📛 Plugin Failed: Error [{JsonConvert.SerializeObject(pluginResult)}]"); + Console.WriteLine($"📛 Plugin Failed: Error [{JsonSerializer.Serialize(pluginResult)}]"); return; } if (!string.IsNullOrEmpty(pluginResult.Data)) + { Console.WriteLine($"╠╣ Directory Plugin Message: {pluginResult.Data}"); + } } } @@ -469,7 +609,7 @@ namespace Roadie.Library.Inspect catch (Exception ex) { Logger.LogError(ex); - Console.WriteLine("📛 Exception: " + ex); + Console.WriteLine($"📛 Exception: {ex}"); } if (!dontDeleteEmptyFolders) @@ -496,120 +636,24 @@ namespace Roadie.Library.Inspect } } - private void InspectImage(bool isReadOnly, bool doCopy, string dest, string subdirectory, FileInfo image) + public static string ReleaseInspectorToken(AudioMetaData metaData) => ToToken(metaData.Artist + metaData.Release); + + public static string ToToken(string input) { - if (!image.Exists) + var hashids = new Hashids(Salt); + var numbers = 0; + var bytes = System.Text.Encoding.ASCII.GetBytes(input); + var looper = bytes.Length / 4; + for (var i = 0; i < looper; i++) { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"╟ ■ InspectImage: Image Not Found [{image.FullName}]"); - Console.ResetColor(); - return; + numbers += BitConverter.ToInt32(bytes, i * 4); + } + if (numbers < 0) + { + numbers *= -1; } - Console.WriteLine($"╟─ Inspecting Image [{image.FullName}]"); - var newImageFolder = new DirectoryInfo(Path.Combine(dest, subdirectory)); - if (!newImageFolder.Exists) newImageFolder.Create(); - var newImagePath = Path.Combine(dest, subdirectory, image.Name); - - if (image.FullName != newImagePath) - { - var looper = 0; - while (File.Exists(newImagePath)) - { - looper++; - newImagePath = Path.Combine(dest, subdirectory, looper.ToString("00"), image.Name); - } - if (isReadOnly) - { - Console.WriteLine($"╟ 🔒 Read Only Mode: Would be [{(doCopy ? "Copied" : "Moved")}] to [{newImagePath}]"); - } - else - { - try - { - if (!doCopy) - { - image.MoveTo(newImagePath); - } - else - { - image.CopyTo(newImagePath, true); - } - Console.ForegroundColor = ConsoleColor.DarkYellow; - Console.WriteLine($"╠═ 🚛 {(doCopy ? "Copied" : "Moved")} Image File to [{newImagePath}]"); - } - catch (Exception ex) - { - Logger.LogError(ex); - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"📛 Error file [{image.FullName}], newImagePath [{newImagePath}], Exception: [{ex}]"); - } - } - } - - Console.ResetColor(); - } - - private void MessageLogger_Messages(object sender, EventMessage e) - { - Console.WriteLine($"Log Level [{e.Level}] Log Message [{e.Message}] "); - var message = e.Message; - switch (e.Level) - { - case LogLevel.Trace: - Logger.LogTrace(message); - break; - - case LogLevel.Debug: - Logger.LogDebug(message); - break; - - case LogLevel.Information: - Logger.LogInformation(message); - break; - - case LogLevel.Warning: - Logger.LogWarning(message); - break; - - case LogLevel.Critical: - Logger.LogCritical(message); - break; - } - } - - private string RunScript(string scriptFilename, bool doCopy, bool isReadOnly, string directoryToInspect, string dest) - { - if (string.IsNullOrEmpty(scriptFilename)) - { - return null; - } - - try - { - Console.WriteLine($"Running Script: [{ scriptFilename }]"); - var script = File.ReadAllText(scriptFilename); - using (var ps = PowerShell.Create()) - { - var r = string.Empty; - var results = ps.AddScript(script) - .AddParameter("DoCopy", doCopy) - .AddParameter("IsReadOnly", isReadOnly) - .AddParameter("DirectoryToInspect", directoryToInspect) - .AddParameter("Dest", dest) - .Invoke(); - foreach (var result in results) - { - r += result + Environment.NewLine; - } - return r; - } - } - catch (Exception ex) - { - Console.WriteLine($"📛 Error with Script File [{scriptFilename}], Error [{ex}] "); - } - return null; + return hashids.Encode(numbers); } } diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/DeleteUnwantedFiles.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/DeleteUnwantedFiles.cs index dfaa631..f06c799 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/DeleteUnwantedFiles.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/DeleteUnwantedFiles.cs @@ -36,7 +36,11 @@ namespace Roadie.Library.Inspect.Plugins.Directory { if (fileExtensionsToDelete.Any(x => x.Equals(file.Extension, StringComparison.OrdinalIgnoreCase))) { - if (!Configuration.Inspector.IsInReadOnlyMode) file.Delete(); + if (!Configuration.Inspector.IsInReadOnlyMode) + { + file.Delete(); + } + deletedFiles.Add(file.Name); Console.WriteLine($" X Deleted File [{file}], Was found in in FileExtensionsToDelete"); } diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureArtistConsistent.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureArtistConsistent.cs index 5ba57e4..493345a 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureArtistConsistent.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureArtistConsistent.cs @@ -36,10 +36,13 @@ namespace Roadie.Library.Inspect.Plugins.Directory var firstMetaData = metaDatasForFilesInFolder.OrderBy(x => x.Filename ?? string.Empty) .ThenBy(x => SafeParser.ToNumber(x.TrackNumber)).FirstOrDefault(); if (firstMetaData == null) + { return new OperationResult("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)) { @@ -47,7 +50,10 @@ namespace Roadie.Library.Inspect.Plugins.Directory 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); + if (!Configuration.Inspector.IsInReadOnlyMode) + { + TagsHelper.WriteTags(metaData, metaData.Filename); + } } data = $"Found [{found}] files, Modified [{modified}] files"; diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureReleaseConsistent.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureReleaseConsistent.cs index 3d5ed16..209c350 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureReleaseConsistent.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureReleaseConsistent.cs @@ -39,7 +39,10 @@ namespace Roadie.Library.Inspect.Plugins.Directory Console.WriteLine( $"╟ Setting Release to [{release}], was [{metaData.Release}] on file [{metaData.FileInfo.Name}"); metaData.Release = release; - if (!Configuration.Inspector.IsInReadOnlyMode) TagsHelper.WriteTags(metaData, metaData.Filename); + if (!Configuration.Inspector.IsInReadOnlyMode) + { + TagsHelper.WriteTags(metaData, metaData.Filename); + } } data = $"Found [{found}] files, Modified [{modified}] files"; diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureYearConsistent.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureYearConsistent.cs index 132e2c8..3d5ac2e 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureYearConsistent.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/EnsureYearConsistent.cs @@ -38,7 +38,10 @@ namespace Roadie.Library.Inspect.Plugins.Directory Console.WriteLine( $"╟ Setting Year to [{year}], was [{metaData.Year}] on file [{metaData.FileInfo.Name}"); metaData.Year = year; - if (!Configuration.Inspector.IsInReadOnlyMode) TagsHelper.WriteTags(metaData, metaData.Filename); + if (!Configuration.Inspector.IsInReadOnlyMode) + { + TagsHelper.WriteTags(metaData, metaData.Filename); + } } data = $"Found [{found}] files, Modified [{modified}] files"; diff --git a/Roadie.Api.Library/Inspect/Plugins/Directory/IInspectorDirectoryPlugin.cs b/Roadie.Api.Library/Inspect/Plugins/Directory/IInspectorDirectoryPlugin.cs index c5c7de0..15697c9 100644 --- a/Roadie.Api.Library/Inspect/Plugins/Directory/IInspectorDirectoryPlugin.cs +++ b/Roadie.Api.Library/Inspect/Plugins/Directory/IInspectorDirectoryPlugin.cs @@ -5,8 +5,11 @@ namespace Roadie.Library.Inspect.Plugins.Directory public interface IInspectorDirectoryPlugin { string Description { get; } + bool IsEnabled { get; } + bool IsPostProcessingPlugin { get; } + int Order { get; } OperationResult Process(DirectoryInfo directory); diff --git a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpArtists.cs b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpArtists.cs index 4c59c0c..9ef5a84 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpArtists.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpArtists.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Logging; +using MetadataExtractor; +using Microsoft.Extensions.Logging; using Roadie.Library.Caching; using Roadie.Library.Configuration; using Roadie.Library.Extensions; @@ -14,16 +15,15 @@ namespace Roadie.Library.Inspect.Plugins.File public override int Order => 5; - public CleanUpArtists(IRoadieSettings configuration, ICacheManager cacheManager, ILogger logger, - IID3TagsHelper tagsHelper) + public CleanUpArtists(IRoadieSettings configuration, ICacheManager cacheManager, ILogger logger, IID3TagsHelper tagsHelper) : base(configuration, cacheManager, logger, tagsHelper) { } public string CleanArtist(string artist, string trackArtist = null) { - artist = artist ?? string.Empty; - trackArtist = trackArtist ?? string.Empty; + artist ??= string.Empty; + trackArtist ??= string.Empty; var splitCharacter = AudioMetaData.ArtistSplitCharacter.ToString(); // Replace seperators with proper split character @@ -39,12 +39,21 @@ namespace Roadie.Library.Inspect.Plugins.File } if (!string.IsNullOrEmpty(result) && !string.IsNullOrEmpty(trackArtist)) { - result = result.Replace(splitCharacter + trackArtist + splitCharacter, "", StringComparison.OrdinalIgnoreCase); - result = result.Replace(trackArtist + splitCharacter, "", StringComparison.OrdinalIgnoreCase); - result = result.Replace(splitCharacter + trackArtist, "", StringComparison.OrdinalIgnoreCase); - result = result.Replace(trackArtist, "", StringComparison.OrdinalIgnoreCase); + result = result.Replace(splitCharacter + trackArtist + splitCharacter, string.Empty, StringComparison.OrdinalIgnoreCase); + result = result.Replace(trackArtist + splitCharacter, string.Empty, StringComparison.OrdinalIgnoreCase); + result = result.Replace(splitCharacter + trackArtist, string.Empty, StringComparison.OrdinalIgnoreCase); + result = result.Replace(trackArtist, string.Empty, StringComparison.OrdinalIgnoreCase); + } + if(Configuration.Processing.DoDetectFeatureFragments) + { + if(!string.IsNullOrWhiteSpace(result)) + { + if(result.HasFeaturingFragments()) + { + throw new RoadieProcessingException($"Artist name [{ result }] has Feature fragments."); + } + } } - return string.IsNullOrEmpty(result) ? null : result; } diff --git a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpComments.cs b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpComments.cs index 6dba96b..70ae4ca 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpComments.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpComments.cs @@ -22,8 +22,13 @@ namespace Roadie.Library.Inspect.Plugins.File { var result = new OperationResult(); if (Configuration.Processing.DoAudioCleanup) + { if (Configuration.Processing.DoClearComments) + { metaData.Comments = null; + } + } + result.Data = metaData; result.IsSuccess = true; return result; diff --git a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpReleaseTitle.cs b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpReleaseTitle.cs index 86a3e7b..88cb03e 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpReleaseTitle.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpReleaseTitle.cs @@ -27,9 +27,21 @@ namespace Roadie.Library.Inspect.Plugins.File var originalRelease = metaData.Release; metaData.Release = metaData.Release ?.CleanString(Configuration, Configuration.Processing.ReleaseRemoveStringsRegex).ToTitleCase(false); - if (string.IsNullOrEmpty(metaData.Release)) metaData.Release = originalRelease; + if (string.IsNullOrEmpty(metaData.Release)) + { + metaData.Release = originalRelease; + } + } + if (Configuration.Processing.DoDetectFeatureFragments) + { + if (!string.IsNullOrWhiteSpace(metaData?.Release)) + { + if (metaData.Release.HasFeaturingFragments()) + { + throw new RoadieProcessingException($"Release title [{ metaData?.Release }] has Feature fragments."); + } + } } - result.Data = metaData; result.IsSuccess = true; return result; diff --git a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpTrackTitle.cs b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpTrackTitle.cs index b1d6c9e..f300b74 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/CleanUpTrackTitle.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/CleanUpTrackTitle.cs @@ -27,9 +27,21 @@ namespace Roadie.Library.Inspect.Plugins.File var originalTitle = metaData.Title; metaData.Title = metaData.Title ?.CleanString(Configuration, Configuration.Processing.TrackRemoveStringsRegex).ToTitleCase(false); - if (string.IsNullOrEmpty(metaData.Title)) metaData.Title = originalTitle; + if (string.IsNullOrEmpty(metaData.Title)) + { + metaData.Title = originalTitle; + } + } + if (Configuration.Processing.DoDetectFeatureFragments) + { + if (!string.IsNullOrWhiteSpace(metaData?.Title)) + { + if (metaData.Release.HasFeaturingFragments()) + { + throw new RoadieProcessingException($"Track title [{ metaData?.Title }] has Feature fragments."); + } + } } - result.Data = metaData; result.IsSuccess = true; return result; diff --git a/Roadie.Api.Library/Inspect/Plugins/File/EnsureFileWriteable.cs b/Roadie.Api.Library/Inspect/Plugins/File/EnsureFileWriteable.cs index 39d7647..0347f6c 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/EnsureFileWriteable.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/EnsureFileWriteable.cs @@ -20,25 +20,27 @@ namespace Roadie.Library.Inspect.Plugins.File { } + private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove) + { + return attributes & ~attributesToRemove; + } + public override OperationResult Process(AudioMetaData metaData) { var result = new OperationResult(); if (Configuration.Processing.DoAudioCleanup) + { if (metaData.FileInfo.IsReadOnly) { metaData.FileInfo.Attributes = RemoveAttribute(metaData.FileInfo.Attributes, FileAttributes.ReadOnly); Console.WriteLine($"╟ Removed read only attribute on file file [{metaData.FileInfo.Name}"); } + } result.Data = metaData; result.IsSuccess = true; return result; } - - private static FileAttributes RemoveAttribute(FileAttributes attributes, FileAttributes attributesToRemove) - { - return attributes & ~attributesToRemove; - } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Inspect/Plugins/File/IInspectorFilePlugin.cs b/Roadie.Api.Library/Inspect/Plugins/File/IInspectorFilePlugin.cs index 5c077a5..41c4b1f 100644 --- a/Roadie.Api.Library/Inspect/Plugins/File/IInspectorFilePlugin.cs +++ b/Roadie.Api.Library/Inspect/Plugins/File/IInspectorFilePlugin.cs @@ -5,7 +5,9 @@ namespace Roadie.Library.Inspect.Plugins.File public interface IInspectorFilePlugin { string Description { get; } + bool IsEnabled { get; } + int Order { get; } OperationResult Process(AudioMetaData metaData); diff --git a/Roadie.Api.Library/Inspect/Plugins/PluginBase.cs b/Roadie.Api.Library/Inspect/Plugins/PluginBase.cs index 9609af6..0c9bd05 100644 --- a/Roadie.Api.Library/Inspect/Plugins/PluginBase.cs +++ b/Roadie.Api.Library/Inspect/Plugins/PluginBase.cs @@ -12,22 +12,21 @@ namespace Roadie.Library.Inspect.Plugins { public abstract class PluginBase { - public abstract string Description { get; } - - public abstract int Order { get; } + private Dictionary> CachedAudioDatas { get; } protected ICacheManager CacheManager { get; } protected IRoadieSettings Configuration { get; } - protected IEnumerable ListReplacements { get; } = new List - {" ; ", " ;", "; ", ";", ";", "\\"}; + protected IEnumerable ListReplacements { get; } = new List { " ; ", " ;", "; ", ";", ";", "\\" }; protected ILogger Logger { get; } protected IID3TagsHelper TagsHelper { get; } - private Dictionary> CachedAudioDatas { get; } + public abstract string Description { get; } + + public abstract int Order { get; } public PluginBase(IRoadieSettings configuration, ICacheManager cacheManager, ILogger logger, IID3TagsHelper tagsHelper) diff --git a/Roadie.Api.Library/Models/Artist.cs b/Roadie.Api.Library/Models/Artist.cs index 988648c..01954e6 100644 --- a/Roadie.Api.Library/Models/Artist.cs +++ b/Roadie.Api.Library/Models/Artist.cs @@ -1,5 +1,4 @@ -using Newtonsoft.Json; -using Roadie.Library.Models.Collections; +using Roadie.Library.Models.Collections; using Roadie.Library.Models.Playlists; using Roadie.Library.Models.Releases; using Roadie.Library.Models.Statistics; @@ -8,6 +7,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; +using System.Text.Json.Serialization; namespace Roadie.Library.Models { @@ -48,7 +48,7 @@ namespace Roadie.Library.Models [IgnoreDataMember] public string ISNI { get; set; } - [JsonProperty("isniList")] + [JsonPropertyName("isniList")] public IEnumerable ISNIList { get diff --git a/Roadie.Api.Library/Models/BookmarkList.cs b/Roadie.Api.Library/Models/BookmarkList.cs index 2623fb6..9bb851d 100644 --- a/Roadie.Api.Library/Models/BookmarkList.cs +++ b/Roadie.Api.Library/Models/BookmarkList.cs @@ -1,9 +1,9 @@ -using Newtonsoft.Json; -using Roadie.Library.Enums; +using Roadie.Library.Enums; using Roadie.Library.Models.Collections; using Roadie.Library.Models.Playlists; using Roadie.Library.Models.Releases; using System; +using System.Text.Json.Serialization; namespace Roadie.Library.Models { diff --git a/Roadie.Api.Library/Models/Collections/CollectionReleaseList.cs b/Roadie.Api.Library/Models/Collections/CollectionReleaseList.cs index f6080a8..d2b2a65 100644 --- a/Roadie.Api.Library/Models/Collections/CollectionReleaseList.cs +++ b/Roadie.Api.Library/Models/Collections/CollectionReleaseList.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using System; +using System; +using System.Text.Json.Serialization; namespace Roadie.Library.Models.Collections { @@ -7,7 +7,9 @@ namespace Roadie.Library.Models.Collections internal class CollectionReleaseList : EntityInfoModelBase { private string _listNumber; + public DataToken Artist { get; set; } + public string ArtistThumbnailUrl { get; set; } public string ListNumber @@ -16,10 +18,16 @@ namespace Roadie.Library.Models.Collections set => _listNumber = value; } - [JsonIgnore] public int ListNumberValue { get; set; } + [JsonIgnore] + public int ListNumberValue { get; set; } + public DataToken Release { get; set; } - [JsonIgnore] public DateTime? ReleaseDateDateTime { get; set; } + + [JsonIgnore] + public DateTime? ReleaseDateDateTime { get; set; } + public short? ReleaseRating { get; set; } + public string ReleaseThumbnailUrl { get; set; } public string ReleaseYear => ReleaseDateDateTime.HasValue diff --git a/Roadie.Api.Library/Models/DataToken.cs b/Roadie.Api.Library/Models/DataToken.cs index 8d755db..1e21365 100644 --- a/Roadie.Api.Library/Models/DataToken.cs +++ b/Roadie.Api.Library/Models/DataToken.cs @@ -1,7 +1,7 @@ using Mapster; -using Newtonsoft.Json; using Roadie.Library.Utility; using System; +using System.Text.Json.Serialization; namespace Roadie.Library.Models { diff --git a/Roadie.Api.Library/Models/EntityInfoModelBase.cs b/Roadie.Api.Library/Models/EntityInfoModelBase.cs index 2ad158b..0ee28e3 100644 --- a/Roadie.Api.Library/Models/EntityInfoModelBase.cs +++ b/Roadie.Api.Library/Models/EntityInfoModelBase.cs @@ -1,8 +1,8 @@ using Mapster; -using Newtonsoft.Json; using Roadie.Library.Utility; using System; using System.ComponentModel.DataAnnotations; +using System.Text.Json.Serialization; namespace Roadie.Library.Models { @@ -26,9 +26,6 @@ namespace Roadie.Library.Models public DateTime? LastUpdated { get; set; } - [MaxLength(250)] - public virtual string SortName { get; set; } - /// /// Random int to sort when Random Request /// @@ -36,6 +33,9 @@ namespace Roadie.Library.Models [JsonIgnore] public int RandomSortId { get; set; } + [MaxLength(250)] + public virtual string SortName { get; set; } + public EntityInfoModelBase() { RandomSortId = StaticRandom.Instance.Next(); diff --git a/Roadie.Api.Library/Models/EntityModelBase.cs b/Roadie.Api.Library/Models/EntityModelBase.cs index 0e5abb1..b5b7c1f 100644 --- a/Roadie.Api.Library/Models/EntityModelBase.cs +++ b/Roadie.Api.Library/Models/EntityModelBase.cs @@ -1,5 +1,4 @@ using Mapster; -using Newtonsoft.Json; using Roadie.Library.Enums; using Roadie.Library.Utility; using System; @@ -7,6 +6,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Runtime.Serialization; +using System.Text.Json.Serialization; namespace Roadie.Library.Models { diff --git a/Roadie.Api.Library/Models/LabelList.cs b/Roadie.Api.Library/Models/LabelList.cs index 39519ea..9885373 100644 --- a/Roadie.Api.Library/Models/LabelList.cs +++ b/Roadie.Api.Library/Models/LabelList.cs @@ -1,5 +1,4 @@ -using Newtonsoft.Json; -using System; +using System; namespace Roadie.Library.Models { @@ -7,9 +6,13 @@ namespace Roadie.Library.Models public sealed class LabelList : EntityInfoModelBase { public int? ArtistCount { get; set; } + public DataToken Label { get; set; } + public int? ReleaseCount { get; set; } + public Image Thumbnail { get; set; } + public int? TrackCount { get; set; } public static LabelList FromDataLabel(Data.Label label, Image labelThumbnail) diff --git a/Roadie.Api.Library/Models/PlayActivityList.cs b/Roadie.Api.Library/Models/PlayActivityList.cs index dcb22a5..cdaa361 100644 --- a/Roadie.Api.Library/Models/PlayActivityList.cs +++ b/Roadie.Api.Library/Models/PlayActivityList.cs @@ -1,35 +1,52 @@ -using Newtonsoft.Json; -using Roadie.Library.Models.Users; +using Roadie.Library.Models.Users; using System; +using System.Text.Json.Serialization; namespace Roadie.Library.Models { [Serializable] public class PlayActivityList { + public DataToken Artist { get; set; } + public Image ArtistThumbnail { get; set; } public bool IsNowPlaying { get; set; } + public string PlayedDate => PlayedDateDateTime.HasValue ? PlayedDateDateTime.Value.ToString("s") : null; - [JsonIgnore] public DateTime? PlayedDateDateTime { get; set; } + [JsonIgnore] + public DateTime? PlayedDateDateTime { get; set; } + public string PlayedDay => PlayedDateDateTime.HasValue ? PlayedDateDateTime.Value.ToString("MM/dd/yyyy") : null; + public int? Rating { get; set; } + public DataToken Release { get; set; } + public string ReleasePlayUrl { get; set; } + public Image ReleaseThumbnail { get; set; } + public TrackList Track { get; set; } + public DataToken TrackArtist { get; set; } + public string TrackPlayUrl { get; set; } + public DataToken User { get; set; } + public int? UserRating { get; set; } + public Image UserThumbnail { get; set; } + public UserTrack UserTrack { get; set; } public override string ToString() { return $"User [{User}], Artist [{Artist}], Release [{Release}], Track [{Track}]"; } + } } \ No newline at end of file diff --git a/Roadie.Api.Library/Models/Player/PlayResult.cs b/Roadie.Api.Library/Models/Player/PlayResult.cs index 9a0cfe3..df1b2fe 100644 --- a/Roadie.Api.Library/Models/Player/PlayResult.cs +++ b/Roadie.Api.Library/Models/Player/PlayResult.cs @@ -1,8 +1,8 @@ -using Newtonsoft.Json; -using Roadie.Library.Configuration; +using Roadie.Library.Configuration; using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json; namespace Roadie.Library.Models.Player { @@ -11,14 +11,11 @@ namespace Roadie.Library.Models.Player { private string _rawTracks; - public string RawTracks => _rawTracks ?? (_rawTracks = JsonConvert.SerializeObject(Tracks)); + public string RawTracks => _rawTracks ?? (_rawTracks = JsonSerializer.Serialize(Tracks)); public string SiteName { get; set; } - public string TotalTrackTime - { - get { return TimeSpan.FromMilliseconds((double)Tracks.Sum(x => x.Duration)).ToString(@"hh\:mm\:ss"); } - } + public string TotalTrackTime => TimeSpan.FromMilliseconds((double)Tracks.Sum(x => x.Duration)).ToString(@"hh\:mm\:ss"); public string TrackCount => Tracks.Count().ToString("D3"); diff --git a/Roadie.Api.Library/Models/Releases/ReleaseLabelList.cs b/Roadie.Api.Library/Models/Releases/ReleaseLabelList.cs index 1f464f9..b72575b 100644 --- a/Roadie.Api.Library/Models/Releases/ReleaseLabelList.cs +++ b/Roadie.Api.Library/Models/Releases/ReleaseLabelList.cs @@ -1,5 +1,5 @@ -using Newtonsoft.Json; -using System; +using System; +using System.Text.Json.Serialization; namespace Roadie.Library.Models.Releases { @@ -7,10 +7,17 @@ namespace Roadie.Library.Models.Releases public sealed class ReleaseLabelList : EntityInfoModelBase { public string BeginDate => BeginDatedDateTime.HasValue ? BeginDatedDateTime.Value.ToString("s") : null; - [JsonIgnore] public DateTime? BeginDatedDateTime { get; set; } + + [JsonIgnore] + public DateTime? BeginDatedDateTime { get; set; } + public string CatalogNumber { get; set; } + public string EndDate => EndDatedDateTime.HasValue ? EndDatedDateTime.Value.ToString("s") : null; - [JsonIgnore] public DateTime? EndDatedDateTime { get; set; } + + [JsonIgnore] + public DateTime? EndDatedDateTime { get; set; } + public DataToken Label { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Models/Releases/ReleaseList.cs b/Roadie.Api.Library/Models/Releases/ReleaseList.cs index d363e6e..e1f7f05 100644 --- a/Roadie.Api.Library/Models/Releases/ReleaseList.cs +++ b/Roadie.Api.Library/Models/Releases/ReleaseList.cs @@ -1,11 +1,11 @@ using Mapster; -using Newtonsoft.Json; using Roadie.Library.Enums; using Roadie.Library.Models.Users; using Roadie.Library.Utility; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Text.Json.Serialization; namespace Roadie.Library.Models.Releases { @@ -14,14 +14,20 @@ namespace Roadie.Library.Models.Releases public sealed class ReleaseList : EntityInfoModelBase { public DataToken Artist { get; set; } + public Image ArtistThumbnail { get; set; } + public decimal? Duration { get; set; } public string DurationTime { get { - if (!Duration.HasValue) return "--:--"; + if (!Duration.HasValue) + { + return "--:--"; + } + return new TimeInfo(Duration.Value).ToFullFormattedString(); } } @@ -41,6 +47,7 @@ namespace Roadie.Library.Models.Releases } public DateTime? LastPlayed { get; set; } + public LibraryStatus? LibraryStatus { get; set; } /// @@ -49,17 +56,26 @@ namespace Roadie.Library.Models.Releases public int? ListNumber { get; set; } public IEnumerable Media { get; set; } + public int? MediaCount { get; set; } + public double? Rank { get; set; } + public short? Rating { get; set; } + public DataToken Release { get; set; } public string ReleaseDate => ReleaseDateDateTime.HasValue ? ReleaseDateDateTime.Value.ToUniversalTime().ToString("yyyy-MM-dd") : null; - [JsonIgnore] public DateTime? ReleaseDateDateTime { get; set; } - [JsonIgnore] [AdaptIgnore] public string ReleaseName => Release?.Text; + [JsonIgnore] + public DateTime? ReleaseDateDateTime { get; set; } + + [JsonIgnore] + [AdaptIgnore] + public string ReleaseName => Release?.Text; + public string ReleasePlayUrl { get; set; } public string ReleaseYear => ReleaseDateDateTime.HasValue @@ -67,10 +83,15 @@ namespace Roadie.Library.Models.Releases : null; public Statuses? Status { get; set; } + public string StatusVerbose => (Status ?? Statuses.Missing).ToString(); + public Image Thumbnail { get; set; } + public int? TrackCount { get; set; } + public int? TrackPlayedCount { get; set; } + public UserRelease UserRating { get; set; } public static ReleaseList FromDataRelease(Data.Release release, Data.Artist artist, string baseUrl, diff --git a/Roadie.Api.Library/Models/ThirdPartyApi/Subsonic/Request.cs b/Roadie.Api.Library/Models/ThirdPartyApi/Subsonic/Request.cs index fbec7c9..7559e6b 100644 --- a/Roadie.Api.Library/Models/ThirdPartyApi/Subsonic/Request.cs +++ b/Roadie.Api.Library/Models/ThirdPartyApi/Subsonic/Request.cs @@ -1,8 +1,8 @@ -using Newtonsoft.Json; -using Roadie.Library.Extensions; +using Roadie.Library.Extensions; using Roadie.Library.Models.Pagination; using Roadie.Library.Utility; using System; +using System.Text.Json.Serialization; namespace Roadie.Library.Models.ThirdPartyApi.Subsonic { @@ -20,8 +20,16 @@ namespace Roadie.Library.Models.ThirdPartyApi.Subsonic { get { - if (string.IsNullOrEmpty(id)) return null; - if (id.StartsWith(ArtistIdIdentifier)) return SafeParser.ToGuid(id); + if (string.IsNullOrEmpty(id)) + { + return null; + } + + if (id.StartsWith(ArtistIdIdentifier)) + { + return SafeParser.ToGuid(id); + } + return null; } } @@ -40,8 +48,16 @@ namespace Roadie.Library.Models.ThirdPartyApi.Subsonic { get { - if (string.IsNullOrEmpty(id)) return null; - if (id.StartsWith(CollectionIdentifier)) return SafeParser.ToGuid(id); + if (string.IsNullOrEmpty(id)) + { + return null; + } + + if (id.StartsWith(CollectionIdentifier)) + { + return SafeParser.ToGuid(id); + } + return null; } } @@ -73,8 +89,12 @@ namespace Roadie.Library.Models.ThirdPartyApi.Subsonic // Default should be false (XML) get { - if (string.IsNullOrEmpty(f)) return false; - return f.ToLower().StartsWith("j"); + if (string.IsNullOrEmpty(f)) + { + return false; + } + + return f.StartsWith("j", StringComparison.OrdinalIgnoreCase); } } @@ -90,8 +110,16 @@ namespace Roadie.Library.Models.ThirdPartyApi.Subsonic { get { - if (string.IsNullOrEmpty(p)) return null; - if (p.StartsWith("enc:")) return p.ToLower().Replace("enc:", "").FromHexString(); + if (string.IsNullOrEmpty(p)) + { + return null; + } + + if (p.StartsWith("enc:")) + { + return p.ToLower().Replace("enc:", string.Empty).FromHexString(); + } + return p; } } @@ -100,8 +128,16 @@ namespace Roadie.Library.Models.ThirdPartyApi.Subsonic { get { - if (string.IsNullOrEmpty(id)) return null; - if (id.StartsWith(PlaylistdIdentifier)) return SafeParser.ToGuid(id); + if (string.IsNullOrEmpty(id)) + { + return null; + } + + if (id.StartsWith(PlaylistdIdentifier)) + { + return SafeParser.ToGuid(id); + } + return null; } } @@ -115,8 +151,16 @@ namespace Roadie.Library.Models.ThirdPartyApi.Subsonic { get { - if (string.IsNullOrEmpty(id)) return null; - if (id.StartsWith(ReleaseIdIdentifier)) return SafeParser.ToGuid(id); + if (string.IsNullOrEmpty(id)) + { + return null; + } + + if (id.StartsWith(ReleaseIdIdentifier)) + { + return SafeParser.ToGuid(id); + } + return null; } } @@ -145,8 +189,16 @@ namespace Roadie.Library.Models.ThirdPartyApi.Subsonic { get { - if (string.IsNullOrEmpty(id)) return null; - if (id.StartsWith(TrackIdIdentifier)) return SafeParser.ToGuid(id); + if (string.IsNullOrEmpty(id)) + { + return null; + } + + if (id.StartsWith(TrackIdIdentifier)) + { + return SafeParser.ToGuid(id); + } + return null; } } diff --git a/Roadie.Api.Library/Models/Track.cs b/Roadie.Api.Library/Models/Track.cs index 7613f7b..4be8a15 100644 --- a/Roadie.Api.Library/Models/Track.cs +++ b/Roadie.Api.Library/Models/Track.cs @@ -1,5 +1,4 @@ -using Newtonsoft.Json; -using Roadie.Library.Models.Releases; +using Roadie.Library.Models.Releases; using Roadie.Library.Models.Statistics; using Roadie.Library.Models.Users; using Roadie.Library.Utility; @@ -7,6 +6,7 @@ using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Runtime.Serialization; +using System.Text.Json.Serialization; namespace Roadie.Library.Models { @@ -17,33 +17,47 @@ namespace Roadie.Library.Models private IEnumerable _partTitles; - [MaxLength(50)] public string AmgId { get; set; } + [MaxLength(50)] + public string AmgId { get; set; } public ArtistList Artist { get; set; } - public IEnumerable Credits { get; set; } + public Image ArtistThumbnail { get; set; } + public IEnumerable Comments { get; set; } + + public IEnumerable Credits { get; set; } + public int Duration { get; set; } public string DurationTime { get { - if (Duration < 1) return "--:--"; + if (Duration < 1) + { + return "--:--"; + } + return new TimeInfo(Duration).ToFullFormattedString(); } } public long FileSize { get; set; } - [MaxLength(32)] public string Hash { get; set; } - [MaxLength(15)] public string ISRC { get; set; } + [MaxLength(32)] + public string Hash { get; set; } - [MaxLength(50)] public string LastFMId { get; set; } + [MaxLength(15)] + public string ISRC { get; set; } + + [MaxLength(50)] + public string LastFMId { get; set; } public DateTime? LastPlayed { get; set; } public Image MediumThumbnail { get; set; } + [MaxLength(100)] public string MusicBrainzId { get; set; } // When populated a "data:image" base64 byte array of an image to use as new Thumbnail @@ -60,7 +74,11 @@ namespace Roadie.Library.Models { if (_partTitles == null) { - if (string.IsNullOrEmpty(PartTitles)) return null; + if (string.IsNullOrEmpty(PartTitles)) + { + return null; + } + return PartTitles.Replace("|", "\n").Split("\n"); } @@ -70,7 +88,9 @@ namespace Roadie.Library.Models } public int PlayedCount { get; set; } + public short Rating { get; set; } + public ReleaseList Release { get; set; } public string ReleaseMediaId { get; set; } @@ -82,7 +102,10 @@ namespace Roadie.Library.Models public TrackStatistics Statistics { get; set; } public Image Thumbnail { get; set; } - [MaxLength(250)] [Required] public string Title { get; set; } + + [MaxLength(250)] + [Required] + public string Title { get; set; } /// /// Track Artist, not release artist. If this is present then the track has an artist different than the release. @@ -90,15 +113,15 @@ namespace Roadie.Library.Models public ArtistList TrackArtist { get; set; } public Image TrackArtistThumbnail { get; set; } + public DataToken TrackArtistToken { get; set; } + [Required] public short TrackNumber { get; set; } public string TrackPlayUrl { get; set; } + public UserTrack UserRating { get; set; } - public override string ToString() - { - return $"Id [{ Id }], Title [{ Title }]"; - } + public override string ToString() => $"Id [{ Id }], Title [{ Title }]"; } } \ No newline at end of file diff --git a/Roadie.Api.Library/Models/TrackList.cs b/Roadie.Api.Library/Models/TrackList.cs index 64f77de..93f0277 100644 --- a/Roadie.Api.Library/Models/TrackList.cs +++ b/Roadie.Api.Library/Models/TrackList.cs @@ -1,15 +1,15 @@ -using Newtonsoft.Json; +using Roadie.Library.Enums; using Roadie.Library.Models.Releases; using Roadie.Library.Models.Users; using Roadie.Library.Utility; using System; -using System.Linq; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Diagnostics; +using System.Linq; using System.Runtime.Serialization; +using System.Text.Json.Serialization; using Release = Roadie.Library.Data.Release; -using Roadie.Library.Enums; namespace Roadie.Library.Models { @@ -18,6 +18,7 @@ namespace Roadie.Library.Models public sealed class TrackList : EntityInfoModelBase { public ArtistList Artist { get; set; } + public int? Duration { get; set; } public string DurationTime => Duration.HasValue ? new TimeInfo(Duration.Value).ToFullFormattedString() : "--:--"; @@ -25,8 +26,11 @@ namespace Roadie.Library.Models public string DurationTimeShort => Duration.HasValue ? new TimeInfo(Duration.Value).ToShortFormattedString() : "--:--"; public int? FavoriteCount { get; set; } + public int? FileSize { get; set; } + public DateTime? LastPlayed { get; set; } + public int? MediaNumber { get; set; } [MaxLength(65535)] @@ -38,100 +42,84 @@ namespace Roadie.Library.Models { get { - if (string.IsNullOrEmpty(PartTitles)) return null; + if (string.IsNullOrEmpty(PartTitles)) + { + return null; + } + return PartTitles.Split('\n'); } } public int? PlayedCount { get; set; } - public short? Rating { get; set; } - public ReleaseList Release { get; set; } - [JsonIgnore] public DateTime? ReleaseDate { get; set; } - public short? ReleaseRating { get; set; } - public Image Thumbnail { get; set; } - public string Title { get; set; } - public DataToken Track { get; set; } - public ArtistList TrackArtist { get; set; } - [JsonIgnore] public string TrackId => Track?.Value; - [JsonIgnore] public string TrackName => Track?.Text; - [JsonIgnore] public string ReleaseName => Release?.Release?.Text; + public short? Rating { get; set; } + + public ReleaseList Release { get; set; } + + [JsonIgnore] + public DateTime? ReleaseDate { get; set; } + + [JsonIgnore] + public string ReleaseName => Release?.Release?.Text; + + public short? ReleaseRating { get; set; } + public Statuses? Status { get; set; } + public string StatusVerbose => (Status ?? Statuses.Missing).ToString(); + + public Image Thumbnail { get; set; } + + public string Title { get; set; } + + public DataToken Track { get; set; } + + public ArtistList TrackArtist { get; set; } + + [JsonIgnore] + public string TrackId => Track?.Value; + + [JsonIgnore] + public string TrackName => Track?.Text; + public int? TrackNumber { get; set; } + public string TrackPlayUrl { get; set; } + public UserTrack UserRating { get; set; } public int? Year { get { - if (ReleaseDate.HasValue) return ReleaseDate.Value.Year; + if (ReleaseDate.HasValue) + { + return ReleaseDate.Value.Year; + } + return null; } } - public int GetArtistReleaseHashCode() => this.Artist?.Artist?.Value.GetHashCode() + this.Release?.Release?.Value.GetHashCode() ?? 0; - - public override int GetHashCode() => this.Artist?.Artist?.Value.GetHashCode() + this.Release?.Release?.Value.GetHashCode() + this.Track?.Value.GetHashCode() ?? 0; - public static IEnumerable AllIndexesOfArtist(IEnumerable tracks, string artistId) { - if(tracks == null || !tracks.Any()) + if (tracks?.Any() != true) { return new int[0]; } - return tracks.Select((b, i) => b.Artist?.Artist?.Value == artistId ? i : -1).Where(i => i != -1).ToArray(); + return tracks.Select((b, i) => b.Artist?.Artist?.Value == artistId ? i : -1).Where(i => i != -1).ToArray(); } public static IEnumerable AllIndexesOfRelease(IEnumerable tracks, string releaseId) { - if (tracks == null || !tracks.Any()) + if (tracks?.Any() != true) { return new int[0]; } return tracks.Select((b, i) => b.Release?.Release?.Value == releaseId ? i : -1).Where(i => i != -1).ToArray(); } - - /// - /// Ensure that the given list is sorted so that Artist and Release don't repeat in sequence. - /// - public static IEnumerable Shuffle(IEnumerable tracks) - { - - var shuffledTracks = new List(); - var skippedTracks = new List(); - foreach(var track in tracks) - { - var trackArtist = track.Artist?.Artist?.Value ?? track.Release?.Artist?.Value; - var trackRelease = track.Release?.Release?.Value; - if (!shuffledTracks.Any(x => x.Artist?.Artist?.Value == trackArtist && - x.Release?.Release?.Value != trackRelease)) - { - shuffledTracks.Add(track); - } - else - { - skippedTracks.Add(track); - } - } - var result = new List(shuffledTracks); - while (skippedTracks.ToList().Any()) - { - var st = skippedTracks.First(); - var trackArtist = st.Artist?.Artist?.Value ?? st.Release?.Artist?.Value; - var insertAt = AllIndexesOfArtist(result, trackArtist).Last() + 2; - if(insertAt < result.Count() - 1) - { - result.Insert(insertAt, st); - skippedTracks.Remove(st); - } - } - return result; - } - - public static TrackList FromDataTrack(string trackPlayUrl, Data.Track track, int releaseMediaNumber, @@ -173,6 +161,44 @@ namespace Roadie.Library.Models }; } + public int GetArtistReleaseHashCode() => this.Artist?.Artist?.Value.GetHashCode() + this.Release?.Release?.Value.GetHashCode() ?? 0; + public override int GetHashCode() => this.Artist?.Artist?.Value.GetHashCode() + this.Release?.Release?.Value.GetHashCode() + this.Track?.Value.GetHashCode() ?? 0; + + /// + /// Ensure that the given list is sorted so that Artist and Release don't repeat in sequence. + /// + public static IEnumerable Shuffle(IEnumerable tracks) + { + var shuffledTracks = new List(); + var skippedTracks = new List(); + foreach (var track in tracks) + { + var trackArtist = track.Artist?.Artist?.Value ?? track.Release?.Artist?.Value; + var trackRelease = track.Release?.Release?.Value; + if (!shuffledTracks.Any(x => x.Artist?.Artist?.Value == trackArtist && + x.Release?.Release?.Value != trackRelease)) + { + shuffledTracks.Add(track); + } + else + { + skippedTracks.Add(track); + } + } + var result = new List(shuffledTracks); + while (skippedTracks.ToList().Count > 0) + { + var st = skippedTracks[0]; + var trackArtist = st.Artist?.Artist?.Value ?? st.Release?.Artist?.Value; + var insertAt = AllIndexesOfArtist(result, trackArtist).Last() + 2; + if (insertAt < result.Count() - 1) + { + result.Insert(insertAt, st); + skippedTracks.Remove(st); + } + } + return result; + } } } \ No newline at end of file diff --git a/Roadie.Api.Library/Models/Users/User.cs b/Roadie.Api.Library/Models/Users/User.cs index 2576979..99dffd7 100644 --- a/Roadie.Api.Library/Models/Users/User.cs +++ b/Roadie.Api.Library/Models/Users/User.cs @@ -3,6 +3,7 @@ using Roadie.Library.Models.Statistics; using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using System.Text.Json.Serialization; namespace Roadie.Library.Models.Users { @@ -11,7 +12,9 @@ namespace Roadie.Library.Models.Users { public const string ActionKeyUserRated = "__userrated__"; public const string DefaultIncludes = "stats"; - [MaxLength(100)] public string ApiToken { get; set; } + + [MaxLength(100)] + public string ApiToken { get; set; } public Image Avatar { get; set; } @@ -20,7 +23,12 @@ namespace Roadie.Library.Models.Users /// public string AvatarData { get; set; } - [Required] [MaxLength(100)] public string ConcurrencyStamp { get; set; } + [Required] + [MaxLength(100)] + public string ConcurrencyStamp { get; set; } + + public short? DefaultRowsPerPage { get; set; } + public bool DoUseHtmlPlayer { get; set; } [Required] @@ -28,18 +36,34 @@ namespace Roadie.Library.Models.Users [DataType(DataType.EmailAddress)] public string Email { get; set; } - [MaxLength(500)] public string FtpDirectory { get; set; } + [MaxLength(500)] + public string FtpDirectory { get; set; } - [MaxLength(500)] public string FtpPassword { get; set; } + [MaxLength(500)] + public string FtpPassword { get; set; } - [MaxLength(250)] public string FtpUrl { get; set; } + [MaxLength(250)] + [DataType(DataType.Url)] + public string FtpUrl { get; set; } - [MaxLength(50)] public string FtpUsername { get; set; } + [MaxLength(50)] + public string FtpUsername { get; set; } + + [JsonPropertyName("UserDbId")] public new int? Id { get; set; } + public bool IsAdmin { get; set; } + public bool IsEditor { get; set; } + public bool IsPrivate { get; set; } + public DateTime LastApiAccess { get; set; } + + public DateTime LastLogin { get; set; } + + public Image MediumThumbnail { get; set; } + /// /// Posted password only used when changing password from profile edits /// @@ -55,23 +79,34 @@ namespace Roadie.Library.Models.Users public string PasswordConfirmation { get; set; } public short? PlayerTrackLimit { get; set; } - [MaxLength(65535)] public string Profile { get; set; } + + [MaxLength(65535)] + public string Profile { get; set; } + public short? RandomReleaseLimit { get; set; } + public short? RecentlyPlayedLimit { get; set; } + public bool RemoveTrackFromQueAfterPlayed { get; set; } - [NotMapped] [AdaptIgnore] public UserStatistics Statistics { get; set; } - [StringLength(50)] [Required] public string Timeformat { get; set; } - [MaxLength(50)] [Required] public string Timezone { get; set; } + [NotMapped] + [AdaptIgnore] + public UserStatistics Statistics { get; set; } - [AdaptMember("RoadieId")] public Guid UserId { get; set; } + [StringLength(50)] + [Required] + public string Timeformat { get; set; } - [Required] [MaxLength(20)] public string UserName { get; set; } - public Image MediumThumbnail { get; set; } + [MaxLength(50)] + [Required] + public string Timezone { get; set; } - public DateTime LastLogin { get; set; } - public DateTime LastApiAccess { get; set; } - public short? DefaultRowsPerPage { get; set; } + [AdaptMember("RoadieId")] + public Guid UserId { get; set; } + + [Required] + [MaxLength(20)] + public string UserName { get; set; } public override string ToString() => $"Id [{Id}], RoadieId [{UserId}], UserName [{UserName}]"; } diff --git a/Roadie.Api.Library/OperationResult.cs b/Roadie.Api.Library/OperationResult.cs index 470a3a2..bb688b8 100644 --- a/Roadie.Api.Library/OperationResult.cs +++ b/Roadie.Api.Library/OperationResult.cs @@ -1,7 +1,7 @@ -using Newtonsoft.Json; -using System; +using System; using System.Collections.Generic; using System.Linq; +using System.Text.Json.Serialization; using System.Xml.Serialization; namespace Roadie.Library @@ -10,6 +10,7 @@ namespace Roadie.Library public class OperationResult { private List _errors; + private List _messages; [XmlIgnore] @@ -22,12 +23,15 @@ namespace Roadie.Library /// /// Client friendly exceptions /// - [JsonProperty("errors")] + [JsonPropertyName("errors")] public IEnumerable AppExceptions { get { - if (Errors == null || !Errors.Any()) return null; + if (Errors?.Any() != true) + { + return null; + } return Errors.Select(x => new AppException(x.Message)); } @@ -41,7 +45,8 @@ namespace Roadie.Library [JsonIgnore] public IEnumerable Errors { get; set; } - [JsonIgnore] public bool IsAccessDeniedResult { get; set; } + [JsonIgnore] + public bool IsAccessDeniedResult { get; set; } [JsonIgnore] public bool IsNotFoundResult { get; set; } @@ -57,29 +62,13 @@ namespace Roadie.Library public OperationResult(IEnumerable messages = null) { - if (messages != null && messages.Any()) + if (messages?.Any() == true) { AdditionalData = new Dictionary(); messages.ToList().ForEach(AddMessage); } } - public OperationResult(bool isNotFoundResult, IEnumerable messages = null) - { - IsNotFoundResult = isNotFoundResult; - if (messages != null && messages.Any()) - { - AdditionalData = new Dictionary(); - messages.ToList().ForEach(AddMessage); - } - } - - public OperationResult(bool isNotFoundResult, string message) - { - IsNotFoundResult = isNotFoundResult; - AddMessage(message); - } - public OperationResult(string message = null) { AdditionalData = new Dictionary(); @@ -91,6 +80,22 @@ namespace Roadie.Library AddError(error); } + public OperationResult(bool isNotFoundResult, IEnumerable messages = null) + { + IsNotFoundResult = isNotFoundResult; + if (messages?.Any() == true) + { + AdditionalData = new Dictionary(); + messages.ToList().ForEach(AddMessage); + } + } + + public OperationResult(bool isNotFoundResult, string message) + { + IsNotFoundResult = isNotFoundResult; + AddMessage(message); + } + public OperationResult(string message = null, Exception error = null) { AddMessage(message); @@ -101,9 +106,7 @@ namespace Roadie.Library { if (exception != null) { - if (_errors == null) _errors = new List(); - - _errors.Add(exception); + (_errors ?? (_errors = new List())).Add(exception); } } @@ -111,9 +114,7 @@ namespace Roadie.Library { if (!string.IsNullOrEmpty(message)) { - if (_messages == null) _messages = new List(); - - _messages.Add(message); + (_messages ?? (_messages = new List())).Add(message); } } } diff --git a/Roadie.Api.Library/Roadie.Library.csproj b/Roadie.Api.Library/Roadie.Library.csproj index 77afb27..c67f074 100644 --- a/Roadie.Api.Library/Roadie.Library.csproj +++ b/Roadie.Api.Library/Roadie.Library.csproj @@ -18,17 +18,19 @@ + - - - - + + + + + - + - - + + @@ -39,6 +41,7 @@ + diff --git a/Roadie.Api.Library/RoadieProcessingException.cs b/Roadie.Api.Library/RoadieProcessingException.cs new file mode 100644 index 0000000..bba5af1 --- /dev/null +++ b/Roadie.Api.Library/RoadieProcessingException.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Roadie.Library +{ + public sealed class RoadieProcessingException : Exception + { + public RoadieProcessingException() : base() + { + } + + public RoadieProcessingException(string message) + : base(message) + { + } + + public RoadieProcessingException(string message, Exception innerException) + : base(message, innerException) + { + } + } +} diff --git a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaData.cs b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaData.cs index f2ec034..e7d84b7 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaData.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/Audio/AudioMetaData.cs @@ -1,10 +1,10 @@ -using Newtonsoft.Json; -using Roadie.Library.Extensions; +using Roadie.Library.Extensions; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using System.Text.Json.Serialization; namespace Roadie.Library.MetaData.Audio { @@ -14,10 +14,11 @@ namespace Roadie.Library.MetaData.Audio public sealed class AudioMetaData : IAudioMetaData { public const char ArtistSplitCharacter = '/'; - public const int MinimumYearValue = 1900; public const string SoundTrackArtist = "Sound Tracks"; + private string _artist; + private bool _doModifyArtistNameOnGet = true; private FileInfo _fileInfo; @@ -43,15 +44,20 @@ namespace Roadie.Library.MetaData.Audio { get { - if (_doModifyArtistNameOnGet) - if (!string.IsNullOrEmpty(_artist) && _artist.Contains(ArtistSplitCharacter.ToString())) - return _artist.Split(ArtistSplitCharacter).First(); + if (_doModifyArtistNameOnGet && !string.IsNullOrEmpty(_artist) && _artist.Contains(ArtistSplitCharacter.ToString())) + { + return _artist.Split(ArtistSplitCharacter)[0]; + } + return _artist; } set { _artist = value; - if (!string.IsNullOrEmpty(_artist)) _artist = _artist.Replace(';', ArtistSplitCharacter); + if (!string.IsNullOrEmpty(_artist)) + { + _artist = _artist.Replace(';', ArtistSplitCharacter); + } } } @@ -66,12 +72,36 @@ namespace Roadie.Library.MetaData.Audio get { var result = AudioMetaDataWeights.None; - if (!string.IsNullOrEmpty(Artist)) result |= AudioMetaDataWeights.Artist; - if (!string.IsNullOrEmpty(Title)) result |= AudioMetaDataWeights.Time; - if ((Year ?? 0) > 1) result |= AudioMetaDataWeights.Year; - if ((TrackNumber ?? 0) > 1) result |= AudioMetaDataWeights.TrackNumber; - if ((TotalTrackNumbers ?? 0) > 1) result |= AudioMetaDataWeights.TrackTotalNumber; - if (TotalSeconds > 1) result |= AudioMetaDataWeights.Time; + if (!string.IsNullOrEmpty(Artist)) + { + result |= AudioMetaDataWeights.Artist; + } + + if (!string.IsNullOrEmpty(Title)) + { + result |= AudioMetaDataWeights.Time; + } + + if ((Year ?? 0) > 1) + { + result |= AudioMetaDataWeights.Year; + } + + if ((TrackNumber ?? 0) > 1) + { + result |= AudioMetaDataWeights.TrackNumber; + } + + if ((TotalTrackNumbers ?? 0) > 1) + { + result |= AudioMetaDataWeights.TrackTotalNumber; + } + + if (TotalSeconds > 1) + { + result |= AudioMetaDataWeights.Time; + } + return result; } } @@ -90,7 +120,11 @@ namespace Roadie.Library.MetaData.Audio { get { - if (string.IsNullOrEmpty(Filename)) return null; + if (string.IsNullOrEmpty(Filename)) + { + return null; + } + return Path.GetDirectoryName(Filename); } } @@ -105,7 +139,8 @@ namespace Roadie.Library.MetaData.Audio /// public string DiscSubTitle { get; set; } - [JsonIgnore] public FileInfo FileInfo => _fileInfo ?? (_fileInfo = new FileInfo(Filename)); + [JsonIgnore] + public FileInfo FileInfo => _fileInfo ?? (_fileInfo = new FileInfo(Filename)); /// /// Full filename to the file used to get this AudioMetaData @@ -114,7 +149,8 @@ namespace Roadie.Library.MetaData.Audio public ICollection Genres { get; set; } - [JsonIgnore] public IEnumerable Images { get; set; } + [JsonIgnore] + public IEnumerable Images { get; set; } public string ISRC { get; internal set; } @@ -122,10 +158,13 @@ namespace Roadie.Library.MetaData.Audio { get { - if (Genres != null && Genres.Any()) + if (Genres?.Any() == true) { var soundtrackGenres = new List { "24", "soundtrack" }; - if (Genres.Intersect(soundtrackGenres, StringComparer.OrdinalIgnoreCase).Any()) return true; + if (Genres.Intersect(soundtrackGenres, StringComparer.OrdinalIgnoreCase).Any()) + { + return true; + } } return false; @@ -142,7 +181,7 @@ namespace Roadie.Library.MetaData.Audio Release = Release == null ? null : Release.Equals("Unknown Release") ? null : Release; if (!string.IsNullOrEmpty(Title)) { - var trackNumberTitle = string.Format("Track {0}", TrackNumber); + var trackNumberTitle = $"Track {TrackNumber}"; Title = Title == trackNumberTitle ? null : Title; } @@ -193,7 +232,10 @@ namespace Roadie.Library.MetaData.Audio set { _title = value; - if (IsSoundTrack) Artist = SoundTrackArtist; + if (IsSoundTrack) + { + Artist = SoundTrackArtist; + } } } @@ -206,7 +248,11 @@ namespace Roadie.Library.MetaData.Audio { get { - if (Time == null) return 0; + if (Time == null) + { + return 0; + } + return Time.Value.TotalSeconds; } } @@ -225,9 +271,11 @@ namespace Roadie.Library.MetaData.Audio { string result = null; if (!string.IsNullOrEmpty(_trackArtist)) - result = _trackArtist.Split(ArtistSplitCharacter).First().ToTitleCase(); - result = !_artist?.Equals(result, StringComparison.OrdinalIgnoreCase) ?? false ? result : null; - return result; + { + result = _trackArtist.Split(ArtistSplitCharacter)[0].ToTitleCase(); + } + + return !String.Equals(_artist, result, StringComparison.OrdinalIgnoreCase) ? result : null; } set => _trackArtist = value; } @@ -242,17 +290,33 @@ namespace Roadie.Library.MetaData.Audio { get { - if (string.IsNullOrEmpty(_trackArtist)) return new string[0]; + if (string.IsNullOrEmpty(_trackArtist)) + { + return new string[0]; + } + if (!_trackArtist.Contains(ArtistSplitCharacter.ToString())) { - if (string.IsNullOrEmpty(TrackArtist)) return new string[0]; + if (string.IsNullOrEmpty(TrackArtist)) + { + return new string[0]; + } + return new string[1] { TrackArtist }; } if (!string.IsNullOrEmpty(_artist) || !string.IsNullOrEmpty(_trackArtist)) - if (!_artist.Equals(_trackArtist, StringComparison.OrdinalIgnoreCase)) - return _trackArtist.Split(ArtistSplitCharacter).Where(x => !string.IsNullOrEmpty(x)) - .Select(x => x.ToTitleCase()).OrderBy(x => x).ToArray(); + { + if (!String.Equals(_artist, _trackArtist, StringComparison.OrdinalIgnoreCase)) + { + return _trackArtist.Split(ArtistSplitCharacter) + .Where(x => !string.IsNullOrEmpty(x)) + .Select(x => x.ToTitleCase()) + .OrderBy(x => x) + .ToArray(); + } + } + return new string[0]; } } @@ -280,8 +344,11 @@ namespace Roadie.Library.MetaData.Audio public override bool Equals(object obj) { - var item = obj as AudioMetaData; - if (item == null) return false; + if (!(obj is AudioMetaData item)) + { + return false; + } + return item.GetHashCode() == GetHashCode(); } @@ -290,12 +357,12 @@ namespace Roadie.Library.MetaData.Audio unchecked { var hash = 17; - hash = hash * 23 + Artist.GetHashCode(); - hash = hash * 23 + Release.GetHashCode(); - hash = hash * 23 + Title.GetHashCode(); - hash = hash * 23 + TrackNumber.GetHashCode(); - hash = hash * 23 + AudioBitrate.GetHashCode(); - hash = hash * 23 + AudioSampleRate.GetHashCode(); + hash = (hash * 23) + Artist.GetHashCode(); + hash = (hash * 23) + Release.GetHashCode(); + hash = (hash * 23) + Title.GetHashCode(); + hash = (hash * 23) + TrackNumber.GetHashCode(); + hash = (hash * 23) + AudioBitrate.GetHashCode(); + hash = (hash * 23) + AudioSampleRate.GetHashCode(); return hash; } } @@ -314,9 +381,17 @@ namespace Roadie.Library.MetaData.Audio { var result = $"IsValid: {IsValid}{(IsSoundTrack ? " [SoundTrack ]" : string.Empty)}, ValidWeight {ValidWeight}, Artist: {Artist}"; - if (!string.IsNullOrEmpty(TrackArtist)) result += $", TrackArtist: {TrackArtist}"; + if (!string.IsNullOrEmpty(TrackArtist)) + { + result += $", TrackArtist: {TrackArtist}"; + } + result += $", Release: {Release}, TrackNumber: {TrackNumber}, TrackTotal: {TotalTrackNumbers}"; - if (TotalDiscCount > 1) result += $", Disc: {Disc}/{TotalDiscCount}"; + if (TotalDiscCount > 1) + { + result += $", Disc: {Disc}/{TotalDiscCount}"; + } + result += $", Title: {Title}, Year: {Year}, Duration: {(Time == null ? "-" : Time.Value.ToString())}"; return result; } diff --git a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/CoverArtEntities.cs b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/CoverArtEntities.cs index c702ca1..3cf0b4a 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/CoverArtEntities.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/CoverArtEntities.cs @@ -13,7 +13,6 @@ public string comment { get; set; } public int edit { get; set; } public bool front { get; set; } - public string id { get; set; } public string image { get; set; } public Thumbnails thumbnails { get; set; } public string[] types { get; set; } diff --git a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/Entities.cs b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/Entities.cs index 58fe118..e1fc59b 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/Entities.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/Entities.cs @@ -1,7 +1,7 @@ -using Newtonsoft.Json; -using System; +using System; using System.Collections.Generic; using System.Diagnostics; +using System.Text.Json.Serialization; namespace Roadie.Library.MetaData.MusicBrainz { @@ -13,51 +13,59 @@ namespace Roadie.Library.MetaData.MusicBrainz public class CoverArtArchive { public bool artwork { get; set; } + public bool back { get; set; } + public int? count { get; set; } public bool darkened { get; set; } + public bool front { get; set; } } public class Label { public List aliases { get; set; } + public string disambiguation { get; set; } + + public NameAndCount[] genres { get; set; } + public string id { get; set; } - [JsonProperty(PropertyName = "label-code")] + [JsonPropertyName("label-code")] public int? labelcode { get; set; } public string name { get; set; } - [JsonProperty(PropertyName = "sort-name")] + [JsonPropertyName("sort-name")] public string sortname { get; set; } public NameAndCount[] tags { get; set; } - public NameAndCount[] genres { get; set; } } [Serializable] public class LabelInfo { - [JsonProperty(PropertyName = "catalog-number")] + [JsonPropertyName("catalog-number")] public string catalognumber { get; set; } public Label label { get; set; } } - [Serializable] public class Medium { public object format { get; set; } + public int? position { get; set; } + public string title { get; set; } - [JsonProperty(PropertyName = "track-count")] + [JsonPropertyName("track-count")] public short? trackcount { get; set; } - [JsonProperty(PropertyName = "track-offset")] + + [JsonPropertyName("track-offset")] public int? trackoffset { get; set; } public List tracks { get; set; } @@ -67,37 +75,57 @@ namespace Roadie.Library.MetaData.MusicBrainz public class Recording { public List aliases { get; set; } + public string disambiguation { get; set; } - public string id { get; set; } - public int? length { get; set; } - public string title { get; set; } - public bool video { get; set; } - public NameAndCount[] tags { get; set; } + public NameAndCount[] genres { get; set; } + + public string id { get; set; } + + public int? length { get; set; } + + public NameAndCount[] tags { get; set; } + + public string title { get; set; } + + public bool video { get; set; } } [Serializable] public class Relation { public List attributes { get; set; } + public AttributeValues attributevalues { get; set; } + public object begin { get; set; } + public string direction { get; set; } + public object end { get; set; } - public bool ended { get; set; } + + public bool? ended { get; set; } + public string sourcecredit { get; set; } + public string targetcredit { get; set; } + public string targettype { get; set; } + public string type { get; set; } + public string typeid { get; set; } + public MbUrl url { get; set; } } [Serializable] public class RepositoryRelease { - public int Id { get; set; } public string ArtistMbId { get; set; } + + public int Id { get; set; } + public Release Release { get; set; } } @@ -106,46 +134,61 @@ namespace Roadie.Library.MetaData.MusicBrainz public class Release { public List aliases { get; set; } + + [JsonPropertyName("artist-credits")] + public Artist[] artistcredits { get; set; } + public string asin { get; set; } + public string barcode { get; set; } + public string country { get; set; } - [JsonProperty(PropertyName = "cover-art-archive")] + [JsonPropertyName("cover-art-archive")] public CoverArtArchive coverartarchive { get; set; } public string coverThumbnailUrl { get; set; } + public string date { get; set; } + public string disambiguation { get; set; } + public string id { get; set; } + public List imageUrls { get; set; } - [JsonProperty(PropertyName = "label-info")] + [JsonPropertyName("label-info")] public List labelinfo { get; set; } public List media { get; set; } + public string packaging { get; set; } + public string quality { get; set; } + public List relations { get; set; } - [JsonProperty(PropertyName = "release-events")] + [JsonPropertyName("release-events")] public List releaseevents { get; set; } - [JsonProperty(PropertyName = "release-group")] + + [JsonPropertyName("release-group")] public ReleaseGroup releasegroup { get; set; } + public string status { get; set; } - [JsonProperty(PropertyName = "text-representation")] + + [JsonPropertyName("text-representation")] public TextRepresentation textrepresentation { get; set; } + public string title { get; set; } - [JsonProperty("artist-credits")] - public Artist[] artistcredits { get; set; } } [Serializable] public class ReleaseBrowseResult { - [JsonProperty(PropertyName = "release-count")] + [JsonPropertyName("release-count")] public int? releasecount { get; set; } - [JsonProperty(PropertyName = "release-offset")] + [JsonPropertyName("release-offset")] public int? releaseoffset { get; set; } public List releases { get; set; } @@ -163,22 +206,31 @@ namespace Roadie.Library.MetaData.MusicBrainz public class ReleaseGroup { public List aliases { get; set; } + public string disambiguation { get; set; } - [JsonProperty("first-release-date")] + + [JsonPropertyName("first-release-date")] public string firstreleasedate { get; set; } - public string id { get; set; } - [JsonProperty("primary-type")] - public string primarytype { get; set; } - public List secondarytypes { get; set; } - public string title { get; set; } - public NameAndCount[] tags { get; set; } + public NameAndCount[] genres { get; set; } + + public string id { get; set; } + + [JsonPropertyName("primary-type")] + public string primarytype { get; set; } + + public List secondarytypes { get; set; } + + public NameAndCount[] tags { get; set; } + + public string title { get; set; } } [Serializable] public class TextRepresentation { public string language { get; set; } + public string script { get; set; } } @@ -186,20 +238,23 @@ namespace Roadie.Library.MetaData.MusicBrainz public class Track { public string id { get; set; } + public int? length { get; set; } public string number { get; set; } - public string position { get; set; } + + public int? position { get; set; } + public Recording recording { get; set; } public string title { get; set; } - } [Serializable] public class MbUrl { public string id { get; set; } + public string resource { get; set; } } } \ No newline at end of file diff --git a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/MusicBrainzProvider.cs b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/MusicBrainzProvider.cs index d7a106f..6774344 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/MusicBrainzProvider.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/MusicBrainzProvider.cs @@ -88,7 +88,7 @@ namespace Roadie.Library.MetaData.MusicBrainz Release = release.title, Title = track.title, Time = track.length.HasValue ? (TimeSpan?)TimeSpan.FromMilliseconds(track.length.Value) : null, - TrackNumber = SafeParser.ToNumber(track.position ?? track.number) ?? 0, + TrackNumber = SafeParser.ToNumber(track.position) ?? SafeParser.ToNumber(track.number) ?? 0, Disc = media.position, Year = date > 0 ? (int?)date : null, TotalTrackNumbers = media.trackcount diff --git a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/MusicBrainzRequestHelper.cs b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/MusicBrainzRequestHelper.cs index 0b01eb1..246cf53 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/MusicBrainzRequestHelper.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/MusicBrainzRequestHelper.cs @@ -1,8 +1,8 @@ -using Newtonsoft.Json; -using Roadie.Library.Utility; +using Roadie.Library.Utility; using System; using System.Diagnostics; using System.Net; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -48,6 +48,7 @@ namespace Roadie.Library.MetaData.MusicBrainz { var tryCount = 0; var result = default(T); + string downloadedString = null; while (result == null && tryCount < MaxRetries) { try @@ -55,7 +56,11 @@ namespace Roadie.Library.MetaData.MusicBrainz using (var webClient = new WebClient()) { webClient.Headers.Add("user-agent", WebHelper.UserAgent); - result = JsonConvert.DeserializeObject(await webClient.DownloadStringTaskAsync(new Uri(url)).ConfigureAwait(false)); + downloadedString = await webClient.DownloadStringTaskAsync(new Uri(url)).ConfigureAwait(false); + if (!string.IsNullOrWhiteSpace(downloadedString)) + { + result = JsonSerializer.Deserialize(downloadedString); + } } } catch (WebException ex) @@ -69,7 +74,7 @@ namespace Roadie.Library.MetaData.MusicBrainz } catch (Exception ex) { - Trace.WriteLine($"GetAsync: [{ ex.ToString() }]", "Warning"); + Trace.WriteLine($"GetAsync: DownloadedString [{ downloadedString }], Exception: [{ ex }]", "Warning"); Thread.Sleep(100); } finally diff --git a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/ResultEntities.cs b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/ResultEntities.cs index 8f3aa74..342096a 100644 --- a/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/ResultEntities.cs +++ b/Roadie.Api.Library/SearchEngines/MetaData/MusicBrainz/ResultEntities.cs @@ -1,140 +1,194 @@ -using Newtonsoft.Json; -using System; -using System.Collections.Generic; +using System; using System.Diagnostics; -using System.Text; +using System.Text.Json.Serialization; namespace Roadie.Library.MetaData.MusicBrainz { [Serializable] public class ArtistResult { - public DateTime created { get; set; } - public int count { get; set; } - public int offset { get; set; } public Artist[] artists { get; set; } + + public int count { get; set; } + + public DateTime created { get; set; } + + public int offset { get; set; } } [Serializable] public class RepositoryArtist { - public int Id { get; set; } - public string ArtistName { get; set; } - public string ArtistMbId { get; set; } public Artist Artist { get; set; } + + public string ArtistMbId { get; set; } + + public string ArtistName { get; set; } + + public int Id { get; set; } } [DebuggerDisplay("name: {name}")] [Serializable] public class Artist { - public string id { get; set; } - public string type { get; set; } - [JsonProperty("type-id")] - public string typeid { get; set; } - public int score { get; set; } - public string name { get; set; } - [JsonProperty("sort-name")] - public string sortname { get; set; } - public string gender { get; set; } - public string country { get; set; } - public Area area { get; set; } - [JsonProperty("begin_area")] - public BeginAndEndArea beginarea { get; set; } - [JsonProperty("end_area")] - public BeginAndEndArea endarea { get; set; } - public string[] ipis { get; set; } - [JsonProperty("life-span")] - public LifeSpan lifespan { get; set; } public Alias[] aliases { get; set; } - public NameAndCount[] tags { get; set; } - public IsniList[] isnilist { get; set; } + + public Area area { get; set; } + + [JsonPropertyName("begin_area")] + public BeginAndEndArea beginarea { get; set; } + + public string country { get; set; } + + [JsonPropertyName("end_area")] + public BeginAndEndArea endarea { get; set; } + + public string gender { get; set; } + public NameAndCount[] genres { get; set; } + + public string id { get; set; } + + public string[] ipis { get; set; } + + public IsniList[] isnilist { get; set; } + + [JsonPropertyName("life-span")] + public LifeSpan lifespan { get; set; } + + public string name { get; set; } + public Relation[] relations { get; set; } + + public int score { get; set; } + + [JsonPropertyName("sort-name")] + public string sortname { get; set; } + + public NameAndCount[] tags { get; set; } + + public string type { get; set; } + + [JsonPropertyName("type-id")] + public string typeid { get; set; } } [Serializable] public class Relations { - [JsonProperty("attribute-ids")] + [JsonPropertyName("attribute-ids")] public string[] attributeids { get; set; } + public string[] attributes { get; set; } - public string direction { get; set; } - [JsonProperty("target-credit")] - public string targetcredit { get; set; } - [JsonProperty("type-id")] - public string typeid { get; set; } - [JsonProperty("target-type")] - public string targettype { get; set; } - public string type { get; set; } - public bool ended { get; set; } - public Url url { get; set; } + public string[] attributevalues { get; set; } - [JsonProperty("source-credit")] - public string sourcecredit { get; set; } - public object end { get; set; } + public object begin { get; set; } + + public string direction { get; set; } + + public object end { get; set; } + + public bool? ended { get; set; } + + [JsonPropertyName("source-credit")] + public string sourcecredit { get; set; } + + [JsonPropertyName("target-credit")] + public string targetcredit { get; set; } + + [JsonPropertyName("target-type")] + public string targettype { get; set; } + + public string type { get; set; } + + [JsonPropertyName("type-id")] + public string typeid { get; set; } + + public Url url { get; set; } } [Serializable] public class Url { - public string resource { get; set; } public string id { get; set; } - } + public string resource { get; set; } + } [Serializable] public class Area { public string id { get; set; } - public string type { get; set; } - [JsonProperty("type-id")] - public string typeid { get; set; } - public string name { get; set; } - [JsonProperty("sort-name")] - public string sortname { get; set; } - [JsonProperty("life-span")] - public LifeSpan lifespan { get; set; } - [JsonProperty("iso-3166-1-codes")] + + [JsonPropertyName("iso-3166-1-codes")] public string[] iso31661codes { get; set; } + + [JsonPropertyName("life-span")] + public LifeSpan lifespan { get; set; } + + public string name { get; set; } + + [JsonPropertyName("sort-name")] + public string sortname { get; set; } + + public string type { get; set; } + + [JsonPropertyName("type-id")] + public string typeid { get; set; } } [Serializable] public class LifeSpan { - public string end { get; set; } - public string ended { get; set; } public string begin { get; set; } + + public string end { get; set; } + + public bool? ended { get; set; } } [Serializable] public class BeginAndEndArea { public string id { get; set; } - public string type { get; set; } - public string typeid { get; set; } - public string name { get; set; } - [JsonProperty("sort-name")] - public string sortname { get; set; } - [JsonProperty("life-span")] + + [JsonPropertyName("life-span")] public LifeSpan lifespan { get; set; } + + public string name { get; set; } + + [JsonPropertyName("sort-name")] + public string sortname { get; set; } + + public string type { get; set; } + + public string typeid { get; set; } } [Serializable] public class Alias { - [JsonProperty("sort-name")] - public string sortname { get; set; } - [JsonProperty("type-id")] - public string typeid { get; set; } - public string name { get; set; } - public string locale { get; set; } - public string type { get; set; } - public string primary { get; set; } public string begin { get; set; } + public string end { get; set; } - public bool ended { get; set; } + + public bool? ended { get; set; } + + public string locale { get; set; } + + public string name { get; set; } + + public bool? primary { get; set; } + + [JsonPropertyName("sort-name")] + public string sortname { get; set; } + + public string type { get; set; } + + [JsonPropertyName("type-id")] + public string typeid { get; set; } } [Serializable] @@ -147,7 +201,7 @@ namespace Roadie.Library.MetaData.MusicBrainz public class NameAndCount { public int? count { get; set; } + public string name { get; set; } } - } diff --git a/Roadie.Api.Services/Roadie.Api.Services.csproj b/Roadie.Api.Services/Roadie.Api.Services.csproj index 35e16b6..da919f1 100644 --- a/Roadie.Api.Services/Roadie.Api.Services.csproj +++ b/Roadie.Api.Services/Roadie.Api.Services.csproj @@ -7,10 +7,10 @@ - + - + diff --git a/Roadie.Api.Services/ServiceBase.cs b/Roadie.Api.Services/ServiceBase.cs index c7f1b7d..b6376cf 100644 --- a/Roadie.Api.Services/ServiceBase.cs +++ b/Roadie.Api.Services/ServiceBase.cs @@ -102,78 +102,56 @@ namespace Roadie.Api.Services return await GetArtist(artistByName.RoadieId).ConfigureAwait(false); } - protected async Task GetArtist(Guid id) + protected Task GetArtist(Guid id) { - if (id == Guid.Empty) - { - return null; - } - return await CacheManager.GetAsync(data.Artist.CacheUrn(id), async () => + return CacheManager.GetAsync(data.Artist.CacheUrn(id), async () => { return await DbContext.Artists .Include(x => x.Genres) .Include("Genres.Genre") - .FirstOrDefaultAsync(x => x.RoadieId == id).ConfigureAwait(false); - }, data.Artist.CacheRegionUrn(id)).ConfigureAwait(false); + .FirstOrDefaultAsync(x => x.RoadieId == id) + .ConfigureAwait(false); + }, data.Artist.CacheRegionUrn(id)); } - protected async Task GetCollection(Guid id) + protected Task GetCollection(Guid id) { - if (id == Guid.Empty) - { - return null; - } - return await CacheManager.GetAsync(data.Collection.CacheUrn(id), async () => + return CacheManager.GetAsync(data.Collection.CacheUrn(id), async () => { return await DbContext.Collections.FirstOrDefaultAsync(x => x.RoadieId == id).ConfigureAwait(false); - }, data.Collection.CacheRegionUrn(id)).ConfigureAwait(false); + }, data.Collection.CacheRegionUrn(id)); } - protected async Task GetGenre(Guid id) + protected Task GetGenre(Guid id) { - if (id == Guid.Empty) - { - return null; - } - return await CacheManager.GetAsync(data.Genre.CacheUrn(id), async () => + return CacheManager.GetAsync(data.Genre.CacheUrn(id), async () => { return await DbContext.Genres.FirstOrDefaultAsync(x => x.RoadieId == id).ConfigureAwait(false); - }, data.Genre.CacheRegionUrn(id)).ConfigureAwait(false); + }, data.Genre.CacheRegionUrn(id)); } - protected async Task GetLabel(Guid id) + protected Task GetLabel(Guid id) { - if (id == Guid.Empty) - { - return null; - } - return await CacheManager.GetAsync(data.Label.CacheUrn(id), async () => + return CacheManager.GetAsync(data.Label.CacheUrn(id), async () => { return await DbContext.Labels.FirstOrDefaultAsync(x => x.RoadieId == id).ConfigureAwait(false); - }, data.Label.CacheRegionUrn(id)).ConfigureAwait(false); + }, data.Label.CacheRegionUrn(id)); } - protected async Task GetPlaylist(Guid id) + protected Task GetPlaylist(Guid id) { - if (id == Guid.Empty) - { - return null; - } - return await CacheManager.GetAsync(data.Playlist.CacheUrn(id), async () => + return CacheManager.GetAsync(data.Playlist.CacheUrn(id), async () => { return await DbContext.Playlists .Include(x => x.User) - .FirstOrDefaultAsync(x => x.RoadieId == id).ConfigureAwait(false); - }, data.Playlist.CacheRegionUrn(id)).ConfigureAwait(false); + .FirstOrDefaultAsync(x => x.RoadieId == id) + .ConfigureAwait(false); + }, data.Playlist.CacheRegionUrn(id)); } - protected async Task GetRelease(Guid id) + protected Task GetRelease(Guid id) { - if (id == Guid.Empty) - { - return null; - } - return await CacheManager.GetAsync(data.Release.CacheUrn(id), async () => + return CacheManager.GetAsync(data.Release.CacheUrn(id), async () => { return await DbContext.Releases .Include(x => x.Artist) @@ -183,7 +161,7 @@ namespace Roadie.Api.Services .Include("Medias.Tracks") .Include("Medias.Tracks.TrackArtist") .FirstOrDefaultAsync(x => x.RoadieId == id).ConfigureAwait(false); - }, data.Release.CacheRegionUrn(id)).ConfigureAwait(false); + }, data.Release.CacheRegionUrn(id)); } /// @@ -199,13 +177,9 @@ namespace Roadie.Api.Services } // Only read operations - protected async Task GetTrack(Guid id) + protected Task GetTrack(Guid id) { - if(id == Guid.Empty) - { - return null; - } - return await CacheManager.GetAsync(data.Track.CacheUrn(id), async () => + return CacheManager.GetAsync(data.Track.CacheUrn(id), async () => { return await DbContext.Tracks .Include(x => x.ReleaseMedia) @@ -213,7 +187,7 @@ namespace Roadie.Api.Services .Include(x => x.ReleaseMedia.Release.Artist) .Include(x => x.TrackArtist) .FirstOrDefaultAsync(x => x.RoadieId == id).ConfigureAwait(false); - }, data.Track.CacheRegionUrn(id)).ConfigureAwait(false); + }, data.Track.CacheRegionUrn(id)); } protected async Task GetUser(string username) @@ -229,13 +203,9 @@ namespace Roadie.Api.Services return await GetUser(userByUsername?.RoadieId).ConfigureAwait(false); } - protected async Task GetUser(Guid? id) + protected Task GetUser(Guid? id) { - if (!id.HasValue) - { - return null; - } - return await CacheManager.GetAsync(User.CacheUrn(id.Value), async () => + return CacheManager.GetAsync(User.CacheUrn(id.Value), async () => { return await DbContext.Users .Include(x => x.UserRoles) @@ -245,7 +215,7 @@ namespace Roadie.Api.Services .Include(x => x.UserQues) .Include("UserQues.Track") .FirstOrDefaultAsync(x => x.RoadieId == id).ConfigureAwait(false); - }, User.CacheRegionUrn(id.Value)).ConfigureAwait(false); + }, User.CacheRegionUrn(id.Value)); } protected string MakeLastFmUrl(string artistName, string releaseTitle) => "http://www.last.fm/music/" + HttpEncoder.UrlEncode($"{artistName}/{releaseTitle}"); diff --git a/Roadie.Api.Services/SubsonicService.cs b/Roadie.Api.Services/SubsonicService.cs index 2ff0902..cda0815 100644 --- a/Roadie.Api.Services/SubsonicService.cs +++ b/Roadie.Api.Services/SubsonicService.cs @@ -2,25 +2,23 @@ using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Library.Caching; using Roadie.Library.Configuration; using Roadie.Library.Data.Context; using Roadie.Library.Encoding; using Roadie.Library.Enums; using Roadie.Library.Extensions; -using Roadie.Library.Identity; using Roadie.Library.Imaging; using Roadie.Library.Models; using Roadie.Library.Models.Pagination; using Roadie.Library.Models.Playlists; using Roadie.Library.Models.Releases; -using Roadie.Library.Models.Users; using Roadie.Library.Utility; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Text.Json; using System.Threading.Tasks; using data = Roadie.Library.Data; using subsonic = Roadie.Library.Models.ThirdPartyApi.Subsonic; @@ -39,19 +37,12 @@ namespace Roadie.Api.Services public const string SubsonicVersion = "1.16.1"; private IArtistService ArtistService { get; } - private IBookmarkService BookmarkService { get; } - private IImageService ImageService { get; } - private IPlayActivityService PlayActivityService { get; } - private IPlaylistService PlaylistService { get; } - private IReleaseService ReleaseService { get; } - private ITrackService TrackService { get; } - private UserManager UserManger { get; } public SubsonicService(IRoadieSettings configuration, @@ -88,8 +79,11 @@ namespace Roadie.Api.Services Library.Models.Users.User roadieUser) { if (string.IsNullOrEmpty(request.Message)) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.RequiredParameterMissing, "Message is required"); + subsonic.ErrorCodes.RequiredParameterMissing, "Message is required"); + } + var chatMessage = new data.ChatMessage { UserId = roadieUser.Id.Value, @@ -115,8 +109,11 @@ namespace Roadie.Api.Services public async Task> AuthenticateAsync(subsonic.Request request) { if (request == null || string.IsNullOrEmpty(request?.u)) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.WrongUsernameOrPassword, "Unknown Username"); + subsonic.ErrorCodes.WrongUsernameOrPassword, "Unknown Username"); + } + try { var user = DbContext.Users.FirstOrDefault(x => x.UserName == request.u); @@ -129,25 +126,35 @@ namespace Roadie.Api.Services var password = request.Password; if (!string.IsNullOrEmpty(request.s)) + { try { var token = HashHelper.CreateMD5((user.ApiToken ?? user.Email) + request.s); - if (!token.Equals(request.t, StringComparison.OrdinalIgnoreCase)) user = null; + if (!token.Equals(request.t, StringComparison.OrdinalIgnoreCase)) + { + user = null; + } } catch { } + } if (user != null && !string.IsNullOrEmpty(user.PasswordHash) && !string.IsNullOrEmpty(password)) + { try { var hashCheck = UserManger.PasswordHasher.VerifyHashedPassword(user, user.PasswordHash, password); - if (hashCheck == PasswordVerificationResult.Failed) user = null; + if (hashCheck == PasswordVerificationResult.Failed) + { + user = null; + } } catch { } + } if (user != null) { @@ -177,7 +184,7 @@ namespace Roadie.Api.Services catch (Exception ex) { Logger.LogError(ex, - "Subsonic.Authenticate, Error CheckPassword [" + JsonConvert.SerializeObject(request) + "]"); + $"Subsonic.Authenticate, Error CheckPassword [{JsonSerializer.Serialize(request)}]"); } return null; @@ -191,14 +198,20 @@ namespace Roadie.Api.Services Library.Models.Users.User roadieUser, int position, string comment) { if (!request.TrackId.HasValue) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track Id [{request.id}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track Id [{request.id}]"); + } + var track = GetTrack(request.TrackId.Value); if (track == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track Id [{request.TrackId.Value}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track Id [{request.TrackId.Value}]"); + } + var userBookmark = DbContext.Bookmarks.FirstOrDefault(x => - x.UserId == roadieUser.Id && x.BookmarkTargetId == track.Id && x.BookmarkType == BookmarkType.Track); + x.UserId == roadieUser.Id && x.BookmarkTargetId == track.Id && x.BookmarkType == BookmarkType.Track); var createdBookmark = false; if (userBookmark == null) { @@ -270,15 +283,21 @@ namespace Roadie.Api.Services playlist = DbContext.Playlists.Include(x => x.Tracks) .FirstOrDefault(x => x.RoadieId == request.PlaylistId); if (playlist == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid PlaylistId [{playlistId}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid PlaylistId [{playlistId}]"); + } // When Create is called again on an existing delete all existing tracks and add given if (playlist.Tracks?.Any() == true) + { DbContext.PlaylistTracks.RemoveRange(playlist.Tracks); + } + var listNumber = playlist.Tracks?.Any() == true - ? playlist.Tracks?.Max(x => x.ListNumber) ?? 0 - : 0; + ? playlist.Tracks?.Max(x => x.ListNumber) ?? 0 + : 0; foreach (var submittedTrack in submittedTracks) + { if (playlist.Tracks?.Any(x => x.TrackId == submittedTrack.Id) != true) { listNumber++; @@ -289,6 +308,7 @@ namespace Roadie.Api.Services TrackId = submittedTrack.Id }); } + } playlist.Name = name ?? playlist.Name; playlist.LastUpdated = DateTime.UtcNow; @@ -320,9 +340,8 @@ namespace Roadie.Api.Services } await DbContext.SaveChangesAsync().ConfigureAwait(false); - Logger.LogTrace( - $"Subsonic: User `{roadieUser}` {(didCreate ? "created" : "modified")} Playlist `{playlist}` added [{songRoadieIds.Length}] Tracks."); - request.id = subsonic.Request.PlaylistdIdentifier + playlist.RoadieId; + Logger.LogTrace($"Subsonic: User `{roadieUser}` {(didCreate ? "created" : "modified")} Playlist `{playlist}` added [{songRoadieIds.Length}] Tracks."); + request.id = $"{subsonic.Request.PlaylistdIdentifier}{playlist.RoadieId}"; return await GetPlaylistAsync(request, roadieUser).ConfigureAwait(false); } @@ -333,14 +352,20 @@ namespace Roadie.Api.Services Library.Models.Users.User roadieUser) { if (!request.TrackId.HasValue) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track Id [{request.id}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track Id [{request.id}]"); + } + var track = GetTrack(request.TrackId.Value); if (track == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track Id [{request.TrackId.Value}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track Id [{request.TrackId.Value}]"); + } + var userBookmark = DbContext.Bookmarks.FirstOrDefault(x => - x.UserId == roadieUser.Id && x.BookmarkTargetId == track.Id && x.BookmarkType == BookmarkType.Track); + x.UserId == roadieUser.Id && x.BookmarkTargetId == track.Id && x.BookmarkType == BookmarkType.Track); if (userBookmark != null) { DbContext.Bookmarks.Remove(userBookmark); @@ -408,12 +433,18 @@ namespace Roadie.Api.Services { var releaseId = SafeParser.ToGuid(request.id); if (!releaseId.HasValue) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.ReleaseId}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.ReleaseId}]"); + } + var release = await GetRelease(releaseId.Value).ConfigureAwait(false); if (release == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.ReleaseId}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.ReleaseId}]"); + } + var trackPagedRequest = request.PagedRequest; trackPagedRequest.Sort = "TrackNumber"; trackPagedRequest.Order = "ASC"; @@ -434,12 +465,12 @@ namespace Roadie.Api.Services Item = new subsonic.AlbumWithSongsID3 { artist = release.Artist.Name, - artistId = subsonic.Request.ArtistIdIdentifier + release.Artist.RoadieId, - coverArt = subsonic.Request.ReleaseIdIdentifier + release.RoadieId, + artistId = $"{subsonic.Request.ArtistIdIdentifier}{release.Artist.RoadieId}", + coverArt = $"{subsonic.Request.ReleaseIdIdentifier}{release.RoadieId}", created = release.CreatedDate, duration = release.Duration.ToSecondsFromMilliseconds(), genre = (genre?.Genre.Name), - id = subsonic.Request.ReleaseIdIdentifier + release.RoadieId, + id = $"{subsonic.Request.ReleaseIdIdentifier}{release.RoadieId}", name = release.Title, playCount = releaseTracks.Rows.Sum(x => x.PlayedCount) ?? 0, playCountSpecified = releaseTracks.Rows.Any(), @@ -455,7 +486,7 @@ namespace Roadie.Api.Services } catch (Exception ex) { - Logger.LogError(ex, "GetAlbum Request [{0}], User [{1}]", JsonConvert.SerializeObject(request), + Logger.LogError(ex, "GetAlbum Request [{0}], User [{1}]", JsonSerializer.Serialize(request), roadieUser.ToString()); } @@ -470,10 +501,16 @@ namespace Roadie.Api.Services { var releaseId = SafeParser.ToGuid(request.id); if (!releaseId.HasValue) + { return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.id}]"); + } + var release = await GetRelease(releaseId.Value).ConfigureAwait(false); if (release == null) + { return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.id}]"); + } + switch (version) { case subsonic.AlbumInfoVersion.One: @@ -542,7 +579,9 @@ namespace Roadie.Api.Services } if (!releaseResult.IsSuccess) + { return new subsonic.SubsonicOperationResult(releaseResult.Message); + } switch (version) { @@ -593,16 +632,22 @@ namespace Roadie.Api.Services { var artistId = SafeParser.ToGuid(request.id); if (!artistId.HasValue) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.id}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.id}]"); + } + var pagedRequest = request.PagedRequest; pagedRequest.Sort = "Id"; pagedRequest.FilterToArtistId = artistId.Value; var artistResult = await ArtistService.ListAsync(roadieUser, pagedRequest).ConfigureAwait(false); var artist = artistResult.Rows.FirstOrDefault(); if (artist == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.id}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Release [{request.id}]"); + } + var artistReleaseResult = await ReleaseService.ListAsync(roadieUser, pagedRequest).ConfigureAwait(false); return new subsonic.SubsonicOperationResult { @@ -612,8 +657,7 @@ namespace Roadie.Api.Services version = SubsonicVersion, status = subsonic.ResponseStatus.ok, ItemElementName = subsonic.ItemChoiceType.artist, - Item = SubsonicArtistWithAlbumsID3ForArtist(artist, - SubsonicAlbumID3ForReleases(artistReleaseResult.Rows)) + Item = SubsonicArtistWithAlbumsID3ForArtist(artist, SubsonicAlbumID3ForReleases(artistReleaseResult.Rows)) } }; } @@ -625,7 +669,10 @@ namespace Roadie.Api.Services { var artistId = SafeParser.ToGuid(request.id); if (!artistId.HasValue) + { return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid ArtistId [{request.id}]"); + } + var artist = await GetArtist(artistId.Value).ConfigureAwait(false); if (artist == null) { @@ -751,42 +798,68 @@ namespace Roadie.Api.Services if (request.ArtistId != null) { var artistImage = await ImageService.ArtistImageAsync(request.ArtistId.Value, size, size).ConfigureAwait(false); - if (!artistImage.IsSuccess) return artistImage.Adapt>(); + if (!artistImage.IsSuccess) + { + return artistImage.Adapt>(); + } + result.Data = new Library.Models.Image(artistImage.Data.Bytes); } else if (request.TrackId != null) { var trackimage = await ImageService.TrackImageAsync(request.TrackId.Value, size, size).ConfigureAwait(false); - if (!trackimage.IsSuccess) return trackimage.Adapt>(); + if (!trackimage.IsSuccess) + { + return trackimage.Adapt>(); + } + result.Data = new Library.Models.Image(trackimage.Data.Bytes); } else if (request.CollectionId != null) { var collectionImage = await ImageService.CollectionImageAsync(request.CollectionId.Value, size, size).ConfigureAwait(false); if (!collectionImage.IsSuccess) + { return collectionImage.Adapt>(); + } + result.Data = new Library.Models.Image(collectionImage.Data.Bytes); } else if (request.ReleaseId != null) { var releaseimage = await ImageService.ReleaseImageAsync(request.ReleaseId.Value, size, size).ConfigureAwait(false); - if (!releaseimage.IsSuccess) return releaseimage.Adapt>(); + if (!releaseimage.IsSuccess) + { + return releaseimage.Adapt>(); + } + result.Data = new Library.Models.Image(releaseimage.Data.Bytes); } else if (request.PlaylistId != null) { var playlistImage = await ImageService.PlaylistImageAsync(request.PlaylistId.Value, size, size).ConfigureAwait(false); - if (!playlistImage.IsSuccess) return playlistImage.Adapt>(); + if (!playlistImage.IsSuccess) + { + return playlistImage.Adapt>(); + } + result.Data = new Library.Models.Image(playlistImage.Data.Bytes); } else if (!string.IsNullOrEmpty(request.u)) { var user = await GetUser(request.u).ConfigureAwait(false); if (user == null) + { return new subsonic.SubsonicFileOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Username [{request.u}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Username [{request.u}]"); + } + var userImage = await ImageService.UserImageAsync(user.RoadieId, size, size).ConfigureAwait(false); - if (!userImage.IsSuccess) return userImage.Adapt>(); + if (!userImage.IsSuccess) + { + return userImage.Adapt>(); + } + result.Data = new Library.Models.Image(userImage.Data.Bytes); } @@ -925,9 +998,12 @@ namespace Roadie.Api.Services var artistId = SafeParser.ToGuid(request.id); var artist = await GetArtist(artistId.Value).ConfigureAwait(false); if (artist == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid ArtistId [{request.id}]"); - directory.id = subsonic.Request.ArtistIdIdentifier + artist.RoadieId; + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid ArtistId [{request.id}]"); + } + + directory.id = $"{subsonic.Request.ArtistIdIdentifier}{artist.RoadieId}"; directory.name = artist.Name; var artistRating = user == null ? null @@ -943,7 +1019,7 @@ namespace Roadie.Api.Services pagedRequest.Sort = "Release.Text"; var artistReleases = await ReleaseService.ListAsync(roadieUser, pagedRequest).ConfigureAwait(false); directory.child = SubsonicChildrenForReleases(artistReleases.Rows, - subsonic.Request.ArtistIdIdentifier + artist.RoadieId); + $"{subsonic.Request.ArtistIdIdentifier}{artist.RoadieId}"); } // Request to get albums for in a Collection else if (request.CollectionId != null) @@ -951,15 +1027,18 @@ namespace Roadie.Api.Services var collectionId = SafeParser.ToGuid(request.id); var collection = await GetCollection(collectionId.Value).ConfigureAwait(false); if (collection == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid CollectionId [{request.id}]"); - directory.id = subsonic.Request.CollectionIdentifier + collection.RoadieId; + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid CollectionId [{request.id}]"); + } + + directory.id = $"{subsonic.Request.CollectionIdentifier}{collection.RoadieId}"; directory.name = collection.Name; var pagedRequest = request.PagedRequest; pagedRequest.FilterToCollectionId = collection.RoadieId; var collectionReleases = await ReleaseService.ListAsync(roadieUser, pagedRequest).ConfigureAwait(false); directory.child = SubsonicChildrenForReleases(collectionReleases.Rows, - subsonic.Request.CollectionIdentifier + collection.RoadieId); + $"{subsonic.Request.CollectionIdentifier}{collection.RoadieId}"); } // Request to get Tracks for an Album else if (request.ReleaseId.HasValue) @@ -967,15 +1046,18 @@ namespace Roadie.Api.Services var releaseId = SafeParser.ToGuid(request.id); var release = await GetRelease(releaseId.Value).ConfigureAwait(false); if (release == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid ReleaseId [{request.id}]"); - directory.id = subsonic.Request.ReleaseIdIdentifier + release.RoadieId; + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid ReleaseId [{request.id}]"); + } + + directory.id = $"{subsonic.Request.ReleaseIdIdentifier}{release.RoadieId}"; directory.name = release.Title; var releaseRating = user == null ? null : await DbContext.UserReleases.FirstOrDefaultAsync(x => x.UserId == user.Id && x.ReleaseId == release.Id).ConfigureAwait(false); directory.averageRating = release.Rating ?? 0; - directory.parent = subsonic.Request.ArtistIdIdentifier + release.Artist.RoadieId; + directory.parent = $"{subsonic.Request.ArtistIdIdentifier}{release.Artist.RoadieId}"; if (releaseRating?.IsFavorite ?? false) { directory.starred = releaseRating.LastUpdated ?? releaseRating.CreatedDate; @@ -993,7 +1075,7 @@ namespace Roadie.Api.Services { return new subsonic.SubsonicOperationResult( subsonic.ErrorCodes.TheRequestedDataWasNotFound, - $"Unknown GetMusicDirectory Type [{JsonConvert.SerializeObject(request)}], id [{request.id}]"); + $"Unknown GetMusicDirectory Type [{JsonSerializer.Serialize(request)}], id [{request.id}]"); } return new subsonic.SubsonicOperationResult @@ -1082,24 +1164,26 @@ namespace Roadie.Api.Services /// /// Returns a listing of files in a saved playlist. /// - public async Task> GetPlaylistAsync(subsonic.Request request, - Library.Models.Users.User roadieUser) + public async Task> GetPlaylistAsync(subsonic.Request request, Library.Models.Users.User roadieUser) { var playListId = SafeParser.ToGuid(request.id); if (!playListId.HasValue) - return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid PlaylistId [{request.id}]"); + { + return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid PlaylistId [{request.id}]"); + } var pagedRequest = request.PagedRequest; pagedRequest.Sort = "Id"; pagedRequest.FilterToPlaylistId = playListId.Value; var playlistResult = await PlaylistService.ListAsync(pagedRequest, roadieUser).ConfigureAwait(false); var playlist = playlistResult.Rows.FirstOrDefault(); if (playlist == null) - return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid PlaylistId [{request.id}]"); + { + return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid PlaylistId [{request.id}]"); + } // For a playlist to show all the tracks in the playlist set the limit to the playlist size pagedRequest.Limit = playlist.PlaylistCount ?? pagedRequest.Limit; var tracksForPlaylist = await TrackService.ListAsync(pagedRequest, roadieUser).ConfigureAwait(false); + var detail = await SubsonicPlaylistForPlaylist(playlist, tracksForPlaylist.Rows).ConfigureAwait(false); return new subsonic.SubsonicOperationResult { IsSuccess = true, @@ -1108,7 +1192,7 @@ namespace Roadie.Api.Services version = SubsonicVersion, status = subsonic.ResponseStatus.ok, ItemElementName = subsonic.ItemChoiceType.playlist, - Item = SubsonicPlaylistForPlaylist(playlist, tracksForPlaylist.Rows) + Item = detail } }; } @@ -1296,16 +1380,22 @@ namespace Roadie.Api.Services Library.Models.Users.User roadieUser) { if (!request.TrackId.HasValue) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track [{request.id}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track [{request.id}]"); + } + var pagedRequest = request.PagedRequest; pagedRequest.FilterToTrackId = request.TrackId.Value; pagedRequest.Sort = "Id"; var trackResult = await TrackService.ListAsync(pagedRequest, roadieUser).ConfigureAwait(false); var track = trackResult.Rows.FirstOrDefault(); if (track == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track [{request.id}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Track [{request.id}]"); + } + return new subsonic.SubsonicOperationResult { IsSuccess = true, @@ -1413,11 +1503,20 @@ namespace Roadie.Api.Services { data.Artist artist = null; if (!string.IsNullOrEmpty(request.ArtistName)) + { artist = await GetArtist(request.ArtistName).ConfigureAwait(false); - else if (request.ArtistId.HasValue) artist = await GetArtist(request.ArtistId.Value).ConfigureAwait(false); + } + else if (request.ArtistId.HasValue) + { + artist = await GetArtist(request.ArtistId.Value).ConfigureAwait(false); + } + if (artist == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Unknown Artist [{request.ArtistName}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Unknown Artist [{request.ArtistName}]"); + } + var pagedRequest = request.PagedRequest; pagedRequest.FilterToArtistId = artist.RoadieId; pagedRequest.FilterTopPlayedOnly = true; @@ -1449,8 +1548,11 @@ namespace Roadie.Api.Services { var user = await GetUser(username).ConfigureAwait(false); if (user == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Username [{username}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Username [{username}]"); + } + return new subsonic.SubsonicOperationResult { IsSuccess = true, @@ -1559,7 +1661,7 @@ namespace Roadie.Api.Services public async Task> SearchAsync(subsonic.Request request, Library.Models.Users.User roadieUser, subsonic.SearchVersion version) { - var query = HttpEncoder.UrlDecode(request.Query).Replace("*", "").Replace("%", "").Replace(";", ""); + var query = HttpEncoder.UrlDecode(request.Query).Replace("*", string.Empty).Replace("%", string.Empty).Replace(";", string.Empty); // Search artists with query returning ArtistCount skipping ArtistOffset var artistPagedRequest = request.PagedRequest; @@ -1644,44 +1746,52 @@ namespace Roadie.Api.Services { var user = await GetUser(roadieUser.UserId).ConfigureAwait(false); if (user == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.UserIsNotAuthorizedForGivenOperation, $"Invalid User [{roadieUser}]"); + subsonic.ErrorCodes.UserIsNotAuthorizedForGivenOperation, $"Invalid User [{roadieUser}]"); + } // Id can be a song, album or artist if (request.TrackId.HasValue) { var starResult = await SetTrackRating(request.TrackId.Value, user, rating).ConfigureAwait(false); if (starResult.IsSuccess) + { return new subsonic.SubsonicOperationResult { IsSuccess = true, Data = new subsonic.Response() }; + } } else if (request.ReleaseId.HasValue) { var starResult = await SetReleaseRating(request.ReleaseId.Value, user, rating).ConfigureAwait(false); if (starResult.IsSuccess) + { return new subsonic.SubsonicOperationResult { IsSuccess = true, Data = new subsonic.Response() }; + } } else if (request.ArtistId.HasValue) { var starResult = await SetArtistRating(request.ArtistId.Value, user, rating).ConfigureAwait(false); if (starResult.IsSuccess) + { return new subsonic.SubsonicOperationResult { IsSuccess = true, Data = new subsonic.Response() }; + } } return new subsonic.SubsonicOperationResult( subsonic.ErrorCodes.TheRequestedDataWasNotFound, - $"Unknown Star Id [{JsonConvert.SerializeObject(request)}]"); + $"Unknown Star Id [{JsonSerializer.Serialize(request)}]"); } /// @@ -1692,39 +1802,47 @@ namespace Roadie.Api.Services { var user = await GetUser(roadieUser.UserId).ConfigureAwait(false); if (user == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.UserIsNotAuthorizedForGivenOperation, $"Invalid User [{roadieUser}]"); + subsonic.ErrorCodes.UserIsNotAuthorizedForGivenOperation, $"Invalid User [{roadieUser}]"); + } // Id can be a song, album or artist if (request.TrackId.HasValue) { var starResult = await ToggleTrackStar(request.TrackId.Value, user, star).ConfigureAwait(false); if (starResult.IsSuccess) + { return new subsonic.SubsonicOperationResult { IsSuccess = true, Data = new subsonic.Response() }; + } } else if (request.ReleaseId.HasValue) { var starResult = await ToggleReleaseStar(request.ReleaseId.Value, user, star).ConfigureAwait(false); if (starResult.IsSuccess) + { return new subsonic.SubsonicOperationResult { IsSuccess = true, Data = new subsonic.Response() }; + } } else if (request.ArtistId.HasValue) { var starResult = await ToggleArtistStar(request.ArtistId.Value, user, star).ConfigureAwait(false); if (starResult.IsSuccess) + { return new subsonic.SubsonicOperationResult { IsSuccess = true, Data = new subsonic.Response() }; + } } else if (albumIds?.Any() == true) { @@ -1735,8 +1853,10 @@ namespace Roadie.Api.Services { var starResult = await ToggleReleaseStar(releaseId.Value, user, star).ConfigureAwait(false); if (!starResult.IsSuccess) + { return new subsonic.SubsonicOperationResult(starResult.ErrorCode.Value, - starResult.Messages.FirstOrDefault()); + starResult.Messages.FirstOrDefault()); + } } } } @@ -1749,15 +1869,17 @@ namespace Roadie.Api.Services { var starResult = await ToggleReleaseStar(artistId.Value, user, star).ConfigureAwait(false); if (!starResult.IsNotFoundResult) + { return new subsonic.SubsonicOperationResult(starResult.ErrorCode.Value, - starResult.Messages.FirstOrDefault()); + starResult.Messages.FirstOrDefault()); + } } } } return new subsonic.SubsonicOperationResult( subsonic.ErrorCodes.TheRequestedDataWasNotFound, - $"Unknown Star Id [{JsonConvert.SerializeObject(request)}]"); + $"Unknown Star Id [{JsonSerializer.Serialize(request)}]"); } /// @@ -1776,16 +1898,24 @@ namespace Roadie.Api.Services { request.id = playListId ?? request.id; if (!request.PlaylistId.HasValue) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Playlist Id [{request.id}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Playlist Id [{request.id}]"); + } + var playlist = await GetPlaylist(request.PlaylistId.Value).ConfigureAwait(false); if (playlist == null) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Playlist Id [{request.TrackId.Value}]"); + subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Playlist Id [{request.TrackId.Value}]"); + } + if (playlist.UserId != roadieUser.Id && !roadieUser.IsAdmin) + { return new subsonic.SubsonicOperationResult( - subsonic.ErrorCodes.UserIsNotAuthorizedForGivenOperation, - "User is not allowed to update playlist."); + subsonic.ErrorCodes.UserIsNotAuthorizedForGivenOperation, + "User is not allowed to update playlist."); + } playlist.Name = name ?? playlist.Name; playlist.IsPublic = isPublic ?? playlist.IsPublic; @@ -1801,6 +1931,7 @@ namespace Roadie.Api.Services var listNumber = playlist.Tracks?.Max(x => x.ListNumber) ?? 0; foreach (var submittedTrack in submittedTracks) + { if (playlist.Tracks == null || playlist.Tracks?.Any(x => x.TrackId == submittedTrack.Id) != true) { listNumber++; @@ -1811,12 +1942,15 @@ namespace Roadie.Api.Services TrackId = submittedTrack.Id }); } + } } if (songIndexesToRemove?.Any() == true) + { // Remove tracks from playlist // Not clear from API documentation if this is zero based, wait until someone calls it to get values passed. - throw new NotImplementedException($"Request [{JsonConvert.SerializeObject(request)}]"); + throw new NotImplementedException($"Request [{JsonSerializer.Serialize(request)}]"); + } await DbContext.SaveChangesAsync().ConfigureAwait(false); @@ -1836,21 +1970,25 @@ namespace Roadie.Api.Services #region Privates - private async Task AllowedUsers() + private Task AllowedUsers() { - return await CacheManager.GetAsync(CacheManagerBase.SystemCacheRegionUrn + ":active_usernames", async () => - { - return await DbContext.Users.Where(x => x.IsActive ?? false).Select(x => x.UserName).ToArrayAsync().ConfigureAwait(false); - }, CacheManagerBase.SystemCacheRegionUrn).ConfigureAwait(false); + return CacheManager.GetAsync(CacheManagerBase.SystemCacheRegionUrn + ":active_usernames", async () => await DbContext.Users.Where(x => x.IsActive ?? false).Select(x => x.UserName).ToArrayAsync().ConfigureAwait(false), CacheManagerBase.SystemCacheRegionUrn); } + //private async Task AllowedUsers() + //{ + // return await CacheManager.GetAsync(CacheManagerBase.SystemCacheRegionUrn + ":active_usernames", async () => + // { + // return await DbContext.Users.Where(x => x.IsActive ?? false).Select(x => x.UserName).ToArrayAsync().ConfigureAwait(false); + // }, CacheManagerBase.SystemCacheRegionUrn).ConfigureAwait(false); + //} + private subsonic.MusicFolder CollectionMusicFolder() { return MusicFolders().First(x => x.id == 1); } - private async Task> GetArtistsAction( - subsonic.Request request, Library.Models.Users.User roadieUser) + private async Task> GetArtistsAction(subsonic.Request request, Library.Models.Users.User roadieUser) { var indexes = new List(); var musicFolder = MusicFolders().Find(x => x.id == (request.MusicFolderId ?? 2)); @@ -1867,12 +2005,13 @@ namespace Roadie.Api.Services pagedRequest.Sort = "Artist.Text"; var artistList = await ArtistService.ListAsync(roadieUser, pagedRequest).ConfigureAwait(false); foreach (var artistGroup in artistList.Rows.GroupBy(x => x.Artist.Text.Substring(0, 1))) + { indexes.Add(new subsonic.IndexID3 { name = artistGroup.Key, artist = SubsonicArtistID3sForArtists(artistGroup) }); - ; + } } return new subsonic.SubsonicOperationResult @@ -1894,8 +2033,7 @@ namespace Roadie.Api.Services private async Task> GetIndexesAction( subsonic.Request request, Library.Models.Users.User roadieUser, long? ifModifiedSince = null) { - var modifiedSinceFilter = - ifModifiedSince.HasValue ? (DateTime?)ifModifiedSince.Value.FromUnixTime() : null; + var modifiedSinceFilter = ifModifiedSince?.FromUnixTime(); var musicFolderFilter = !request.MusicFolderId.HasValue ? new subsonic.MusicFolder() : MusicFolders().Find(x => x.id == request.MusicFolderId.Value); @@ -1908,6 +2046,7 @@ namespace Roadie.Api.Services let first = c.Name.Substring(0, 1) orderby first select first).Distinct().ToArray()) + { indexes.Add(new subsonic.Index { name = collectionFirstLetter, @@ -1924,6 +2063,7 @@ namespace Roadie.Api.Services userRating = 0 }).ToArray() }); + } } else { @@ -1934,12 +2074,13 @@ namespace Roadie.Api.Services pagedRequest.Sort = "Artist.Text"; var artistList = await ArtistService.ListAsync(roadieUser, pagedRequest).ConfigureAwait(false); foreach (var artistGroup in artistList.Rows.GroupBy(x => x.Artist.Text.Substring(0, 1))) + { indexes.Add(new subsonic.Index { name = artistGroup.Key, artist = SubsonicArtistsForArtists(artistGroup) }); - ; + } } return new subsonic.SubsonicOperationResult @@ -1968,18 +2109,13 @@ namespace Roadie.Api.Services }; } - private subsonic.MusicFolder MusicMusicFolder() - { - return MusicFolders().First(x => x.id == 2); - } - - private new async Task> SetArtistRating(Guid artistId, - Library.Identity.User user, short rating) + private new async Task> SetArtistRating(Guid artistId, Library.Identity.User user, short rating) { var r = await base.SetArtistRating(artistId, user, rating).ConfigureAwait(false); if (r.IsNotFoundResult) - return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, - $"Invalid Artist Id [{artistId}]"); + { + return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, $"Invalid Artist Id [{artistId}]"); + } return new subsonic.SubsonicOperationResult { IsSuccess = r.IsSuccess, @@ -1992,8 +2128,11 @@ namespace Roadie.Api.Services { var r = await base.SetReleaseRating(releaseId, user, rating).ConfigureAwait(false); if (r.IsNotFoundResult) + { return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, - $"Invalid Release Id [{releaseId}]"); + $"Invalid Release Id [{releaseId}]"); + } + return new subsonic.SubsonicOperationResult { IsSuccess = r.IsSuccess, @@ -2006,8 +2145,11 @@ namespace Roadie.Api.Services { var r = await base.SetTrackRating(trackId, user, rating).ConfigureAwait(false); if (r.IsNotFoundResult) + { return new subsonic.SubsonicOperationResult(subsonic.ErrorCodes.TheRequestedDataWasNotFound, - $"Invalid Track Id [{trackId}]"); + $"Invalid Track Id [{trackId}]"); + } + return new subsonic.SubsonicOperationResult { IsSuccess = r.IsSuccess, @@ -2019,13 +2161,13 @@ namespace Roadie.Api.Services { return new subsonic.AlbumID3 { - id = subsonic.Request.ReleaseIdIdentifier + r.Id, + id = $"{subsonic.Request.ReleaseIdIdentifier}{r.Id}", artistId = r.Artist.Value, name = r.Release.Text, songCount = r.TrackCount ?? 0, duration = r.Duration.ToSecondsFromMilliseconds(), artist = r.Artist.Text, - coverArt = subsonic.Request.ReleaseIdIdentifier + r.Id, + coverArt = $"{subsonic.Request.ReleaseIdIdentifier}{r.Id}", created = r.CreatedDate.Value, genre = r.Genre.Text, playCount = r.TrackPlayedCount ?? 0, @@ -2039,7 +2181,11 @@ namespace Roadie.Api.Services private subsonic.AlbumID3[] SubsonicAlbumID3ForReleases(IEnumerable r) { - if (r == null || !r.Any()) return new subsonic.AlbumID3[0]; + if (r?.Any() != true) + { + return new subsonic.AlbumID3[0]; + } + return r.Select(x => SubsonicAlbumID3ForRelease(x)).ToArray(); } @@ -2047,7 +2193,7 @@ namespace Roadie.Api.Services { return new subsonic.Artist { - id = subsonic.Request.ArtistIdIdentifier + artist.Artist.Value, + id = $"{subsonic.Request.ArtistIdIdentifier}{artist.Artist.Value}", name = artist.Artist.Text, artistImageUrl = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, artist.Id).Url, averageRating = artist.Rating ?? 0, @@ -2055,7 +2201,7 @@ namespace Roadie.Api.Services starred = artist.UserRating?.RatedDate ?? DateTime.UtcNow, starredSpecified = artist.UserRating?.IsFavorite ?? false, userRating = artist.UserRating != null ? artist.UserRating.Rating ?? 0 : 0, - userRatingSpecified = artist.UserRating != null && artist.UserRating.Rating != null + userRatingSpecified = artist.UserRating?.Rating != null }; } @@ -2064,7 +2210,7 @@ namespace Roadie.Api.Services var artistImageUrl = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, artist.Id).Url; return new subsonic.ArtistID3 { - id = subsonic.Request.ArtistIdIdentifier + artist.Artist.Value, + id = $"{subsonic.Request.ArtistIdIdentifier}{artist.Artist.Value}", name = artist.Artist.Text, albumCount = artist.ReleaseCount ?? 0, coverArt = artistImageUrl, @@ -2076,7 +2222,11 @@ namespace Roadie.Api.Services private subsonic.ArtistID3[] SubsonicArtistID3sForArtists(IEnumerable artists) { - if (artists == null || !artists.Any()) return new subsonic.ArtistID3[0]; + if (artists?.Any() != true) + { + return new subsonic.ArtistID3[0]; + } + return artists.Select(x => SubsonicArtistID3ForArtist(x)).ToArray(); } @@ -2085,11 +2235,11 @@ namespace Roadie.Api.Services return new subsonic.ArtistInfo2 { biography = artist.BioContext, - largeImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, "artist", Configuration.LargeImageSize).Url, - mediumImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, "artist", Configuration.MediumImageSize).Url, + largeImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, nameof(artist), Configuration.LargeImageSize).Url, + mediumImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, nameof(artist), Configuration.MediumImageSize).Url, musicBrainzId = artist.MusicBrainzId, similarArtist = new subsonic.ArtistID3[0], - smallImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, "artist", Configuration.SmallImageSize).Url + smallImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, nameof(artist), Configuration.SmallImageSize).Url }; } @@ -2098,29 +2248,32 @@ namespace Roadie.Api.Services return new subsonic.ArtistInfo { biography = artist.BioContext, - largeImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, "artist", Configuration.LargeImageSize).Url, - mediumImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, "artist", Configuration.MediumImageSize).Url, + largeImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, nameof(artist), Configuration.LargeImageSize).Url, + mediumImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, nameof(artist), Configuration.MediumImageSize).Url, musicBrainzId = artist.MusicBrainzId, similarArtist = new subsonic.Artist[0], - smallImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, "artist", Configuration.SmallImageSize).Url + smallImageUrl = ImageHelper.MakeImage(Configuration, HttpContext, artist.RoadieId, nameof(artist), Configuration.SmallImageSize).Url }; } private subsonic.Artist[] SubsonicArtistsForArtists(IEnumerable artists) { - if (artists == null || !artists.Any()) return new subsonic.Artist[0]; + if (artists?.Any() != true) + { + return new subsonic.Artist[0]; + } + return artists.Select(x => SubsonicArtistForArtist(x)).ToArray(); } - private subsonic.ArtistWithAlbumsID3 SubsonicArtistWithAlbumsID3ForArtist(ArtistList artist, - subsonic.AlbumID3[] releases) + private subsonic.ArtistWithAlbumsID3 SubsonicArtistWithAlbumsID3ForArtist(ArtistList artist, subsonic.AlbumID3[] releases) { var artistImageUrl = ImageHelper.MakeArtistThumbnailImage(Configuration, HttpContext, artist.Id).Url; return new subsonic.ArtistWithAlbumsID3 { - id = subsonic.Request.ArtistIdIdentifier + artist.Artist.Value, + id = $"{subsonic.Request.ArtistIdIdentifier}{artist.Artist.Value}", album = releases, - albumCount = releases.Count(), + albumCount = releases.Length, artistImageUrl = artistImageUrl, coverArt = artistImageUrl, name = artist.Artist.Text, @@ -2145,7 +2298,11 @@ namespace Roadie.Api.Services private subsonic.Bookmark[] SubsonicBookmarksForBookmarks(IEnumerable bb, IEnumerable childTracks) { - if (bb == null || !bb.Any()) return new subsonic.Bookmark[0]; + if (bb?.Any() != true) + { + return new subsonic.Bookmark[0]; + } + var result = new List(); foreach (var bookmark in bb) { @@ -2153,8 +2310,7 @@ namespace Roadie.Api.Services switch (bookmark.Type.Value) { case BookmarkType.Track: - child = SubsonicChildForTrack(childTracks.FirstOrDefault(x => - x.Id == SafeParser.ToGuid(bookmark.Bookmark.Value))); + child = SubsonicChildForTrack(childTracks.FirstOrDefault(x => x.Id == SafeParser.ToGuid(bookmark.Bookmark.Value))); break; default: @@ -2171,13 +2327,13 @@ namespace Roadie.Api.Services { return new subsonic.Child { - id = subsonic.Request.ReleaseIdIdentifier + r.Id, + id = $"{subsonic.Request.ReleaseIdIdentifier}{r.Id}", album = r.Release.Text, - albumId = subsonic.Request.ReleaseIdIdentifier + r.Id, + albumId = $"{subsonic.Request.ReleaseIdIdentifier}{r.Id}", artist = r.Artist.Text, averageRating = r.Rating ?? 0, averageRatingSpecified = true, - coverArt = subsonic.Request.ReleaseIdIdentifier + r.Id, + coverArt = $"{subsonic.Request.ReleaseIdIdentifier}{r.Id}", created = r.CreatedDate.Value, createdSpecified = true, genre = r.Genre.Text, @@ -2190,7 +2346,7 @@ namespace Roadie.Api.Services starredSpecified = r.UserRating?.IsFavorite ?? false, title = r.Release.Text, userRating = r.UserRating != null ? r.UserRating.Rating ?? 0 : 0, - userRatingSpecified = r.UserRating != null && r.UserRating.Rating != null, + userRatingSpecified = r.UserRating?.Rating != null, year = SafeParser.ToNumber(r.ReleaseYear), yearSpecified = true }; @@ -2208,17 +2364,17 @@ namespace Roadie.Api.Services } return new subsonic.Child { - id = subsonic.Request.TrackIdIdentifier + t.Id, + id = $"{subsonic.Request.TrackIdIdentifier}{t.Id}", album = t.Release.Release.Text, - albumId = subsonic.Request.ReleaseIdIdentifier + t.Release.Release.Value, + albumId = $"{subsonic.Request.ReleaseIdIdentifier}{t.Release.Release.Value}", artist = t.Artist.Artist.Text, - artistId = subsonic.Request.ArtistIdIdentifier + t.Artist.Artist.Value, + artistId = $"{subsonic.Request.ArtistIdIdentifier}{t.Artist.Artist.Value}", averageRating = t.Rating ?? 0, averageRatingSpecified = true, bitRate = 320, bitRateSpecified = true, contentType = MimeTypeHelper.Mp3MimeType, - coverArt = subsonic.Request.TrackIdIdentifier + t.Id, + coverArt = $"{subsonic.Request.TrackIdIdentifier}{t.Id}", created = t.CreatedDate.Value, createdSpecified = true, discNumber = t.MediaNumber ?? 0, @@ -2226,7 +2382,7 @@ namespace Roadie.Api.Services duration = t.Duration.ToSecondsFromMilliseconds(), durationSpecified = true, isDir = false, - parent = subsonic.Request.ReleaseIdIdentifier + t.Release.Release.Value, + parent = $"{subsonic.Request.ReleaseIdIdentifier}{t.Release.Release.Value}", path = $"{t.Artist.Artist.Text}/{t.Release.Release.Text}/{t.TrackNumber} - {t.Title}.mp3", playCountSpecified = true, size = t.FileSize ?? 0, @@ -2253,13 +2409,19 @@ namespace Roadie.Api.Services private subsonic.Child[] SubsonicChildrenForReleases(IEnumerable r, string parent) { - if (r == null || !r.Any()) return new subsonic.Child[0]; + if (r?.Any() != true) + { + return new subsonic.Child[0]; + } return r.Select(x => SubsonicChildForRelease(x, parent, $"{x.Artist.Text}/{x.Release.Text}/")).ToArray(); } private subsonic.Child[] SubsonicChildrenForTracks(IEnumerable tracks) { - if (tracks == null || !tracks.Any()) return new subsonic.Child[0]; + if (tracks?.Any() != true) + { + return new subsonic.Child[0]; + } return tracks.Select(x => SubsonicChildForTrack(x)).ToArray(); } @@ -2272,7 +2434,7 @@ namespace Roadie.Api.Services changed = playlist.LastUpdated ?? playlist.CreatedDate ?? DateTime.UtcNow, created = playlist.CreatedDate ?? DateTime.UtcNow, duration = playlist.Duration.ToSecondsFromMilliseconds(), - id = subsonic.Request.PlaylistdIdentifier + playlist.Id, + id = $"{subsonic.Request.PlaylistdIdentifier}{playlist.Id}", name = playlist.Playlist.Text, owner = playlist.User.Text, @public = playlist.IsPublic, @@ -2289,7 +2451,7 @@ namespace Roadie.Api.Services return new subsonic.Playlist[0]; } var result = new List(); - foreach(var playlist in playlists) + foreach (var playlist in playlists) { result.Add(await SubsonicPlaylistForPlaylist(playlist).ConfigureAwait(false)); } diff --git a/Roadie.Api.Services/TrackService.cs b/Roadie.Api.Services/TrackService.cs index bd61a5d..1e9954b 100644 --- a/Roadie.Api.Services/TrackService.cs +++ b/Roadie.Api.Services/TrackService.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Library; using Roadie.Library.Caching; using Roadie.Library.Configuration; @@ -24,6 +23,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Linq.Dynamic.Core; +using System.Text.Json; using System.Threading.Tasks; using data = Roadie.Library.Data; @@ -791,7 +791,7 @@ namespace Roadie.Api.Services } catch (Exception ex) { - Logger.LogError(ex, "Error In List, Request [{0}], User [{1}]", JsonConvert.SerializeObject(request), roadieUser); + Logger.LogError(ex, "Error In List, Request [{0}], User [{1}]", JsonSerializer.Serialize(request), roadieUser); return new Library.Models.Pagination.PagedResult { Message = "An Error has occured" diff --git a/Roadie.Api.Services/UserService.cs b/Roadie.Api.Services/UserService.cs index 3351cdd..91f3cfe 100644 --- a/Roadie.Api.Services/UserService.cs +++ b/Roadie.Api.Services/UserService.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Library; using Roadie.Library.Caching; using Roadie.Library.Configuration; @@ -23,6 +22,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Linq.Dynamic.Core; +using System.Text.Json; using System.Threading.Tasks; using data = Roadie.Library.Data; using models = Roadie.Library.Models; @@ -593,7 +593,7 @@ namespace Roadie.Api.Services result.AdditionalData.Add("Timing", sw.ElapsedMilliseconds); Logger.LogTrace( - $"User `{roadieUser}` set rating [{rating}] on TrackId [{trackId}]. Result [{JsonConvert.SerializeObject(result)}]"); + $"User `{roadieUser}` set rating [{rating}] on TrackId [{trackId}]. Result [{JsonSerializer.Serialize(result)}]"); return result; } diff --git a/Roadie.Api/Controllers/EntityControllerBase.cs b/Roadie.Api/Controllers/EntityControllerBase.cs index d94785c..06debd2 100644 --- a/Roadie.Api/Controllers/EntityControllerBase.cs +++ b/Roadie.Api/Controllers/EntityControllerBase.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Api.Services; using Roadie.Library.Caching; using Roadie.Library.Configuration; @@ -13,6 +12,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; +using System.Text.Json; using System.Threading.Tasks; using models = Roadie.Library.Models.Users; @@ -146,7 +146,7 @@ namespace Roadie.Api.Controllers }; await playActivityService.NowPlayingAsync(user, scrobble).ConfigureAwait(false); sw.Stop(); - Logger.LogTrace($"StreamTrack ElapsedTime [{sw.ElapsedMilliseconds}], Timings [{JsonConvert.SerializeObject(timings)}], StreamInfo `{info?.Data}`"); + Logger.LogTrace($"StreamTrack ElapsedTime [{sw.ElapsedMilliseconds}], Timings [{JsonSerializer.Serialize(timings)}], StreamInfo `{info?.Data}`"); return new EmptyResult(); } diff --git a/Roadie.Api/Controllers/SubsonicController.cs b/Roadie.Api/Controllers/SubsonicController.cs index e60ac3e..69e4b80 100644 --- a/Roadie.Api/Controllers/SubsonicController.cs +++ b/Roadie.Api/Controllers/SubsonicController.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Api.ModelBinding; using Roadie.Api.Services; using Roadie.Library.Caching; @@ -15,6 +14,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; +using System.Text.Json; using System.Threading.Tasks; using User = Roadie.Library.Models.Users.User; @@ -364,7 +364,7 @@ namespace Roadie.Api.Controllers if (!result.IsSuccess) { - Logger.LogWarning($"GetCoverArt Failed For [{JsonConvert.SerializeObject(request)}]"); + Logger.LogWarning($"GetCoverArt Failed For [{ JsonSerializer.Serialize(request)}]"); return StatusCode((int)HttpStatusCode.InternalServerError); } @@ -901,7 +901,7 @@ namespace Roadie.Api.Controllers } else { - jsonResult = $"{{ \"subsonic-response\": {{ \"status\":\"{status}\", \"version\": \"{version}\", \"{responseType}\":{((response?.Data != null ? JsonConvert.SerializeObject(response.Data.Item) : string.Empty))}}}}}"; + jsonResult = $"{{ \"subsonic-response\": {{ \"status\":\"{status}\", \"version\": \"{version}\", \"{responseType}\":{((response?.Data != null ? JsonSerializer.Serialize(response.Data.Item) : string.Empty))}}}}}"; } if ((request?.f ?? string.Empty).Equals("jsonp", StringComparison.OrdinalIgnoreCase)) diff --git a/Roadie.Api/Controllers/UserController.cs b/Roadie.Api/Controllers/UserController.cs index b5822a4..2343c2f 100644 --- a/Roadie.Api/Controllers/UserController.cs +++ b/Roadie.Api/Controllers/UserController.cs @@ -21,9 +21,7 @@ namespace Roadie.Api.Controllers [Authorize] public class UserController : EntityControllerBase { - private IHttpContext RoadieHttpContext { get; } - private IUserService UserService { get; } private readonly ITokenService TokenService; @@ -65,8 +63,14 @@ namespace Roadie.Api.Controllers public async Task Get(Guid id, string inc = null) { var user = await CurrentUserModel().ConfigureAwait(false); - var result = await CacheManager.GetAsync($"urn:user_model_by_id:{id}", - async () => await UserService.ByIdAsync(user, id, (inc ?? Library.Models.Users.User.DefaultIncludes).ToLower().Split(",")).ConfigureAwait(false), ControllerCacheRegionUrn).ConfigureAwait(false); + var result = await CacheManager.GetAsync($"urn:user_model_by_id:{id}", async () => + { + return await UserService.ByIdAsync(user, id, (inc ?? Library.Models.Users.User.DefaultIncludes) + .ToLower() + .Split(",")) + .ConfigureAwait(false); + }, + ControllerCacheRegionUrn).ConfigureAwait(false); if (result?.IsNotFoundResult != false) { return NotFound(); @@ -386,11 +390,5 @@ namespace Roadie.Api.Controllers DefaultRowsPerPage = modelUser.DefaultRowsPerPage ?? RoadieSettings.DefaultRowsPerPage }); } - - public class PagingParams - { - public int Limit { get; set; } = 5; - public int Page { get; set; } = 1; - } } } \ No newline at end of file diff --git a/Roadie.Api/Program.cs b/Roadie.Api/Program.cs index f9427bb..a3d6ab8 100644 --- a/Roadie.Api/Program.cs +++ b/Roadie.Api/Program.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; +using Pastel; using Serilog; using System; using System.Diagnostics; @@ -31,19 +32,19 @@ namespace Roadie.Api #if DEBUG // Logging Output tests - Log.Verbose(":: Log Test: Verbose (Trace,None)"); // Microsoft.Extensions.Logging.LogLevel.Trace and Microsoft.Extensions.Logging.LogLevel.None - Log.Debug(":: Log Test: Debug"); // Microsoft.Extensions.Logging.LogLevel.Debug - Log.Information(":: Log Test: Information"); // Microsoft.Extensions.Logging.LogLevel.Information - Log.Warning(":: Log Test: Warning"); // Microsoft.Extensions.Logging.LogLevel.Warning - Log.Error(new Exception("Log Test Exception"), "Log Test Error Message"); // Microsoft.Extensions.Logging.LogLevel.Error - Log.Fatal(":: Log Test: Fatal (Critial)"); // Microsoft.Extensions.Logging.LogLevel.Critical - Trace.WriteLine(":: Log Test: Trace WriteLine()"); + Log.Verbose(":: Log Test: Verbose (Trace,None), Test 'value', Test: Value"); // Microsoft.Extensions.Logging.LogLevel.Trace and Microsoft.Extensions.Logging.LogLevel.None + Log.Debug(":: Log Test: Debug, Test 'value', Test: Value"); // Microsoft.Extensions.Logging.LogLevel.Debug + Log.Information(":: Log Test: Information, Test 'value', Test: Value"); // Microsoft.Extensions.Logging.LogLevel.Information + Log.Warning(":: Log Test: Warning, Test 'value', Test: Value"); // Microsoft.Extensions.Logging.LogLevel.Warning + Log.Error(new Exception("Log Test Exception"), "Log Test Error Message, Test 'value', Test: Value"); // Microsoft.Extensions.Logging.LogLevel.Error + Log.Fatal(":: Log Test: Fatal (Critial), Test 'value', Test: Value"); // Microsoft.Extensions.Logging.LogLevel.Critical + Trace.WriteLine(":: Log Test: Trace WriteLine(), Test 'value', Test: Value"); #endif Console.WriteLine(""); - Console.WriteLine(@" ____ __ __ ____ __ ____ __ ____ __ "); - Console.WriteLine(@"( _ \ / \ / _\ ( \( )( __) / _\ ( _ \( ) "); - Console.WriteLine(@" ) /( O )/ \ ) D ( )( ) _) / \ ) __/ )( "); - Console.WriteLine(@"(__\_) \__/ \_/\_/(____/(__)(____) \_/\_/(__) (__) "); + Console.WriteLine(@" ____ __ __ ____ __ ____ __ ____ __ ".Pastel("#FEFF0E")); + Console.WriteLine(@"( _ \ / \ / _\ ( \( )( __) / _\ ( _ \( ) ".Pastel("#F49014")); + Console.WriteLine(@" ) /( O )/ \ ) D ( )( ) _) / \ ) __/ )( ".Pastel("#E30014")); + Console.WriteLine(@"(__\_) \__/ \_/\_/(____/(__)(____) \_/\_/(__) (__) ".Pastel("#DB0083")); Console.WriteLine(""); CreateHostBuilder(args).Build().Run(); diff --git a/Roadie.Api/Roadie.Api.csproj b/Roadie.Api/Roadie.Api.csproj index 7f93191..e2904f5 100644 --- a/Roadie.Api/Roadie.Api.csproj +++ b/Roadie.Api/Roadie.Api.csproj @@ -1,7 +1,7 @@  - 1.1.2 + 1.1.3 @@ -31,15 +31,16 @@ - - + + - - - + + + + @@ -49,7 +50,7 @@ - + diff --git a/Roadie.Api/RoadieSerilogThemes.cs b/Roadie.Api/RoadieSerilogThemes.cs new file mode 100644 index 0000000..d9e9616 --- /dev/null +++ b/Roadie.Api/RoadieSerilogThemes.cs @@ -0,0 +1,33 @@ +using Serilog.Sinks.SystemConsole.Themes; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Roadie.Api +{ + public static class RoadieSerilogThemes + { + public static AnsiConsoleTheme RoadieRainbow { get; } = new AnsiConsoleTheme( + new Dictionary + { + [ConsoleThemeStyle.Text] = "\x1b[38;5;0034m", + [ConsoleThemeStyle.SecondaryText] = "\x1b[38;5;0025m", + [ConsoleThemeStyle.TertiaryText] = "\x1b[38;5;0089m", + [ConsoleThemeStyle.Invalid] = "\x1b[38;5;0126m", + [ConsoleThemeStyle.Null] = "\x1b[38;5;0100m", + [ConsoleThemeStyle.Name] = "\x1b[38;5;0007m", + [ConsoleThemeStyle.String] = "\x1b[38;5;0117m", + [ConsoleThemeStyle.Number] = "\x1b[38;5;0200m", + [ConsoleThemeStyle.Boolean] = "\x1b[38;5;0027m", + [ConsoleThemeStyle.Scalar] = "\x1b[38;5;0085m", + [ConsoleThemeStyle.LevelVerbose] = "\x1b[38;5;0007m", + [ConsoleThemeStyle.LevelDebug] = "\x1b[38;5;0015m", + [ConsoleThemeStyle.LevelInformation] = "\x1b[38;5;0015m", + [ConsoleThemeStyle.LevelWarning] = "\x1b[38;5;0011m", + [ConsoleThemeStyle.LevelError] = "\x1b[38;5;0015m\x1b[48;5;0196m", + [ConsoleThemeStyle.LevelFatal] = "\x1b[38;5;0011m\x1b[48;5;0009m", + } + ); + } +} diff --git a/Roadie.Api/Startup.cs b/Roadie.Api/Startup.cs index 2e720b9..7761180 100644 --- a/Roadie.Api/Startup.cs +++ b/Roadie.Api/Startup.cs @@ -16,7 +16,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; -using Newtonsoft.Json; using Roadie.Api.Hubs; using Roadie.Api.ModelBinding; using Roadie.Api.Services; @@ -113,10 +112,17 @@ namespace Roadie.Api services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(options => + { + var logger = options.GetService>(); + return new Utf8JsonCacheSerializer(logger); + }); + services.AddSingleton(options => { var logger = options.GetService>(); - return new MemoryCacheManager(logger, new CachePolicy(TimeSpan.FromHours(4))); + var serializer = options.GetService(); + return new MemoryCacheManager(logger, serializer, new CachePolicy(TimeSpan.FromHours(4))); }); var dbFolder = new DirectoryInfo(settings.FileDatabaseOptions.DatabaseFolder); @@ -326,11 +332,7 @@ namespace Roadie.Api options.RespectBrowserAcceptHeader = true; // false by default options.ModelBinderProviders.Insert(0, new SubsonicRequestBinderProvider()); }) - .AddNewtonsoftJson(options => - { - options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; - options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; - }) + .AddJsonOptions(options => options.JsonSerializerOptions.IgnoreNullValues = true) .AddXmlSerializerFormatters(); services.Configure(options => diff --git a/Roadie.Api/appsettings.json b/Roadie.Api/appsettings.json index 917ad66..94bfef0 100644 --- a/Roadie.Api/appsettings.json +++ b/Roadie.Api/appsettings.json @@ -20,8 +20,8 @@ { "Name": "Console", "Args": { - "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console", - "restrictedToMinimumLevel": "Information" + "theme": "Roadie.Api.RoadieSerilogThemes::RoadieRainbow, Roadie.Api", + "restrictedToMinimumLevel": "Verbose" } }, { diff --git a/Roadie.Dlna/Server/Handlers/MediaMount_SOAP.cs b/Roadie.Dlna/Server/Handlers/MediaMount_SOAP.cs index b0f80c7..ee50429 100644 --- a/Roadie.Dlna/Server/Handlers/MediaMount_SOAP.cs +++ b/Roadie.Dlna/Server/Handlers/MediaMount_SOAP.cs @@ -1,5 +1,4 @@ using Microsoft.Extensions.Logging; -using Newtonsoft.Json; using Roadie.Dlna.Server.Metadata; using Roadie.Dlna.Utility; using System; @@ -13,23 +12,16 @@ namespace Roadie.Dlna.Server internal partial class MediaMount { private const string NS_DC = "http://purl.org/dc/elements/1.1/"; - private const string NS_DIDL = "urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"; - private const string NS_DLNA = "urn:schemas-dlna-org:metadata-1-0/"; - private const string NS_SEC = "http://www.sec.co.kr/"; - private const string NS_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/"; - private const string NS_UPNP = "urn:schemas-upnp-org:metadata-1-0/upnp/"; - private static readonly IDictionary soapCache = new LeastRecentlyUsedDictionary(200); - - private static readonly XmlNamespaceManager namespaceMgr = CreateNamespaceManager(); - private static readonly string featureList = Encoding.UTF8.GetString(ResourceHelper.GetResourceData("x_featurelist.xml") ?? new byte[0]); + private static readonly IDictionary soapCache = new LeastRecentlyUsedDictionary(200); + private static void AddBookmarkInfo(IMediaResource resource, XmlElement item) { var bookmarkable = resource as IBookmarkable; @@ -79,10 +71,7 @@ namespace Roadie.Dlna.Server var res = result.CreateElement(string.Empty, "res", NS_DIDL); res.InnerText = curl; - res.SetAttribute("protocolInfo", string.Format( - "http-get:*:{1}:DLNA.ORG_PN={0};DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS={2}", - c.PN, DlnaMaps.Mime[c.Type], DlnaMaps.DefaultStreaming - )); + res.SetAttribute("protocolInfo", $"http-get:*:{DlnaMaps.Mime[c.Type]}:DLNA.ORG_PN={c.PN};DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS={DlnaMaps.DefaultStreaming}"); var width = c.MetaWidth; var height = c.MetaHeight; if (width.HasValue && height.HasValue) @@ -270,10 +259,7 @@ namespace Roadie.Dlna.Server res.SetAttribute("duration", prop); } - res.SetAttribute("protocolInfo", string.Format( - "http-get:*:{1}:DLNA.ORG_PN={0};DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS={2}", - resource.PN, DlnaMaps.Mime[resource.Type], DlnaMaps.DefaultStreaming - )); + res.SetAttribute("protocolInfo", $"http-get:*:{DlnaMaps.Mime[resource.Type]}:DLNA.ORG_PN={resource.PN};DLNA.ORG_OP=01;DLNA.ORG_CI=0;DLNA.ORG_FLAGS={DlnaMaps.DefaultStreaming}"); item.AppendChild(res); AddCover(request, resource, item); @@ -509,7 +495,7 @@ namespace Roadie.Dlna.Server { Logger.LogError(ex, $"ProcessSoapRequest. Error Loading Request From [{ request.RemoteEndpoint.Address }], Body [{ request.Body }]"); } - var sparams = new RawHeaders(); + var sparams = new RawHeaders(); var body = soap.SelectSingleNode("//soap:Body", namespaceMgr); if (body == null) { @@ -625,5 +611,7 @@ namespace Roadie.Dlna.Server rv.Headers.Add("EXT", string.Empty); return rv; } + + private static readonly XmlNamespaceManager namespaceMgr = CreateNamespaceManager(); } } \ No newline at end of file diff --git a/libraries/libwebp_x64.dll b/libraries/libwebp_x64.dll new file mode 100644 index 0000000000000000000000000000000000000000..9fcabfdbb2ef022c818c56a2ba51bd9c1c683685 GIT binary patch literal 633344 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%0D>dE4~yh+>4fhG&y%bn;;T-)lb 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

-E|5QOy= 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 literal 0 HcmV?d00001