2022-11-13 16:33:32 +00:00
|
|
|
#!/usr/bin/env python3
|
2022-11-13 16:14:26 +00:00
|
|
|
import argparse
|
|
|
|
import re
|
|
|
|
from urllib.parse import urlencode, urlparse
|
|
|
|
|
|
|
|
from bs4 import BeautifulSoup
|
|
|
|
from dns import rdatatype, resolver
|
|
|
|
from requests import Session, adapters
|
|
|
|
from urllib3.util.connection import HAS_IPV6
|
|
|
|
|
|
|
|
BLACKLIST_WORDS = ["dvd", "iso"]
|
2022-11-13 19:06:48 +00:00
|
|
|
YGGTORRENT_BASE_URL = "https://www5.yggtorrent.fi"
|
2022-11-13 16:14:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument("-u", "--uploader", action="append")
|
|
|
|
parser.add_argument("-y", "--year", type=int)
|
2022-11-13 17:24:28 +00:00
|
|
|
parser.add_argument("-s", "--size", type=int, default=10)
|
2022-11-13 16:14:26 +00:00
|
|
|
parser.add_argument("query")
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
|
|
def parse_size(size):
|
|
|
|
units = {"o": 1, "Ko": 10**3, "Mo": 10**6, "Go": 10**9, "To": 10**12}
|
|
|
|
match = re.search("([0-9.]+)([^0-9]+)", size)
|
|
|
|
number = match.group(1).strip()
|
|
|
|
unit = match.group(2).strip()
|
|
|
|
return int(float(number) * units[unit])
|
|
|
|
|
|
|
|
|
|
|
|
DNS_RESOLVER = resolver.Resolver()
|
|
|
|
DNS_RESOLVER.cache = resolver.LRUCache() # type: ignore
|
|
|
|
|
|
|
|
|
|
|
|
class DNSAdapter(adapters.HTTPAdapter):
|
|
|
|
def __init__(self, nameservers):
|
|
|
|
self.nameservers = nameservers
|
|
|
|
super().__init__()
|
|
|
|
|
|
|
|
def resolve(self, host, nameservers):
|
|
|
|
DNS_RESOLVER.nameservers = nameservers
|
|
|
|
|
|
|
|
if HAS_IPV6:
|
|
|
|
try:
|
2022-11-13 17:48:45 +00:00
|
|
|
answers_v6 = DNS_RESOLVER.query(host, rdatatype.AAAA)
|
2022-11-13 16:14:26 +00:00
|
|
|
for rdata_v6 in answers_v6:
|
|
|
|
return f"[{str(rdata_v6)}]"
|
|
|
|
except resolver.NoAnswer:
|
|
|
|
pass
|
|
|
|
|
2022-11-13 17:48:45 +00:00
|
|
|
answers_v4 = DNS_RESOLVER.query(host, rdatatype.A)
|
2022-11-13 16:14:26 +00:00
|
|
|
for rdata_v4 in answers_v4:
|
|
|
|
return str(rdata_v4)
|
|
|
|
|
|
|
|
def send(self, request, **kwargs):
|
|
|
|
connection_pool_kwargs = self.poolmanager.connection_pool_kw
|
|
|
|
result = urlparse(request.url)
|
|
|
|
resolved_ip = self.resolve(result.hostname, self.nameservers)
|
|
|
|
request.url = request.url.replace(result.hostname, resolved_ip)
|
|
|
|
request.headers["Host"] = result.hostname
|
|
|
|
request.headers[
|
|
|
|
"User-Agent"
|
|
|
|
] = "Googlebot/2.1 (+http://www.google.com/bot.html)"
|
|
|
|
|
|
|
|
if result.scheme == "https":
|
|
|
|
connection_pool_kwargs["server_hostname"] = result.hostname
|
|
|
|
connection_pool_kwargs["assert_hostname"] = result.hostname
|
|
|
|
|
|
|
|
return super().send(request, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
session = Session()
|
|
|
|
session.mount("http://", DNSAdapter(["1.1.1.1"]))
|
|
|
|
session.mount("https://", DNSAdapter(["1.1.1.1"]))
|
|
|
|
|
|
|
|
|
|
|
|
def get_files(id):
|
2022-11-13 19:06:48 +00:00
|
|
|
req = session.get(f"{YGGTORRENT_BASE_URL}/engine/get_files", params={"torrent": id})
|
2022-11-13 17:24:28 +00:00
|
|
|
files = req.json()
|
2022-11-13 16:14:26 +00:00
|
|
|
html = BeautifulSoup(files["html"], "html.parser")
|
|
|
|
trs = html.select("tr")
|
|
|
|
return len(trs)
|
|
|
|
|
|
|
|
|
2022-11-14 17:42:52 +00:00
|
|
|
def search_ygg(query, multi, full):
|
2022-11-13 16:14:26 +00:00
|
|
|
ygg_params = {
|
2022-11-14 13:51:25 +00:00
|
|
|
"name": query,
|
2022-11-13 16:14:26 +00:00
|
|
|
"description": "",
|
|
|
|
"file": "",
|
|
|
|
"uploader": "",
|
|
|
|
"category": "2145",
|
|
|
|
"sub_category": "2183",
|
|
|
|
"do": "search",
|
|
|
|
"order": "asc",
|
|
|
|
"sort": "publish_date",
|
|
|
|
}
|
|
|
|
|
2022-11-14 17:42:52 +00:00
|
|
|
if full and args.year:
|
|
|
|
ygg_params["name"] += f" {args.year}"
|
|
|
|
|
2022-11-13 16:14:26 +00:00
|
|
|
if multi:
|
2022-11-13 19:19:44 +00:00
|
|
|
ygg_params["option_langue:multiple[]"] = "4"
|
2022-11-13 16:14:26 +00:00
|
|
|
|
2022-11-13 19:06:48 +00:00
|
|
|
req = session.get(f"{YGGTORRENT_BASE_URL}/engine/search", params=ygg_params)
|
2022-11-13 16:14:26 +00:00
|
|
|
html = BeautifulSoup(req.text, "html.parser")
|
|
|
|
trs = html.select("table.table tr")
|
|
|
|
|
|
|
|
if len(trs) > 1:
|
|
|
|
for i, tr in enumerate(trs):
|
|
|
|
if not i:
|
|
|
|
continue
|
|
|
|
|
|
|
|
tds = tr.find_all("td")
|
|
|
|
size = tds[5].get_text()
|
2022-11-17 00:12:13 +00:00
|
|
|
downloads = tds[6].get_text()
|
2022-11-13 16:14:26 +00:00
|
|
|
name = tds[1].get_text().lower().strip()
|
|
|
|
|
2022-11-13 17:24:28 +00:00
|
|
|
if parse_size(size) > parse_size(f"{args.size}Go"):
|
2022-11-13 16:14:26 +00:00
|
|
|
continue
|
|
|
|
|
2022-11-17 00:12:13 +00:00
|
|
|
if int(downloads) < 10:
|
|
|
|
continue
|
|
|
|
|
2022-11-13 16:14:26 +00:00
|
|
|
if any(word.lower() in name for word in BLACKLIST_WORDS):
|
|
|
|
continue
|
|
|
|
|
2022-11-14 17:11:22 +00:00
|
|
|
if args.year and str(args.year) not in name:
|
2022-11-14 13:51:25 +00:00
|
|
|
continue
|
|
|
|
|
2022-11-13 16:14:26 +00:00
|
|
|
if args.uploader and not any(
|
|
|
|
uploader.lower() in name for uploader in args.uploader
|
|
|
|
):
|
|
|
|
continue
|
|
|
|
|
|
|
|
link = tds[1].a["href"]
|
|
|
|
id = link.split("/")[-1].split("-")[0]
|
|
|
|
|
|
|
|
if get_files(id) > 1:
|
|
|
|
continue
|
|
|
|
|
2022-11-14 13:51:25 +00:00
|
|
|
print(f"{name} {link}")
|
2022-11-13 16:14:26 +00:00
|
|
|
exit(0)
|
|
|
|
|
|
|
|
|
|
|
|
query_string = {"query": args.query, "filters": "type:movie"}
|
|
|
|
|
|
|
|
if args.year:
|
2022-11-13 17:24:28 +00:00
|
|
|
query_string["filters"] += f" AND year:{args.year}"
|
2022-11-13 16:14:26 +00:00
|
|
|
|
|
|
|
tvdb = session.post(
|
|
|
|
"https://tvshowtime-dsn.algolia.net/1/indexes/TVDB/query",
|
|
|
|
params={
|
|
|
|
"x-algolia-application-id": "tvshowtime",
|
|
|
|
"x-algolia-api-key": "c9d5ec1316cec12f093754c69dd879d3",
|
|
|
|
},
|
|
|
|
json={"params": urlencode(query_string)},
|
|
|
|
)
|
|
|
|
|
2022-11-13 17:24:28 +00:00
|
|
|
tvdata = tvdb.json()
|
2022-11-13 16:14:26 +00:00
|
|
|
|
|
|
|
if not tvdata["nbHits"] > 0:
|
|
|
|
print("Can't find query on TheTVDB")
|
|
|
|
exit(1)
|
|
|
|
|
|
|
|
eng = tvdata["hits"][0]["name"]
|
|
|
|
|
|
|
|
fra = (
|
|
|
|
tvdata["hits"][0]["translations"]["fra"]
|
|
|
|
if "fra" in tvdata["hits"][0]["translations"]
|
|
|
|
else args.query
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2022-11-14 17:42:52 +00:00
|
|
|
search_ygg(args.query, True, True)
|
|
|
|
search_ygg(fra, True, True)
|
|
|
|
search_ygg(eng, True, True)
|
|
|
|
search_ygg(args.query, False, True)
|
|
|
|
search_ygg(fra, False, True)
|
|
|
|
search_ygg(eng, False, True)
|
|
|
|
|
|
|
|
if args.year:
|
|
|
|
search_ygg(args.query, True, False)
|
|
|
|
search_ygg(fra, True, False)
|
|
|
|
search_ygg(eng, True, False)
|
|
|
|
search_ygg(args.query, False, False)
|
|
|
|
search_ygg(fra, False, False)
|
|
|
|
search_ygg(eng, False, False)
|
2022-11-13 17:24:28 +00:00
|
|
|
|
|
|
|
print("No results :(")
|