This commit is contained in:
2026-04-16 12:56:33 +02:00
parent a1a06aa547
commit 4683d6f853
6 changed files with 183 additions and 20 deletions
+10 -10
View File
@@ -35,16 +35,6 @@ STUCK_AFTER_HOURS = 168 # progress >= 95% ale < 100% po 7 dnech → dea
# }, # },
CLIENTS = [ CLIENTS = [
{
"name": "UltraCC Seedbox",
"max_concurrent": 30,
"qbt": {
"host": "https://vladob.zen.usbx.me/qbittorrent",
"username": "vladob",
"password": "jCni3U6d#y4bfcm",
"VERIFY_WEBUI_CERTIFICATE": False,
},
},
{ {
"name": "Local qBittorrent", "name": "Local qBittorrent",
"max_concurrent": 30, "max_concurrent": 30,
@@ -55,6 +45,16 @@ CLIENTS = [
"password": "adminadmin", "password": "adminadmin",
}, },
}, },
{
"name": "UltraCC Seedbox",
"max_concurrent": 30,
"qbt": {
"host": "https://vladob.zen.usbx.me/qbittorrent",
"username": "vladob",
"password": "jCni3U6d#y4bfcm",
"VERIFY_WEBUI_CERTIFICATE": False,
},
},
] ]
DB_CONFIG = { DB_CONFIG = {
+8 -3
View File
@@ -160,15 +160,20 @@ def parse_page(html):
# DOWNLOAD .TORRENT FILE # DOWNLOAD .TORRENT FILE
# ============================================================ # ============================================================
def download_torrent(session, url): def download_torrent(session, url, retries=10, retry_delay=10):
for attempt in range(1, retries + 1):
try: try:
r = session.get(url, timeout=15) r = session.get(url, timeout=15)
r.raise_for_status() r.raise_for_status()
if len(r.content) < 20: if len(r.content) < 20:
return None raise ValueError(f"Odpověď příliš krátká ({len(r.content)} B)")
return r.content return r.content
except Exception as e: except Exception as e:
print(f" ⚠️ Stažení selhalo: {e}") if attempt < retries:
print(f" ⚠️ Pokus {attempt}/{retries} selhal: {e} — čekám {retry_delay}s")
time.sleep(retry_delay)
else:
print(f" ✖ Všechny pokusy ({retries}) selhaly: {e}")
return None return None
+158
View File
@@ -0,0 +1,158 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
96 RetryFailedDownloads — sktorrent.eu
- Najde torrenty v DB, kde torrent_content IS NULL (stažení selhalo)
- Pokusí se je znovu stáhnout z download_url
- Nevyžaduje Selenium — stačí requests + cookies
"""
import pymysql
import requests
import json
import time
import sys
from pathlib import Path
from datetime import datetime
# ============================================================
# CONFIG
# ============================================================
COOKIE_FILE = Path(__file__).parent.parent / "sktorrent_cookies.json"
BACKUP_DIR = Path(__file__).parent.parent / "saved_torrents"
SLEEP_BETWEEN = 2.0 # pauza mezi stáženími
DB_CONFIG = {
"host": "192.168.1.76",
"port": 3306,
"user": "root",
"password": "Vlado9674+",
"database": "torrents",
"charset": "utf8mb4",
"autocommit": True,
}
# ============================================================
# HELPERS
# ============================================================
def build_session():
if not COOKIE_FILE.exists():
raise FileNotFoundError(f"Cookie soubor nenalezen: {COOKIE_FILE}")
with open(COOKIE_FILE, "r", encoding="utf-8") as f:
cookies = json.load(f)
session = requests.Session()
session.headers["User-Agent"] = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
)
for c in cookies:
session.cookies.set(c["name"], c["value"], domain=c.get("domain", ""))
return session
def sanitize_filename(name: str) -> str:
import re
clean = re.sub(r'[<>:"/\\|?*]', '', name)
return clean.strip()[:100]
# ============================================================
# MAIN
# ============================================================
def main():
sys.stdout.reconfigure(encoding="utf-8")
print("=" * 60)
print("RETRY FAILED DOWNLOADS — sktorrent.eu")
print(f"Spuštěno: {datetime.now():%Y-%m-%d %H:%M:%S}")
print("=" * 60)
BACKUP_DIR.mkdir(exist_ok=True)
db = pymysql.connect(**DB_CONFIG)
cursor = db.cursor()
cursor.execute(
"SELECT torrent_hash, title_visible, download_url "
"FROM torrents "
"WHERE torrent_content IS NULL AND download_url IS NOT NULL "
"ORDER BY added_datetime DESC"
)
rows = cursor.fetchall()
if not rows:
print("Žádné chybějící .torrent soubory — vše je staženo.")
db.close()
return
print(f"Nalezeno {len(rows)} torrentů bez obsahu:\n")
for i, (t_hash, title, url) in enumerate(rows, 1):
print(f" {i}. {title}")
print()
session = build_session()
success = 0
failed = 0
for i, (t_hash, title, url) in enumerate(rows, 1):
print(f"[{i}/{len(rows)}] {title}")
print(f" URL: {url}")
try:
r = session.get(url, timeout=20)
if r.status_code == 404:
print(" ✖ 404 — soubor na serveru neexistuje (přeskakuji)")
failed += 1
continue
if r.status_code == 403:
print(" ✖ 403 — cookie pravděpodobně expiraly, zastav a obnov přihlášení")
failed += 1
break
r.raise_for_status()
content = r.content
if len(content) < 20:
print(f" ✖ Odpověď příliš krátká ({len(content)} B) — přeskakuji")
failed += 1
continue
# Ulož do DB
cursor.execute(
"UPDATE torrents SET torrent_content = %s WHERE torrent_hash = %s",
(content, t_hash)
)
# Ulož na disk
fname = f"{sanitize_filename(title)}_{t_hash[:6]}.torrent"
fpath = BACKUP_DIR / fname
fpath.write_bytes(content)
print(f" ✔ Staženo ({len(content):,} B) → {fname}")
success += 1
except Exception as e:
print(f" ✖ Chyba: {e}")
failed += 1
if i < len(rows):
time.sleep(SLEEP_BETWEEN)
db.close()
print()
print("=" * 60)
print(f"Hotovo: {datetime.now():%Y-%m-%d %H:%M:%S}")
print(f"Úspěšně staženo : {success}")
print(f"Selhalo / 404 : {failed}")
print("=" * 60)
if __name__ == "__main__":
main()