Browse Source

add config options for musicbrainz

dkanada 5 years ago
parent
commit
65a9d618cc

+ 0 - 1
Emby.Server.Implementations/ConfigurationOptions.cs

@@ -8,7 +8,6 @@ namespace Emby.Server.Implementations
         public static Dictionary<string, string> Configuration => new Dictionary<string, string>
         {
             { "HttpListenerHost:DefaultRedirectPath", "web/index.html" },
-            { "MusicBrainz:BaseUrl", "https://www.musicbrainz.org" },
             { FfmpegProbeSizeKey, "1G" },
             { FfmpegAnalyzeDurationKey, "200M" }
         };

+ 1 - 2
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<MusicArtist>()
                 .OrderBy(i => i.IsAccessedByName ? 1 : 0)
                 .Cast<T>()
@@ -1080,7 +1079,7 @@ namespace Emby.Server.Implementations.Library
 
             var innerProgress = new ActionableProgress<double>();
 
-            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);

+ 1 - 0
MediaBrowser.Controller/Entities/Audio/MusicArtist.cs

@@ -198,6 +198,7 @@ namespace MediaBrowser.Controller.Entities.Audio
                     return true;
                 }
             }
+
             return base.RequiresRefresh();
         }
 

+ 4 - 4
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<BaseItem>();
 
                 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)
                     {

+ 5 - 0
MediaBrowser.Providers/MediaBrowser.Providers.csproj

@@ -24,4 +24,9 @@
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
   </PropertyGroup>
 
+  <ItemGroup>
+    <None Remove="Plugins\MusicBrainz\Configuration\config.html" />
+    <EmbeddedResource Include="Plugins\MusicBrainz\Configuration\config.html" />
+  </ItemGroup>
+
 </Project>

+ 0 - 95
MediaBrowser.Providers/Music/MusicExternalIds.cs

@@ -5,101 +5,6 @@ using MediaBrowser.Model.Entities;
 
 namespace MediaBrowser.Providers.Music
 {
-    public class MusicBrainzReleaseGroupExternalId : IExternalId
-    {
-        /// <inheritdoc />
-        public string Name => "MusicBrainz Release Group";
-
-        /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString();
-
-        /// <inheritdoc />
-        public string UrlFormatString => "https://musicbrainz.org/release-group/{0}";
-
-        /// <inheritdoc />
-        public bool Supports(IHasProviderIds item)
-            => item is Audio || item is MusicAlbum;
-    }
-
-    public class MusicBrainzAlbumArtistExternalId : IExternalId
-    {
-        /// <inheritdoc />
-        public string Name => "MusicBrainz Album Artist";
-
-        /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString();
-
-        /// <inheritdoc />
-        public string UrlFormatString => "https://musicbrainz.org/artist/{0}";
-
-        /// <inheritdoc />
-        public bool Supports(IHasProviderIds item)
-            => item is Audio;
-    }
-
-    public class MusicBrainzAlbumExternalId : IExternalId
-    {
-        /// <inheritdoc />
-        public string Name => "MusicBrainz Album";
-
-        /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzAlbum.ToString();
-
-        /// <inheritdoc />
-        public string UrlFormatString => "https://musicbrainz.org/release/{0}";
-
-        /// <inheritdoc />
-        public bool Supports(IHasProviderIds item)
-            => item is Audio || item is MusicAlbum;
-    }
-
-    public class MusicBrainzArtistExternalId : IExternalId
-    {
-        /// <inheritdoc />
-        public string Name => "MusicBrainz";
-
-        /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzArtist.ToString();
-
-        /// <inheritdoc />
-        public string UrlFormatString => "https://musicbrainz.org/artist/{0}";
-
-        /// <inheritdoc />
-        public bool Supports(IHasProviderIds item) => item is MusicArtist;
-    }
-
-    public class MusicBrainzOtherArtistExternalId : IExternalId
-    {
-        /// <inheritdoc />
-        public string Name => "MusicBrainz Artist";
-
-        /// <inheritdoc />
-
-        public string Key => MetadataProviders.MusicBrainzArtist.ToString();
-
-        /// <inheritdoc />
-        public string UrlFormatString => "https://musicbrainz.org/artist/{0}";
-
-        /// <inheritdoc />
-        public bool Supports(IHasProviderIds item)
-            => item is Audio || item is MusicAlbum;
-    }
-
-    public class MusicBrainzTrackId : IExternalId
-    {
-        /// <inheritdoc />
-        public string Name => "MusicBrainz Track";
-
-        /// <inheritdoc />
-        public string Key => MetadataProviders.MusicBrainzTrack.ToString();
-
-        /// <inheritdoc />
-        public string UrlFormatString => "https://musicbrainz.org/track/{0}";
-
-        /// <inheritdoc />
-        public bool Supports(IHasProviderIds item) => item is Audio;
-    }
-
     public class ImvdbId : IExternalId
     {
         /// <inheritdoc />

+ 22 - 23
MediaBrowser.Providers/Music/MusicBrainzAlbumProvider.cs → 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
         /// </summary>
-        private const long MusicBrainzQueryIntervalMs = 1050u;
+        private readonly long _musicBrainzQueryIntervalMs = 1050u;
 
         /// <summary>
         /// 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
         /// <inheritdoc />
         public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(AlbumInfo searchInfo, CancellationToken cancellationToken)
         {
+            // TODO maybe remove when artist metadata can be disabled
+            if (!Plugin.Instance.Configuration.Enable)
+            {
+                return Enumerable.Empty<RemoteSearchResult>();
+            }
+
             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
-
-                                    /*
-                                     * <artist-credit>
-<name-credit>
-<artist id="e225cda5-882d-4b80-b8a3-b36d7175b1ea">
-<name>SARCASTIC+ZOOKEEPER</name>
-<sort-name>SARCASTIC+ZOOKEEPER</sort-name>
-</artist>
-</name-credit>
-</artist-credit>
-                                     */
                                     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);
 

+ 18 - 1
MediaBrowser.Providers/Music/MusicBrainzArtistProvider.cs → 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
         /// <inheritdoc />
         public async Task<IEnumerable<RemoteSearchResult>> GetSearchResults(ArtistInfo searchInfo, CancellationToken cancellationToken)
         {
+            // TODO maybe remove when artist metadata can be disabled
+            if (!Plugin.Instance.Configuration.Enable)
+            {
+                return Enumerable.Empty<RemoteSearchResult>();
+            }
+
             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;
+                    }
                 }
             }
 

+ 16 - 0
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;
+    }
+}

