50 lines
1.9 KiB
Python
50 lines
1.9 KiB
Python
"""Collect best per-season magnets for a show. Prints SEASON|infohash|size|seeders|name."""
|
|
import asyncio
|
|
import sys
|
|
from torrent_search.wrapper import TorrentSearchApi
|
|
|
|
|
|
async def collect(show: str, seasons: range):
|
|
api = TorrentSearchApi()
|
|
for s in seasons:
|
|
best = None
|
|
for q in (
|
|
f"{show} season {s} 1080p x265",
|
|
f"{show} s{s:02d} 1080p",
|
|
f"{show} season {s} complete 720p",
|
|
f"{show} season {s}",
|
|
):
|
|
ts = await api.search_torrents(q, max_items=20)
|
|
cands = []
|
|
for t in ts:
|
|
fn = t.filename.lower()
|
|
# Match this exact season, avoid multi-season packs and wrong show
|
|
if show.split()[0].lower() not in fn:
|
|
continue
|
|
hit = (
|
|
f"s{s:02d}" in fn
|
|
or f"season {s:02d}" in fn
|
|
or f"season {s} " in fn
|
|
or f"season {s}." in fn
|
|
or fn.rstrip().endswith(f"season {s}")
|
|
)
|
|
# Reject ranges like S01-S07 / Seasons 1 to N
|
|
rangey = "-s" in fn or " to " in fn or "1-" in fn or "complete series" in fn
|
|
if hit and not rangey:
|
|
score = (1 if ("x265" in fn or "hevc" in fn) else 0, int(t.seeders or 0))
|
|
cands.append((score, t))
|
|
if cands:
|
|
cands.sort(key=lambda x: x[0], reverse=True)
|
|
b = cands[0][1]
|
|
if b.magnet_link and "btih:" in b.magnet_link:
|
|
ih = b.magnet_link.split("btih:", 1)[1][:40]
|
|
print(f"S{s:02d}|{ih}|{b.size}|{b.seeders}|{b.filename[:60]}", flush=True)
|
|
break
|
|
else:
|
|
print(f"S{s:02d}|MISSING", flush=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
show = sys.argv[1]
|
|
lo, hi = int(sys.argv[2]), int(sys.argv[3])
|
|
asyncio.run(collect(show, range(lo, hi + 1)))
|