Skip to content

Commit

Permalink
Simple ULCX implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
l3mon4id committed Sep 19, 2024
1 parent 622a140 commit 8c542f4
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ A simple tool to take the work out of uploading.
- Can re-use existing torrents instead of hashing new
- Generates proper name for your upload using Mediainfo/BDInfo and TMDb/IMDb conforming to site rules
- Checks for existing releases already on site
- Uploads to PTP/BLU/BHD/Aither/THR/STC/R4E(limited)/STT/HP/ACM/LCD/LST/NBL/ANT/FL/HUNO/RF/SN/RTF/OTW/FNP/CBR/UTP/HDB/AL/SHRI/OE/TL/BHDTV/HDT/JPTV/LT/MTV/PTER/TDC/TTG/UTP/PSS
- Uploads to PTP/BLU/BHD/Aither/THR/STC/R4E(limited)/STT/HP/ACM/LCD/LST/NBL/ANT/FL/HUNO/RF/SN/RTF/OTW/FNP/CBR/UTP/HDB/AL/SHRI/OE/TL/BHDTV/HDT/JPTV/LT/MTV/PTER/TDC/TTG/UTP/PSS/ULCX
- Adds to your client with fast resume, seeding instantly (rtorrent/qbittorrent/deluge/watch folder)
- ALL WITH MINIMAL INPUT!
- Currently works with .mkv/.mp4/Blu-ray/DVD/HD-DVDs
Expand Down
256 changes: 256 additions & 0 deletions src/trackers/ULCX.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
# -*- coding: utf-8 -*-
# import discord
import asyncio
import platform

import requests
from src.console import console
from src.trackers.COMMON import COMMON


class ULCX:
def __init__(self, config):
self.config = config
self.tracker = "ULCX"
self.source_flag = "ULCX"
self.upload_url = "https://upload.cx/api/torrents/upload"
self.search_url = "https://upload.cx/api/torrents/filter"
self.signature = "\n[center][url=https://github.com/Audionut/Upload-Assistant]Created by L4G's Upload Assistant[/url][/center]"
self.banned_groups = [
"Tigole",
"x0r",
"Judas",
"SPDVD",
"MeGusta",
"YIFY",
"SWTYBLZ",
"TAoE",
"TSP",
"TSPxL",
"LAMA",
"4K4U",
"ION10",
"Will1869",
"TGx",
"Sicario",
"QxR",
"Hi10",
"EMBER",
"FGT",
"AROMA",
"d3g",
"nikt0",
"Grym",
"RARBG",
"iVy",
"NuBz",
"NAHOM",
"EDGE2020",
"FnP",
]

async def get_cat_id(self, category_name):
category_id = {
"MOVIE": "1",
"TV": "2",
}.get(category_name, "0")
return category_id

async def get_type_id(self, type):
type_id = {
"DISC": "1",
"REMUX": "2",
"WEBDL": "4",
"WEBRIP": "5",
"HDTV": "6",
"ENCODE": "3",
}.get(type, "0")
return type_id

async def get_res_id(self, resolution):
resolution_id = {
"8640p": "10",
"4320p": "1",
"2160p": "2",
"1440p": "3",
"1080p": "3",
"1080i": "4",
"720p": "5",
"576p": "6",
"576i": "7",
"480p": "8",
"480i": "9",
}.get(resolution, "10")
return resolution_id

async def upload(self, meta):
common = COMMON(config=self.config)
await common.edit_torrent(meta, self.tracker, self.source_flag)
cat_id = await self.get_cat_id(meta["category"])
type_id = await self.get_type_id(meta["type"])
resolution_id = await self.get_res_id(meta["resolution"])
await common.unit3d_edit_desc(meta, self.tracker, signature=self.signature)
region_id = await common.unit3d_region_ids(meta.get("region"))
distributor_id = await common.unit3d_distributor_ids(meta.get("distributor"))
if meta["anon"] != 0 or self.config["TRACKERS"][self.tracker].get(
"anon", False
):
anon = 1
else:
anon = 0

