126 lines
4 KiB
Python
Executable file
126 lines
4 KiB
Python
Executable file
#!/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)
|