Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
19 changes: 15 additions & 4 deletions .cursor/rules/development-patterns.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,22 @@ description: Development patterns and coding standards for ccBitTorrent
- **Orchestration modules**: [`ccbt/cli/downloads.py`](mdc:ccbt/cli/downloads.py), [`ccbt/cli/status.py`](mdc:ccbt/cli/status.py), [`ccbt/cli/resume.py`](mdc:ccbt/cli/resume.py) bridge CLI→Session.

### Session Delegation Pattern
- `AsyncSessionManager` orchestrates; delegates to controllers:
- [`ccbt/session/announce.py`](mdc:ccbt/session/announce.py): Tracker announces
- [`ccbt/session/checkpointing.py`](mdc:ccbt/session/checkpointing.py): Checkpoint operations
- `AsyncTorrentSession` orchestrates; delegates to controllers:
- [`ccbt/session/lifecycle.py`](mdc:ccbt/session/lifecycle.py): Lifecycle sequencing (start/pause/resume/stop/cancel)
- [`ccbt/session/checkpointing.py`](mdc:ccbt/session/checkpointing.py): Checkpoint operations with fast resume support
- [`ccbt/session/status_aggregation.py`](mdc:ccbt/session/status_aggregation.py): Status collection and aggregation
- [`ccbt/session/announce.py`](mdc:ccbt/session/announce.py): Tracker announces (AnnounceLoop, AnnounceController)
- [`ccbt/session/metrics_status.py`](mdc:ccbt/session/metrics_status.py): Status monitoring loop (StatusLoop)
- [`ccbt/session/peers.py`](mdc:ccbt/session/peers.py): Peer management (PeerManagerInitializer, PeerConnectionHelper, PexBinder)
- [`ccbt/session/peer_events.py`](mdc:ccbt/session/peer_events.py): Peer event binding (PeerEventsBinder)
- [`ccbt/session/magnet_handling.py`](mdc:ccbt/session/magnet_handling.py): Magnet file selection (MagnetHandler)
- [`ccbt/session/dht_setup.py`](mdc:ccbt/session/dht_setup.py): DHT discovery setup (DiscoveryController)
- [`ccbt/session/download_startup.py`](mdc:ccbt/session/download_startup.py): Download initialization
- [`ccbt/session/torrent_addition.py`](mdc:ccbt/session/torrent_addition.py): Torrent addition flow
- `AsyncSessionManager` orchestrates; delegates to managers:
- [`ccbt/session/torrent_addition.py`](mdc:ccbt/session/torrent_addition.py): Torrent addition flow (TorrentAdditionHandler)
- [`ccbt/session/manager_background.py`](mdc:ccbt/session/manager_background.py): Background tasks (ManagerBackgroundTasks)
- [`ccbt/session/scrape.py`](mdc:ccbt/session/scrape.py): Tracker scraping (ScrapeManager)
- [`ccbt/session/checkpoint_operations.py`](mdc:ccbt/session/checkpoint_operations.py): Manager-level checkpoint operations (CheckpointOperations)
- [`ccbt/session/manager_startup.py`](mdc:ccbt/session/manager_startup.py): Component startup sequence

### Dependency Injection
Expand Down
51 changes: 6 additions & 45 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,51 +54,12 @@ jobs:

- name: Build documentation
run: |
uv run python << 'PYTHON_EOF'
# Apply patch BEFORE importing mkdocs
import mkdocs_static_i18n
from mkdocs_static_i18n.plugin import I18n
import mkdocs_static_i18n.reconfigure

# Store original functions
original_is_relative_to = mkdocs_static_i18n.is_relative_to
original_reconfigure_files = I18n.reconfigure_files

# Create patched functions
def patched_is_relative_to(src_path, dest_path):
if src_path is None:
return False
try:
return original_is_relative_to(src_path, dest_path)
except (TypeError, AttributeError):
return False

def patched_reconfigure_files(self, files, mkdocs_config):
valid_files = [f for f in files if hasattr(f, 'abs_src_path') and f.abs_src_path is not None]
invalid_files = [f for f in files if not hasattr(f, 'abs_src_path') or f.abs_src_path is None]
if valid_files:
result = original_reconfigure_files(self, valid_files, mkdocs_config)
# Add invalid files back using append (I18nFiles is not a list)
if invalid_files:
for invalid_file in invalid_files:
result.append(invalid_file)
return result
# If no valid files, return original files object (shouldn't happen but safe fallback)
return files

# Apply patches - patch the source module first
mkdocs_static_i18n.is_relative_to = patched_is_relative_to
# Patch the local reference in reconfigure module (it imports from __init__)
mkdocs_static_i18n.reconfigure.is_relative_to = patched_is_relative_to
# Patch the reconfigure_files method on the I18n class
I18n.reconfigure_files = patched_reconfigure_files

# Now import and run mkdocs in the same process
import sys
from mkdocs.__main__ import cli
sys.argv = ['mkdocs', 'build', '--strict', '-f', 'dev/mkdocs.yml']
cli()
PYTHON_EOF
# Use the patched build script which includes all necessary patches:
# - i18n plugin fixes (alternates attribute, Locale validation for 'arc')
# - git-revision-date-localized plugin fix for 'arc' locale
# - All patches are applied before mkdocs is imported
# Set MKDOCS_STRICT=true to enable strict mode in CI
MKDOCS_STRICT=true uv run python dev/build_docs_patched_clean.py

- name: Upload documentation artifact
uses: actions/upload-artifact@v4
Expand Down
6 changes: 6 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ build:
os: ubuntu-24.04
tools:
python: "3.11"
commands:
# Use the patched build script to ensure i18n plugin works correctly
# This applies patches to mkdocs-static-i18n before building
- python dev/build_docs_patched_clean.py

# MkDocs configuration
# Point to the mkdocs.yml file in the dev directory
# Note: We override the default build with build.commands above,
# but this is still needed for Read the Docs to detect MkDocs project
mkdocs:
configuration: dev/mkdocs.yml

Expand Down
Loading
Loading