diff --git a/README.md b/README.md index 7829b4d..674f63e 100644 --- a/README.md +++ b/README.md @@ -15,21 +15,24 @@ A Flask-based webcomic website with server-side rendering using Jinja2 templates ``` sunday/ ├── app.py # Main Flask application +├── comics_data.py # Comic data (edit this to add comics) ├── requirements.txt # Python dependencies +├── scripts/ # Utility scripts +│ ├── add_comic.py # Script to add new comic entries +│ └── generate_rss.py # Script to generate RSS feed ├── templates/ # Jinja2 templates │ ├── base.html # Base template with navigation │ ├── index.html # Latest comic page │ ├── comic.html # Individual comic viewer │ ├── archive.html # Archive grid │ ├── about.html # About page -│ ├── contact.html # Contact page │ └── 404.html # Error page └── static/ # Static files ├── css/ │ └── style.css # Main stylesheet - ├── js/ - └── images/ # Comic images - └── thumbs/ # Thumbnail images for archive + ├── images/ # Comic images + │ └── thumbs/ # Thumbnail images for archive + └── feed.rss # RSS feed (generated) ``` ## Setup @@ -44,32 +47,115 @@ pip install -r requirements.txt python app.py ``` -3. Visit http://127.0.0.1:5000 in your browser +3. Visit http://127.0.0.1:3000 in your browser + +## Environment Variables + +The app can be configured via environment variables: + +- `SECRET_KEY` - Flask secret key (defaults to 'your-secret-key') +- `PORT` - Port to run on (defaults to 3000) +- `DEBUG` - Enable debug mode (defaults to False) + +**Development:** +```bash +export DEBUG=True +python app.py +``` + +**Production:** +```bash +export SECRET_KEY="your-secure-random-secret-key" +export PORT=3000 +python app.py +``` ## Adding Comics -Currently, comics are stored in the `COMICS` list in `app.py`. Each comic needs: +Comics are stored in the `COMICS` list in `comics_data.py`. Each comic entry: ```python { - 'number': 1, # Comic number (sequential) - 'title': 'Comic Title', # Title of the comic - 'filename': 'comic-001.png', # Image filename - 'date': '2025-01-01', # Publication date - 'alt_text': 'Alt text for comic', # Accessibility text - 'transcript': 'Optional transcript' # Optional transcript + 'number': 1, # Comic number (required, sequential) + 'filename': 'comic-001.png', # Image filename (required) + 'date': '2025-01-01', # Publication date (required) + 'alt_text': 'Alt text for comic', # Accessibility text (required) + 'title': 'Comic Title', # Title (optional, shows #X if absent) + 'author_note': 'Optional note' # Author note (optional) } ``` ### Adding a New Comic +**Option 1: Use the script (recommended)** +```bash +python scripts/add_comic.py +``` +This will automatically add a new entry with defaults. Then edit `comics_data.py` to customize. + +**Option 2: Manual** 1. Save your comic image in `static/images/` (e.g., `comic-001.png`) 2. Optionally, create a thumbnail in `static/images/thumbs/` with the same filename -3. Add the comic entry to the `COMICS` list in `app.py` +3. Add the comic entry to the `COMICS` list in `comics_data.py` + +### Generating RSS Feed + +After adding comics, regenerate the RSS feed: +```bash +python scripts/generate_rss.py +``` +This creates/updates `static/feed.rss` + +## Production Deployment + +For production, you should **NOT** use Flask's built-in development server. Instead: + +### 1. Generate a Secure Secret Key + +```bash +python -c "import secrets; print(secrets.token_hex(32))" +``` + +### 2. Set Environment Variables + +```bash +export SECRET_KEY="generated-secret-key-from-above" +export DEBUG=False +export PORT=3000 +``` + +### 3. Use a Production WSGI Server + +**Install Gunicorn:** +```bash +pip install gunicorn +``` + +**Run with Gunicorn:** +```bash +gunicorn app:app --bind 0.0.0.0:3000 --workers 4 +``` + +### 4. Use a Reverse Proxy (Recommended) + +Set up Nginx or another reverse proxy in front of Gunicorn for: +- HTTPS/SSL termination +- Static file serving +- Load balancing +- Better security + +### 5. Additional Production Considerations + +- Use a process manager (systemd, supervisor) +- Set appropriate file permissions +- Enable HTTPS with Let's Encrypt +- Consider using a CDN for static assets +- Monitor logs and performance +- Set up automated backups of `comics_data.py` ## Upgrading to a Database -For production use, consider replacing the `COMICS` list with a database: +For larger comic archives, consider replacing the `COMICS` list with a database: - SQLite for simple setups - PostgreSQL/MySQL for production @@ -94,7 +180,7 @@ For production use, consider replacing the `COMICS` list with a database: - `/comic/` - View a specific comic by number - `/archive` - Browse all comics in a grid - `/about` - About the comic and author -- `/contact` - Contact form +- `/static/feed.rss` - RSS feed ## License