2025-08-01 13:13:06 -04:00
2025-08-01 13:01:15 -04:00
2025-07-15 14:32:57 +03:00
2025-08-01 13:13:06 -04:00

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

  1. Clone and navigate to the project:

    git clone <your-repo-url>
    cd qr-code_manager
    
  2. Create environment file:

    cp .env.example .env
    # Edit .env with your preferred settings
    
  3. Deploy with Docker:

    ./deploy.sh
    
  4. Access the application:

Method 2: Local Development

  1. Set up Python environment:

    python -m venv .venv
    source .venv/bin/activate  # On Windows: .venv\Scripts\activate
    
  2. Install dependencies:

    pip install -r requirements.txt
    
  3. Run the application:

    python main.py
    

<EFBFBD> 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:

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

# 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

# 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

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

# Development settings
FLASK_ENV=development
SECRET_KEY=dev-secret-key
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin123
APP_DOMAIN=localhost:5000

For Production:

# 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

<EFBFBD>🔐 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:

    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:

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

    # 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

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:

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
  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
  • 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:

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

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

0 2 * * * cd /opt/qr-code_manager && ./docker_backup.sh

Weekly Cleanup:

0 3 * * 0 curl -X POST http://localhost:8066/api/backup/cleanup

📖 Detailed Documentation: See 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:

python clean_data.py

Option 2: Shell Script (Quick)

./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

Description
No description provided
Readme 304 KiB
Languages
HTML 58.3%
Python 33.6%
Shell 7.6%
Dockerfile 0.5%