8.5 KiB
8.5 KiB
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
# 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:
cd /opt/media-downloader/web/backend
python3 api.py
Terminal 2 - Frontend:
cd /opt/media-downloader/web/frontend
npm run dev
Access the web interface at: http://localhost:5173
Production Build
# 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:
{
"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:
[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:
sudo systemctl enable media-downloader-api
sudo systemctl start media-downloader-api
Option 2: Nginx Reverse Proxy
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
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:
- Add JWT authentication
- Use HTTPS/SSL
- Restrict CORS origins
- Implement rate limiting
- Use environment variables for secrets
Recommended Setup
# 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
# 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
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
# Check browser console for errors
# Verify backend is running
# Check CORS settings in api.py
Development
Adding New API Endpoints
backend/api.py:
@app.get("/api/custom")
async def custom_endpoint():
return {"message": "Hello"}
frontend/src/lib/api.ts:
async getCustom() {
return this.get<{message: string}>('/custom')
}
Adding New Pages
- Create component in
src/pages/NewPage.tsx - Add route in
src/App.tsx - Add navigation item in
src/App.tsx
WebSocket Events
Backend:
await manager.broadcast({
"type": "custom_event",
"data": {...}
})
Frontend:
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)