From d4c063df56a5d758dcce18258d1bf6c026dfb87e Mon Sep 17 00:00:00 2001 From: Carl Lewis Date: Sat, 29 Jul 2023 12:45:13 -0400 Subject: [PATCH] Added additional filtering capability by Media airing status. Note: Anilist currently does not support this type of filtering at the query level, so this is done as a post-processing step. --- .../ImportLists/AniList/AniListImportBase.cs | 5 -- .../ImportLists/AniList/AniListTypes.cs | 28 +++++++++++ .../ImportLists/AniList/List/AniListImport.cs | 5 ++ .../AniList/{ => List}/AniListParser.cs | 48 +++++++++++++++++-- .../AniList/List/AniListSettings.cs | 32 ++++++++++--- 5 files changed, 103 insertions(+), 15 deletions(-) rename src/NzbDrone.Core/ImportLists/AniList/{ => List}/AniListParser.cs (70%) diff --git a/src/NzbDrone.Core/ImportLists/AniList/AniListImportBase.cs b/src/NzbDrone.Core/ImportLists/AniList/AniListImportBase.cs index c3d876ec2..ab971ae1a 100644 --- a/src/NzbDrone.Core/ImportLists/AniList/AniListImportBase.cs +++ b/src/NzbDrone.Core/ImportLists/AniList/AniListImportBase.cs @@ -47,11 +47,6 @@ namespace NzbDrone.Core.ImportLists.AniList public Dictionary Mappings => _cache.Get(_cacheKey, GetMappingData, _cacheInterval); - public override AniListParser GetParser() - { - return new AniListParser(_logger, Mappings); - } - public override object RequestAction(string action, IDictionary query) { if (action == "startOAuth") diff --git a/src/NzbDrone.Core/ImportLists/AniList/AniListTypes.cs b/src/NzbDrone.Core/ImportLists/AniList/AniListTypes.cs index 373f01c3c..7ed22af59 100644 --- a/src/NzbDrone.Core/ImportLists/AniList/AniListTypes.cs +++ b/src/NzbDrone.Core/ImportLists/AniList/AniListTypes.cs @@ -39,6 +39,34 @@ namespace NzbDrone.Core.ImportLists.AniList public const string Repeating = "REPEATING"; } + public static class MediaStatus + { + /// + /// Anime series has finished airing + /// + public const string Finished = "FINISHED"; + + /// + /// Anime series is currently airing + /// + public const string Releasing = "RELEASING"; + + /// + /// Anime series had not yet begun airing + /// + public const string Unreleased = "NOT_YET_RELEASED"; + + /// + /// Anime series was cancelled + /// + public const string Cancelled = "CANCELLED"; + + /// + /// Anime series is currently on hiatus + /// + public const string Hiatus = "HIATUS"; + } + /// /// Data during token refresh cycles /// diff --git a/src/NzbDrone.Core/ImportLists/AniList/List/AniListImport.cs b/src/NzbDrone.Core/ImportLists/AniList/List/AniListImport.cs index 4f49d7d75..cc241b20b 100644 --- a/src/NzbDrone.Core/ImportLists/AniList/List/AniListImport.cs +++ b/src/NzbDrone.Core/ImportLists/AniList/List/AniListImport.cs @@ -39,6 +39,11 @@ namespace NzbDrone.Core.ImportLists.AniList.List }; } + public override AniListParser GetParser() + { + return new AniListParser(_logger, Settings, Mappings); + } + /// /// Anilist caps the result list to 50 items at maximum per query, so the data must be pulled in batches. /// diff --git a/src/NzbDrone.Core/ImportLists/AniList/AniListParser.cs b/src/NzbDrone.Core/ImportLists/AniList/List/AniListParser.cs similarity index 70% rename from src/NzbDrone.Core/ImportLists/AniList/AniListParser.cs rename to src/NzbDrone.Core/ImportLists/AniList/List/AniListParser.cs index 9388c76ea..f59fbd4e9 100644 --- a/src/NzbDrone.Core/ImportLists/AniList/AniListParser.cs +++ b/src/NzbDrone.Core/ImportLists/AniList/List/AniListParser.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using System.Net; using NLog; using NzbDrone.Common.Extensions; @@ -6,17 +7,19 @@ using NzbDrone.Common.Serializer; using NzbDrone.Core.ImportLists.Exceptions; using NzbDrone.Core.Parser.Model; -namespace NzbDrone.Core.ImportLists.AniList +namespace NzbDrone.Core.ImportLists.AniList.List { public class AniListParser : IParseImportListResponse { private readonly Dictionary _mappings; private readonly Logger _logger; + private readonly AniListSettings _settings; - public AniListParser(Logger logger, Dictionary mappings) + public AniListParser(Logger logger, AniListSettings settings, Dictionary mappings) { _mappings = mappings; _logger = logger; + _settings = settings; } public virtual IList ParseResponse(ImportListResponse importListResponse) @@ -42,7 +45,11 @@ namespace NzbDrone.Core.ImportLists.AniList return result; } - foreach (var item in jsonResponse.Data.Page.MediaList) + // Filter out unwanted series status types + var filtered = jsonResponse.Data.Page.MediaList + .Where(x => ValidateMediaStatus(x.Media)); + + foreach (var item in filtered) { var media = item.Media; @@ -85,6 +92,41 @@ namespace NzbDrone.Core.ImportLists.AniList return result; } + /// + /// Filter by media status, based on user settings. + /// + /// Anilist currently does not support filtering this at the query level, so it must be done in post. + /// + private bool ValidateMediaStatus(MediaInfo media) + { + if (media.Status == MediaStatus.Finished && _settings.ImportFinished) + { + return true; + } + + if (media.Status == MediaStatus.Releasing && _settings.ImportReleasing) + { + return true; + } + + if (media.Status == MediaStatus.Unreleased && _settings.ImportUnreleased) + { + return true; + } + + if (media.Status == MediaStatus.Cancelled && _settings.ImportCancelled) + { + return true; + } + + if (media.Status == MediaStatus.Hiatus && _settings.ImportHiatus) + { + return true; + } + + return false; + } + protected virtual bool PreProcess(ImportListResponse netImportResponse) { if (netImportResponse.HttpResponse.StatusCode != HttpStatusCode.OK) diff --git a/src/NzbDrone.Core/ImportLists/AniList/List/AniListSettings.cs b/src/NzbDrone.Core/ImportLists/AniList/List/AniListSettings.cs index cf36ed3ab..1b7fae84e 100644 --- a/src/NzbDrone.Core/ImportLists/AniList/List/AniListSettings.cs +++ b/src/NzbDrone.Core/ImportLists/AniList/List/AniListSettings.cs @@ -19,13 +19,16 @@ namespace NzbDrone.Core.ImportLists.AniList.List public class AniListSettings : AniListSettingsBase { public const string sectionImport = "Import List Status"; - public const string unitStatusType = "Status Type"; + public const string unitListStatus = "List Status"; + public const string unitMediaStatus = "Media Status"; public AniListSettings() : base() { ImportCurrent = true; ImportPlanning = true; + ImportReleasing = true; + ImportFinished = true; } protected override AbstractValidator Validator => new AniListSettingsValidator(); @@ -33,22 +36,37 @@ namespace NzbDrone.Core.ImportLists.AniList.List [FieldDefinition(1, Label = "Username", HelpText = "Username for the List to import from")] public string Username { get; set; } - [FieldDefinition(0, Label = "Import Watching", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitStatusType)] + [FieldDefinition(0, Label = "Import Watching", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitListStatus)] public bool ImportCurrent { get; set; } - [FieldDefinition(0, Label = "Import Planning", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitStatusType)] + [FieldDefinition(0, Label = "Import Planning", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitListStatus)] public bool ImportPlanning { get; set; } - [FieldDefinition(0, Label = "Import Completed", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitStatusType)] + [FieldDefinition(0, Label = "Import Completed", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitListStatus)] public bool ImportCompleted { get; set; } - [FieldDefinition(0, Label = "Import Dropped", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitStatusType)] + [FieldDefinition(0, Label = "Import Dropped", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitListStatus)] public bool ImportDropped { get; set; } - [FieldDefinition(0, Label = "Import Paused", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitStatusType)] + [FieldDefinition(0, Label = "Import Paused", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitListStatus)] public bool ImportPaused { get; set; } - [FieldDefinition(0, Label = "Import Repeating", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitStatusType)] + [FieldDefinition(0, Label = "Import Repeating", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitListStatus)] public bool ImportRepeating { get; set; } + + [FieldDefinition(0, Label = "Import Finished Airing Series", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitMediaStatus)] + public bool ImportFinished { get; set; } + + [FieldDefinition(0, Label = "Import Currently Airing Series", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitMediaStatus)] + public bool ImportReleasing { get; set; } + + [FieldDefinition(0, Label = "Import Not Yet Airing Series", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitMediaStatus)] + public bool ImportUnreleased { get; set; } + + [FieldDefinition(0, Label = "Import Cancelled Series", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitMediaStatus)] + public bool ImportCancelled { get; set; } + + [FieldDefinition(0, Label = "Import Series on Hiatus", Type = FieldType.Checkbox, Section = sectionImport, Unit = unitMediaStatus)] + public bool ImportHiatus { get; set; } } }