# QR Code Manager A modern Flask web application for generating and managing QR codes with authentication and dynamic link pages. ## ๐Ÿš€ Features - **Multiple QR Code Types**: Text, URL, WiFi, Email, SMS, vCard - **Dynamic Link Pages**: Create collections of links accessible via QR codes - **URL Shortener**: Generate shortened URLs with custom domains and QR codes - **Admin Authentication**: Secure login with bcrypt password hashing - **Customizable Styling**: Different QR code styles (square, rounded, circle) - **Logo Integration**: Add custom logos to QR codes - **Click Tracking**: Monitor short URL usage and statistics - **๐Ÿ†• Comprehensive Backup System**: Full backup lifecycle management - Create backups on-demand or automated - Download, delete, and cleanup old backups - Web-based backup management interface - Docker-aware backup operations - **Docker Deployment**: Production-ready containerization - **Responsive Design**: Modern web interface that works on all devices ## ๐Ÿ“ Project Structure ``` qr-code_manager/ โ”œโ”€โ”€ README.md # Project documentation โ”œโ”€โ”€ main.py # Application entry point โ”œโ”€โ”€ Dockerfile # Docker container definition โ”œโ”€โ”€ docker-compose.yml # Docker orchestration โ”œโ”€โ”€ requirements.txt # Python dependencies โ”œโ”€โ”€ .env.example # Environment variables template โ”œโ”€โ”€ deploy.sh # Deployment script โ”œโ”€โ”€ app/ # Main application package โ”‚ โ”œโ”€โ”€ __init__.py # Flask app factory โ”‚ โ”œโ”€โ”€ templates/ # Jinja2 templates โ”‚ โ”‚ โ”œโ”€โ”€ index.html # Main dashboard โ”‚ โ”‚ โ”œโ”€โ”€ login.html # Authentication page โ”‚ โ”‚ โ”œโ”€โ”€ link_page.html # Public link display โ”‚ โ”‚ โ””โ”€โ”€ edit_links.html # Link management interface โ”‚ โ”œโ”€โ”€ static/ # Static files โ”‚ โ”‚ โ”œโ”€โ”€ qr_codes/ # Generated QR code images โ”‚ โ”‚ โ””โ”€โ”€ logos/ # Uploaded logo files โ”‚ โ”œโ”€โ”€ routes/ # Route handlers โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py # Route package โ”‚ โ”‚ โ”œโ”€โ”€ main.py # Main page routes โ”‚ โ”‚ โ”œโ”€โ”€ auth.py # Authentication routes โ”‚ โ”‚ โ””โ”€โ”€ api.py # API endpoints โ”‚ โ””โ”€โ”€ utils/ # Utility modules โ”‚ โ”œโ”€โ”€ __init__.py # Utils package โ”‚ โ”œโ”€โ”€ auth.py # Authentication utilities โ”‚ โ”œโ”€โ”€ qr_generator.py # QR code generation โ”‚ โ”œโ”€โ”€ link_manager.py # Dynamic link management โ”‚ โ”œโ”€โ”€ url_shortener.py # URL shortening utilities โ”‚ โ””โ”€โ”€ data_manager.py # Data storage utilities ``` ## ๐Ÿ› ๏ธ Quick Start ### Method 1: Docker (Recommended) 1. **Clone and navigate to the project:** ```bash git clone cd qr-code_manager ``` 2. **Create environment file:** ```bash cp .env.example .env # Edit .env with your preferred settings ``` 3. **Deploy with Docker:** ```bash ./deploy.sh ``` 4. **Access the application:** - Open http://localhost:5000 - Login with: admin / admin123 (change in production!) ### Method 2: Local Development 1. **Set up Python environment:** ```bash python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate ``` 2. **Install dependencies:** ```bash pip install -r requirements.txt ``` 3. **Run the application:** ```bash python main.py ``` ## ๏ฟฝ Production vs Development Modes The QR Code Manager supports two distinct runtime modes with different behaviors and optimizations. ### ๐Ÿ› ๏ธ Development Mode (Default) **When it runs:** - When `FLASK_ENV` is not set to "production" - When running `python main.py` locally - Default mode for local development **Characteristics:** - Uses Flask's built-in development server - Debug mode enabled with auto-reload - Detailed error messages and stack traces - Console shows default login credentials - Not suitable for production use **How to run:** ```bash # Method 1: Direct execution python main.py # Method 2: With explicit development environment FLASK_ENV=development python main.py # Method 3: Using environment file echo "FLASK_ENV=development" > .env python main.py ``` **Console output in development:** ``` ๐Ÿ› ๏ธ Starting QR Code Manager in DEVELOPMENT mode ๐Ÿ” Admin user: admin ๐Ÿ”‘ Default password: admin123 ๐ŸŒ Domain configured: localhost:5000 ๐Ÿ”— URL shortener available at: /s/ * Serving Flask app 'app' * Debug mode: on * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 ``` ### ๐Ÿš€ Production Mode **When it runs:** - When `FLASK_ENV=production` is set - When deployed with Docker (automatic) - For live/production deployments **Characteristics:** - Uses Gunicorn WSGI server (4 workers) - Debug mode disabled - Optimized for performance and security - No default credentials shown - Production-grade error handling **How to run:** #### Option 1: Docker (Recommended) ```bash # Copy and edit production environment cp .env.production .env # Edit .env with your production settings # Deploy with Docker docker-compose up -d ``` #### Option 2: Manual Gunicorn ```bash # Set production environment export FLASK_ENV=production export SECRET_KEY=your-super-secret-key export ADMIN_USERNAME=your-admin-username export ADMIN_PASSWORD=your-secure-password export APP_DOMAIN=your-domain.com # Run with Gunicorn gunicorn -c gunicorn.conf.py main:app ``` #### Option 3: Environment File + Gunicorn ```bash # Create production environment file cp .env.production .env # Edit .env with your settings: # FLASK_ENV=production # SECRET_KEY=your-super-secret-key # ADMIN_USERNAME=your-admin-username # ADMIN_PASSWORD=your-secure-password # APP_DOMAIN=your-domain.com # Run with Gunicorn gunicorn -c gunicorn.conf.py main:app ``` **Console output in production:** ``` Admin user initialized: your-admin-username Default password: your-secure-password [2025-07-16 17:27:27 +0000] [1] [INFO] Starting gunicorn 21.2.0 [2025-07-16 17:27:27 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1) [2025-07-16 17:27:27 +0000] [1] [INFO] Using worker: sync [2025-07-16 17:27:27 +0000] [7] [INFO] Booting worker with pid: 7 [2025-07-16 17:27:27 +0000] [8] [INFO] Booting worker with pid: 8 [2025-07-16 17:27:27 +0000] [9] [INFO] Booting worker with pid: 9 [2025-07-16 17:27:27 +0000] [10] [INFO] Booting worker with pid: 10 ``` ### ๐Ÿ”ง Environment Configuration Create a `.env` file in the project root with your configuration: **For Development:** ```bash # Development settings FLASK_ENV=development SECRET_KEY=dev-secret-key ADMIN_USERNAME=admin ADMIN_PASSWORD=admin123 APP_DOMAIN=localhost:5000 ``` **For Production:** ```bash # Production settings (copy from .env.production and customize) FLASK_ENV=production SECRET_KEY=your-super-secret-key-change-this ADMIN_USERNAME=your-admin-username ADMIN_PASSWORD=your-secure-password APP_DOMAIN=your-domain.com # Security settings SESSION_COOKIE_SECURE=true # Set to true for HTTPS SESSION_COOKIE_HTTPONLY=true SESSION_COOKIE_SAMESITE=Lax # Performance settings UPLOAD_MAX_SIZE=10485760 # 10MB CACHE_TIMEOUT=3600 # 1 hour ``` ### ๐Ÿ›ก๏ธ Security Considerations **Development Mode:** - โš ๏ธ Never use in production - Default credentials are visible - Debug information exposed - Single-threaded server **Production Mode:** - โœ… Use Gunicorn WSGI server - โœ… Change default credentials - โœ… Use strong SECRET_KEY - โœ… Enable HTTPS when possible - โœ… Set secure cookie flags - โœ… Multiple worker processes ### ๐Ÿ“Š Performance Comparison | Feature | Development | Production | |---------|-------------|------------| | Server | Flask dev server | Gunicorn (4 workers) | | Performance | Basic | Optimized | | Concurrency | Single-threaded | Multi-worker | | Auto-reload | Yes | No | | Debug info | Full | Minimal | | Error handling | Verbose | Secure | | Session security | Basic | Enhanced | ## ๏ฟฝ๐Ÿ” Authentication - **Default Credentials**: admin / admin123 - **Environment Variables**: - `ADMIN_USERNAME`: Set custom admin username - `ADMIN_PASSWORD`: Set custom admin password - `SECRET_KEY`: Set Flask secret key for sessions ## ๐Ÿณ Docker Deployment The application is fully containerized with Docker: - **Build and run**: `docker-compose up -d` - **View logs**: `docker-compose logs -f` - **Stop**: `docker-compose down` - **Full rebuild**: `docker-compose up --build -d` ### Production Configuration 1. **Set environment variables in .env:** ```bash FLASK_ENV=production SECRET_KEY=your-super-secret-key-here ADMIN_USERNAME=your-admin-username ADMIN_PASSWORD=your-secure-password APP_DOMAIN=[your-domain] # Your custom domain for URL shortener ``` 2. **Deploy:** ```bash docker-compose up -d ``` ### URL Shortener Configuration The URL shortener feature uses the `APP_DOMAIN` environment variable to generate short URLs: - **Development**: `APP_DOMAIN=localhost:5000` - **Production**: `APP_DOMAIN=[your-domain]` or `APP_DOMAIN=https://[your-domain]` Short URLs will be available at: `https://[your-domain]/s/[short-code]` ## ๐ŸŒ Reverse Proxy Configuration (Nginx) When deploying behind a reverse proxy like Nginx Proxy Manager or standard Nginx, configure the proxy to route **HTTPS traffic to HTTP backend**: ### โš ๏ธ Important Proxy Configuration - **Frontend (Public)**: HTTPS (Port 443) - **Backend (Docker)**: HTTP (Port 8066) - **SSL Termination**: At the proxy level ### Nginx Proxy Manager Setup 1. **Create Proxy Host**: - Domain: `[your-domain]` (your domain) - Forward Hostname/IP: `your-server-ip` - Forward Port: `8066` - **Protocol**: HTTP (not HTTPS) 2. **SSL Configuration**: - Enable SSL certificate (Let's Encrypt) - Force SSL: Yes - HTTP/2 Support: Yes 3. **Advanced Settings** (if needed): ```nginx # Custom Nginx configuration proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; ``` ### Standard Nginx Configuration ```nginx server { listen 443 ssl http2; server_name [your-domain]; # SSL Configuration ssl_certificate /path/to/ssl/cert.pem; ssl_certificate_key /path/to/ssl/private.key; # Proxy to Docker container location / { proxy_pass http://localhost:8066; # Note: HTTP, not HTTPS proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Port $server_port; } } # Redirect HTTP to HTTPS server { listen 80; server_name [your-domain]; return 301 https://$server_name$request_uri; } ``` ### Common Proxy Issues & Solutions | Issue | Cause | Solution | |-------|-------|----------| | 502 Bad Gateway | HTTPSโ†’HTTPS routing | Change backend to HTTP | | SSL errors | Missing certificates | Configure SSL at proxy level | | 404 on subpaths | Missing headers | Add proxy headers | | Session issues | Domain mismatch | Set correct `APP_DOMAIN` | ### Docker Configuration for Proxy Ensure your `docker-compose.yml` exposes the correct port: ```yaml services: qr-manager: ports: - "8066:5000" # Maps container port 5000 to host port 8066 environment: - APP_DOMAIN=[your-domain] # Your public domain ``` ## ๐Ÿ“ฑ Usage ### Generating QR Codes 1. **Login** to the admin interface 2. **Select QR type**: Text, URL, WiFi, Email, SMS, or vCard 3. **Fill in the details** for your chosen type 4. **Customize appearance**: Size, colors, style, border 5. **Add logo** (optional): Upload custom logo for branding 6. **Generate and download** your QR code ### Dynamic Link Pages 1. **Create a link page** from the main interface 2. **Add links** to your collection via the edit interface 3. **Share the QR code** that points to your link page 4. **Update links anytime** without changing the QR code ### URL Shortener 1. **Create shortened URLs** with optional custom codes 2. **Generate QR codes** for shortened URLs 3. **Track clicks** and monitor usage statistics 4. **Redirect seamlessly** from short URLs to original destinations 5. **Integrate with link pages** by enabling shortener for individual links **Examples:** - Original: `https://very-long-domain.com/extremely/long/path/to/resource` - Short: `https://[your-domain]/s/abc123` ## ๐Ÿ›ก๏ธ Security Features - **Password Hashing**: Uses bcrypt for secure password storage - **Session Management**: Secure Flask sessions with signing - **Authentication Required**: All admin functions require login - **Docker Security**: Non-root user in container - **Environment Variables**: Sensitive data via environment configuration ## ๐Ÿ”ง Development ### Project Architecture The application follows a modular Flask structure: - **App Factory Pattern**: Clean application initialization - **Blueprint Organization**: Separate route modules for different features - **Utility Modules**: Reusable components for QR generation, auth, etc. - **Template Organization**: Structured Jinja2 templates - **Static File Management**: Organized asset storage ### Adding New Features 1. **New Routes**: Add to appropriate blueprint in `app/routes/` 2. **New Utilities**: Create modules in `app/utils/` 3. **New Templates**: Add to `app/templates/` 4. **New Dependencies**: Update `requirements.txt` ## ๐Ÿ“Š API Endpoints ### QR Code Management - `POST /api/generate` - Generate QR code - `GET /api/qr_codes` - List all QR codes - `GET /api/qr_codes/{id}` - Get specific QR code - `DELETE /api/qr_codes/{id}` - Delete QR code ### Dynamic Link Pages - `POST /api/create_link_page` - Create dynamic link page - `POST /api/link_pages/{id}/links` - Add link to page - `PUT /api/link_pages/{id}/links/{link_id}` - Update link - `DELETE /api/link_pages/{id}/links/{link_id}` - Delete link ### URL Shortener - `POST /api/shorten` - Create standalone short URL - `POST /api/generate_shortened_qr` - Generate QR code with short URL - `GET /api/short_urls` - List all short URLs - `GET /api/short_urls/{code}/stats` - Get short URL statistics - `GET /s/{code}` - Redirect short URL to original - `POST /api/link_pages/{id}/links` - Add link to page - `PUT /api/link_pages/{id}/links/{link_id}` - Update link - `DELETE /api/link_pages/{id}/links/{link_id}` - Delete link ## ๐Ÿšจ Troubleshooting ### Common Issues 1. **Permission Denied**: Ensure Docker has proper permissions 2. **Port 5000 in use**: Change port in docker-compose.yml 3. **Authentication Failed**: Check admin credentials in .env 4. **Image Generation Failed**: Verify PIL/Pillow installation ### Health Check Visit `/health` to check application status: ```bash curl http://localhost:5000/health ``` ## ๐Ÿ“ License This project is licensed under the MIT License - see the LICENSE file for details. ## ๐Ÿ’พ Backup & Restore System The QR Code Manager includes a comprehensive backup system for data protection and migration. ### Quick Start **Create Backup:** - Via Web: Navigate to backup management page โ†’ "Create Backup" - Via API: `curl -X POST http://localhost:8066/api/backup/create` - Via CLI: `python backup.py` or `./docker_backup.sh` **Manage Backups:** - **List**: View all backups with timestamps and sizes - **Download**: Get backup files directly from web interface - **Delete**: Remove individual backups with confirmation - **Cleanup**: Bulk remove backups older than 7 days ### What Gets Backed Up Each backup includes: - โœ… All QR code data and metadata - โœ… Short URL database - โœ… Dynamic link page configurations - โœ… Generated QR code images - โœ… Application settings ### Restore Process ```bash # 1. Stop application docker compose down # 2. Extract backup to data directory cd data/ unzip ../backups/backup_20250801_143022.zip # 3. Restart application docker compose up -d ``` ### Automated Backups **Daily Backup (2 AM):** ```bash 0 2 * * * cd /opt/qr-code_manager && ./docker_backup.sh ``` **Weekly Cleanup:** ```bash 0 3 * * 0 curl -X POST http://localhost:8066/api/backup/cleanup ``` > ๐Ÿ“– **Detailed Documentation**: See [BACKUP_SYSTEM.md](BACKUP_SYSTEM.md) for complete backup system documentation. ## ๐Ÿค Contributing 1. Fork the repository 2. Create a feature branch 3. Make your changes 4. Add tests if applicable 5. Submit a pull request ## ๐Ÿงน Data Cleanup for Deployment When preparing for a fresh deployment or when you need to clear all data, use the provided cleanup scripts: ### Option 1: Python Script (Recommended) ```bash python clean_data.py ``` ### Option 2: Shell Script (Quick) ```bash ./clean_data.sh ``` ### What Gets Cleaned Both scripts will remove: - **All QR codes and their data** - Clears the QR codes database and deletes all generated PNG images - **All dynamic link pages** - Removes all link collections and their settings - **All short URLs** - Clears the URL shortener database - **All Flask sessions** - Removes user session files - **All log files** - Deletes any application log files - **Python cache files** - Removes `__pycache__` directories and `.pyc` files ### Safety Features - **Confirmation prompt** - Both scripts require typing 'YES' to confirm the action - **Directory preservation** - Required directories are recreated after cleanup - **Error handling** - Scripts handle missing files/directories gracefully ### Post-Cleanup Steps After running the cleanup script: 1. Start the application: `python main.py` 2. Login with default credentials: `admin` / `admin123` 3. **Important**: Change the default admin password immediately 4. Begin creating your QR codes and link pages ### Use Cases - **Fresh deployment** - Clean slate for production deployment - **Development reset** - Clear test data during development - **Data migration** - Prepare for moving to a new system - **Security cleanup** - Remove all data when decommissioning ## ๐Ÿ“ž Support For support, please open an issue on GitHub or contact the development team. --- **Made with โค๏ธ for easy QR code management**