2020from __future__ import annotations
2121
2222from logging import getLogger
23- from typing import Any , Dict , List , Literal , Mapping , Optional , Set , Tuple , Type , Union
23+ from typing import (
24+ Any ,
25+ Dict ,
26+ Iterable ,
27+ List ,
28+ Literal ,
29+ Mapping ,
30+ Optional ,
31+ Set ,
32+ Tuple ,
33+ Type ,
34+ Union ,
35+ cast ,
36+ )
2437
2538from buildarr .config import RemoteMapEntry
2639from buildarr .types import BaseEnum , NonEmptyStr , Password , RssUrl
27- from pydantic import AnyHttpUrl , Field , PositiveInt
40+ from pydantic import AnyHttpUrl , Field , PositiveInt , validator
2841from typing_extensions import Annotated , Self
2942
3043from ..api import api_delete , api_get , api_post , api_put
3548
3649
3750class NabCategory (BaseEnum ):
38- """
39- Newznab/Torznab category enumeration.
40- """
51+ # https://github.com/Prowlarr/Prowlarr/blob/develop/src/NzbDrone.Core/Indexers/NewznabStandardCategory.cs
52+ TV = (5000 , "TV" )
53+ TV_WEBDL = (5010 , "TV/WEB-DL" )
54+ TV_FOREIGN = (5020 , "TV/Foreign" )
55+ TV_SD = (5030 , "TV/SD" )
56+ TV_HD = (5040 , "TV/HD" )
57+ TV_UHD = (5045 , "TV/UHD" )
58+ TV_OTHER = (5050 , "TV/Other" )
59+ TV_SPORT = (5060 , "TV/Sport" , "TV/Sports" )
60+ TV_ANIME = (5070 , "TV/Anime" )
61+ TV_DOCUMENTARY = (5080 , "TV/Documentary" )
62+ TV_X265 = (5090 , "TV/x265" )
4163
42- TV = 5000
43- TV_WEBDL = 5010
44- TV_FOREIGN = 5020
45- TV_SD = 5030
46- TV_HD = 5040
47- TV_UHD = 5045
48- TV_OTHER = 5050
49- TV_SPORTS = 5060
50- TV_ANIME = 5070
51- TV_DOCUMENTARY = 5080
64+ @classmethod
65+ def decode (cls , value : int ) -> Union [Self , int ]:
66+ try :
67+ return cls (value )
68+ except ValueError :
69+ return value
5270
53- # TODO: Make the enum also accept these values.
54- # TV_WEBDL = "TV/WEB-DL"
55- # TV_FOREIGN = "TV/Foreign"
56- # TV_SD = "TV/SD"
57- # TV_HD = "TV/HD"
58- # TV_UHD = "TV/UHD"
59- # TV_OTHER = "TV/Other"
60- # TV_SPORTS = "TV/Sports"
61- # TV_ANIME = "TV/Anime"
62- # TV_DOCUMENTARY = "TV/Documentary"
71+ @classmethod
72+ def encode (cls , value : Union [Self , int ]) -> int :
73+ return value if isinstance (value , int ) else cast (int , value .value )
6374
6475
6576class FilelistCategory (BaseEnum ):
@@ -368,22 +379,28 @@ class NewznabIndexer(UsenetIndexer):
368379 API key for use with the Newznab API.
369380 """
370381
371- categories : Set [NabCategory ] = {NabCategory .TV_SD , NabCategory .TV_HD }
382+ categories : Set [Union [ NabCategory , int ] ] = {NabCategory .TV_SD , NabCategory .TV_HD }
372383 """
373384 Categories to monitor for standard/daily shows.
374385 Define as empty to disable.
375386
376387 Values:
377388
378- * `TV-WEBDL`
379- * `TV-Foreign`
380- * `TV-SD`
381- * `TV-HD`
382- * `TV-UHD`
383- * `TV-Other`
384- * `TV-Sports`
385- * `TV-Anime`
386- * `TV-Documentary`
389+ * `TV`
390+ * `TV/WEB-DL`
391+ * `TV/Foreign`
392+ * `TV/SD`
393+ * `TV/HD`
394+ * `TV/UHD`
395+ * `TV/Other`
396+ * `TV/Sport`
397+ * `TV/Anime`
398+ * `TV/Documentary`
399+ * `TV/x265`
400+
401+ *Changed in version 0.6.1*: The Sonarr-native values for Newznab/Torznab categories
402+ (e.g. `TV/WEB-DL`) can now be specified, instead of the Buildarr-native values
403+ (e.g. `TV-WEBDL`). The old values can still be used.
387404 """
388405
389406 anime_categories : Set [NabCategory ] = set ()
@@ -393,15 +410,21 @@ class NewznabIndexer(UsenetIndexer):
393410
394411 Values:
395412
396- * `TV-WEBDL`
397- * `TV-Foreign`
398- * `TV-SD`
399- * `TV-HD`
400- * `TV-UHD`
401- * `TV-Other`
402- * `TV-Sports`
403- * `TV-Anime`
404- * `TV-Documentary`
413+ * `TV`
414+ * `TV/WEB-DL`
415+ * `TV/Foreign`
416+ * `TV/SD`
417+ * `TV/HD`
418+ * `TV/UHD`
419+ * `TV/Other`
420+ * `TV/Sport`
421+ * `TV/Anime`
422+ * `TV/Documentary`
423+ * `TV/x265`
424+
425+ *Changed in version 0.6.1*: The Sonarr-native values for Newznab/Torznab categories
426+ (e.g. `TV/WEB-DL`) can now be specified, instead of the Buildarr-native values
427+ (e.g. `TV-WEBDL`). The old values can still be used.
405428 """
406429
407430 anime_standard_format_search : bool = False
@@ -424,12 +447,12 @@ class NewznabIndexer(UsenetIndexer):
424447 (
425448 "categories" ,
426449 "categories" ,
427- {"is_field" : True , "encoder" : lambda v : sorted (c . value for c in v )},
450+ {"is_field" : True , "encoder" : lambda v : sorted (NabCategory . encode ( c ) for c in v )},
428451 ),
429452 (
430453 "anime_categories" ,
431454 "animeCategories" ,
432- {"is_field" : True , "encoder" : lambda v : sorted (c . value for c in v )},
455+ {"is_field" : True , "encoder" : lambda v : sorted (NabCategory . encode ( c ) for c in v )},
433456 ),
434457 ("anime_standard_format_search" , "animeStandardFormatSearch" , {"is_field" : True }),
435458 (
@@ -439,6 +462,16 @@ class NewznabIndexer(UsenetIndexer):
439462 ),
440463 ]
441464
465+ @validator ("categories" , "anime_categories" )
466+ def validate_categories (
467+ cls ,
468+ value : Iterable [Union [NabCategory , int ]],
469+ ) -> Set [Union [NabCategory , int ]]:
470+ return set (
471+ NabCategory .decode (category ) if isinstance (category , int ) else category
472+ for category in value
473+ )
474+
442475
443476class OmgwtfnzbsIndexer (UsenetIndexer ):
444477 """
@@ -860,15 +893,21 @@ class TorznabIndexer(TorrentIndexer):
860893
861894 Values:
862895
863- * `TV-WEBDL`
864- * `TV-Foreign`
865- * `TV-SD`
866- * `TV-HD`
867- * `TV-UHD`
868- * `TV-Other`
869- * `TV-Sports`
870- * `TV-Anime`
871- * `TV-Documentary`
896+ * `TV`
897+ * `TV/WEB-DL`
898+ * `TV/Foreign`
899+ * `TV/SD`
900+ * `TV/HD`
901+ * `TV/UHD`
902+ * `TV/Other`
903+ * `TV/Sport`
904+ * `TV/Anime`
905+ * `TV/Documentary`
906+ * `TV/x265`
907+
908+ *Changed in version 0.6.1*: The Sonarr-native values for Newznab/Torznab categories
909+ (e.g. `TV/WEB-DL`) can now be specified, instead of the Buildarr-native values
910+ (e.g. `TV-WEBDL`). The old values can still be used.
872911 """
873912
874913 anime_categories : Set [NabCategory ] = set ()
@@ -877,15 +916,21 @@ class TorznabIndexer(TorrentIndexer):
877916
878917 Values:
879918
880- * `TV-WEBDL`
881- * `TV-Foreign`
882- * `TV-SD`
883- * `TV-HD`
884- * `TV-UHD`
885- * `TV-Other`
886- * `TV-Sports`
887- * `TV-Anime`
888- * `TV-Documentary`
919+ * `TV`
920+ * `TV/WEB-DL`
921+ * `TV/Foreign`
922+ * `TV/SD`
923+ * `TV/HD`
924+ * `TV/UHD`
925+ * `TV/Other`
926+ * `TV/Sport`
927+ * `TV/Anime`
928+ * `TV/Documentary`
929+ * `TV/x265`
930+
931+ *Changed in version 0.6.1*: The Sonarr-native values for Newznab/Torznab categories
932+ (e.g. `TV/WEB-DL`) can now be specified, instead of the Buildarr-native values
933+ (e.g. `TV-WEBDL`). The old values can still be used.
889934 """
890935
891936 anime_standard_format_search : bool = False
@@ -908,12 +953,12 @@ class TorznabIndexer(TorrentIndexer):
908953 (
909954 "categories" ,
910955 "categories" ,
911- {"is_field" : True , "encoder" : lambda v : sorted (c . value for c in v )},
956+ {"is_field" : True , "encoder" : lambda v : sorted (NabCategory . encode ( c ) for c in v )},
912957 ),
913958 (
914959 "anime_categories" ,
915960 "animeCategories" ,
916- {"is_field" : True , "encoder" : lambda v : sorted (c . value for c in v )},
961+ {"is_field" : True , "encoder" : lambda v : sorted (NabCategory . encode ( c ) for c in v )},
917962 ),
918963 ("anime_standard_format_search" , "animeStandardFormatSearch" , {"is_field" : True }),
919964 (
@@ -923,6 +968,16 @@ class TorznabIndexer(TorrentIndexer):
923968 ),
924969 ]
925970
971+ @validator ("categories" , "anime_categories" )
972+ def validate_categories (
973+ cls ,
974+ value : Iterable [Union [NabCategory , int ]],
975+ ) -> Set [Union [NabCategory , int ]]:
976+ return set (
977+ NabCategory .decode (category ) if isinstance (category , int ) else category
978+ for category in value
979+ )
980+
926981
927982INDEXER_TYPES : Tuple [Type [Indexer ], ...] = (
928983 FanzubIndexer ,
0 commit comments