Created
August 11, 2025 12:15
-
-
Save fabriziosalmi/c53556327a1c8a9562549efa8b7c095e to your computer and use it in GitHub Desktop.
index all bia 2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import json | |
import argparse | |
import logging | |
import sqlite3 | |
from collections import defaultdict | |
from datetime import datetime | |
from tqdm import tqdm # Importa tqdm per la progress bar | |
# --- CONFIGURAZIONE --- | |
BASE_PATH = "/mnt/user" | |
EXCLUDE_DIRS = [ | |
"appdata", "domains", "isos", "Backup_Appdata", "system", | |
"TUTTO", "MUSICA", "AUDIOLIBRI", | |
] | |
# Nomi dei file di output | |
DB_FILE_NAME = "media_index.db" | |
JSON_FILE_NAME = "media_index.json" | |
TXT_FILE_PREFIX = "index" | |
# -------------------- | |
def setup_logging(debug_mode: bool): | |
"""Configura il logging.""" | |
level = logging.DEBUG if debug_mode else logging.INFO | |
logging.basicConfig( | |
level=level, | |
format="[%(asctime)s] [%(levelname)s] - %(message)s", | |
datefmt="%Y-%m-%d %H:%M:%S", | |
) | |
def setup_database(db_path: str): | |
"""Crea la tabella nel database SQLite se non esiste.""" | |
try: | |
conn = sqlite3.connect(db_path) | |
cursor = conn.cursor() | |
# Una tabella semplice per memorizzare percorsi e file | |
# L'indice su 'path' velocizzerà le future ricerche | |
cursor.execute(""" | |
CREATE TABLE IF NOT EXISTS files ( | |
id INTEGER PRIMARY KEY AUTOINCREMENT, | |
path TEXT NOT NULL, | |
filename TEXT NOT NULL, | |
UNIQUE(path, filename) | |
); | |
""") | |
cursor.execute("CREATE INDEX IF NOT EXISTS idx_path ON files (path);") | |
# Pulisci la tabella per un nuovo inserimento | |
cursor.execute("DELETE FROM files;") | |
conn.commit() | |
return conn | |
except sqlite3.Error as e: | |
logging.error(f"Errore del database SQLite: {e}") | |
return None | |
def index_media_and_save(base_path, exclude_dirs, follow_links, output_format): | |
""" | |
Scansiona le directory e salva i risultati direttamente nel formato scelto | |
per minimizzare l'uso della memoria. | |
""" | |
full_exclude_paths = [os.path.join(base_path, d) for d in exclude_dirs] | |
logging.info(f"Inizio scansione da '{base_path}'. Formato output: {output_format}") | |
# Prepara connessione al DB se necessario | |
conn = None | |
cursor = None | |
if output_format in ["sqlite", "all"]: | |
conn = setup_database(DB_FILE_NAME) | |
if conn: | |
cursor = conn.cursor() | |
else: | |
# Se il DB fallisce, non procedere con l'output sqlite | |
output_format = "json" if output_format == "all" else "none" | |
# Struttura dati in memoria solo se richiesta | |
in_memory_index = defaultdict(list) if output_format in ["json", "txt", "all"] else None | |
total_files_count = 0 | |
# Usiamo un iteratore per poterlo passare a tqdm | |
walker = os.walk(base_path, topdown=True, followlinks=follow_links) | |
# tqdm mostra una barra di avanzamento dinamica | |
for root, dirs, files in tqdm(walker, desc="Scansione cartelle", unit="dir"): | |
if any(root.startswith(ex_path) for ex_path in full_exclude_paths): | |
dirs[:] = [] | |
continue | |
if not files: | |
continue | |
sorted_files = sorted(files) | |
# Salva in memoria se necessario | |
if in_memory_index is not None: | |
in_memory_index[root] = sorted_files | |
# Salva direttamente su SQLite | |
if cursor: | |
try: | |
# Usa executemany per un inserimento in blocco, molto più veloce | |
entries_to_insert = [(root, f) for f in sorted_files] | |
cursor.executemany("INSERT INTO files (path, filename) VALUES (?, ?)", entries_to_insert) | |
except sqlite3.Error as e: | |
logging.error(f"Errore inserimento dati per la cartella {root}: {e}") | |
total_files_count += len(sorted_files) | |
if conn: | |
conn.commit() | |
conn.close() | |
logging.info(f"Dati salvati con successo nel database '{DB_FILE_NAME}'.") | |
logging.info(f"Scansione completata. Trovati {total_files_count} file in {len(in_memory_index) if in_memory_index is not None else 'N/A'} cartelle.") | |
# Gestione output finali da dati in memoria | |
if output_format in ["json", "all"]: | |
save_json_index(in_memory_index, JSON_FILE_NAME) | |
if output_format in ["txt", "all"]: | |
save_txt_index(in_memory_index, TXT_FILE_PREFIX) | |
def save_json_index(index_data, filename): | |
"""Salva l'indice in formato JSON.""" | |
logging.info(f"Salvataggio indice JSON in '{filename}'...") | |
try: | |
with open(filename, "w", encoding="utf-8") as f: | |
json.dump(index_data, f, ensure_ascii=False, indent=2) | |
logging.info("Indice JSON salvato.") | |
except IOError as e: | |
logging.error(f"Impossibile scrivere il file JSON '{filename}': {e}") | |
def save_txt_index(index_data, filename_prefix): | |
"""Salva un report testuale formattato.""" | |
date_str = datetime.now().strftime("%Y-%m-%d") | |
filename = f"{filename_prefix}_{date_str}.txt" | |
logging.info(f"Creazione report TXT in '{filename}'...") | |
try: | |
with open(filename, "w", encoding="utf-8") as out: | |
for folder, files in sorted(index_data.items()): | |
display_folder = folder.replace(BASE_PATH, "", 1) or "/" | |
out.write(f"📁 {display_folder}\n") | |
for file in files: | |
out.write(f" - {file}\n") | |
out.write("\n") | |
logging.info(f"Report TXT creato con {len(index_data)} cartelle.") | |
except IOError as e: | |
logging.error(f"Impossibile scrivere il file TXT '{filename}': {e}") | |
def main(): | |
parser = argparse.ArgumentParser(description="Indicizzatore di file per Unraid.") | |
parser.add_argument("--debug", action="store_true", help="Abilita log dettagliati.") | |
parser.add_argument("--follow-links", action="store_true", help="Segue i link simbolici.") | |
parser.add_argument( | |
"--output-format", | |
choices=["json", "txt", "sqlite", "all"], | |
default="all", | |
help="Scegli il formato di output." | |
) | |
args = parser.parse_args() | |
setup_logging(args.debug) | |
index_media_and_save(BASE_PATH, EXCLUDE_DIRS, args.follow_links, args.output_format) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment