diff --git a/.gitignore b/.gitignore index e06fac5..17e9328 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,4 @@ target/ # Unit test reports TEST*.xml +mc_box_config.json diff --git a/DEPLOYMENT_phase2.md b/DEPLOYMENT_phase2.md new file mode 100644 index 0000000..412d60f --- /dev/null +++ b/DEPLOYMENT_phase2.md @@ -0,0 +1,324 @@ +# Video Optimizer — Production Deployment + +Assumes: server is running, Apache is configured, SSL certificate is active, Azure AD app registration is done. + +**Server:** `ai-sandbox.oliver.solutions` +**URL:** `https://ai-sandbox.oliver.solutions/video-optimizer` +**Backend dir:** `/opt/video-optimizer-back/` +**Frontend dir:** `/var/www/html/video-optimizer/` + +--- + +## Step 1 — Transfer Files to Server + +Connect via SFTP (FileZilla or scp) and upload the following: + +| Local path | Upload to | +|---|---| +| `backend/` (all `.py` files + `requirements.txt`) | `/opt/video-optimizer-back/backend/` | +| `frontend/` (all `.html`, `.js`, `.css` files) | `/opt/video-optimizer-back/frontend/` | +| `deployment/video-optimizer-backend.service` | `/opt/video-optimizer-back/deployment/` | +| `oliver_box_config.json` | `/opt/video-optimizer-back/` | +| `.env.example` | `/opt/video-optimizer-back/` | + +**Do NOT upload:** +- `venv/` +- `backend/uploads/`, `backend/outputs/`, `backend/logs/` +- `backend/__pycache__/`, `*.pyc` +- `.git/` +- `backend/platform_specs.json`, `backend/naming_conventions.json` (auto-generated) + +**Via scp (alternative to FileZilla):** +```bash +# Run from local machine — create and upload tarball +tar -czf video-optimizer.tar.gz \ + --exclude='venv' \ + --exclude='backend/uploads' \ + --exclude='backend/outputs' \ + --exclude='backend/logs' \ + --exclude='backend/__pycache__' \ + --exclude='backend/*.pyc' \ + --exclude='backend/platform_specs.json' \ + --exclude='backend/naming_conventions.json' \ + --exclude='.git' \ + backend/ frontend/ deployment/ oliver_box_config.json .env.example + +scp video-optimizer.tar.gz user@ai-sandbox.oliver.solutions:/tmp/ + +# On server: extract to destination +ssh user@ai-sandbox.oliver.solutions +cd /tmp && tar -xzf video-optimizer.tar.gz +sudo mv backend frontend deployment oliver_box_config.json .env.example /opt/video-optimizer-back/ +rm video-optimizer.tar.gz +``` + +--- + +## Step 2 — Copy Frontend to Web Root + +```bash +sudo cp -r /opt/video-optimizer-back/frontend/* /var/www/html/video-optimizer/ +sudo chown -R www-data:www-data /var/www/html/video-optimizer/ +``` + +--- + +## Step 3 — Configure .env + +```bash +cd /opt/video-optimizer-back +sudo cp .env.example .env +sudo nano .env +``` + +Set these values: + +```env +# Environment +FLASK_ENV=production + +# Azure AD (already configured) +AZURE_CLIENT_ID=9079054c-9620-4757-a256-23413042f1ef +AZURE_TENANT_ID=e519c2e6-bc6d-4fdf-8d9c-923c2f002385 +REDIRECT_URI=https://ai-sandbox.oliver.solutions/video-optimizer + +# API +BACKEND_PORT=5000 +FRONTEND_URL=https://ai-sandbox.oliver.solutions/video-optimizer + +# File management +MAX_FILE_SIZE_MB=500 +FILE_RETENTION_HOURS=24 +CLEANUP_CHECK_INTERVAL_MINUTES=60 + +# Security — generate a new key: +# python3 -c "import secrets; print(secrets.token_hex(32))" +SECRET_KEY=REPLACE_WITH_GENERATED_KEY + +# Logging +LOG_LEVEL=WARNING + +# Box.com automation +BOX_CONFIG_PATH=../oliver_box_config.json +BOX_VIDEO_OPTIMIZER_FOLDER_ID=362124323515 +BOX_AS_USER_ID= +BOX_WEBHOOK_SECRET= +BOX_USE_POLLING=false +BOX_POLL_INTERVAL_SECONDS=60 +``` + +Secure the credentials files: + +```bash +sudo chmod 600 /opt/video-optimizer-back/.env +sudo chown www-data:www-data /opt/video-optimizer-back/.env + +sudo chmod 600 /opt/video-optimizer-back/oliver_box_config.json +sudo chown www-data:www-data /opt/video-optimizer-back/oliver_box_config.json +``` + +--- + +## Step 4 — Python Virtual Environment & Dependencies + +```bash +cd /opt/video-optimizer-back + +# Create virtual environment +sudo python3 -m venv venv + +# Install dependencies +sudo venv/bin/pip install --upgrade pip +sudo venv/bin/pip install -r backend/requirements.txt + +# Create required runtime directories +sudo mkdir -p backend/uploads backend/outputs backend/logs/conversions + +# Set all ownership to www-data +sudo chown -R www-data:www-data /opt/video-optimizer-back/ +``` + +--- + +## Step 5 — Install and Start systemd Service + +```bash +# Copy service file to systemd +sudo cp /opt/video-optimizer-back/deployment/video-optimizer-backend.service /etc/systemd/system/ + +# Reload systemd, enable and start +sudo systemctl daemon-reload +sudo systemctl enable video-optimizer-backend +sudo systemctl start video-optimizer-backend + +# Confirm it is running +sudo systemctl status video-optimizer-backend +``` + +--- + +## Step 6 — Verify Deployment + +```bash +# Service status +sudo systemctl status video-optimizer-backend + +# Backend health check (local) +curl http://localhost:5000/api/health +# Expected: {"status":"ok","ffmpeg_installed":true,"timestamp":"..."} + +# Backend health check (through Apache) +curl https://ai-sandbox.oliver.solutions/video-optimizer/api/health + +# Box automation status (optional) +sudo -u www-data /opt/video-optimizer-back/venv/bin/python \ + /opt/video-optimizer-back/backend/box_setup.py +``` + +Then open in browser: +- `https://ai-sandbox.oliver.solutions/video-optimizer` — main app (requires SSO login) +- `https://ai-sandbox.oliver.solutions/video-optimizer/admin.html` — admin panel + +--- + +## Step 7 — Updating the Application + +When deploying code changes: + +```bash +# 1. Upload changed files via SFTP to /opt/video-optimizer-back/ +# (overwrite existing files — do not overwrite .env or oliver_box_config.json) + +# 2. Sync frontend to web root +sudo cp -r /opt/video-optimizer-back/frontend/* /var/www/html/video-optimizer/ +sudo chown -R www-data:www-data /var/www/html/video-optimizer/ + +# 3. Update Python dependencies (only if requirements.txt changed) +sudo /opt/video-optimizer-back/venv/bin/pip install -r /opt/video-optimizer-back/backend/requirements.txt + +# 4. Restart backend service +sudo systemctl restart video-optimizer-backend +sudo systemctl status video-optimizer-backend + +# 5. Verify +curl http://localhost:5000/api/health +``` + +--- + +## File Cleanup Cron Job + +Set up automatic deletion of old uploads/outputs (runs hourly): + +```bash +sudo crontab -u www-data -e + +# Add this line: +0 * * * * /opt/video-optimizer-back/venv/bin/python /opt/video-optimizer-back/backend/run_cleanup.py >> /opt/video-optimizer-back/backend/logs/cleanup.log 2>&1 +``` + +--- + +## Apache Config Snippet + +This should already be in the existing VirtualHost — included here for reference. Add inside the `` block if missing: + +```apache +# Frontend — static files +Alias /video-optimizer /var/www/html/video-optimizer + + Options -Indexes +FollowSymLinks + AllowOverride None + Require all granted + + +# Backend API — proxy to Flask + + ProxyPass http://127.0.0.1:5000/api + ProxyPassReverse http://127.0.0.1:5000/api + ProxyTimeout 600 + ProxyPreserveHost On + RequestHeader set X-Forwarded-Proto "https" + RequestHeader set X-Forwarded-Port "443" + + +# Box webhook endpoint + + ProxyPass http://127.0.0.1:5000/webhooks/box + ProxyPassReverse http://127.0.0.1:5000/webhooks/box + ProxyTimeout 600 + ProxyPreserveHost On + RequestHeader set X-Forwarded-Proto "https" + +``` + +After any Apache config change: +```bash +sudo apache2ctl configtest # must say "Syntax OK" +sudo systemctl reload apache2 +``` + +--- + +## Quick Reference + +```bash +# Service management +sudo systemctl status video-optimizer-backend # status +sudo systemctl restart video-optimizer-backend # restart +sudo systemctl stop video-optimizer-backend # stop +sudo journalctl -u video-optimizer-backend -f # live logs +sudo journalctl -u video-optimizer-backend -n 50 # last 50 lines + +# Health checks +curl http://localhost:5000/api/health +curl http://localhost:5000/api/box/health # Box automation status + +# Check port +sudo ss -tulpn | grep 5000 + +# Disk usage +df -h /opt/video-optimizer-back +sudo du -sh /opt/video-optimizer-back/backend/uploads/ +sudo du -sh /opt/video-optimizer-back/backend/outputs/ +``` + +--- + +## Troubleshooting + +**Service won't start:** +```bash +sudo journalctl -u video-optimizer-backend -n 50 +# Common causes: missing .env, wrong file ownership, port 5000 in use +sudo ss -tulpn | grep 5000 +sudo chown -R www-data:www-data /opt/video-optimizer-back/ +``` + +**502 Bad Gateway from Apache:** +```bash +curl http://localhost:5000/api/health # is backend running? +sudo systemctl restart video-optimizer-backend +sudo tail -f /var/log/apache2/error.log +``` + +**Missing Python module:** +```bash +sudo /opt/video-optimizer-back/venv/bin/pip install -r /opt/video-optimizer-back/backend/requirements.txt +sudo systemctl restart video-optimizer-backend +``` + +**Box automation not initialising:** +```bash +sudo -u www-data /opt/video-optimizer-back/venv/bin/python \ + /opt/video-optimizer-back/backend/box_setup.py +# Check .env has BOX_VIDEO_OPTIMIZER_FOLDER_ID=362124323515 +# Check oliver_box_config.json exists and is readable by www-data +``` + +**Frontend changes not showing:** +```bash +sudo cp -r /opt/video-optimizer-back/frontend/* /var/www/html/video-optimizer/ +sudo chown -R www-data:www-data /var/www/html/video-optimizer/ +# Hard refresh browser: Cmd+Shift+R / Ctrl+Shift+R +``` diff --git a/backend/logs/conversions/2026-02-25_conversions.json b/backend/logs/conversions/2026-02-25_conversions.json new file mode 100644 index 0000000..708b536 --- /dev/null +++ b/backend/logs/conversions/2026-02-25_conversions.json @@ -0,0 +1,15 @@ +[ + { + "timestamp": "2026-02-25T10:09:34.785361", + "user_email": "box_automation@system", + "platform": "tiktok", + "aspect_ratio": "9:16", + "input_file_size": 0, + "output_file_size": 0, + "size_reduction_percent": 0.0, + "conversion_duration_seconds": 5.32, + "status": "failure", + "file_id": "2110559542857", + "error_message": "Failed to download file from Box" + } +] \ No newline at end of file diff --git a/backend/logs/conversions/2026-03-10_conversions.json b/backend/logs/conversions/2026-03-10_conversions.json new file mode 100644 index 0000000..230fdd8 --- /dev/null +++ b/backend/logs/conversions/2026-03-10_conversions.json @@ -0,0 +1,67 @@ +[ + { + "timestamp": "2026-03-10T15:20:21.849401", + "user_email": "box_automation@system", + "platform": "tiktok", + "aspect_ratio": "9:16", + "input_file_size": 3017463, + "output_file_size": 404827, + "size_reduction_percent": 86.58, + "conversion_duration_seconds": 8.28, + "status": "success", + "file_id": "2144852661548", + "error_message": null + }, + { + "timestamp": "2026-03-10T15:27:36.777419", + "user_email": "box_automation@system", + "platform": "tiktok", + "aspect_ratio": "9:16", + "input_file_size": 142025887, + "output_file_size": 2752307, + "size_reduction_percent": 98.06, + "conversion_duration_seconds": 58.2, + "status": "success", + "file_id": "2110559542857", + "error_message": null + }, + { + "timestamp": "2026-03-10T16:18:08.941089", + "user_email": "manish.tanwar@brandtech.plus", + "platform": "amazon_prime", + "aspect_ratio": "16:9", + "input_file_size": 3627980, + "output_file_size": 4242893, + "size_reduction_percent": -16.95, + "conversion_duration_seconds": 1.62, + "status": "success", + "file_id": "6f02a8e1-1a41-4262-9367-6d0113a5d970", + "error_message": null + }, + { + "timestamp": "2026-03-10T16:19:39.675452", + "user_email": "box_automation@system", + "platform": "tiktok", + "aspect_ratio": "9:16", + "input_file_size": 112004766, + "output_file_size": 2611071, + "size_reduction_percent": 97.67, + "conversion_duration_seconds": 178.87, + "status": "success", + "file_id": "2110554249247", + "error_message": null + }, + { + "timestamp": "2026-03-10T16:20:06.536122", + "user_email": "box_automation@system", + "platform": "tiktok", + "aspect_ratio": "9:16", + "input_file_size": 112004766, + "output_file_size": 0, + "size_reduction_percent": 100.0, + "conversion_duration_seconds": 202.92, + "status": "failure", + "file_id": "2110554249247", + "error_message": "Failed to upload optimised video to OUT_SUCCESS" + } +] \ No newline at end of file