+ 69 - 0
MediaBrowser.Providers/Plugins/MusicBrainz/Configuration/config.html

@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>MusicBrainz</title>
+</head>
+<body>
+    <div data-role="page" class="page type-interior pluginConfigurationPage musicBrainzConfigPage" data-require="emby-input,emby-button,emby-checkbox">
+        <div data-role="content">
+            <div class="content-primary">
+                <form class="musicBrainzConfigForm">
+                    <div class="inputContainer">
+                        <input is="emby-input" type="text" id="server" label="Server:" />
+                        <div class="fieldDescription">This can either be a mirror of the official server or a custom server.</div>
+                    </div>
+                    <div class="inputContainer">
+                        <input is="emby-input" type="number" id="rateLimit" pattern="[0-9]*" required min="400" max="10000" label="Rate Limit:" />
+                        <div class="fieldDescription">Span of time between each request in milliseconds.</div>
+                    </div>
+                    <label class="checkboxContainer">
+                        <input is="emby-checkbox" type="checkbox" id="enable" />
+                        <span>Enable this provider for metadata searches on artists and albums.</span>
+                    </label>
+                    <label class="checkboxContainer">
+                        <input is="emby-checkbox" type="checkbox" id="replaceArtistName" />
+                        <span>When an artist is found during a metadata search, replace the artist name with the value on the server.</span>
+                    </label>
+                    <br />
+                    <div>
+                        <button is="emby-button" type="submit" class="raised button-submit block"><span>Save</span></button>
+                    </div>
+                </form>
+            </div>
+        </div>
+        <script type="text/javascript">
+            var MusicBrainzPluginConfig = {
+                uniquePluginId: "8c95c4d2-e50c-4fb0-a4f3-6c06ff0f9a1a"
+            };
+
+            $('.musicBrainzConfigPage').on('pageshow', function () {
+                Dashboard.showLoadingMsg();
+                ApiClient.getPluginConfiguration(MusicBrainzPluginConfig.uniquePluginId).then(function (config) {
+                    $('#server').val(config.Server).change();
+                    $('#rateLimit').val(config.RateLimit).change();
+                    $('#enable').checked(config.Enable);
+                    $('#replaceArtistName').checked(config.ReplaceArtistName);
+
+                    Dashboard.hideLoadingMsg();
+                });
+            });
+
+            $('.musicBrainzConfigForm').on('submit', function (e) {
+                Dashboard.showLoadingMsg();
+
+                var form = this;
+                ApiClient.getPluginConfiguration(MusicBrainzPluginConfig.uniquePluginId).then(function (config) {
+                    config.Server = $('#server', form).val();
+                    config.RateLimit = $('#rateLimit', form).val();
+                    config.Enable = $('#enable', form).checked();
+                    config.ReplaceArtistName = $('#replaceArtistName', form).checked();
+
+                    ApiClient.updatePluginConfiguration(MusicBrainzPluginConfig.uniquePluginId, config).then(Dashboard.processPluginConfigurationUpdateResult);
+                });
+
+                return false;
+            });
+        </script>
+    </div>
+</body>
+</html>

