z230
This commit is contained in:
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()
|
||||
Reference in New Issue
Block a user