modq = await self.get_flag(meta, "modq")

if meta["bdinfo"] is not None:
mi_dump = None
bd_dump = open(
f"{meta['base_dir']}/tmp/{meta['uuid']}/BD_SUMMARY_00.txt",
"r",
encoding="utf-8",
).read()
else:
mi_dump = open(
f"{meta['base_dir']}/tmp/{meta['uuid']}/MEDIAINFO.txt",
"r",
encoding="utf-8",
).read()
bd_dump = None
desc = open(
f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]DESCRIPTION.txt",
"r",
).read()
open_torrent = open(
f"{meta['base_dir']}/tmp/{meta['uuid']}/[{self.tracker}]{meta['clean_name']}.torrent",
"rb",
)
files = {"torrent": open_torrent}
data = {
"name": meta["name"],
"description": desc,
"mediainfo": mi_dump,
"bdinfo": bd_dump,
"category_id": cat_id,
"type_id": type_id,
"resolution_id": resolution_id,
"tmdb": meta["tmdb"],
"imdb": meta["imdb_id"].replace("tt", ""),
"tvdb": meta["tvdb_id"],
"mal": meta["mal_id"],
"igdb": 0,
"anonymous": anon,
"stream": meta["stream"],
"sd": meta["sd"],
"keywords": meta["keywords"],
"personal_release": int(meta.get("personalrelease", False)),
"internal": 0,
"featured": 0,
"free": 0,
"doubleup": 0,
"sticky": 0,
"mod_queue_opt_in": modq,
}
# Internal
if self.config["TRACKERS"][self.tracker].get("internal", False):
if meta["tag"] != "" and (
meta["tag"][1:]
in self.config["TRACKERS"][self.tracker].get("internal_groups", [])
):
data["internal"] = 1

if region_id != 0:
data["region_id"] = region_id
if distributor_id != 0:
data["distributor_id"] = distributor_id
if meta.get("category") == "TV":
data["season_number"] = meta.get("season_int", "0")
data["episode_number"] = meta.get("episode_int", "0")
headers = {
"User-Agent": f"Upload Assistant/2.1 ({platform.system()} {platform.release()})"
}
params = {"api_token": self.config["TRACKERS"][self.tracker]["api_key"].strip()}

if not meta["debug"]:
success = "Unknown"
try:
response = requests.post(
url=self.upload_url,
files=files,
data=data,
headers=headers,
params=params,
)
response.raise_for_status()
response_json = response.json()
success = response_json.get("success", False)
data = response_json.get("data", {})
except Exception as e:
console.print(
f"[red]Encountered Error: {e}[/red]\n[bold yellow]May have uploaded, please go check.."
)

if success == "Unknown":
console.print(
"[bold yellow]Status of upload is unknown, please go check.."
)
success = False
elif success:
console.print("[bold green]Torrent uploaded successfully!")
else:
console.print("[bold red]Torrent upload failed.")

if data:
if (
"name" in data
and "The name has already been taken." in data["name"]
):
console.print("[red]Name has already been taken.")
if (
"info_hash" in data
and "The info hash has already been taken." in data["info_hash"]
):
console.print("[red]Info hash has already been taken.")
else:
console.print("[cyan]Request Data:")
console.print(data)

try:
open_torrent.close()
except Exception as e:
console.print(f"[red]Failed to close torrent file: {e}[/red]")

return success

async def get_flag(self, meta, flag_name):
config_flag = self.config["TRACKERS"][self.tracker].get(flag_name)
if config_flag is not None:
return 1 if config_flag else 0

return 1 if meta.get(flag_name, False) else 0