+ 102 - 0
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
+    {
+        /// <inheritdoc />
+        public string Name => "MusicBrainz Release Group";
+
+        /// <inheritdoc />
+        public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString();
+
+        /// <inheritdoc />
+        public string UrlFormatString => "https://musicbrainz.org/release-group/{0}";
+
+        /// <inheritdoc />
+        public bool Supports(IHasProviderIds item)
+            => item is Audio || item is MusicAlbum;
+    }
+
+    public class MusicBrainzAlbumArtistExternalId : IExternalId
+    {
+        /// <inheritdoc />
+        public string Name => "MusicBrainz Album Artist";
+
+        /// <inheritdoc />
+        public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString();
+
+        /// <inheritdoc />
+        public string UrlFormatString => "https://musicbrainz.org/artist/{0}";
+
+        /// <inheritdoc />
+        public bool Supports(IHasProviderIds item)
+            => item is Audio;
+    }
+
+    public class MusicBrainzAlbumExternalId : IExternalId
+    {
+        /// <inheritdoc />
+        public string Name => "MusicBrainz Album";
+
+        /// <inheritdoc />
+        public string Key => MetadataProviders.MusicBrainzAlbum.ToString();
+
+        /// <inheritdoc />
+        public string UrlFormatString => "https://musicbrainz.org/release/{0}";
+
+        /// <inheritdoc />
+        public bool Supports(IHasProviderIds item)
+            => item is Audio || item is MusicAlbum;
+    }
+
+    public class MusicBrainzArtistExternalId : IExternalId
+    {
+        /// <inheritdoc />
+        public string Name => "MusicBrainz";
+
+        /// <inheritdoc />
+        public string Key => MetadataProviders.MusicBrainzArtist.ToString();
+
+        /// <inheritdoc />
+        public string UrlFormatString => "https://musicbrainz.org/artist/{0}";
+
+        /// <inheritdoc />
+        public bool Supports(IHasProviderIds item) => item is MusicArtist;
+    }
+
+    public class MusicBrainzOtherArtistExternalId : IExternalId
+    {
+        /// <inheritdoc />
+        public string Name => "MusicBrainz Artist";
+
+        /// <inheritdoc />
+
+        public string Key => MetadataProviders.MusicBrainzArtist.ToString();
+
+        /// <inheritdoc />
+        public string UrlFormatString => "https://musicbrainz.org/artist/{0}";
+
+        /// <inheritdoc />
+        public bool Supports(IHasProviderIds item)
+            => item is Audio || item is MusicAlbum;
+    }
+
+    public class MusicBrainzTrackId : IExternalId
+    {
+        /// <inheritdoc />
+        public string Name => "MusicBrainz Track";
+
+        /// <inheritdoc />
+        public string Key => MetadataProviders.MusicBrainzTrack.ToString();
+
+        /// <inheritdoc />
+        public string UrlFormatString => "https://musicbrainz.org/track/{0}";
+
+        /// <inheritdoc />
+        public bool Supports(IHasProviderIds item) => item is Audio;
+    }
+}

+ 35 - 0
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<PluginConfiguration>, IHasWebPages
+    {
+        public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
+            : base(applicationPaths, xmlSerializer)
+        {
+            Instance = this;
+        }
+
+        public IEnumerable<PluginPageInfo> 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; }
+    }
+}