#!/usr/bin/env python3 from time import sleep import requests import toml import logging import xml.dom.minidom import re import transmission_rpc import os import sys from dataclasses import dataclass logging.basicConfig(format="%(name)s - %(levelname)s - %(message)s", level=logging.INFO) logger = logging.getLogger(__name__) config = toml.load("/etc/nyaa-tools/config.toml") series = toml.load("/etc/nyaa-tools/series.toml") release_groups = toml.load("/etc/nyaa-tools/release-groups.toml") def jelly_path(name: str, season: int, episode=None, offset=0) -> str: if episode is None: return "{base}/{name}/Season {season:02}".format( base=config["library"]["base_path"], name=name, season=season, ) else: return "{base}/{name}/Season {season:02}/Episode S{season:02}E{episode:02}.mkv".format( base=config["library"]["base_path"], name=name, season=season, episode=episode + offset, ) if len(sys.argv) > 1: logger.info("Searching for {}".format(" ".join(sys.argv[1:]))) nyaa_body = requests.get( "https://nyaa.si/?page=rss&q={}".format(" ".join(sys.argv[1:])) ).text else: nyaa_body = requests.get("https://nyaa.si/?page=rss").text items = xml.dom.minidom.parseString(nyaa_body).getElementsByTagName("item") @dataclass class DownloadItem: torrent_id: int name: str season: int episode: int offset: int downloading: list[DownloadItem] = [] client: transmission_rpc.Client = None for item in items: title: str = item.getElementsByTagName("title")[0].firstChild.data link: str = item.getElementsByTagName("link")[0].firstChild.data logger.debug("Checking {}".format(title)) for season in series["tracking"]: regex = re.search(release_groups[season["release_group"]], title) if regex is None: continue if season["name"] in regex.group("title"): logger.debug("Title matched for {}".format(season["name"])) # Extract chapter number chapter = int(regex.group("episode")) logger.debug("Chapter extracted: {}".format(chapter)) # Check if chapter already exists path = jelly_path( season["name"], season["season"], chapter, season.get("offset", 0) ) if os.path.exists(path): logger.debug( 'Chapter {} for "{}" already exists. Skipping'.format( chapter, season["name"] ) ) continue # Sign in to Transmission client = transmission_rpc.Client(host=config["transmission"]["host"]) torrent = client.add_torrent(link) downloading.append( DownloadItem( torrent.id, season["name"], season["season"], chapter, season.get("offset", 0), ) ) logger.info("Downloading {}".format(title)) while len(downloading) > 0: for item in downloading: torrent = client.get_torrent(item.torrent_id) if torrent.left_until_done == 0: if not os.path.exists(jelly_path(item.name, item.season)): logger.warning( 'Season folder for "{}" did not exist, creating recursively'.format( item.name ) ) os.makedirs(jelly_path(item.name, item.season)) os.link( config["transmission"]["download_path"] + "/" + torrent.get_files()[0].name, jelly_path(item.name, item.season, item.episode, item.offset), ) logger.info( 'Linked "{}" season {} chapter {}'.format( item.name, item.season, item.episode + item.offset ) ) downloading.remove(item) sleep(5)