# Aniworld Download Manager A web-based anime download manager with REST API, WebSocket real-time updates, and a modern web interface. ## Features - Web interface for managing anime library - REST API for programmatic access - WebSocket real-time progress updates - Download queue with priority management - Automatic library scanning for missing episodes - **NFO metadata management with TMDB integration** - **Automatic poster/fanart/logo downloads** - JWT-based authentication - SQLite database for persistence - **Comprehensive test coverage** (1,070+ tests, 91.3% coverage) ## Quick Start ### Prerequisites - Python 3.10+ - Conda (recommended) or virtualenv ### Installation 1. Clone the repository: ```bash git clone https://github.com/your-repo/aniworld.git cd aniworld ``` 2. Create and activate conda environment: ```bash conda create -n AniWorld python=3.10 conda activate AniWorld ``` 3. Install dependencies: ```bash pip install -r requirements.txt ``` 4. Start the server: ```bash python -m uvicorn src.server.fastapi_app:app --host 127.0.0.1 --port 8000 ``` 5. Open http://127.0.0.1:8000 in your browser ### First-Time Setup 1. Navigate to http://127.0.0.1:8000/setup 2. Set a master password (minimum 8 characters, mixed case, number, special character) 3. Configure your anime directory path 4. **(Optional)** Configure NFO settings with your TMDB API key 5. Login with your master password ### NFO Metadata Setup (Optional) For automatic NFO file generation with metadata and images: 1. Get a free TMDB API key from https://www.themoviedb.org/settings/api 2. Go to Configuration → NFO Settings in the web interface 3. Enter your TMDB API key and click "Test Connection" 4. Enable auto-creation and select which images to download 5. NFO files will be created automatically during downloads ## Documentation | Document | Description | | ---------------------------------------------- | -------------------------------- | | [docs/API.md](docs/API.md) | REST API and WebSocket reference | | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) | System architecture and design | | [docs/CONFIGURATION.md](docs/CONFIGURATION.md) | Configuration options | | [docs/DATABASE.md](docs/DATABASE.md) | Database schema | | [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) | Developer setup guide | | [docs/TESTING.md](docs/TESTING.md) | Testing guidelines | ## Project Structure ``` src/ +-- cli/ # CLI interface (legacy) +-- config/ # Application settings +-- core/ # Domain logic | +-- SeriesApp.py # Main application facade | +-- SerieScanner.py # Directory scanning | +-- entities/ # Domain entities | +-- providers/ # External provider adapters +-- server/ # FastAPI web server +-- api/ # REST API endpoints +-- services/ # Business logic +-- models/ # Pydantic models +-- database/ # SQLAlchemy ORM +-- middleware/ # Auth, rate limiting ``` ## API Endpoints | Endpoint | Description | | ------------------------------ | -------------------------------- | | `POST /api/auth/login` | Authenticate and get JWT token | | `GET /api/anime` | List anime with missing episodes | | `GET /api/anime/search?query=` | Search for anime | | `POST /api/queue/add` | Add episodes to download queue | | `POST /api/queue/start` | Start queue processing | | `GET /api/queue/status` | Get queue status | | `GET /api/nfo/check` | Check NFO status for anime | | `POST /api/nfo/create` | Create NFO files | | `WS /ws/connect` | WebSocket for real-time updates | See [docs/API.md](docs/API.md) for complete API reference. ## Configuration Environment variables (via `.env` file): | Variable | Default | Description | | ----------------- | ------------------------------ | ------------------------- | | `JWT_SECRET_KEY` | (random) | Secret for JWT signing | | `DATABASE_URL` | `sqlite:///./data/aniworld.db` | Database connection | | `ANIME_DIRECTORY` | (empty) | Path to anime library | | `TMDB_API_KEY` | (empty) | TMDB API key for metadata | | `LOG_LEVEL` | `INFO` | Logging level | See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for all options. ## Running Tests The project includes a comprehensive test suite with **1,070+ tests** and **91.3% coverage** across all critical systems: ```bash # Run all Python tests conda run -n AniWorld python -m pytest tests/ -v # Run unit tests only conda run -n AniWorld python -m pytest tests/unit/ -v # Run integration tests conda run -n AniWorld python -m pytest tests/integration/ -v # Run with coverage report conda run -n AniWorld python -m pytest tests/ --cov --cov-report=html # Run JavaScript/E2E tests (requires Node.js) npm test # Unit tests (Vitest) npm run test:e2e # E2E tests (Playwright) ``` **Test Coverage:** - ✅ 1,070+ tests across 4 priority tiers (644 Python tests passing, 426 JavaScript/E2E tests) - ✅ 91.3% code coverage - ✅ **TIER 1 Critical**: 159/159 tests - Scheduler, NFO batch, download queue, persistence - ✅ **TIER 2 High Priority**: 390/390 tests - Frontend UI, WebSocket, dark mode, settings - ✅ **TIER 3 Medium Priority**: 95/156 tests - Performance, edge cases (core scenarios complete) - ✅ **TIER 4 Polish**: 426 tests - Internationalization, accessibility, media server compatibility - ✅ Security: Complete coverage (authentication, authorization, CSRF, XSS, SQL injection) - ✅ Performance: Validated (200+ concurrent WebSocket clients, batch operations) See [docs/TESTING_COMPLETE.md](docs/TESTING_COMPLETE.md) for comprehensive testing documentation. ## Technology Stack - **Web Framework**: FastAPI 0.104.1 - **Database**: SQLite + SQLAlchemy 2.0 - **Auth**: JWT (python-jose) + passlib - **Validation**: Pydantic 2.5 - **Logging**: structlog - **Testing**: pytest + pytest-asyncio ## Application Lifecycle ### Initialization On first startup, the application performs a one-time sync of series from data files to the database: 1. FastAPI lifespan starts 2. Database is initialized 3. `sync_series_from_data_files()` reads all data files from the anime directory (creates temporary SeriesApp) 4. Series metadata is synced to the database 5. DownloadService initializes (triggers main `SeriesApp` creation) 6. `SeriesApp` loads series from database via service layer (not from files) On subsequent startups, the same flow applies but the sync finds no new series. `SeriesApp` always initializes with an empty series list (`skip_load=True`) and loads data from the database on demand, avoiding redundant file system scans. ### Adding New Series When adding a new series: 1. Series is added to the database via `AnimeService` 2. Data file is created in the anime directory 3. In-memory `SerieList` is updated via `load_series_from_list()` ## License MIT License