From 65a9d618ccfb5e015eb2dccf437e8795ac5350d5 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 22 Feb 2020 15:04:52 +0900 Subject: [PATCH 01/31] add config options for musicbrainz --- .../ConfigurationOptions.cs | 1 - .../Library/LibraryManager.cs | 3 +- .../Entities/Audio/MusicArtist.cs | 1 + MediaBrowser.Controller/Entities/Folder.cs | 8 +- .../MediaBrowser.Providers.csproj | 5 + .../Music/MusicExternalIds.cs | 95 ---------------- .../MusicBrainz/AlbumProvider.cs} | 45 ++++---- .../MusicBrainz/ArtistProvider.cs} | 19 +++- .../Configuration/PluginConfiguration.cs | 16 +++ .../MusicBrainz/Configuration/config.html | 69 ++++++++++++ .../MusicBrainz/MusicBrainzExternalIds.cs | 102 ++++++++++++++++++ .../Plugins/MusicBrainz/Plugin.cs | 35 ++++++ 12 files changed, 273 insertions(+), 126 deletions(-) rename MediaBrowser.Providers/{Music/MusicBrainzAlbumProvider.cs => Plugins/MusicBrainz/AlbumProvider.cs} (96%) rename MediaBrowser.Providers/{Music/MusicBrainzArtistProvider.cs => Plugins/MusicBrainz/ArtistProvider.cs} (94%) create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzExternalIds.cs create mode 100644 MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs index 2ea7ff6e91..d0f3d67230 100644 --- a/Emby.Server.Implementations/ConfigurationOptions.cs +++ b/Emby.Server.Implementations/ConfigurationOptions.cs @@ -8,7 +8,6 @@ namespace Emby.Server.Implementations public static Dictionary Configuration => new Dictionary { { "HttpListenerHost:DefaultRedirectPath", "web/index.html" }, - { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" }, { FfmpegProbeSizeKey, "1G" }, { FfmpegAnalyzeDurationKey, "200M" } }; diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 55566ed517..8a66ffdaac 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -944,7 +944,6 @@ namespace Emby.Server.Implementations.Library IncludeItemTypes = new[] { typeof(T).Name }, Name = name, DtoOptions = options - }).Cast() .OrderBy(i => i.IsAccessedByName ? 1 : 0) .Cast() @@ -1080,7 +1079,7 @@ namespace Emby.Server.Implementations.Library var innerProgress = new ActionableProgress(); - innerProgress.RegisterAction(pct => progress.Report(pct * pct * 0.96)); + innerProgress.RegisterAction(pct => progress.Report(pct * 0.96)); // Validate the entire media library await RootFolder.ValidateChildren(innerProgress, cancellationToken, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), recursive: true).ConfigureAwait(false); diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs index efe0d3cf70..5e3056ccb0 100644 --- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs +++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs @@ -198,6 +198,7 @@ namespace MediaBrowser.Controller.Entities.Audio return true; } } + return base.RequiresRefresh(); } diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs index 07fbe60350..a892be7a97 100644 --- a/MediaBrowser.Controller/Entities/Folder.cs +++ b/MediaBrowser.Controller/Entities/Folder.cs @@ -322,10 +322,10 @@ namespace MediaBrowser.Controller.Entities ProviderManager.OnRefreshProgress(this, 5); } - //build a dictionary of the current children we have now by Id so we can compare quickly and easily + // Build a dictionary of the current children we have now by Id so we can compare quickly and easily var currentChildren = GetActualChildrenDictionary(); - //create a list for our validated children + // Create a list for our validated children var newItems = new List(); cancellationToken.ThrowIfCancellationRequested(); @@ -391,7 +391,7 @@ namespace MediaBrowser.Controller.Entities var folder = this; innerProgress.RegisterAction(p => { - double newPct = .80 * p + 10; + double newPct = 0.80 * p + 10; progress.Report(newPct); ProviderManager.OnRefreshProgress(folder, newPct); }); @@ -421,7 +421,7 @@ namespace MediaBrowser.Controller.Entities var folder = this; innerProgress.RegisterAction(p => { - double newPct = .10 * p + 90; + double newPct = 0.10 * p + 90; progress.Report(newPct); if (recursive) { diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj index 5593c5036c..48c16b6433 100644 --- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj +++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj @@ -24,4 +24,9 @@ true + + + + + diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 585c98af9e..b431c1e41f 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -5,101 +5,6 @@ using MediaBrowser.Model.Entities; namespace MediaBrowser.Providers.Music { - public class MusicBrainzReleaseGroupExternalId : IExternalId - { - /// - public string Name => "MusicBrainz Release Group"; - - /// - public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString(); - - /// - public string UrlFormatString => "https://musicbrainz.org/release-group/{0}"; - - /// - public bool Supports(IHasProviderIds item) - => item is Audio || item is MusicAlbum; - } - - public class MusicBrainzAlbumArtistExternalId : IExternalId - { - /// - public string Name => "MusicBrainz Album Artist"; - - /// - public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString(); - - /// - public string UrlFormatString => "https://musicbrainz.org/artist/{0}"; - - /// - public bool Supports(IHasProviderIds item) - => item is Audio; - } - - public class MusicBrainzAlbumExternalId : IExternalId - { - /// - public string Name => "MusicBrainz Album"; - - /// - public string Key => MetadataProviders.MusicBrainzAlbum.ToString(); - - /// - public string UrlFormatString => "https://musicbrainz.org/release/{0}"; - - /// - public bool Supports(IHasProviderIds item) - => item is Audio || item is MusicAlbum; - } - - public class MusicBrainzArtistExternalId : IExternalId - { - /// - public string Name => "MusicBrainz"; - - /// - public string Key => MetadataProviders.MusicBrainzArtist.ToString(); - - /// - public string UrlFormatString => "https://musicbrainz.org/artist/{0}"; - - /// - public bool Supports(IHasProviderIds item) => item is MusicArtist; - } - - public class MusicBrainzOtherArtistExternalId : IExternalId - { - /// - public string Name => "MusicBrainz Artist"; - - /// - - public string Key => MetadataProviders.MusicBrainzArtist.ToString(); - - /// - public string UrlFormatString => "https://musicbrainz.org/artist/{0}"; - - /// - public bool Supports(IHasProviderIds item) - => item is Audio || item is MusicAlbum; - } - - public class MusicBrainzTrackId : IExternalId - { - /// - public string Name => "MusicBrainz Track"; - - /// - public string Key => MetadataProviders.MusicBrainzTrack.ToString(); - - /// - public string UrlFormatString => "https://musicbrainz.org/track/{0}"; - - /// - public bool Supports(IHasProviderIds item) => item is Audio; - } - public class ImvdbId : IExternalId { /// diff --git a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs similarity index 96% rename from MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs rename to MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs index 8e71b625ee..0fddb05579 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs @@ -15,7 +15,7 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; -using Microsoft.Extensions.Configuration; +using MediaBrowser.Providers.Plugins.MusicBrainz; using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Music @@ -28,7 +28,7 @@ namespace MediaBrowser.Providers.Music /// Be prudent, use a value slightly above the minimun required. /// https://musicbrainz.org/doc/XML_Web_Service/Rate_Limiting /// - private const long MusicBrainzQueryIntervalMs = 1050u; + private readonly long _musicBrainzQueryIntervalMs = 1050u; /// /// For each single MB lookup/search, this is the maximum number of @@ -50,14 +50,14 @@ namespace MediaBrowser.Providers.Music public MusicBrainzAlbumProvider( IHttpClient httpClient, IApplicationHost appHost, - ILogger logger, - IConfiguration configuration) + ILogger logger) { _httpClient = httpClient; _appHost = appHost; _logger = logger; - _musicBrainzBaseUrl = configuration["MusicBrainz:BaseUrl"]; + _musicBrainzBaseUrl = Plugin.Instance.Configuration.Server; + _musicBrainzQueryIntervalMs = Plugin.Instance.Configuration.RateLimit; // Use a stopwatch to ensure we don't exceed the MusicBrainz rate limit _stopWatchMusicBrainz.Start(); @@ -74,6 +74,12 @@ namespace MediaBrowser.Providers.Music /// public async Task> GetSearchResults(AlbumInfo searchInfo, CancellationToken cancellationToken) { + // TODO maybe remove when artist metadata can be disabled + if (!Plugin.Instance.Configuration.Enable) + { + return Enumerable.Empty(); + } + var releaseId = searchInfo.GetReleaseId(); var releaseGroupId = searchInfo.GetReleaseGroupId(); @@ -107,8 +113,8 @@ namespace MediaBrowser.Providers.Music url = string.Format( CultureInfo.InvariantCulture, "/ws/2/release/?query=\"{0}\" AND artist:\"{1}\"", - WebUtility.UrlEncode(queryName), - WebUtility.UrlEncode(searchInfo.GetAlbumArtist())); + WebUtility.UrlEncode(queryName), + WebUtility.UrlEncode(searchInfo.GetAlbumArtist())); } } @@ -170,7 +176,6 @@ namespace MediaBrowser.Providers.Music } return result; - }); } } @@ -187,6 +192,12 @@ namespace MediaBrowser.Providers.Music Item = new MusicAlbum() }; + // TODO maybe remove when artist metadata can be disabled + if (!Plugin.Instance.Configuration.Enable) + { + return result; + } + // If we have a release group Id but not a release Id... if (string.IsNullOrWhiteSpace(releaseId) && !string.IsNullOrWhiteSpace(releaseGroupId)) { @@ -456,18 +467,6 @@ namespace MediaBrowser.Providers.Music } case "artist-credit": { - // TODO - - /* - * - - -SARCASTIC+ZOOKEEPER -SARCASTIC+ZOOKEEPER - - - - */ using (var subReader = reader.ReadSubtree()) { var artist = ParseArtistCredit(subReader); @@ -764,10 +763,10 @@ namespace MediaBrowser.Providers.Music { attempts++; - if (_stopWatchMusicBrainz.ElapsedMilliseconds < MusicBrainzQueryIntervalMs) + if (_stopWatchMusicBrainz.ElapsedMilliseconds < _musicBrainzQueryIntervalMs) { // MusicBrainz is extremely adamant about limiting to one request per second - var delayMs = MusicBrainzQueryIntervalMs - _stopWatchMusicBrainz.ElapsedMilliseconds; + var delayMs = _musicBrainzQueryIntervalMs - _stopWatchMusicBrainz.ElapsedMilliseconds; await Task.Delay((int)delayMs, cancellationToken).ConfigureAwait(false); } @@ -778,7 +777,7 @@ namespace MediaBrowser.Providers.Music response = await _httpClient.SendAsync(options, "GET").ConfigureAwait(false); - // We retry a finite number of times, and only whilst MB is indcating 503 (throttling) + // We retry a finite number of times, and only whilst MB is indicating 503 (throttling) } while (attempts < MusicBrainzQueryAttempts && response.StatusCode == HttpStatusCode.ServiceUnavailable); diff --git a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs similarity index 94% rename from MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs rename to MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs index 5d675392c9..260a3b6e7b 100644 --- a/MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ArtistProvider.cs @@ -14,6 +14,7 @@ using MediaBrowser.Controller.Extensions; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Providers; +using MediaBrowser.Providers.Plugins.MusicBrainz; namespace MediaBrowser.Providers.Music { @@ -22,6 +23,12 @@ namespace MediaBrowser.Providers.Music /// public async Task> GetSearchResults(ArtistInfo searchInfo, CancellationToken cancellationToken) { + // TODO maybe remove when artist metadata can be disabled + if (!Plugin.Instance.Configuration.Enable) + { + return Enumerable.Empty(); + } + var musicBrainzId = searchInfo.GetMusicBrainzArtistId(); if (!string.IsNullOrWhiteSpace(musicBrainzId)) @@ -226,6 +233,12 @@ namespace MediaBrowser.Providers.Music Item = new MusicArtist() }; + // TODO maybe remove when artist metadata can be disabled + if (!Plugin.Instance.Configuration.Enable) + { + return result; + } + var musicBrainzId = id.GetMusicBrainzArtistId(); if (string.IsNullOrWhiteSpace(musicBrainzId)) @@ -237,8 +250,12 @@ namespace MediaBrowser.Providers.Music if (singleResult != null) { musicBrainzId = singleResult.GetProviderId(MetadataProviders.MusicBrainzArtist); - //result.Item.Name = singleResult.Name; result.Item.Overview = singleResult.Overview; + + if (Plugin.Instance.Configuration.ReplaceArtistName) + { + result.Item.Name = singleResult.Name; + } } } diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs new file mode 100644 index 0000000000..6bce0b4478 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using MediaBrowser.Model.Plugins; + +namespace MediaBrowser.Providers.Plugins.MusicBrainz +{ + public class PluginConfiguration : BasePluginConfiguration + { + public bool Enable { get; set; } = false; + + public bool ReplaceArtistName { get; set; } = false; + + public string Server { get; set; } = "https://www.musicbrainz.org"; + + public long RateLimit { get; set; } = 1000u; + } +} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html new file mode 100644 index 0000000000..dfffa90655 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html @@ -0,0 +1,69 @@ + + + + MusicBrainz + + +
+
+
+
+
+ +
This can either be a mirror of the official server or a custom server.
+
+
+ +
Span of time between each request in milliseconds.
+
+ + +
+
+ +
+
+
+
+ +
+ + diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzExternalIds.cs new file mode 100644 index 0000000000..0184d42410 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzExternalIds.cs @@ -0,0 +1,102 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Model.Entities; + +namespace MediaBrowser.Providers.Music +{ + public class MusicBrainzReleaseGroupExternalId : IExternalId + { + /// + public string Name => "MusicBrainz Release Group"; + + /// + public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString(); + + /// + public string UrlFormatString => "https://musicbrainz.org/release-group/{0}"; + + /// + public bool Supports(IHasProviderIds item) + => item is Audio || item is MusicAlbum; + } + + public class MusicBrainzAlbumArtistExternalId : IExternalId + { + /// + public string Name => "MusicBrainz Album Artist"; + + /// + public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString(); + + /// + public string UrlFormatString => "https://musicbrainz.org/artist/{0}"; + + /// + public bool Supports(IHasProviderIds item) + => item is Audio; + } + + public class MusicBrainzAlbumExternalId : IExternalId + { + /// + public string Name => "MusicBrainz Album"; + + /// + public string Key => MetadataProviders.MusicBrainzAlbum.ToString(); + + /// + public string UrlFormatString => "https://musicbrainz.org/release/{0}"; + + /// + public bool Supports(IHasProviderIds item) + => item is Audio || item is MusicAlbum; + } + + public class MusicBrainzArtistExternalId : IExternalId + { + /// + public string Name => "MusicBrainz"; + + /// + public string Key => MetadataProviders.MusicBrainzArtist.ToString(); + + /// + public string UrlFormatString => "https://musicbrainz.org/artist/{0}"; + + /// + public bool Supports(IHasProviderIds item) => item is MusicArtist; + } + + public class MusicBrainzOtherArtistExternalId : IExternalId + { + /// + public string Name => "MusicBrainz Artist"; + + /// + + public string Key => MetadataProviders.MusicBrainzArtist.ToString(); + + /// + public string UrlFormatString => "https://musicbrainz.org/artist/{0}"; + + /// + public bool Supports(IHasProviderIds item) + => item is Audio || item is MusicAlbum; + } + + public class MusicBrainzTrackId : IExternalId + { + /// + public string Name => "MusicBrainz Track"; + + /// + public string Key => MetadataProviders.MusicBrainzTrack.ToString(); + + /// + public string UrlFormatString => "https://musicbrainz.org/track/{0}"; + + /// + public bool Supports(IHasProviderIds item) => item is Audio; + } +} diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs new file mode 100644 index 0000000000..2211d513f9 --- /dev/null +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Plugin.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Plugins; +using MediaBrowser.Model.Plugins; +using MediaBrowser.Model.Serialization; + +namespace MediaBrowser.Providers.Plugins.MusicBrainz +{ + public class Plugin : BasePlugin, IHasWebPages + { + public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer) + : base(applicationPaths, xmlSerializer) + { + Instance = this; + } + + public IEnumerable GetPages() + { + yield return new PluginPageInfo + { + Name = Name, + EmbeddedResourcePath = GetType().Namespace + ".Configuration.config.html" + }; + } + + public override Guid Id => new Guid("8c95c4d2-e50c-4fb0-a4f3-6c06ff0f9a1a"); + + public override string Name => "MusicBrainz"; + + public override string Description => "Get artist and album metadata from any MusicBrainz server."; + + public static Plugin Instance { get; private set; } + } +} From a34826008f001fcfee9dabde4e439a0d83e821ea Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 24 Feb 2020 00:22:23 +0900 Subject: [PATCH 02/31] update external ids --- MediaBrowser.Providers/Music/MusicExternalIds.cs | 1 - .../MusicBrainz/{MusicBrainzExternalIds.cs => ExternalIds.cs} | 1 - 2 files changed, 2 deletions(-) rename MediaBrowser.Providers/Plugins/MusicBrainz/{MusicBrainzExternalIds.cs => ExternalIds.cs} (98%) diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index b431c1e41f..628b9a9a10 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -1,5 +1,4 @@ using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs similarity index 98% rename from MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzExternalIds.cs rename to MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs index 0184d42410..fd85465f37 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/MusicBrainzExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs @@ -1,4 +1,3 @@ -using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; From 19a609a88980b2ac21050eeb991e2abb55675e9c Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 24 Feb 2020 00:24:03 +0900 Subject: [PATCH 03/31] update musicbrainz options --- .../MusicBrainz/Configuration/PluginConfiguration.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs index 6bce0b4478..607ba0cbcb 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs @@ -5,12 +5,12 @@ namespace MediaBrowser.Providers.Plugins.MusicBrainz { public class PluginConfiguration : BasePluginConfiguration { - public bool Enable { get; set; } = false; - - public bool ReplaceArtistName { get; set; } = false; - public string Server { get; set; } = "https://www.musicbrainz.org"; public long RateLimit { get; set; } = 1000u; + + public bool Enable { get; set; } + + public bool ReplaceArtistName { get; set; } } } From 940990708e3df623056cc790351e6d5d52af5a0f Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 24 Feb 2020 00:25:27 +0900 Subject: [PATCH 04/31] remove unused assignment --- MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs index 0fddb05579..748c23216c 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/AlbumProvider.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Providers.Music /// Be prudent, use a value slightly above the minimun required. /// https://musicbrainz.org/doc/XML_Web_Service/Rate_Limiting ///
- private readonly long _musicBrainzQueryIntervalMs = 1050u; + private readonly long _musicBrainzQueryIntervalMs; /// /// For each single MB lookup/search, this is the maximum number of From 4ae80a5d56f291a0865dddc5393cf1e3c4b9277b Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 24 Feb 2020 14:35:30 +0900 Subject: [PATCH 05/31] partially fix issue with music scans --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 5280d455c4..bf10108b8c 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -238,7 +238,7 @@ namespace MediaBrowser.Model.Configuration CodecsUsed = Array.Empty(); PathSubstitutions = Array.Empty(); IgnoreVirtualInterfaces = false; - EnableSimpleArtistDetection = true; + EnableSimpleArtistDetection = false; DisplaySpecialsWithinSeasons = true; EnableExternalContentInSuggestions = true; From 8e20d2e931b273b54ef369c9b75021ab04118e04 Mon Sep 17 00:00:00 2001 From: Vasily Date: Thu, 27 Feb 2020 14:51:34 +0300 Subject: [PATCH 06/31] Simplify AlphanumericComparer, reduce code duplication --- MediaBrowser.Controller/Entities/BaseItem.cs | 8 +- .../Sorting/AlphanumComparator.cs | 32 +++-- .../Sorting/SortExtensions.cs | 122 +----------------- MediaBrowser.Controller/Sorting/SortHelper.cs | 25 ---- 4 files changed, 22 insertions(+), 165 deletions(-) rename {Emby.Server.Implementations => MediaBrowser.Controller}/Sorting/AlphanumComparator.cs (73%) delete mode 100644 MediaBrowser.Controller/Sorting/SortHelper.cs diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 353c675cb3..09cdfc9eaf 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -387,15 +387,12 @@ namespace MediaBrowser.Controller.Entities while (thisMarker < s1.Length) { - if (thisMarker >= s1.Length) - { - break; - } char thisCh = s1[thisMarker]; var thisChunk = new StringBuilder(); + bool isNumeric = char.IsDigit(thisCh); - while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || SortHelper.InChunk(thisCh, thisChunk[0]))) + while ((thisMarker < s1.Length) && (char.IsDigit(thisCh) == isNumeric)) { thisChunk.Append(thisCh); thisMarker++; @@ -406,7 +403,6 @@ namespace MediaBrowser.Controller.Entities } } - var isNumeric = thisChunk.Length > 0 && char.IsDigit(thisChunk[0]); list.Add(new Tuple(thisChunk, isNumeric)); } diff --git a/Emby.Server.Implementations/Sorting/AlphanumComparator.cs b/MediaBrowser.Controller/Sorting/AlphanumComparator.cs similarity index 73% rename from Emby.Server.Implementations/Sorting/AlphanumComparator.cs rename to MediaBrowser.Controller/Sorting/AlphanumComparator.cs index 2e00c24d75..ad1eaf7bf7 100644 --- a/Emby.Server.Implementations/Sorting/AlphanumComparator.cs +++ b/MediaBrowser.Controller/Sorting/AlphanumComparator.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Text; using MediaBrowser.Controller.Sorting; -namespace Emby.Server.Implementations.Sorting +namespace MediaBrowser.Controller.Sorting { public class AlphanumComparator : IComparer { @@ -31,8 +31,9 @@ namespace Emby.Server.Implementations.Sorting var thisChunk = new StringBuilder(); var thatChunk = new StringBuilder(); + bool thisNumeric = char.IsDigit(thisCh), thatNumeric = char.IsDigit(thatCh); - while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || SortHelper.InChunk(thisCh, thisChunk[0]))) + while ((thisMarker < s1.Length) && (char.IsDigit(thisCh) == thisNumeric)) { thisChunk.Append(thisCh); thisMarker++; @@ -43,7 +44,7 @@ namespace Emby.Server.Implementations.Sorting } } - while ((thatMarker < s2.Length) && (thatChunk.Length == 0 || SortHelper.InChunk(thatCh, thatChunk[0]))) + while ((thatMarker < s2.Length) && (char.IsDigit(thatCh) == thatNumeric)) { thatChunk.Append(thatCh); thatMarker++; @@ -54,38 +55,35 @@ namespace Emby.Server.Implementations.Sorting } } - int result = 0; + // If both chunks contain numeric characters, sort them numerically - if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0])) + if (thisNumeric && thatNumeric) { - if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk)) - { - return 0; - } - if (!int.TryParse(thatChunk.ToString(), out thatNumericChunk)) + if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk) + || !int.TryParse(thatChunk.ToString(), out thatNumericChunk)) { return 0; } if (thisNumericChunk < thatNumericChunk) { - result = -1; + return -1; } if (thisNumericChunk > thatNumericChunk) { - result = 1; + return 1; } } else { - result = thisChunk.ToString().CompareTo(thatChunk.ToString()); + int result = thisChunk.ToString().CompareTo(thatChunk.ToString()); + if (result != 0) + { + return result; + } } - if (result != 0) - { - return result; - } } return 0; diff --git a/MediaBrowser.Controller/Sorting/SortExtensions.cs b/MediaBrowser.Controller/Sorting/SortExtensions.cs index 111f4f17fc..bc98c58f0c 100644 --- a/MediaBrowser.Controller/Sorting/SortExtensions.cs +++ b/MediaBrowser.Controller/Sorting/SortExtensions.cs @@ -7,137 +7,25 @@ namespace MediaBrowser.Controller.Sorting { public static class SortExtensions { + private static IComparer _comparer = new AlphanumComparator(); public static IEnumerable OrderByString(this IEnumerable list, Func getName) { - return list.OrderBy(getName, new AlphanumComparator()); + return list.OrderBy(getName, _comparer); } public static IEnumerable OrderByStringDescending(this IEnumerable list, Func getName) { - return list.OrderByDescending(getName, new AlphanumComparator()); + return list.OrderByDescending(getName, _comparer); } public static IOrderedEnumerable ThenByString(this IOrderedEnumerable list, Func getName) { - return list.ThenBy(getName, new AlphanumComparator()); + return list.ThenBy(getName, _comparer); } public static IOrderedEnumerable ThenByStringDescending(this IOrderedEnumerable list, Func getName) { - return list.ThenByDescending(getName, new AlphanumComparator()); - } - - private class AlphanumComparator : IComparer - { - private enum ChunkType { Alphanumeric, Numeric }; - - private static bool InChunk(char ch, char otherCh) - { - var type = ChunkType.Alphanumeric; - - if (char.IsDigit(otherCh)) - { - type = ChunkType.Numeric; - } - - if ((type == ChunkType.Alphanumeric && char.IsDigit(ch)) - || (type == ChunkType.Numeric && !char.IsDigit(ch))) - { - return false; - } - - return true; - } - - public static int CompareValues(string s1, string s2) - { - if (s1 == null || s2 == null) - { - return 0; - } - - int thisMarker = 0, thisNumericChunk = 0; - int thatMarker = 0, thatNumericChunk = 0; - - while ((thisMarker < s1.Length) || (thatMarker < s2.Length)) - { - if (thisMarker >= s1.Length) - { - return -1; - } - else if (thatMarker >= s2.Length) - { - return 1; - } - char thisCh = s1[thisMarker]; - char thatCh = s2[thatMarker]; - - var thisChunk = new StringBuilder(); - var thatChunk = new StringBuilder(); - - while ((thisMarker < s1.Length) && (thisChunk.Length == 0 || InChunk(thisCh, thisChunk[0]))) - { - thisChunk.Append(thisCh); - thisMarker++; - - if (thisMarker < s1.Length) - { - thisCh = s1[thisMarker]; - } - } - - while ((thatMarker < s2.Length) && (thatChunk.Length == 0 || InChunk(thatCh, thatChunk[0]))) - { - thatChunk.Append(thatCh); - thatMarker++; - - if (thatMarker < s2.Length) - { - thatCh = s2[thatMarker]; - } - } - - int result = 0; - // If both chunks contain numeric characters, sort them numerically - if (char.IsDigit(thisChunk[0]) && char.IsDigit(thatChunk[0])) - { - if (!int.TryParse(thisChunk.ToString(), out thisNumericChunk)) - { - return 0; - } - if (!int.TryParse(thatChunk.ToString(), out thatNumericChunk)) - { - return 0; - } - - if (thisNumericChunk < thatNumericChunk) - { - result = -1; - } - - if (thisNumericChunk > thatNumericChunk) - { - result = 1; - } - } - else - { - result = thisChunk.ToString().CompareTo(thatChunk.ToString()); - } - - if (result != 0) - { - return result; - } - } - - return 0; - } - - public int Compare(string x, string y) - { - return CompareValues(x, y); - } + return list.ThenByDescending(getName, _comparer); } } } diff --git a/MediaBrowser.Controller/Sorting/SortHelper.cs b/MediaBrowser.Controller/Sorting/SortHelper.cs deleted file mode 100644 index 05981d9757..0000000000 --- a/MediaBrowser.Controller/Sorting/SortHelper.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace MediaBrowser.Controller.Sorting -{ - public static class SortHelper - { - private enum ChunkType { Alphanumeric, Numeric }; - - public static bool InChunk(char ch, char otherCh) - { - var type = ChunkType.Alphanumeric; - - if (char.IsDigit(otherCh)) - { - type = ChunkType.Numeric; - } - - if ((type == ChunkType.Alphanumeric && char.IsDigit(ch)) - || (type == ChunkType.Numeric && !char.IsDigit(ch))) - { - return false; - } - - return true; - } - } -} From d1670f81808a74865f8c4fb2c2a77ab01eb3bde9 Mon Sep 17 00:00:00 2001 From: Vasily Date: Thu, 27 Feb 2020 16:02:18 +0300 Subject: [PATCH 07/31] Apply suggestions from code review Co-Authored-By: Claus Vium --- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.Controller/Sorting/AlphanumComparator.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 09cdfc9eaf..66de080a39 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -392,7 +392,7 @@ namespace MediaBrowser.Controller.Entities var thisChunk = new StringBuilder(); bool isNumeric = char.IsDigit(thisCh); - while ((thisMarker < s1.Length) && (char.IsDigit(thisCh) == isNumeric)) + while (thisMarker < s1.Length && char.IsDigit(thisCh) == isNumeric) { thisChunk.Append(thisCh); thisMarker++; diff --git a/MediaBrowser.Controller/Sorting/AlphanumComparator.cs b/MediaBrowser.Controller/Sorting/AlphanumComparator.cs index ad1eaf7bf7..65dc120ca8 100644 --- a/MediaBrowser.Controller/Sorting/AlphanumComparator.cs +++ b/MediaBrowser.Controller/Sorting/AlphanumComparator.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Sorting var thatChunk = new StringBuilder(); bool thisNumeric = char.IsDigit(thisCh), thatNumeric = char.IsDigit(thatCh); - while ((thisMarker < s1.Length) && (char.IsDigit(thisCh) == thisNumeric)) + while (thisMarker < s1.Length && char.IsDigit(thisCh) == thisNumeric) { thisChunk.Append(thisCh); thisMarker++; @@ -44,7 +44,7 @@ namespace MediaBrowser.Controller.Sorting } } - while ((thatMarker < s2.Length) && (char.IsDigit(thatCh) == thatNumeric)) + while (thatMarker < s2.Length && char.IsDigit(thatCh) == thatNumeric) { thatChunk.Append(thatCh); thatMarker++; From e80444d11b874f539c9a41f7867c8f93a0fbaeec Mon Sep 17 00:00:00 2001 From: dkanada Date: Fri, 28 Feb 2020 01:43:57 +0900 Subject: [PATCH 08/31] use the custom server for external ids --- .../Configuration/PluginConfiguration.cs | 36 ++++++++++++++++--- .../MusicBrainz/Configuration/config.html | 8 ++--- .../Plugins/MusicBrainz/ExternalIds.cs | 25 ++++++------- .../Plugins/MusicBrainz/Plugin.cs | 20 ++++++----- 4 files changed, 59 insertions(+), 30 deletions(-) diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs index 607ba0cbcb..bd13cdddd5 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/PluginConfiguration.cs @@ -1,13 +1,41 @@ -using System.Collections.Generic; -using MediaBrowser.Model.Plugins; +using MediaBrowser.Model.Plugins; namespace MediaBrowser.Providers.Plugins.MusicBrainz { public class PluginConfiguration : BasePluginConfiguration { - public string Server { get; set; } = "https://www.musicbrainz.org"; + private string server = Plugin.Instance.DefaultServer; - public long RateLimit { get; set; } = 1000u; + private long rateLimit = Plugin.Instance.DefaultRateLimit; + + public string Server + { + get + { + return server; + } + + set + { + server = value.TrimEnd('/'); + } + } + + public long RateLimit + { + get + { + return rateLimit; + } + + set + { + if (value < 2000u && server == Plugin.Instance.DefaultServer) + { + RateLimit = Plugin.Instance.DefaultRateLimit; + } + } + } public bool Enable { get; set; } diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html index dfffa90655..1f02461da2 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html @@ -9,12 +9,12 @@
- -
This can either be a mirror of the official server or a custom server.
+ +
This can be a mirror of the official server or even a custom server.
- -
Span of time between each request in milliseconds.
+ +
Span of time between requests in milliseconds. The official server is limited to one request every two seconds.