This commit is contained in:
Fengqing Liu
2025-10-24 21:57:11 +11:00
parent 46291e83d8
commit cf69deb6d7

View File

@@ -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 `<project_root>/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,12 +382,14 @@ 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