From 7cd556bab2faf886d3c3b148571da3f5f932e2cf Mon Sep 17 00:00:00 2001 From: Nic Jones Date: Fri, 20 Mar 2026 22:14:28 -0400 Subject: [PATCH] Added tracker info to releases --- src/watfag/__init__.py | 2 +- src/watfag/parsers/generic/__init__.py | 37 +++++++++++++++++++------ src/watfag/parsers/movie/__init__.py | 10 +++++-- src/watfag/parsers/tvboxset/__init__.py | 10 +++++-- src/watfag/search.py | 18 ++++++------ src/watfag/trackers.py | 19 +++++++++++++ 6 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 src/watfag/trackers.py diff --git a/src/watfag/__init__.py b/src/watfag/__init__.py index 7863915..976498a 100644 --- a/src/watfag/__init__.py +++ b/src/watfag/__init__.py @@ -1 +1 @@ -__version__ = "1.0.2" +__version__ = "1.0.3" diff --git a/src/watfag/parsers/generic/__init__.py b/src/watfag/parsers/generic/__init__.py index 9ebfebc..94d854a 100644 --- a/src/watfag/parsers/generic/__init__.py +++ b/src/watfag/parsers/generic/__init__.py @@ -2,25 +2,30 @@ import importlib from pathlib import Path from pkgutil import iter_modules from typing import Optional, Type +from xml.etree.ElementTree import Element from watfag.parsers.generic.parsers import DataParser from watfag.parsers.generic.watfag import * from watfag.parsers.generic.watfag import WATFAG +from watfag.trackers import TrackerInfo class Release: def __init__( self, - unparsed_text, - dl_link, - **kwargs + xml_result: Element, + tracker_info: Optional[TrackerInfo] = None ): - self.original_text: str = unparsed_text + self.xml: Element = xml_result + self.tracker_info: Optional[TrackerInfo] = tracker_info + self.original_text: str = '' self.metadata_text: Optional[str] = '' - self.dl_link: str = dl_link - self.view_link: str = kwargs.get('view_link', dl_link) - self.size: int = kwargs.get('size', 0) - self.seeders: int = kwargs.get('seeders', 0) + self.dl_link: str = '' + self.view_link: str = '' + self.size: int = 0 + self.seeders: int = 0 + self.tracker: str = '' + self.tracker_abbr: str = '' self.seed_status: Optional[SeedStatus] = None self.parser_results: dict[str, bool] = {} # Stores which parsers have been run and their results. @@ -37,6 +42,22 @@ class Release: self.repack: Optional[Repack] = None self.multi: Optional[Multi] = None + self._parse_xml() + + def _parse_xml(self): + # Get the torznab attributes + attrs: dict[str, list[str]] = {} + for attr in self.xml.findall('torznab:attr', namespaces={'torznab': 'http://torznab.com/schemas/2015/feed'}): + attrs[attr.get('name')] = attrs.get(attr.get('name'), []) + [attr.get('value')] + + self.original_text = self.xml.find('title').text + self.dl_link = self.xml.find('link').text + self.size = int(self.xml.find('size').text) + self.seeders = int(attrs.get('seeders')[0]) + self.view_link = self.xml.find('comments').text + self.tracker = self.xml.find('jackettindexer').text + self.tracker_abbr = self.tracker_info.get_tracker_info(self.tracker).get('Abbreviation') if self.tracker_info else self.tracker + def __lt__(self, other): return self.watfag < other.watfag diff --git a/src/watfag/parsers/movie/__init__.py b/src/watfag/parsers/movie/__init__.py index 694131f..811da9d 100644 --- a/src/watfag/parsers/movie/__init__.py +++ b/src/watfag/parsers/movie/__init__.py @@ -2,15 +2,21 @@ import importlib from pathlib import Path from pkgutil import iter_modules from typing import Optional +from xml.etree.ElementTree import Element from watfag.parsers.generic import Release, ParserManager +from watfag.trackers import TrackerInfo class MovieRelease(Release): """Holds info representing a release of a movie.""" - def __init__(self, unparsed_text, dl_link, **kwargs): - super().__init__(unparsed_text, dl_link, **kwargs) + def __init__( + self, + xml_result: Element, + tracker_info: Optional[TrackerInfo] = None + ): + super().__init__(xml_result, tracker_info) self.year: int = 0 self.edition: Optional[str] = None diff --git a/src/watfag/parsers/tvboxset/__init__.py b/src/watfag/parsers/tvboxset/__init__.py index 2940d2e..9f59fd1 100644 --- a/src/watfag/parsers/tvboxset/__init__.py +++ b/src/watfag/parsers/tvboxset/__init__.py @@ -2,14 +2,20 @@ import importlib from pathlib import Path from pkgutil import iter_modules from typing import Optional +from xml.etree.ElementTree import Element from watfag.parsers.generic import Release, ParserManager +from watfag.trackers import TrackerInfo class TVBoxSetRelease(Release): """Holds info representing a release of a TV box set.""" - def __init__(self, unparsed_text, dl_link, **kwargs): - super().__init__(unparsed_text, dl_link, **kwargs) + def __init__( + self, + xml_result: Element, + tracker_info: Optional[TrackerInfo] = None + ): + super().__init__(xml_result, tracker_info) self.seasons: Optional[str] = None def __str__(self): diff --git a/src/watfag/search.py b/src/watfag/search.py index d2f2543..c560f84 100644 --- a/src/watfag/search.py +++ b/src/watfag/search.py @@ -5,6 +5,7 @@ from httpx import AsyncClient from watfag.parsers.generic import Release from watfag.parsers.movie import MovieRelease, MovieParserManager from watfag.parsers.tvboxset import TVBoxSetRelease, TVBoxSetParserManager +from watfag.trackers import TrackerInfo class Jackett: @@ -13,6 +14,9 @@ class Jackett: self.base_url = base_url self.movie_parser = MovieParserManager() self.tvboxset_parser = TVBoxSetParserManager() + self.tracker_info = TrackerInfo( + "https://raw.githubusercontent.com/HDVinnie/Private-Trackers-Spreadsheet/refs/heads/master/trackers.json" + ) async def get_capabilities(self): params = { @@ -45,21 +49,15 @@ class Jackett: # Find out from categories what kind of result this is if any(cat.startswith('2') for cat in attrs.get('category')): # This is a movie release = MovieRelease( - item.find('title').text, - item.find('link').text, - size=int(item.find('size').text), - seeders=int(attrs.get('seeders')[0]), - view_link=item.find('comments').text + item, + self.tracker_info ) self.movie_parser.run_parsers(release) releases.append(release) elif any(cat == '100027' for cat in attrs.get('category')): # This is a TV boxset release = TVBoxSetRelease( - item.find('title').text, - item.find('link').text, - size=int(item.find('size').text), - seeders=int(attrs.get('seeders')[0]), - view_link=item.find('comments').text + item, + self.tracker_info ) self.tvboxset_parser.run_parsers(release) releases.append(release) diff --git a/src/watfag/trackers.py b/src/watfag/trackers.py new file mode 100644 index 0000000..8575265 --- /dev/null +++ b/src/watfag/trackers.py @@ -0,0 +1,19 @@ +from typing import Optional + +import httpx + + +class TrackerInfo: + def __init__(self, url): + self.url = url + self.json: Optional[dict] = None + + def _refresh(self): + r = httpx.get(self.url) + r.raise_for_status() + self.json = r.json().get('trackers', []) + + def get_tracker_info(self, tracker_name): + if self.json is None: + self._refresh() + return next((tracker for tracker in self.json if tracker['Name'] == tracker_name), None)