From cf69deb6d7b46f5fafd0eef468aefe083bcfa902 Mon Sep 17 00:00:00 2001 From: Fengqing Liu Date: Fri, 24 Oct 2025 21:57:11 +1100 Subject: [PATCH] format --- CLAUDE.md | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b325016..791b78d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,6 +7,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co Twitch Drops Miner is a Python application that automatically mines timed Twitch drops without downloading stream data. It uses Twitch's GraphQL API and websocket connections to simulate watching streams while tracking drop progress. **Key Characteristics:** + - Python 3.10+ required - Web-based GUI using FastAPI and Socket.IO - Async/await architecture with asyncio @@ -43,11 +44,13 @@ source env/bin/activate && python main.py --dump ### Development Setup The application requires: + - Python 3.10+ - Virtual environment at `env/` (must be activated before running commands) - Dependencies from `pyproject.toml` (includes FastAPI, uvicorn, Socket.IO) Docker deployment: + ```bash # Build and run with docker-compose docker-compose up -d @@ -63,7 +66,7 @@ The application now uses a clean `src/` package structure with clear separation ### Project Structure -``` +```text src/ ├── models/ # Domain models (Game, Channel, Campaign, Drop, Benefit) ├── config/ # Configuration (constants, paths, operations, settings, client_info) @@ -91,10 +94,12 @@ lang/ # Translation JSON files (19 languages) ### Core Components **main.py** - Simple launcher: + - Runs the `src` package as a module using `runpy.run_module("src")` - All application logic is now in `src/__main__.py` -**src/__main__.py** - Entry point: +**src/**main**.py** - Entry point: + - Parses command-line arguments - Initializes Settings, Twitch client, and WebGUIManager - Starts the FastAPI web server (uvicorn on port 8080) @@ -102,6 +107,7 @@ lang/ # Translation JSON files (19 languages) - Handles signals (SIGINT, SIGTERM on Linux) and exit codes **src/core/client.py** - Central client (`Twitch` class): + - State machine: IDLE, INVENTORY_FETCH, GAMES_UPDATE, CHANNELS_CLEANUP, CHANNELS_FETCH, CHANNEL_SWITCH, EXIT - Composes `_AuthState`, `HTTPClient`, and `GQLClient` - Delegates to service layer for business logic @@ -109,6 +115,7 @@ lang/ # Translation JSON files (19 languages) - Manages WebsocketPool and maintenance tasks **src/services/** - Business logic layer (fully implemented): + - `ChannelService`: Channel management and selection logic - `InventoryService`: Campaign and drop inventory operations - `WatchService`: Drop mining watch payload logic @@ -118,39 +125,46 @@ lang/ # Translation JSON files (19 languages) Note: The services layer is complete and handles all business logic that was previously in the monolithic client file. **src/models/channel.py** - Channel and Stream: + - `Channel` class: Twitch channel with online/offline status - `Stream` class: Active stream with game, viewers, drop status - Stream URL fetching and validation - ACL-based vs directory channels **src/models/campaign.py** - Drop campaigns: + - `DropsCampaign`: Campaign with game, timeframe, allowed channels - Time-based eligibility and progress tracking **src/models/drop.py** - Drop types: + - `TimedDrop`: Drops with minute requirements and progress - `BaseDrop`: Base class with claim logic - Precondition chains for sequential drops **src/web/gui_manager.py** - Web GUI: + - `WebGUIManager`: Main GUI coordinator - Composes individual managers for different UI concerns (status, console, channels, campaigns, inventory, login, settings, cache) - Uses `WebSocketBroadcaster` for real-time Socket.IO updates - Pure asyncio, no tkinter dependency **src/web/app.py** - FastAPI application: + - REST API endpoints: `/api/status`, `/api/channels`, `/api/campaigns`, `/api/settings`, `/api/login`, `/api/oauth/confirm`, `/api/reload`, `/api/close` - Socket.IO server for real-time bi-directional communication - Serves static web frontend from `web/` directory - Integrates with WebGUIManager via `set_managers()` **src/websocket/pool.py** - WebSocket management: + - Sharded connections (up to 50 topics per socket, max 199 channels) - Topics: User.Drops, User.Notifications, Channel.StreamState, Channel.StreamUpdate - Automatic reconnection with exponential backoff - Message routing to registered callbacks **src/config/settings.py** - Application settings: + - Games to watch list (auto-populated from available campaigns if empty) - Connection quality multiplier - Language selection @@ -180,6 +194,7 @@ Note: The services layer is complete and handles all business logic that was pre ### Drop Mining Mechanism The application sends periodic "watch" payloads to a spade URL every ~20 seconds: + - Payload contains minute-watched events with channel/broadcast IDs - Twitch reports progress via websocket (User.Drops topic) - If websocket updates stop, fallback to GQL CurrentDrop query @@ -188,6 +203,7 @@ The application sends periodic "watch" payloads to a spade URL every ~20 seconds ### GraphQL Operations Defined in `src/config/operations.py` as `GQL_OPERATIONS`: + - **Inventory** - Fetch in-progress campaigns and claimed benefits - **Campaigns** - List available active/upcoming campaigns - **CampaignDetails** - Detailed drop info for a campaign @@ -209,12 +225,14 @@ Defined in `src/config/operations.py` as `GQL_OPERATIONS`: ### Maintenance Task Runs in background to trigger: + - Channel cleanup when drops start/end (based on time_triggers) - Inventory reload every ~60 minutes ### Translation System **Architecture:** + - All translations stored as JSON files in `lang/` directory (19 languages supported) - English (`lang/English.json`) is the single source of truth and fallback language - Strongly typed with TypedDict schema defined in `src/i18n/translator.py` @@ -222,6 +240,7 @@ Runs in background to trigger: - Singleton instance `_` available via `from src.i18n import _` **Supported Languages:** + - English, Dansk (Danish), Deutsch (German), Español (Spanish), Français (French) - Indonesian, Italiano (Italian), Nederlandse (Dutch), Polski (Polish), Português (Portuguese) - Română (Romanian), Türkçe (Turkish), Čeština (Czech) @@ -229,6 +248,7 @@ Runs in background to trigger: - 日本語 (Japanese), 简体中文 (Simplified Chinese), 繁體中文 (Traditional Chinese) **Translation Structure:** + ```python Translation = { "language_name": str, # Display name of language @@ -241,6 +261,7 @@ Translation = { ``` **Usage:** + ```python from src.i18n import _ @@ -250,6 +271,7 @@ login_text = _("login", "status", "logged_in") # Returns "Logged in" ``` **Language Persistence:** + - Language selection persisted in `settings.json` (DATA_DIR) - Dynamic language switching supported in web GUI - Changes take effect immediately without restart @@ -265,7 +287,7 @@ login_text = _("login", "status", "logged_in") # Returns "Logged in" - **src/utils/** - Helper utilities (string_utils, json_utils, async_helpers, rate_limiter, backoff) - **src/i18n/** - Internationalization package with TypedDict schema and Translator class - **translator.py** - Translator class with typed translation schema (Translation TypedDict) - - **__init__.py** - Exports translation types and `_` (Translator instance) + - ****init**.py** - Exports translation types and `_` (Translator instance) - **lang/** - Translation JSON files for 19 languages (English.json is the single source of truth) - **src/version.py** - Version string - **src/web/app.py** - FastAPI application with REST API and Socket.IO @@ -275,12 +297,13 @@ login_text = _("login", "status", "logged_in") # Returns "Logged in" ## Testing The project does not include a test suite. Manual testing workflow: + 1. Run with `-vvv` for maximum verbosity (levels: -v, -vv, -vvv, -vvvv) 2. Use `--dump` to generate debug data dumps 3. Check timestamped log files in `./logs/` directory (always created as `TDM.TIMESTAMP.log`) -5. Use `--debug-ws` for websocket debug logging -6. Use `--debug-gql` for GraphQL debug logging -7. Monitor web GUI console output and browser developer tools +4. Use `--debug-ws` for websocket debug logging +5. Use `--debug-gql` for GraphQL debug logging +6. Monitor web GUI console output and browser developer tools ## Web GUI Architecture @@ -289,17 +312,20 @@ The application uses a web-based interface accessible via browser: ### Web GUI Components **src/web/gui_manager.py** - WebGUIManager class: + - Managers: StatusManager, ConsoleOutputManager, ChannelListManager, CampaignProgressManager, InventoryManager, LoginFormManager, SettingsManager, CacheManager - Uses WebSocketBroadcaster to push real-time updates to connected clients via Socket.IO - Pure async/await implementation **src/web/app.py** - FastAPI application: + - REST API endpoints: `/api/status`, `/api/channels`, `/api/campaigns`, `/api/console`, `/api/settings`, `/api/login`, `/api/oauth/confirm`, `/api/reload`, `/api/close` - Socket.IO events for real-time bi-directional communication - Serves static web frontend from `web/` directory - Integrates with WebGUIManager via `set_managers(gui, twitch)` **web/** - Frontend assets: + - `index.html` - Single-page application layout with tabs - `static/app.js` - Socket.IO client, real-time UI updates, API calls - `static/styles.css` - Responsive design with dark mode support @@ -307,6 +333,7 @@ The application uses a web-based interface accessible via browser: ### Communication Protocol **Server → Client (Socket.IO events):** + - `initial_state` - Full state on connect - `status_update` - Status bar changes - `console_output` - New log lines @@ -317,12 +344,14 @@ The application uses a web-based interface accessible via browser: - `settings_updated` - Settings changed **Client → Server:** + - REST API for actions (login, settings, channel selection) - Socket.IO for connection management ### Docker Integration **src/config/paths.py:** + - Detects Docker environment via `DOCKER_ENV` env var or `/.dockerenv` file - Docker: Uses `/app` for code, `/app/data` for persistent storage - Development: Uses `/data` for persistent storage @@ -330,12 +359,14 @@ The application uses a web-based interface accessible via browser: - Provides `_resource_path()` helper for locating bundled resources **Dockerfile:** + - Based on `python:3.11-slim` - Installs dependencies from `pyproject.toml` - Exposes port 8080 - Health check on `/api/status` **docker-compose.yml:** + - Volume mounts `./data:/app/data` for persistence - Port mapping `8080:8080` - Auto-restart policy @@ -351,13 +382,15 @@ The application uses a web-based interface accessible via browser: ## Project Scope **Supported:** + - ✅ Web GUI - browser-based interface - ✅ Docker deployment - containerized for any platform - ✅ Remote access - access from any device on network - ✅ Headless operation - no display server required **NOT supported:** + - Multi-account support - Channel points mining - Mining for unlinked campaigns -- Desktop GUI (removed in favor of web-only) \ No newline at end of file +- Desktop GUI (removed in favor of web-only)