From 7d7d3c1d1b652be8bf8c742e2a3361265a766cbf Mon Sep 17 00:00:00 2001 From: Jason Krause Date: Sun, 25 Feb 2024 09:48:37 -0700 Subject: [PATCH] new: Musicbrainz Label --- .../MusicBrainzLabel/MusicBrainzLabel.cs | 38 ++++++++++ .../MusicBrainzLabel/MusicBrainzLabelApi.cs | 13 ++++ .../MusicBrainzLabelParser.cs | 70 +++++++++++++++++++ .../MusicBrainzLabelRequestGenerator.cs | 36 ++++++++++ .../MusicBrainzLabelSettings.cs | 30 ++++++++ 5 files changed, 187 insertions(+) create mode 100644 src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabel.cs create mode 100644 src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelApi.cs create mode 100644 src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelParser.cs create mode 100644 src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelRequestGenerator.cs create mode 100644 src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelSettings.cs diff --git a/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabel.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabel.cs new file mode 100644 index 000000000..f07725955 --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabel.cs @@ -0,0 +1,38 @@ +using System; +using NLog; +using NzbDrone.Common.Http; +using NzbDrone.Core.Configuration; +using NzbDrone.Core.MetadataSource; +using NzbDrone.Core.Parser; +using NzbDrone.Core.ThingiProvider; + +namespace NzbDrone.Core.ImportLists.MusicBrainzLabel +{ + public class MusicBrainzLabel : HttpImportListBase + { + public override string Name => "MusicBrainz Label"; + + public override ProviderMessage Message => new ProviderMessage("MusicBrainz Label only supports release groups within Label, other types of member will not be picked up by Lidarr", ProviderMessageType.Warning); + + public override ImportListType ListType => ImportListType.Other; + public override TimeSpan MinRefreshInterval => TimeSpan.FromHours(12); + + private readonly IMetadataRequestBuilder _requestBuilder; + + public MusicBrainzLabel(IHttpClient httpClient, IImportListStatusService importListStatusService, IConfigService configService, IParsingService parsingService, IMetadataRequestBuilder requestBuilder, Logger logger) + : base(httpClient, importListStatusService, configService, parsingService, logger) + { + _requestBuilder = requestBuilder; + } + + public override IImportListRequestGenerator GetRequestGenerator() + { + return new MusicBrainzLabelRequestGenerator(_requestBuilder) { Settings = Settings }; + } + + public override IParseImportListResponse GetParser() + { + return new MusicBrainzLabelParser(Settings); + } + } +} diff --git a/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelApi.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelApi.cs new file mode 100644 index 000000000..7f94f06dd --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelApi.cs @@ -0,0 +1,13 @@ +using System; + +namespace NzbDrone.Core.ImportLists.MusicBrainzLabel +{ + public class MusicBrainzLabelAlbum + { + public string ArtistName { get; set; } + public string AlbumTitle { get; set; } + public string ArtistId { get; set; } + public string AlbumId { get; set; } + public DateTime? ReleaseDate { get; set; } + } +} diff --git a/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelParser.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelParser.cs new file mode 100644 index 000000000..03c312fdb --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelParser.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using System.Net; +using Newtonsoft.Json; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.ImportLists.Exceptions; +using NzbDrone.Core.Parser.Model; + +namespace NzbDrone.Core.ImportLists.MusicBrainzLabel +{ + public class MusicBrainzLabelParser : IParseImportListResponse + { + private readonly MusicBrainzLabelSettings _settings; + private ImportListResponse _importListResponse; + + public MusicBrainzLabelParser(MusicBrainzLabelSettings settings) + { + _settings = settings; + } + + public IList ParseResponse(ImportListResponse importListResponse) + { + _importListResponse = importListResponse; + + var items = new List(); + + if (!PreProcess(_importListResponse)) + { + return items; + } + + var jsonResponse = JsonConvert.DeserializeObject>(_importListResponse.Content); + + // no albums were return + if (jsonResponse == null) + { + return items; + } + + foreach (var item in jsonResponse) + { + items.AddIfNotNull(new ImportListItemInfo + { + Artist = item.ArtistName, + Album = item.AlbumTitle, + ArtistMusicBrainzId = item.ArtistId, + AlbumMusicBrainzId = item.AlbumId, + ReleaseDate = item.ReleaseDate.GetValueOrDefault() + }); + } + + return items; + } + + protected virtual bool PreProcess(ImportListResponse importListResponse) + { + if (importListResponse.HttpResponse.StatusCode != HttpStatusCode.OK) + { + throw new ImportListException(importListResponse, "Import List API call resulted in an unexpected StatusCode [{0}]", importListResponse.HttpResponse.StatusCode); + } + + if (importListResponse.HttpResponse.Headers.ContentType != null && importListResponse.HttpResponse.Headers.ContentType.Contains("text/json") && + importListResponse.HttpRequest.Headers.Accept != null && !importListResponse.HttpRequest.Headers.Accept.Contains("text/json")) + { + throw new ImportListException(importListResponse, "Import List responded with html content. Site is likely blocked or unavailable."); + } + + return true; + } + } +} diff --git a/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelRequestGenerator.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelRequestGenerator.cs new file mode 100644 index 000000000..16af3293c --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelRequestGenerator.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using NzbDrone.Core.MetadataSource; + +namespace NzbDrone.Core.ImportLists.MusicBrainzLabel +{ + public class MusicBrainzLabelRequestGenerator : IImportListRequestGenerator + { + public MusicBrainzLabelSettings Settings { get; set; } + + private readonly IMetadataRequestBuilder _requestBulder; + + public MusicBrainzLabelRequestGenerator(IMetadataRequestBuilder requestBuilder) + { + _requestBulder = requestBuilder; + } + + public virtual ImportListPageableRequestChain GetListItems() + { + var pageableRequests = new ImportListPageableRequestChain(); + + pageableRequests.Add(GetPagedRequests()); + + return pageableRequests; + } + + private IEnumerable GetPagedRequests() + { + var request = _requestBulder.GetRequestBuilder() + .Create() + .SetSegment("route", "Label/" + Settings.LabelId) + .Build(); + + yield return new ImportListRequest(request); + } + } +} diff --git a/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelSettings.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelSettings.cs new file mode 100644 index 000000000..5f9717635 --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzLabel/MusicBrainzLabelSettings.cs @@ -0,0 +1,30 @@ +using FluentValidation; +using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.ImportLists.MusicBrainzLabel +{ + public class MusicBrainzLabelSettingsValidator : AbstractValidator + { + } + + public class MusicBrainzLabelSettings : IImportListSettings + { + private static readonly MusicBrainzLabelSettingsValidator Validator = new MusicBrainzLabelSettingsValidator(); + + public MusicBrainzLabelSettings() + { + BaseUrl = ""; + } + + public string BaseUrl { get; set; } + + [FieldDefinition(0, Label = "Label Id", HelpText = "The GUID at the end of the MusicBrainz URL (e.g. 4b5f2897-9b05-4799-b895-6620e27143e7)")] + public string LabelId { get; set; } + + public NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } + } +}