mirror of
https://github.com/Dasemu/x-space-downloader.git
synced 2026-10-13 13:39:45 +00:00
chore: initial commit
This commit is contained in:
188
docs/plans/2025-10-26-x-space-downloader-design.md
Normal file
188
docs/plans/2025-10-26-x-space-downloader-design.md
Normal file
@@ -0,0 +1,188 @@
|
||||
# X Space Downloader - Design Document
|
||||
|
||||
**Date:** 2025-10-26
|
||||
**Status:** Approved
|
||||
|
||||
## Overview
|
||||
|
||||
A Python CLI tool that downloads X (Twitter) Space recordings and outputs them as MP3 files. Takes a Space URL as input and produces an audio file.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Input:** X Space recording URL (e.g., `https://x.com/i/spaces/1ZkKzZWnVRRKv`)
|
||||
- **Output:** MP3 audio file
|
||||
- **Interface:** Command-line tool
|
||||
- **Authentication:** Supports X account credentials via cookies
|
||||
- **Scope:** Recordings only (not live Spaces)
|
||||
- **Error Handling:** Clear error messages for invalid or non-recording URLs
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
### Technology Choices
|
||||
|
||||
- **Language:** Python
|
||||
- **Core Engine:** yt-dlp (handles X authentication and media extraction)
|
||||
- **CLI Framework:** Click (argument parsing and user interface)
|
||||
- **Pattern:** Thin wrapper around yt-dlp
|
||||
|
||||
### Project Structure
|
||||
|
||||
```
|
||||
x-space-downloader/
|
||||
├── src/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # CLI entry point with argument parsing
|
||||
│ ├── downloader.py # Wraps yt-dlp functionality
|
||||
│ └── validator.py # URL validation and error handling
|
||||
├── tests/
|
||||
│ ├── test_validator.py
|
||||
│ └── test_downloader.py
|
||||
├── requirements.txt # Dependencies: yt-dlp, click
|
||||
├── setup.py # Makes it installable
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### User Workflow
|
||||
|
||||
```bash
|
||||
x-space-dl --cookies cookies.txt https://x.com/i/spaces/1ZkKzZWnVRRKv
|
||||
# Output: space_1ZkKzZWnVRRKv.mp3
|
||||
```
|
||||
|
||||
## Component Design
|
||||
|
||||
### validator.py
|
||||
|
||||
**Responsibilities:**
|
||||
- Validate URL format (must match X Spaces pattern: `https://x.com/i/spaces/{SPACE_ID}`)
|
||||
- Check if URL points to a recording vs live Space
|
||||
- Return clear error messages for invalid inputs
|
||||
|
||||
**Key Interface:**
|
||||
```python
|
||||
def validate_space_url(url: str) -> Tuple[bool, Optional[str], Optional[str]]:
|
||||
"""
|
||||
Validates X Space URL.
|
||||
|
||||
Returns:
|
||||
(is_valid, space_id, error_message)
|
||||
"""
|
||||
```
|
||||
|
||||
### downloader.py
|
||||
|
||||
**Responsibilities:**
|
||||
- Configure yt-dlp options (format: mp3, quality, output template)
|
||||
- Pass cookie file to yt-dlp for authentication
|
||||
- Translate yt-dlp output/errors to user-friendly messages
|
||||
- Show download progress
|
||||
|
||||
**Key Interface:**
|
||||
```python
|
||||
def download_space(
|
||||
space_url: str,
|
||||
output_dir: str,
|
||||
cookies_file: Optional[str]
|
||||
) -> str:
|
||||
"""
|
||||
Downloads Space recording using yt-dlp.
|
||||
|
||||
Returns:
|
||||
Path to downloaded MP3 file
|
||||
"""
|
||||
```
|
||||
|
||||
**yt-dlp Configuration:**
|
||||
- Output format: mp3 (audio only)
|
||||
- Output template: `space_{space_id}.mp3`
|
||||
- Post-processing: convert to mp3 if needed
|
||||
- Progress hooks for user feedback
|
||||
|
||||
### main.py
|
||||
|
||||
**Responsibilities:**
|
||||
- CLI argument parsing with Click
|
||||
- Orchestrate validation → download flow
|
||||
- Handle and display errors appropriately
|
||||
- Exit with appropriate status codes
|
||||
|
||||
**CLI Arguments:**
|
||||
- `URL` (required): X Space URL
|
||||
- `--cookies` (optional): Path to cookies file
|
||||
- `--output` (optional): Output directory (default: current directory)
|
||||
|
||||
**Exit Codes:**
|
||||
- `0`: Success
|
||||
- `1`: Invalid URL
|
||||
- `2`: Download failed
|
||||
- `3`: Authentication required
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. User provides URL + optional cookies file
|
||||
2. **Validator** checks URL format → extracts space_id
|
||||
3. **Downloader** configures yt-dlp with:
|
||||
- Output format: mp3 (audio only)
|
||||
- Output template: `space_{space_id}.mp3`
|
||||
- Cookies file if provided
|
||||
- Post-processing: convert to mp3 if needed
|
||||
4. yt-dlp fetches metadata, downloads audio stream, converts to mp3
|
||||
5. Return file path to user
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error Scenario | Detection | User Message |
|
||||
|----------------|-----------|--------------|
|
||||
| Invalid URL format | Validator regex check | "Invalid URL format. Expected: https://x.com/i/spaces/{SPACE_ID}" |
|
||||
| Space doesn't exist | yt-dlp 404 error | "Recording not found. Check URL or Space may be deleted." |
|
||||
| Authentication required | yt-dlp auth error | "Authentication required. Please provide cookies file with --cookies" |
|
||||
| Network errors | yt-dlp timeout/connection | "Network error. Check connection and try again." |
|
||||
| Space is live | Validator metadata check | "Error: This is a live Space, not a recording." |
|
||||
| Disk space/permissions | File system errors | "Cannot write to output directory. Check permissions and disk space." |
|
||||
|
||||
## Authentication
|
||||
|
||||
**Cookie-based Authentication:**
|
||||
- User exports cookies from logged-in X session
|
||||
- Provides cookie file path via `--cookies` flag
|
||||
- yt-dlp uses cookies for authenticated requests
|
||||
|
||||
**Cookie Export Instructions:**
|
||||
- Browser extensions: "Get cookies.txt", "cookies.txt"
|
||||
- Manual: Export via browser DevTools
|
||||
- Instructions included in README
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
**Unit Tests:**
|
||||
- Validator: Test various URL formats, valid/invalid patterns
|
||||
- Error message generation
|
||||
|
||||
**Integration Tests:**
|
||||
- Full download flow with yt-dlp
|
||||
- Use test Space URLs or mock yt-dlp calls
|
||||
- Cookie authentication flow
|
||||
|
||||
**Error Scenario Tests:**
|
||||
- Invalid URLs
|
||||
- Missing cookies
|
||||
- Network failures
|
||||
- Live Space detection
|
||||
|
||||
## Dependencies
|
||||
|
||||
**Core:**
|
||||
- `yt-dlp`: Media downloading and extraction
|
||||
- `click`: CLI framework
|
||||
|
||||
**Development:**
|
||||
- `pytest`: Testing framework
|
||||
- `pytest-mock`: Mocking for tests
|
||||
|
||||
## Future Considerations (Out of Scope)
|
||||
|
||||
- Live Space recording
|
||||
- Batch downloading multiple Spaces
|
||||
- GUI interface
|
||||
- Format options beyond MP3
|
||||
- Metadata extraction (speakers, title, description)
|
||||
Reference in New Issue
Block a user