- Reemplaza zxdb.py por main.py + paquete zxdb/ (database, organizer, downloader, filesystem) - Añade zxdb/setup/: orquestador Docker, descarga e import de ZXDB automáticos - main.py integra el setup al arrancar y detiene el contenedor al salir (try/finally) - Elimina DB_HOST de config.py: la conexión usa siempre 127.0.0.1 (port mapping Docker) - Actualiza requirements.txt a versiones más recientes y elimina logging (stdlib) - Actualiza README con el nuevo flujo de uso Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.6 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Overview
This is a Python script that downloads ZX Spectrum game files from the ZXDB open database. It queries a local MySQL instance containing ZXDB data, then downloads and organizes game files (tapes, disks, snapshots, pokes) into a configurable folder structure with caching support.
Setup
Virtual environment:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
MySQL database: Runs in a Docker container. Connect with:
mysql -h 172.18.0.2 -P 3306 -u root -p
# Password: unJEPimbJddHP8
# Then: use zxdb
# To import: source /path/to/ZXDB.sql
Configuration: Edit config.py directly (tracked in git; credentials are intentionally non-sensitive). Key settings:
DB_*— MySQL connection paramsDESTINATION_PATH/CACHE_PATH/TEMP_FILE— local pathsSHOULD_CLEAR_DESTINATION_PATH— wipes destination before each runSHOULD_SPLIT_MODERN_AND_CLASSIC/SHOULD_SORT_BY_YEAR/SHOULD_SORT_BY_LETTER/SHOULD_SORT_BY_DEVELOPER— folder organization modesWAIT/MIN_WAIT/MAX_WAIT— rate limiting between downloadsLAST_CLASSIC_YEAR— year cutoff for classic/modern splitZXDB_SQL_PATH— where to place the extractedZXDB_mysql.sql(used byzxdb/setup/database_import.py)ZXDB_STATE_FILE— JSON file tracking the last successful import (github_commit_date + last_import)
Running
python main.py
Architecture
The code is organized as a Python package (zxdb/) orchestrated by main.py. There is no global state: data flows as a list of dictionaries between functions.
Entry point (main.py):
elements = database.connect(query_index=3)
elements = organizer.process_elements(elements)
filesystem.print_elements(elements, mode=1)
filesystem.clear_destination_folder()
downloader.get_files(elements)
filesystem.remove_empty_directories(config.DESTINATION_PATH)
Module structure:
zxdb/database.py—load_queries(),select(),connect(): connects to MySQL and returns elements listzxdb/organizer.py—normalize_path(),update_url(),url_filename(),process_elements(),get_final_destination_folder()zxdb/downloader.py—download_file(),unzip_file(),process_cache_file(),get_files(elements)zxdb/filesystem.py—clear_destination_folder(),remove_empty_directories(),print_elements(elements, mode),print_status()zxdb/queries.sql— Four SQL queries (index 0–3), loaded viaPath(__file__).parent / "queries.sql"zxdb/setup/database_import.py—download_zxdb(destination): streaming download ofZXDB_mysql.sql.zipfrom GitHub + ZIP extraction; runnable viapython -m zxdb.setup.database_importzxdb/setup/docker_manager.py—ensure_container(),wait_for_mysql(container, timeout),db_exists(container),import_sql(container, sql_path): Docker container management and SQL importzxdb/setup/__main__.py— Full setup orchestrator: Docker → MySQL ready → GitHub change detection → download → import → save state. Run viapython -m zxdb.setup
SQL queries (zxdb/queries.sql): Four queries (index 0–3). Query 3 (current default) filters for ZX-Spectrum machines only (m.text like 'ZX-%') and returns only tape/disk/snapshot/poke file types.
Folder organization (get_final_destination_folder()): Builds a path from up to four nested levels based on the sort flags in config.py:
folder1:classics/modern,by_developer,by_year, or emptyfolder2: developer letter + developer name (e.g.,D/Dinamic) or emptyfolder3: release year orunknownfolder4: first letter of game title (e.g.,A,0-9) or empty
URL resolution (update_url()): URLs from the DB are relative paths. They get prefixed based on their start: /zxdb → spectrumcomputing.co.uk, /pub → WOS mirror, /nvg → NVG mirror.
Cache: Files are stored in CACHE_PATH/<game_folder_name>/<subfolder>/. The cache key is the original game_folder_name (title + year + developer), independent of the current sort configuration, so changing sort options reuses cached files.
File types stored at game root (no subfolder): Tape image, Disk image, Snapshot image, POK pokes file. All other file types go into a named subfolder.
ZIP extraction (unzip_file()): Only extracts files matching known emulator formats: .tap, .tzx, .stl, .sna, .z80, .dsk, .fdi, .trd, .img, .mgt, .szx, .dck.