Skip to content
This repository was archived by the owner on Jun 14, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 38 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,41 +49,44 @@ Many thanks to all who have contributed.

|Name|Acronym|Name|Acronym|
|-|:-:|-|:-:|
|Aither|AITHER|Alpharatio|AR|
|Amigos-Share|ASC|Anthelion|ANT|
|AsianCinema|ACM|Aura4K|A4K|
|AvistaZ|AZ|Beyond-HD|BHD|
|BitHDTV|BHDTV|Blutopia|BLU|
|BrasilJapão-Share|BJS|BrasilTracker|BT|
|CapybaraBR|CBR|CinemaZ|CZ|
|Cinematik|TIK|DarkPeers|DP|
|DigitalCore|DC|DesiTorrents|DT|
|Emuwarez|EMUW|
|FearNoPeer|FNP|FileList|FL|
|Friki|FRIKI|FunFile|FF|
|GreatPosterWall|GPW|hawke-uno|HUNO|
|HDBits|HDB|HD-Space|HDS|
|HD-Torrents|HDT|HomieHelpDesk|HHD|
|ImmortalSeed|IS|InfinityHD|IHD|
|ItaTorrents|ITT|LastDigitalUnderground|LDU|
|Lat-Team|LT|Locadora|LCD|
|LST|LST|Luminarr|LUME|
|MoreThanTV|MTV|Nebulance|NBL|
|OldToonsWorld|OTW|OnlyEncodes+|OE|
|PassThePopcorn|PTP|PolishTorrent|PTT|
|Portugas|PT|PrivateHD|PHD|
|PTerClub|PTER|PTSKIT|PTS|
|Racing4Everyone|R4E|Rastastugan|RAS|
|ReelFLiX|RF|RetroFlix|RTF|
|Samaritano|SAM|seedpool|SP|
|ShareIsland|SHRI|SkipTheCommerials|STC|
|SpeedApp|SPD|Swarmazon|SN|
|The Leach Zone|TLZ|TheOldSchool|TOS|
|ToTheGlory|TTG|TorrentHR|THR|
|Torrenteros|TTR|TorrentLeech|TL|
|TVChaosUK|TVC|ULCX|ULCX|
|UTOPIA|UTP|YOiNKED|YOINK|
|YUSCENE|YUS|||
Aither|AITHER|Luminarr|LUME
Alpharatio|AR|MoreThanTV|MTV
Amigos-Share|ASC|M-Team|MTEAM
Anthelion|ANT|Nebulance|NBL
AsianCinema|ACM|OldToonsWorld|OTW
Aura4K|A4K|OnlyEncodes+|OE
AvistaZ|AZ|PassThePopcorn|PTP
Beyond-HD|BHD|PolishTorrent|PTT
BitHDTV|BHDTV|Portugas|PT
Blutopia|BLU|PrivateHD|PHD
BrasilJapão-Share|BJS|PT GTK|PTGTK
BrasilTracker|BT|ptcafe|PTCAFE
CapybaraBR|CBR|PTerClub|PTER
Cinematik|TIK|PTFans|PTFANS
CinemaZ|CZ|PTSKIT|PTS
DarkPeers|DP|Racing4Everyone|R4E
DesiTorrents|DT|RailgunPT|RPT
DigitalCore|DC|Rastastugan|RAS
Emuwarez|EMUW|ReelFLiX|RF
FearNoPeer|FNP|RetroFlix|RTF
FileList|FL|Samaritano|SAM
Friki|FRIKI|seedpool|SP
FunFile|FF|ShareIsland|SHRI
GreatPosterWall|GPW|SkipTheCommerials|STC
hawke-uno|HUNO|SpeedApp|SPD
HDBits|HDB|Swarmazon|SN
HD-Space|HDS|The Leach Zone|TLZ
HD-Torrents|HDT|TheOldSchool|TOS
HomieHelpDesk|HHD|Torrenteros|TTR
ImmortalSeed|IS|TorrentHR|THR
InfinityHD|IHD|TorrentLeech|TL
ItaTorrents|ITT|ToTheGlory|TTG
lajidui|LAJIDUI|TVChaosUK|TVC
LastDigitalUnderground|LDU|ULCX|ULCX
Lat-Team|LT|UTOPIA|UTP
Locadora|LCD|YOiNKED|YOINK
LongPT|LPT|YUSCENE|YUS
LST|LST||

## **Setup:**
- **REQUIRES AT LEAST PYTHON 3.9 AND PIP3**
Expand Down
57 changes: 56 additions & 1 deletion data/example-config.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@

"TRACKERS": {
# Which trackers do you want to upload to?
# Available tracker: A4K, ACM, AITHER, ANT, AR, ASC, AZ, BHD, BHDTV, BJS, BLU, BT, CBR, CZ, DC, DP, DT, EMUW, FF, FL, FNP, FRIKI, GPW, HDB, HDS, HDT, HHD, HUNO, IHD, IS, ITT, LCD, LDU, LST, LT, LUME, MTV, NBL, OE, OTW, PHD, PT, PTER, PTP, PTS, PTT, R4E, RAS, RF, RTF, SAM, SHRI, SN, SP, SPD, STC, THR, TIK, TL, TLZ, TOS, TTG, TTR, TVC, ULCX, UTP, YOINK, YUS
# Available tracker: A4K, ACM, AITHER, ANT, AR, ASC, AZ, BHD, BHDTV, BJS, BLU, BT, CBR, CZ, DC, DP, DT, EMUW, FF, FL, FNP, FRIKI, GPW, HDB, HDS, HDT, HHD, HUNO, IHD, IS, ITT, LAJIDUI, LCD, LDU, LPT, LST, LT, LUME, MTEAM, MTV, NBL, OE, OTW, PHD, PT, PTCAFE, PTER, PTFANS, PTGTK, PTP, PTS, PTT, R4E, RAS, RF, RPT, RTF, SAM, SHRI, SN, SP, SPD, STC, THR, TIK, TL, TLZ, TOS, TTG, TTR, TVC, ULCX, UTP, YOINK, YUS
# Only add the trackers you want to upload to on a regular basis
"default_trackers": "",

Expand Down Expand Up @@ -638,6 +638,14 @@
"api_key": "",
"anon": False,
},
"LAJIDUI": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
# for LAJIDUI to work you need to export cookies from https://pt.lajidui.top/ using https://addons.mozilla.org/en-US/firefox/addon/export-cookies-txt/.
# cookies need to be in netscape format and need to be in data/cookies/LAJIDUI.txt
"announce_url": "https://pt.lajidui.top/announce.php?passkey=<PASSKEY>",
"anon": False,
},
"LCD": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
Expand All @@ -650,6 +658,14 @@
"api_key": "",
"anon": False,
},
"LPT": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
# for LPT to work you need to export cookies from https://longpt.org/ using https://addons.mozilla.org/en-US/firefox/addon/export-cookies-txt/.
# cookies need to be in netscape format and need to be in data/cookies/LPT.txt
"announce_url": "https://longpt.org/announce.php?passkey=<PASSKEY>",
"anon": False,
},
"LST": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
Expand Down Expand Up @@ -678,6 +694,13 @@
# Send uploads to LUME modq for staff approval
"modq": False,
},
"MTEAM": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
"api_key": "",
"anon": False,
"base_url": "kp.m-team.cc"
},
"MTV": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
Expand Down Expand Up @@ -732,6 +755,14 @@
"api_key": "",
"anon": False,
},
"PTCAFE": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
# for PTCAFE to work you need to export cookies from https://ptcafe.club/ using https://addons.mozilla.org/en-US/firefox/addon/export-cookies-txt/.
# cookies need to be in netscape format and need to be in data/cookies/PTCAFE.txt
"announce_url": "https://tracker.ptcafe.club/announce.php?passkey=<PASSKEY>",
"anon": False,
},
"PTER": { # Does not appear to be working at all
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
Expand All @@ -742,6 +773,22 @@
"ptgen_api": "",
"anon": True,
},
"PTFANS": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
# for PTFANS to work you need to export cookies from https://ptfans.cc/ using https://addons.mozilla.org/en-US/firefox/addon/export-cookies-txt/.
# cookies need to be in netscape format and need to be in data/cookies/PTFANS.txt
"announce_url": "https://ptfans.cc/announce.php?passkey=<PASSKEY>",
"anon": False,
},
"PTGTK": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
# for PTGTK to work you need to export cookies from https://pt.gtkpw.xyz using https://addons.mozilla.org/en-US/firefox/addon/export-cookies-txt/.
# cookies need to be in netscape format and need to be in data/cookies/PTGTK.txt
"announce_url": "https://t.myaltbox.com/announce.php?passkey=<PASSKEY>",
"anon": False,
},
"PTP": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
Expand Down Expand Up @@ -786,6 +833,14 @@
"api_key": "",
"anon": False,
},
"RPT": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
# for RPT to work you need to export cookies from https://bilibili.download using https://addons.mozilla.org/en-US/firefox/addon/export-cookies-txt/.
# cookies need to be in netscape format and need to be in data/cookies/RPT.txt
"announce_url": "https://bilibili.download/announce.php?passkey=<PASSKEY>",
"anon": False,
},
"RTF": {
# Instead of using the tracker acronym for folder name when sym/hard linking, you can use a custom name
"link_dir_name": "",
Expand Down
2 changes: 2 additions & 0 deletions src/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ def parse(self, argv: Sequence[str], meta: dict[str, Any]) -> tuple[dict[str, An
parser.add_argument('-mal', '--mal', nargs=1, required=False, help="MAL ID", type=str, dest='mal_manual')
parser.add_argument('-tvmaze', '--tvmaze', nargs=1, required=False, help="TVMAZE ID", type=str, dest='tvmaze_manual')
parser.add_argument('-tvdb', '--tvdb', nargs=1, required=False, help="TVDB ID", type=str, dest='tvdb_manual')
parser.add_argument("-douban", "--douban", nargs=1, required=False, help="Douban ID (Number only)", type=int, dest="douban_manual", default=0)
parser.add_argument('-g', '--tag', nargs='*', required=False, help="Group Tag", type=str)
parser.add_argument('-serv', '--service', nargs='*', required=False, help="Streaming Service", type=str)
parser.add_argument('-dist', '--distributor', nargs='*', required=False, help="Disc Distributor e.g.(Criterion, BFI, etc.)", type=str)
Expand Down Expand Up @@ -197,6 +198,7 @@ def parse(self, argv: Sequence[str], meta: dict[str, Any]) -> tuple[dict[str, An
parser.add_argument('-emby_debug', '--emby_debug', action='store_true', required=False, help="Does debugging stuff for Audionut")
parser.add_argument('-ch', '--channel', nargs=1, required=False, help="SPD only: Channel ID number or tag to upload to (preferably the ID), without '@'. Example: '-ch spd' when using a tag, or '-ch 1' when using an ID.", type=str, dest='spd_channel', default="")
parser.add_argument("-excl", "--exclusive", nargs=1, required=False, help="Set exclusive flag on all supported trackers", dest="exclusive")
parser.add_argument("-diy", "--diy-disc", nargs=1, required=False, help="Set DIY flag for disc uploads", dest="diy_disc")
parsed_args_ns, before_args = parser.parse_known_args(input)
parsed_args: dict[str, Any] = vars(parsed_args_ns)
# console.print(args)
Expand Down
21 changes: 20 additions & 1 deletion src/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,26 @@ def bloated_check(meta: Meta, audio_languages: Union[Sequence[str], str], is_eng
if isinstance(audio_languages, str):
audio_languages = [audio_languages]

bloat_is_allowed = ["ASC", "BJS", "BT", "CBR", "DC", "FF", "LCD", "SAM", "SHRI", "SP", "TL", "TOS"]
bloat_is_allowed = [
"ASC",
"BJS",
"BT",
"CBR",
"DC",
"FF",
"LAJIDUI",
"LCD",
"LPT",
"PTCAFE",
"PTFANS",
"PTGTK",
"RPT",
"SAM",
"SHRI",
"SP",
"TL",
"TOS",
]
# Trackers that allow specific languages (list of allowed language codes per tracker)
tracker_allowed_bloat_languages = {
"AITHER": ["en"],
Expand Down
2 changes: 1 addition & 1 deletion src/get_desc.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ async def get_tv_info(self, meta: dict[str, Any], resize: bool = False) -> tuple
return title, image, overview

async def get_mediainfo_section(self, meta: dict[str, Any]) -> str:
"""Returns the mediainfo/bdinfo section, using a cache file if available."""
"""Returns the mediainfo section, using a cache file if available."""
if meta.get("is_disc") == "BDMV":
return ""

Expand Down
48 changes: 47 additions & 1 deletion src/metadata_searching.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
from collections.abc import Awaitable
from typing import Any, Optional, Union, cast

import httpx
from bs4 import BeautifulSoup

from src.console import console
from src.imdb import imdb_manager
from src.tmdb import TmdbManager
Expand Down Expand Up @@ -1038,7 +1041,50 @@ async def get_tvdb_tvmaze_tmdb_episode_data(meta: dict[str, Any], tvdb_handler:
console.print("[green]TMDb episode data retrieved successfully.[/green]")
elif isinstance(tmdb_episode_data, Exception):
console.print(f"[yellow]TMDb episode data retrieval failed: {tmdb_episode_data}[/yellow]")

return meta


async def get_douban_id(meta) -> int:
douban_id: int = 0
try:
douban_manual = int(meta.get("douban_manual") or 0)
except (ValueError, TypeError):
console.print("[bold yellow]Invalid douban_manual value, ignoring.[/bold yellow]")
douban_manual = 0

if douban_manual:
console.print(f"Using manual Douban ID: {douban_manual}")
return douban_manual

imdb_id = meta.get("imdb_info", {}).get("imdbID")
if not imdb_id:
return douban_id

search_url = f"https://m.douban.com/search/?query={imdb_id}"
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"}

try:
async with httpx.AsyncClient(headers=headers, follow_redirects=True) as client:
response = await client.get(search_url)
response.raise_for_status()

soup = BeautifulSoup(response.text, "html.parser")
result = soup.find("ul", class_="search_results_subjects")

if result:
link_tag = result.find("a")
if link_tag and "href" in link_tag.attrs:
link_mobile = str(link_tag["href"])
match = re.search(r"subject/(\d+)", link_mobile)
if match:
douban_id = int(match.group(1))
return douban_id

console.print(f"[bold yellow]No Douban ID found for IMDb ID {imdb_id}.[/bold yellow]")
return douban_id

except Exception as e:
console.print(f"[bold yellow]Failed to fetch Douban ID for IMDb ID {imdb_id}: {e}[/bold yellow]")
return douban_id


Loading
Loading