Skip to content

Latest commit

Β 

History

History
326 lines (291 loc) Β· 16.5 KB

File metadata and controls

326 lines (291 loc) Β· 16.5 KB

GenieHelper Media Hub - Architecture

System Overview

GenieHelper Media Hub is a monolithic Flask application designed for media processing. The architecture prioritizes simplicity, self-hosting capability, and efficient resource usage on modest hardware.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           CLIENT LAYER                                   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   Web Browser   β”‚ Chrome Extensionβ”‚         Mobile Browser              β”‚
β”‚   (Desktop)     β”‚   (extension-ui)β”‚      (Responsive UI)                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                 β”‚                          β”‚
         β–Ό                 β–Ό                          β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         PRESENTATION LAYER                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Jinja2      β”‚  β”‚   HTMX       β”‚  β”‚   Tailwind CSS               β”‚  β”‚
β”‚  β”‚  Templates   β”‚  β”‚   Dynamic    β”‚  β”‚   Styling                    β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         APPLICATION LAYER                                β”‚
β”‚                         Flask 3.1 (app.py)                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Routes                                                            β”‚  β”‚
β”‚  β”‚  β”œβ”€β”€ Page Routes (/, /dashboard, /convert, /resize, etc.)        β”‚  β”‚
β”‚  β”‚  β”œβ”€β”€ API Routes (/api/files, /api/tasks, /api/dashboard/stats)   β”‚  β”‚
β”‚  β”‚  └── Operation Routes (/convert/image, /resize/video, etc.)      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  Middleware                                                        β”‚  β”‚
β”‚  β”‚  β”œβ”€β”€ File Upload Handler (werkzeug)                               β”‚  β”‚
β”‚  β”‚  β”œβ”€β”€ Request Validation                                           β”‚  β”‚
β”‚  β”‚  └── Error Handling                                               β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          SERVICE LAYER                                   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚  services/                                                          β”‚β”‚
β”‚  β”‚  β”œβ”€β”€ file_manager.py    β†’ File upload, storage, retrieval          β”‚β”‚
β”‚  β”‚  β”œβ”€β”€ database.py        β†’ SQLite connection management             β”‚β”‚
β”‚  β”‚  └── task_queue/        β†’ Background task processing               β”‚β”‚
β”‚  β”‚      └── threading_backend.py                                       β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”β”‚
β”‚  β”‚  services/media/                                                    β”‚β”‚
β”‚  β”‚  β”œβ”€β”€ image_ops.py       β†’ crop, resize, convert (Pillow)           β”‚β”‚
β”‚  β”‚  β”œβ”€β”€ video_ops.py       β†’ compress, crop, resize, trim (FFmpeg)    β”‚β”‚
β”‚  β”‚  β”œβ”€β”€ doc_ops.py         β†’ PDF, DOCX conversion                     β”‚β”‚
β”‚  β”‚  └── media_info.py      β†’ Metadata extraction (ffprobe)            β”‚β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                           DATA LAYER                                     β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                       β”‚
β”‚  β”‚     files.db        β”‚  β”‚     tasks.db        β”‚                       β”‚
β”‚  β”‚     (SQLite)        β”‚  β”‚     (SQLite)        β”‚                       β”‚
β”‚  β”‚  β”œβ”€β”€ files table    β”‚  β”‚  β”œβ”€β”€ tasks table    β”‚                       β”‚
β”‚  β”‚  └── metadata       β”‚  β”‚  └── status/logs    β”‚                       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  File System                                                      β”‚   β”‚
β”‚  β”‚  β”œβ”€β”€ files/staging/     β†’ Temporary uploaded files               β”‚   β”‚
β”‚  β”‚  β”œβ”€β”€ files/output/      β†’ Processed output files                 β”‚   β”‚
β”‚  β”‚  β”œβ”€β”€ media-output/      β†’ Public download directory              β”‚   β”‚
β”‚  β”‚  └── logs/              β†’ Application logs                       β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                 β”‚
                                 β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       EXTERNAL DEPENDENCIES                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   FFmpeg     β”‚  β”‚ ImageMagick  β”‚  β”‚        yt-dlp               β”‚  β”‚
