# Media Downloader Web Interface Modern web interface for managing the Media Downloader system. ## Architecture **Backend**: FastAPI (Python 3.11+) - Direct integration with existing media-downloader modules - REST API + WebSocket for real-time updates - Runs on port 8000 **Frontend**: React + Vite + TypeScript - Modern, responsive dashboard - Real-time updates via WebSocket - Tailwind CSS for styling - Runs on port 5173 (dev) or served by backend (production) ## Quick Start ### Prerequisites ```bash # Install backend dependencies cd /opt/media-downloader/web/backend pip3 install -r requirements.txt # Install frontend dependencies cd /opt/media-downloader/web/frontend npm install ``` ### Development Mode **Terminal 1 - Backend:** ```bash cd /opt/media-downloader/web/backend python3 api.py ``` **Terminal 2 - Frontend:** ```bash cd /opt/media-downloader/web/frontend npm run dev ``` Access the web interface at: **http://localhost:5173** ### Production Build ```bash # Build frontend cd /opt/media-downloader/web/frontend npm run build # The built files will be in /opt/media-downloader/web/frontend/dist # Serve them with nginx or directly from FastAPI ``` ## Features ### Dashboard - **Real-time statistics** - Total downloads, recent activity, storage usage - **Platform distribution chart** - Visual breakdown by platform - **Recent activity feed** - Latest downloads with real-time updates - **System status** - Scheduler status, WebSocket connections ### Downloads - **Browse all downloads** - Paginated list with search and filters - **Filter by platform** - Instagram, TikTok, Snapchat, Forums - **Filter by source** - Username or forum name - **Delete records** - Remove entries from database - **Detailed information** - File size, date, path, content type ### Platforms - **Visual platform cards** - Color-coded, icon-based UI - **Manual triggers** - Start downloads with one click - **Platform status** - Enabled/disabled, check intervals, account counts - **Real-time feedback** - Loading states, success/error notifications ### Logs - **Real-time log streaming** - Live updates via WebSocket - **Log level filtering** - ERROR, WARNING, SUCCESS, DEBUG, INFO - **Auto-scroll** - Follows new log entries automatically - **Export logs** - Download logs as text file - **Statistics** - Count of each log level ### Configuration - **JSON editor** - Edit settings.json directly from web UI - **Syntax validation** - Catch JSON errors before saving - **Reference documentation** - Built-in configuration guide - **Save/reset** - Apply changes or revert to saved version ## API Endpoints ### System ``` GET /api/health - Health check GET /api/status - System status overview ``` ### Downloads ``` GET /api/downloads - List downloads (paginated, filterable) GET /api/downloads/stats - Download statistics DELETE /api/downloads/:id - Delete download record ``` ### Platforms ``` GET /api/platforms - List all platforms POST /api/platforms/:name/trigger - Manually trigger download ``` ### Configuration ``` GET /api/config - Get configuration PUT /api/config - Update configuration ``` ### Logs ``` GET /api/logs?lines=100 - Get recent log entries ``` ### WebSocket ``` WS /ws - Real-time updates ``` ## WebSocket Events **Server → Client:** ```javascript { "type": "connected", "timestamp": "2025-10-29T17:30:00" } { "type": "log", "level": "info", "message": "Download started...", "platform": "fastdl" } { "type": "download_started", "platform": "fastdl", "username": "evalongoria", "timestamp": "2025-10-29T17:30:00" } { "type": "download_completed", "platform": "fastdl", "username": "evalongoria", "exit_code": 0, "timestamp": "2025-10-29T17:35:00" } { "type": "download_error", "platform": "fastdl", "error": "Connection timeout", "timestamp": "2025-10-29T17:35:00" } { "type": "download_deleted", "id": 123 } { "type": "config_updated", "timestamp": "2025-10-29T17:35:00" } ``` ## Production Deployment ### Option 1: Systemd Services Create `/etc/systemd/system/media-downloader-api.service`: ```ini [Unit] Description=Media Downloader API After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/media-downloader/web/backend ExecStart=/usr/bin/python3 api.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` Enable and start: ```bash sudo systemctl enable media-downloader-api sudo systemctl start media-downloader-api ``` ### Option 2: Nginx Reverse Proxy ```nginx server { listen 80; server_name media-downloader.local; # Frontend static files location / { root /opt/media-downloader/web/frontend/dist; try_files $uri $uri/ /index.html; } # API proxy location /api { proxy_pass http://localhost:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } # WebSocket proxy location /ws { proxy_pass http://localhost:8000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; } } ``` ### Option 3: Docker Compose ```yaml version: '3.8' services: api: build: context: ./backend dockerfile: Dockerfile ports: - "8000:8000" volumes: - /opt/media-downloader:/opt/media-downloader environment: - DB_PATH=/opt/media-downloader/database/media_downloader.db - CONFIG_PATH=/opt/media-downloader/config/settings.json restart: unless-stopped frontend: build: context: ./frontend dockerfile: Dockerfile ports: - "3000:80" depends_on: - api restart: unless-stopped ``` ## Security ### Authentication (TODO) Currently, the API has no authentication. For production use: 1. **Add JWT authentication** 2. **Use HTTPS/SSL** 3. **Restrict CORS origins** 4. **Implement rate limiting** 5. **Use environment variables for secrets** ### Recommended Setup ```bash # Behind Tailscale VPN # Access only via: http://media-downloader.tailscale-machine.ts.net # Or behind nginx with basic auth htpasswd -c /etc/nginx/.htpasswd admin ``` ## Troubleshooting ### Backend won't start ```bash # Check if port 8000 is available sudo lsof -i :8000 # Check database permissions ls -la /opt/media-downloader/database/ # Check logs cd /opt/media-downloader/web/backend python3 api.py ``` ### Frontend won't build ```bash cd /opt/media-downloader/web/frontend # Clear node_modules and reinstall rm -rf node_modules package-lock.json npm install # Check Node version (needs 18+) node --version ``` ### WebSocket not connecting ```bash # Check browser console for errors # Verify backend is running # Check CORS settings in api.py ``` ## Development ### Adding New API Endpoints **backend/api.py:** ```python @app.get("/api/custom") async def custom_endpoint(): return {"message": "Hello"} ``` **frontend/src/lib/api.ts:** ```typescript async getCustom() { return this.get<{message: string}>('/custom') } ``` ### Adding New Pages 1. Create component in `src/pages/NewPage.tsx` 2. Add route in `src/App.tsx` 3. Add navigation item in `src/App.tsx` ### WebSocket Events **Backend:** ```python await manager.broadcast({ "type": "custom_event", "data": {...} }) ``` **Frontend:** ```typescript wsClient.on('custom_event', (data) => { console.log(data) }) ``` ## Project Structure ``` web/ ├── backend/ │ ├── api.py # FastAPI server │ ├── requirements.txt # Python dependencies │ └── README.md # This file │ └── frontend/ ├── src/ │ ├── components/ # React components │ ├── pages/ # Page components │ │ ├── Dashboard.tsx │ │ ├── Downloads.tsx │ │ ├── Platforms.tsx │ │ ├── Logs.tsx │ │ └── Configuration.tsx │ ├── lib/ │ │ ├── api.ts # API client │ │ └── utils.ts # Utilities │ ├── App.tsx # Main app │ ├── main.tsx # Entry point │ └── index.css # Global styles ├── index.html ├── package.json ├── vite.config.ts ├── tsconfig.json └── tailwind.config.js ``` ## License Part of the Media Downloader project (v6.2.2)