Merge remote-tracking branch 'origin/master'
This commit is contained in:
94
Seedbox/50 PrintFilenamesFromTorrentFiles.py
Normal file
94
Seedbox/50 PrintFilenamesFromTorrentFiles.py
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import pymysql
|
||||||
|
import bencodepy
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# DB CONFIG – UPRAV
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.1.50",
|
||||||
|
"user": "root",
|
||||||
|
"password": "Vlado9674+",
|
||||||
|
"database": "torrents",
|
||||||
|
"charset": "utf8mb4",
|
||||||
|
"cursorclass": pymysql.cursors.SSCursor # streaming
|
||||||
|
}
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# HELPERS
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def decode_if_bytes(value):
|
||||||
|
if isinstance(value, bytes):
|
||||||
|
return value.decode("utf-8", errors="replace")
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def parse_torrent(blob):
|
||||||
|
data = bencodepy.decode(blob)
|
||||||
|
|
||||||
|
info = data[b"info"]
|
||||||
|
|
||||||
|
torrent_name = decode_if_bytes(info[b"name"])
|
||||||
|
|
||||||
|
files = []
|
||||||
|
|
||||||
|
# multi-file torrent
|
||||||
|
if b"files" in info:
|
||||||
|
for f in info[b"files"]:
|
||||||
|
path = "/".join(decode_if_bytes(p) for p in f[b"path"])
|
||||||
|
length = f[b"length"]
|
||||||
|
files.append((path, length))
|
||||||
|
|
||||||
|
# single file torrent
|
||||||
|
else:
|
||||||
|
length = info[b"length"]
|
||||||
|
files.append((torrent_name, length))
|
||||||
|
|
||||||
|
return torrent_name, files
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# MAIN
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
conn = pymysql.connect(**DB_CONFIG)
|
||||||
|
|
||||||
|
with conn.cursor() as cursor:
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT id, title_visible, torrent_content
|
||||||
|
FROM torrents
|
||||||
|
WHERE torrent_content IS NOT NULL
|
||||||
|
""")
|
||||||
|
|
||||||
|
for row in cursor:
|
||||||
|
torrent_id = row[0]
|
||||||
|
title_visible = row[1]
|
||||||
|
blob = row[2]
|
||||||
|
|
||||||
|
try:
|
||||||
|
name, files = parse_torrent(blob)
|
||||||
|
|
||||||
|
print("=" * 70)
|
||||||
|
print(f"DB ID : {torrent_id}")
|
||||||
|
print(f"Title visible : {title_visible}")
|
||||||
|
print(f"Torrent name : {name}")
|
||||||
|
print("Files:")
|
||||||
|
|
||||||
|
for f, size in files:
|
||||||
|
print(f" - {f} ({size} bytes)")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"ERROR parsing torrent ID {torrent_id}: {e}")
|
||||||
|
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
137
Seedbox/51 ExportTorrentObsahuDoExcel.py
Normal file
137
Seedbox/51 ExportTorrentObsahuDoExcel.py
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import pymysql
|
||||||
|
import bencodepy
|
||||||
|
from openpyxl import Workbook
|
||||||
|
from openpyxl.utils import get_column_letter
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# DB CONFIG
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.1.50",
|
||||||
|
"user": "root",
|
||||||
|
"password": "Vlado9674+",
|
||||||
|
"database": "torrents",
|
||||||
|
"charset": "utf8mb4",
|
||||||
|
"cursorclass": pymysql.cursors.SSCursor
|
||||||
|
}
|
||||||
|
|
||||||
|
OUTPUT_FILE = "torrent_report.xlsx"
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# HELPERS
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def decode_if_bytes(value):
|
||||||
|
if isinstance(value, bytes):
|
||||||
|
return value.decode("utf-8", errors="replace")
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def get_root_name(info):
|
||||||
|
# prefer UTF-8 variant
|
||||||
|
if b"name.utf-8" in info:
|
||||||
|
return decode_if_bytes(info[b"name.utf-8"])
|
||||||
|
return decode_if_bytes(info[b"name"])
|
||||||
|
|
||||||
|
|
||||||
|
def get_file_parts(file_entry):
|
||||||
|
# prefer UTF-8 variant
|
||||||
|
if b"path.utf-8" in file_entry:
|
||||||
|
return [decode_if_bytes(p) for p in file_entry[b"path.utf-8"]]
|
||||||
|
return [decode_if_bytes(p) for p in file_entry[b"path"]]
|
||||||
|
|
||||||
|
|
||||||
|
def parse_torrent(blob):
|
||||||
|
|
||||||
|
data = bencodepy.decode(blob)
|
||||||
|
info = data[b"info"]
|
||||||
|
|
||||||
|
root_name = get_root_name(info)
|
||||||
|
|
||||||
|
files = []
|
||||||
|
|
||||||
|
# =====================
|
||||||
|
# MULTI FILE TORRENT
|
||||||
|
# =====================
|
||||||
|
if b"files" in info:
|
||||||
|
|
||||||
|
for f in info[b"files"]:
|
||||||
|
|
||||||
|
parts = get_file_parts(f)
|
||||||
|
|
||||||
|
# ochrana proti root/root duplicite
|
||||||
|
if parts and parts[0] == root_name:
|
||||||
|
full_path = "/".join(parts)
|
||||||
|
else:
|
||||||
|
full_path = root_name + "/" + "/".join(parts)
|
||||||
|
|
||||||
|
files.append(full_path)
|
||||||
|
|
||||||
|
# =====================
|
||||||
|
# SINGLE FILE TORRENT
|
||||||
|
# =====================
|
||||||
|
else:
|
||||||
|
files.append(root_name)
|
||||||
|
|
||||||
|
return files
|
||||||
|
|
||||||
|
|
||||||
|
# ============================================================
|
||||||
|
# MAIN
|
||||||
|
# ============================================================
|
||||||
|
|
||||||
|
def main():
|
||||||
|
|
||||||
|
conn = pymysql.connect(**DB_CONFIG)
|
||||||
|
|
||||||
|
wb = Workbook()
|
||||||
|
ws = wb.active
|
||||||
|
ws.title = "Torrent report"
|
||||||
|
|
||||||
|
ws.append(["QB Status", "Title", "Torrent Path"])
|
||||||
|
|
||||||
|
with conn.cursor() as cursor:
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT qb_state, title_visible, torrent_content
|
||||||
|
FROM torrents
|
||||||
|
WHERE torrent_content IS NOT NULL
|
||||||
|
""")
|
||||||
|
|
||||||
|
for qb_state, title_visible, blob in cursor:
|
||||||
|
|
||||||
|
qb_state = qb_state or "UNKNOWN"
|
||||||
|
title_visible = title_visible or ""
|
||||||
|
|
||||||
|
try:
|
||||||
|
files = parse_torrent(blob)
|
||||||
|
|
||||||
|
for f in files:
|
||||||
|
ws.append([qb_state, title_visible, f])
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
ws.append([qb_state, title_visible, f"ERROR: {e}"])
|
||||||
|
|
||||||
|
# autosize
|
||||||
|
for col in ws.columns:
|
||||||
|
max_len = 0
|
||||||
|
col_letter = get_column_letter(col[0].column)
|
||||||
|
|
||||||
|
for cell in col:
|
||||||
|
if cell.value:
|
||||||
|
max_len = max(max_len, len(str(cell.value)))
|
||||||
|
|
||||||
|
ws.column_dimensions[col_letter].width = min(max_len + 2, 90)
|
||||||
|
|
||||||
|
wb.save(OUTPUT_FILE)
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
print("DONE ->", OUTPUT_FILE)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
48
Seedbox/52 UložBalíkAudioknih.py
Normal file
48
Seedbox/52 UložBalíkAudioknih.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import pymysql
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# CONFIG
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
DB_CONFIG = {
|
||||||
|
"host": "192.168.1.50",
|
||||||
|
"user": "root",
|
||||||
|
"password": "Vlado9674+",
|
||||||
|
"database": "torrents",
|
||||||
|
"charset": "utf8mb4"
|
||||||
|
}
|
||||||
|
|
||||||
|
SEARCH_NAME = "Balík audioknih"
|
||||||
|
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# MAIN
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
conn = pymysql.connect(**DB_CONFIG)
|
||||||
|
|
||||||
|
with conn.cursor() as cursor:
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
SELECT id, title_visible, torrent_content
|
||||||
|
FROM torrents
|
||||||
|
WHERE title_visible LIKE %s
|
||||||
|
LIMIT 1
|
||||||
|
""", ("%" + SEARCH_NAME + "%",))
|
||||||
|
|
||||||
|
row = cursor.fetchone()
|
||||||
|
|
||||||
|
if not row:
|
||||||
|
print("Torrent not found")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
torrent_id, title, blob = row
|
||||||
|
|
||||||
|
filename = f"{title}.torrent".replace("/", "_")
|
||||||
|
|
||||||
|
with open(filename, "wb") as f:
|
||||||
|
f.write(blob)
|
||||||
|
|
||||||
|
print("Saved:", filename)
|
||||||
|
|
||||||
|
conn.close()
|
||||||
@@ -23,7 +23,7 @@ from datetime import datetime
|
|||||||
CLIENTS = [
|
CLIENTS = [
|
||||||
{
|
{
|
||||||
"name": "UltraCC Seedbox",
|
"name": "UltraCC Seedbox",
|
||||||
"max_concurrent": 20,
|
"max_concurrent": 30,
|
||||||
"qbt": {
|
"qbt": {
|
||||||
"host": "https://vladob.zen.usbx.me/qbittorrent",
|
"host": "https://vladob.zen.usbx.me/qbittorrent",
|
||||||
"username": "vladob",
|
"username": "vladob",
|
||||||
@@ -33,7 +33,7 @@ CLIENTS = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Local qBittorrent",
|
"name": "Local qBittorrent",
|
||||||
"max_concurrent": 20,
|
"max_concurrent": 30,
|
||||||
"qbt": {
|
"qbt": {
|
||||||
"host": "192.168.1.76",
|
"host": "192.168.1.76",
|
||||||
"port": 8080,
|
"port": 8080,
|
||||||
|
|||||||
473
Seedbox/Balík audioknih.torrent
Normal file
473
Seedbox/Balík audioknih.torrent
Normal file
File diff suppressed because one or more lines are too long
BIN
Seedbox/torrent_report.xlsx
Normal file
BIN
Seedbox/torrent_report.xlsx
Normal file
Binary file not shown.
Reference in New Issue
Block a user