β”‚  β”‚   (Video)    β”‚  β”‚   (Images)   β”‚  β”‚   (YouTube Downloads)       β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Component Details

1. Flask Application (app.py)

The main application file contains:

app.py (~1200 lines)
β”œβ”€β”€ Configuration & Initialization
β”‚   β”œβ”€β”€ Flask app setup
β”‚   β”œβ”€β”€ Logging configuration
β”‚   β”œβ”€β”€ Database initialization
β”‚   └── File manager instance
β”‚
β”œβ”€β”€ Helper Functions
β”‚   β”œβ”€β”€ allowed_file() - Extension validation
β”‚   β”œβ”€β”€ get_upload_path() - Staging directory
β”‚   β”œβ”€β”€ get_output_path() - Output directory
β”‚   β”œβ”€β”€ save_uploaded_file() - File persistence
β”‚   └── get_dashboard_stats() - Statistics
β”‚
β”œβ”€β”€ Page Routes
β”‚   β”œβ”€β”€ / β†’ workflow.html
β”‚   β”œβ”€β”€ /dashboard β†’ dashboard_interactive.html
β”‚   β”œβ”€β”€ /convert, /resize, /crop, etc.
β”‚   └── /files, /tasks, /queue
β”‚
β”œβ”€β”€ Operation Routes
β”‚   β”œβ”€β”€ /convert/image (POST)
β”‚   β”œβ”€β”€ /resize/image, /resize/video (POST)
β”‚   β”œβ”€β”€ /crop/image, /crop/video (POST)
β”‚   β”œβ”€β”€ /compress/video (POST)
β”‚   β”œβ”€β”€ /download/video (POST)
β”‚   β”œβ”€β”€ /trim/video (POST)
β”‚   └── /join/videos (POST)
β”‚
└── API Routes
    β”œβ”€β”€ /api/files (GET/POST)
    β”œβ”€β”€ /api/files/<id> (GET/DELETE)
    β”œβ”€β”€ /api/tasks (GET)
    └── /api/dashboard/stats (GET)

2. Service Layer

File Manager (services/file_manager.py)

FileManager
β”œβ”€β”€ list_files()      β†’ Get all tracked files
β”œβ”€β”€ add_file()        β†’ Register new file
β”œβ”€β”€ get_file()        β†’ Retrieve file info
β”œβ”€β”€ delete_file()     β†’ Remove file
└── cleanup_old()     β†’ Remove expired files

Database (services/database.py)

Database Functions
β”œβ”€β”€ init_db()              β†’ Create tables if not exist
β”œβ”€β”€ get_db_connection()    β†’ Get SQLite connection
└── execute_query()        β†’ Run SQL queries

Media Operations (services/media/)

image_ops.py
β”œβ”€β”€ convert_image()   β†’ Format conversion
β”œβ”€β”€ resize_image()    β†’ Scale by percentage
β”œβ”€β”€ crop_image()      β†’ Crop to coordinates
└── get_image_info()  β†’ Metadata extraction

video_ops.py
β”œβ”€β”€ compress_video()   β†’ CRF-based compression
β”œβ”€β”€ resize_video()     β†’ Resolution scaling
β”œβ”€β”€ crop_video()       β†’ Frame cropping
β”œβ”€β”€ trim_video()       β†’ Segment extraction
β”œβ”€β”€ join_videos()      β†’ Concatenation
β”œβ”€β”€ convert_video()    β†’ Format conversion
└── download_youtube() β†’ yt-dlp wrapper

doc_ops.py
β”œβ”€β”€ convert_document() β†’ PDF/DOCX/MD/HTML conversion

3. Database Schema

files.db

CREATE TABLE files (
    id TEXT PRIMARY KEY,
    filename TEXT NOT NULL,
    path TEXT NOT NULL,
    size INTEGER,
    mime_type TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    metadata TEXT  -- JSON blob
);

tasks.db

CREATE TABLE tasks (
    id TEXT PRIMARY KEY,
    type TEXT NOT NULL,           -- 'convert', 'resize', etc.
    status TEXT DEFAULT 'pending', -- pending, processing, completed, failed
    input_file TEXT,
    output_file TEXT,
    params TEXT,                   -- JSON blob
    error TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    completed_at TIMESTAMP
);

4. Request Flow

User Action β†’ HTTP Request
    β”‚
    β–Ό
Flask Route Handler
    β”‚
    β”œβ”€β”€ Validate Input
    β”‚   β”œβ”€β”€ Check file extension
    β”‚   β”œβ”€β”€ Validate parameters
    β”‚   └── Check file size
    β”‚
    β”œβ”€β”€ Save Uploaded File
    β”‚   β”œβ”€β”€ Generate unique filename
    β”‚   └── Save to staging/
    β”‚
    β”œβ”€β”€ Process Media
    β”‚   β”œβ”€β”€ Call appropriate service
    β”‚   β”œβ”€β”€ FFmpeg/ImageMagick execution
    β”‚   └── Generate output file
    β”‚
    β”œβ”€β”€ Cleanup
    β”‚   └── Remove staging file
    β”‚
    └── Return Response
        β”œβ”€β”€ HTML fragment (HTMX)
        β”œβ”€β”€ JSON (API)
        └── Download link

5. UI Architecture

Dashboard Hub (Level 0)
    β”‚
    β”œβ”€β”€ Convert β†’ Convert Page
    β”‚   β”œβ”€β”€ Image Conversion
    β”‚   └── Document Conversion
    β”‚
    β”œβ”€β”€ Resize β†’ Resize Page
    β”‚   β”œβ”€β”€ Image Resize
    β”‚   └── Video Resize
    β”‚
    β”œβ”€β”€ Crop β†’ Crop Page
    β”‚   β”œβ”€β”€ Image Crop (Interactive)
    β”‚   └── Video Crop
    β”‚
    β”œβ”€β”€ Compress β†’ Compress Page
    β”‚   └── Video Compression
    β”‚
    └── Download β†’ Download Page
        └── YouTube Download

Navigation Pattern:
- Hub β†’ Operation Page β†’ Action β†’ Result
- Back button returns to Hub
- HTMX for dynamic updates without page reload

6. Chrome Extension

extension-ui/
β”œβ”€β”€ manifest.json       β†’ Extension configuration
β”œβ”€β”€ background.js       β†’ Service worker
β”œβ”€β”€ contentScript.js    β†’ Page injection
β”œβ”€β”€ index.html          β†’ Popup UI
└── assets/             β†’ Icons

Design Decisions

Why Flask (not FastAPI)?

  • Simpler deployment on shared hosting
  • Jinja2 templates for SSR
  • Lower memory footprint
  • Sufficient for file processing workloads

Why SQLite (not PostgreSQL)?

  • Zero configuration
  • Single file per database
  • Sufficient for single-server deployment
  • Easy backup (just copy file)

Why Threading (not Celery)?

  • Simpler architecture
  • No Redis/RabbitMQ dependency
  • Adequate for light task queues
  • Can upgrade later if needed

Why HTMX (not React/Vue)?

  • Progressive enhancement
  • Server-side rendering
  • Minimal JavaScript
  • Faster initial load

Scaling Considerations

Current Capacity

  • Single server deployment
  • ~100 concurrent users
  • ~500MB max file size
  • Files cleaned after 24 hours

Future Scaling Options

  1. Add Redis - Session storage, task queue
  2. Add Celery - Distributed task processing
  3. S3 Storage - Offload file storage
  4. CDN - Static asset delivery
  5. Load Balancer - Multiple Flask instances

Security Measures

  1. File Validation - Extension whitelist
  2. Size Limits - Max upload size enforced
  3. Secure Filenames - Sanitized via werkzeug
  4. HTTPS - Enforced via Plesk/nginx
  5. No Execution - Uploaded files never executed

Version: 1.0.0 Last Updated: January 25, 2026