diff --git a/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeries.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeries.cs new file mode 100644 index 000000000..b7852620f --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeries.cs @@ -0,0 +1,36 @@ +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.MusicBrainzSeries +{ + public class MusicBrainzSeries : HttpImportListBase + { + public override string Name => "MusicBrainz Series"; + + public override ProviderMessage Message => new ProviderMessage("MusicBrainz Series only supports release groups within series, other types of member will not be picked up by Lidarr", ProviderMessageType.Warning); + + public override ImportListType ListType => ImportListType.Other; + + private readonly IMetadataRequestBuilder _requestBuilder; + + public MusicBrainzSeries(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 MusicBrainzSeriesRequestGenerator(_requestBuilder) { Settings = Settings }; + } + + public override IParseImportListResponse GetParser() + { + return new MusicBrainzSeriesParser(Settings); + } + } +} diff --git a/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesApi.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesApi.cs new file mode 100644 index 000000000..e38396c46 --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesApi.cs @@ -0,0 +1,13 @@ +using System; + +namespace NzbDrone.Core.ImportLists.MusicBrainzSeries +{ + public class MusicBrainzSeriesAlbum + { + 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/MusicBrainzSeries/MusicBrainzSeriesParser.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesParser.cs new file mode 100644 index 000000000..3b137655f --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesParser.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.MusicBrainzSeries +{ + public class MusicBrainzSeriesParser : IParseImportListResponse + { + private readonly MusicBrainzSeriesSettings _settings; + private ImportListResponse _importListResponse; + + public MusicBrainzSeriesParser(MusicBrainzSeriesSettings 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/MusicBrainzSeries/MusicBrainzSeriesRequestGenerator.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesRequestGenerator.cs new file mode 100644 index 000000000..4c25b71e3 --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesRequestGenerator.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using NzbDrone.Core.MetadataSource; + +namespace NzbDrone.Core.ImportLists.MusicBrainzSeries +{ + public class MusicBrainzSeriesRequestGenerator : IImportListRequestGenerator + { + public MusicBrainzSeriesSettings Settings { get; set; } + + private readonly IMetadataRequestBuilder _requestBulder; + + public MusicBrainzSeriesRequestGenerator(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", "series/" + Settings.SeriesId) + .Build(); + + yield return new ImportListRequest(request); + } + } +} diff --git a/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesSettings.cs b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesSettings.cs new file mode 100644 index 000000000..0c083dc42 --- /dev/null +++ b/src/NzbDrone.Core/ImportLists/MusicBrainzSeries/MusicBrainzSeriesSettings.cs @@ -0,0 +1,33 @@ +using FluentValidation; +using NzbDrone.Core.Annotations; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.ImportLists.MusicBrainzSeries +{ + public class MusicBrainzSeriesSettingsValidator : AbstractValidator + { + public MusicBrainzSeriesSettingsValidator() + { + } + } + + public class MusicBrainzSeriesSettings : IImportListSettings + { + private static readonly MusicBrainzSeriesSettingsValidator Validator = new MusicBrainzSeriesSettingsValidator(); + + public MusicBrainzSeriesSettings() + { + BaseUrl = ""; + } + + public string BaseUrl { get; set; } + + [FieldDefinition(0, Label = "Series Id", HelpText = "The GUID at the end of the MusicBrainz URL (e.g. 4b5f2897-9b05-4799-b895-6620e27143e7)")] + public string SeriesId { get; set; } + + public NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } + } +}