mirror of
https://github.com/maxdorninger/MediaManager.git
synced 2026-04-17 15:13:24 +02:00
85 lines
3.6 KiB
Python
85 lines
3.6 KiB
Python
import logging
|
|
import xml.etree.ElementTree as ET
|
|
from datetime import datetime
|
|
from email.utils import parsedate_to_datetime
|
|
|
|
from media_manager.indexer.schemas import IndexerQueryResult
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class TorznabMixin:
|
|
def process_search_result(self, xml: str) -> list[IndexerQueryResult]:
|
|
result_list: list[IndexerQueryResult] = []
|
|
xml_tree = ET.fromstring(xml) # noqa: S314 # trusted source, since it is user controlled
|
|
xmlns = {
|
|
"torznab": "http://torznab.com/schemas/2015/feed",
|
|
"atom": "http://www.w3.org/2005/Atom",
|
|
}
|
|
for item in xml_tree.findall("channel/item"):
|
|
try:
|
|
flags = []
|
|
seeders = 0
|
|
age = 0
|
|
indexer_name = "unknown"
|
|
|
|
if item.find("jackettindexer") is not None:
|
|
indexer_name = item.find("jackettindexer").text
|
|
if item.find("prowlarrindexer") is not None:
|
|
indexer_name = item.find("prowlarrindexer").text
|
|
|
|
is_usenet = (
|
|
item.find("enclosure").attrib["type"] != "application/x-bittorrent"
|
|
)
|
|
|
|
attributes = list(item.findall("torznab:attr", xmlns))
|
|
for attribute in attributes:
|
|
if is_usenet:
|
|
if attribute.attrib["name"] == "usenetdate":
|
|
posted_date = parsedate_to_datetime(
|
|
attribute.attrib["value"]
|
|
)
|
|
now = datetime.now(datetime.UTC)
|
|
age = int((now - posted_date).total_seconds())
|
|
else:
|
|
if attribute.attrib["name"] == "seeders":
|
|
seeders = int(attribute.attrib["value"])
|
|
|
|
if attribute.attrib["name"] == "downloadvolumefactor":
|
|
download_volume_factor = float(attribute.attrib["value"])
|
|
if download_volume_factor == 0:
|
|
flags.append("freeleech")
|
|
if download_volume_factor == 0.5:
|
|
flags.append("halfleech")
|
|
if download_volume_factor == 0.75:
|
|
flags.append("freeleech75")
|
|
if download_volume_factor == 0.25:
|
|
flags.append("freeleech25")
|
|
|
|
if attribute.attrib["name"] == "uploadvolumefactor":
|
|
upload_volume_factor = int(attribute.attrib["value"])
|
|
if upload_volume_factor == 2:
|
|
flags.append("doubleupload")
|
|
|
|
if not item.find("size") or item.find("size").text is None:
|
|
log.warning(
|
|
f"Torznab item {item.find('title').text} has no size, skipping."
|
|
)
|
|
continue
|
|
size = int(item.find("size").text or "0")
|
|
|
|
result = IndexerQueryResult(
|
|
title=item.find("title").text or "unknown",
|
|
download_url=str(item.find("enclosure").attrib["url"]),
|
|
seeders=seeders,
|
|
flags=flags,
|
|
size=size,
|
|
usenet=is_usenet,
|
|
age=age,
|
|
indexer=indexer_name,
|
|
)
|
|
result_list.append(result)
|
|
except Exception:
|
|
log.exception("1 Torznab search result failed")
|
|
return result_list
|