# 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)
