400 lines
8.5 KiB
Markdown
400 lines
8.5 KiB
Markdown
# 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)
|