async def search_existing(self, meta):
dupes = {}
console.print("[yellow]Searching for existing torrents on site...")
params = {
"api_token": self.config["TRACKERS"][self.tracker]["api_key"].strip(),
"tmdbId": meta["tmdb"],
"categories[]": await self.get_cat_id(meta["category"]),
"types[]": await self.get_type_id(meta["type"]),
"resolutions[]": await self.get_res_id(meta["resolution"]),
"name": "",
}
if meta.get("edition", "") != "":
params["name"] = params["name"] + f" {meta['edition']}"
try:
response = requests.get(url=self.search_url, params=params)
response = response.json()
for each in response["data"]:
result = each["attributes"]["name"]
size = each["attributes"]["size"]
dupes[result] = size
except Exception as e:
console.print(
f"[bold red]Unable to search for existing torrents on site. Either the site is down or your API key is incorrect. Error: {e}"
)
await asyncio.sleep(5)

return dupes
6 changes: 4 additions & 2 deletions upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from src.trackers.AL import AL
from src.trackers.SHRI import SHRI
from src.trackers.PSS import PSS
from src.trackers.ULCX import ULCX
import json
from pathlib import Path
import asyncio
Expand Down Expand Up @@ -248,18 +249,19 @@ async def do_the_thing(base_dir):
####### Upload to Trackers ####### # noqa #F266
####################################
common = COMMON(config=config)
api_trackers = ['BLU', 'AITHER', 'STC', 'R4E', 'STT', 'RF', 'ACM', 'LCD', 'HUNO', 'SN', 'LT', 'NBL', 'ANT', 'JPTV', 'TDC', 'OE', 'BHDTV', 'RTF', 'OTW', 'FNP', 'CBR', 'UTP', 'AL', 'SHRI', 'LST', 'BHD', 'TL', 'PSS']
api_trackers = ['BLU', 'AITHER', 'STC', 'R4E', 'STT', 'RF', 'ACM', 'LCD', 'HUNO', 'SN', 'LT', 'NBL', 'ANT', 'JPTV', 'TDC', 'OE', 'BHDTV', 'RTF', 'OTW', 'FNP', 'CBR', 'UTP', 'AL', 'SHRI', 'LST', 'BHD', 'TL', 'PSS', 'ULCX']
http_trackers = ['HDB', 'TTG', 'FL', 'PTER', 'HDT', 'MTV']
tracker_class_map = {
'BLU': BLU, 'BHD': BHD, 'AITHER': AITHER, 'STC': STC, 'R4E': R4E, 'THR': THR, 'STT': STT, 'HP': HP, 'PTP': PTP, 'RF': RF, 'SN': SN,
'ACM': ACM, 'HDB': HDB, 'LCD': LCD, 'TTG': TTG, 'LST': LST, 'HUNO': HUNO, 'FL': FL, 'LT': LT, 'NBL': NBL, 'ANT': ANT, 'PTER': PTER, 'JPTV': JPTV,
'TL': TL, 'TDC': TDC, 'HDT': HDT, 'MTV': MTV, 'OE': OE, 'BHDTV': BHDTV, 'RTF': RTF, 'OTW': OTW, 'FNP': FNP, 'CBR': CBR, 'UTP': UTP, 'AL': AL, 'SHRI': SHRI, 'PSS': PSS}
'TL': TL, 'TDC': TDC, 'HDT': HDT, 'MTV': MTV, 'OE': OE, 'BHDTV': BHDTV, 'RTF': RTF, 'OTW': OTW, 'FNP': FNP, 'CBR': CBR, 'UTP': UTP, 'AL': AL, 'SHRI': SHRI, 'PSS': PSS, 'ULCX': ULCX}

tracker_capabilities = {
'LST': {'mod_q': True, 'draft': True},
'BLU': {'mod_q': True, 'draft': False},
'AITHER': {'mod_q': True, 'draft': False},
'BHD': {'draft_live': True},
'ULCX': {'mod_q': True}
}

async def check_mod_q_and_draft(tracker_class, meta, debug):
Expand Down

0 comments on commit 8c542f4

Please sign in to comment.