diff --git a/README_MIGRATION.md b/README_MIGRATION.md new file mode 100644 index 0000000..830c612 --- /dev/null +++ b/README_MIGRATION.md @@ -0,0 +1,111 @@ +# Database Migration Guide + +## Session Changes Migration + +During this development session, the following database changes were made: + +### Changes Applied +1. **Added `likes` column** - INTEGER DEFAULT 0 (for the cookie-based like system) +2. **Ensured `description` column exists** - TEXT (for pet picture descriptions) +3. **Verified `posted` column** - BOOLEAN DEFAULT 0 (for admin posting control) + +### Migration Script + +Run the migration script to update your database: + +```bash +# Make sure you're in the project directory +cd /path/to/pet-picture-queue + +# Activate virtual environment (if using one) +source .venv/bin/activate + +# Run the migration +python migrate_session_changes.py +``` + +### What the Migration Does + +The `migrate_session_changes.py` script: + +- ✅ **Idempotent**: Safe to run multiple times +- ✅ **Backwards Compatible**: Won't break existing data +- ✅ **Verification**: Checks that migration completed successfully +- ✅ **Error Handling**: Proper error messages and rollback protection +- ✅ **Database Detection**: Automatically finds your database file + +### Migration Output + +You should see output like: +``` +============================================================ +Pet Picture Database Migration Script +Session Changes: Adding likes system and ensuring schema consistency +============================================================ +Using database: pet_pictures.db +Starting database migration... +• Description column already exists +✓ Added likes column and initialized existing records +• Posted column already exists +✓ Cleaned up NULL values + +Final table schema: + id INTEGER NOT NULL + filename TEXT NOT NULL + subscriber_name TEXT NOT NULL + description TEXT NULL + uploaded_at TIMESTAMP NOT NULL + posted BOOLEAN NULL DEFAULT 0 + likes INTEGER NULL DEFAULT 0 + +Migration completed successfully! +Applied 1 migrations +Database contains X pet pictures +Migration completed at: 2025-01-XX... + +============================================================ +Verifying migration... +✅ Verification successful: All required columns present +🎉 Migration completed successfully! +============================================================ +``` + +### Troubleshooting + +**If migration fails:** +1. Check that the database file exists and is accessible +2. Ensure you have write permissions to the database file +3. Make sure no other process is using the database +4. Check the error message for specific issues + +**If you need to start fresh:** +```bash +# Backup existing database (optional) +cp pet_pictures.db pet_pictures.db.backup + +# Remove database and let app recreate it +rm pet_pictures.db + +# Run the app - it will create a new database with correct schema +python main.py +``` + +### Schema After Migration + +The final `pet_pictures` table schema: + +| Column | Type | Constraints | Default | Description | +|--------|------|-------------|---------|-------------| +| id | INTEGER | PRIMARY KEY, AUTOINCREMENT | | Unique picture ID | +| filename | TEXT | NOT NULL | | Stored filename | +| subscriber_name | TEXT | NOT NULL | | Name of submitter | +| description | TEXT | | | Optional picture description | +| uploaded_at | TIMESTAMP | NOT NULL | | Upload timestamp | +| posted | BOOLEAN | | 0 | Admin approval status | +| likes | INTEGER | | 0 | Number of likes received | + +### Files Created + +- `migrate_session_changes.py` - Main migration script +- `README_MIGRATION.md` - This documentation +- `add_likes_column.py` - Individual likes column migration (deprecated, use main script) \ No newline at end of file diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..27b2d75 --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,45 @@ +""" +Pets of Powerwashing - A Flask application for managing pet picture submissions +""" + +from flask import Flask +import os + + +def create_app(): + """Application factory pattern for Flask app creation""" + app = Flask(__name__) + + # Import configuration + from app.config import Config + app.config.from_object(Config) + + # Ensure upload directory exists + os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) + + # Setup logging + from app.utils.logging_config import setup_logging + setup_logging(app) + + # Register error handlers + from app.utils.error_handlers import register_error_handlers + register_error_handlers(app) + + # Initialize database + from app.models.database import init_db, close_db + with app.app_context(): + init_db() + + # Register database close function + app.teardown_appcontext(close_db) + + # Register blueprints + from app.routes.main import main_bp + from app.routes.auth import auth_bp + from app.routes.pictures import pictures_bp + + app.register_blueprint(main_bp) + app.register_blueprint(auth_bp) + app.register_blueprint(pictures_bp) + + return app \ No newline at end of file diff --git a/app/config.py b/app/config.py new file mode 100644 index 0000000..28b860f --- /dev/null +++ b/app/config.py @@ -0,0 +1,40 @@ +""" +Configuration settings for the application +""" + +import os + + +class Config: + """Base configuration class""" + + # Flask settings + SECRET_KEY = os.environ.get('SECRET_KEY') or os.urandom(24) + + # Upload settings + UPLOAD_FOLDER = os.environ.get('UPLOAD_FOLDER') or 'app/static/uploads' + MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB max file size + ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'} + + # Authentication settings + ADMIN_USERNAME = os.environ.get('ADMIN_USERNAME') or 'admin' + ADMIN_PASSWORD = os.environ.get('ADMIN_PASSWORD') or 'password123' + + # Database settings + DATABASE_PATH = os.environ.get('DATABASE_PATH') or 'pet_pictures.db' + + +class DevelopmentConfig(Config): + """Development configuration""" + DEBUG = True + + +class ProductionConfig(Config): + """Production configuration""" + DEBUG = False + + +class TestingConfig(Config): + """Testing configuration""" + TESTING = True + DATABASE_PATH = ':memory:' \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py new file mode 100644 index 0000000..d8cfe8a --- /dev/null +++ b/app/models/__init__.py @@ -0,0 +1 @@ +# Models package \ No newline at end of file diff --git a/app/models/database.py b/app/models/database.py new file mode 100644 index 0000000..a0bccba --- /dev/null +++ b/app/models/database.py @@ -0,0 +1,94 @@ +""" +Database operations and models for pet pictures +""" + +import sqlite3 +from flask import current_app, g + + +def get_db(): + """Get database connection""" + if 'db' not in g: + g.db = sqlite3.connect("pet_pictures.db") + g.db.row_factory = sqlite3.Row + return g.db + + +def close_db(e=None): + """Close database connection""" + db = g.pop('db', None) + if db is not None: + db.close() + + +def init_db(): + """Initialize database with required tables""" + db = get_db() + db.execute( + """ + CREATE TABLE IF NOT EXISTS pet_pictures ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + filename TEXT NOT NULL, + subscriber_name TEXT NOT NULL, + description TEXT, + uploaded_at TIMESTAMP NOT NULL, + posted BOOLEAN DEFAULT 0, + likes INTEGER DEFAULT 0 + ) + """ + ) + db.commit() + + +class PetPicture: + """Model for pet picture operations""" + + @staticmethod + def get_all(): + """Get all pet pictures""" + db = get_db() + return db.execute( + "SELECT * FROM pet_pictures ORDER BY uploaded_at DESC" + ).fetchall() + + @staticmethod + def get_posted(): + """Get only posted pet pictures""" + db = get_db() + return db.execute( + "SELECT * FROM pet_pictures WHERE posted = 1 ORDER BY uploaded_at DESC" + ).fetchall() + + @staticmethod + def create(filename, subscriber_name, description, uploaded_at): + """Create new pet picture record""" + db = get_db() + db.execute( + "INSERT INTO pet_pictures (filename, subscriber_name, description, uploaded_at) VALUES (?, ?, ?, ?)", + (filename, subscriber_name, description, uploaded_at) + ) + db.commit() + + @staticmethod + def mark_as_posted(picture_id): + """Mark picture as posted""" + db = get_db() + db.execute("UPDATE pet_pictures SET posted = 1 WHERE id = ?", (picture_id,)) + db.commit() + + @staticmethod + def update_likes(picture_id, increment=True): + """Update like count for a picture""" + db = get_db() + if increment: + db.execute("UPDATE pet_pictures SET likes = likes + 1 WHERE id = ?", (picture_id,)) + else: + db.execute("UPDATE pet_pictures SET likes = likes - 1 WHERE id = ?", (picture_id,)) + db.commit() + + @staticmethod + def get_like_count(picture_id): + """Get current like count for a picture""" + db = get_db() + result = db.execute("SELECT likes FROM pet_pictures WHERE id = ?", (picture_id,)).fetchone() + return result['likes'] if result else 0 \ No newline at end of file diff --git a/app/routes/__init__.py b/app/routes/__init__.py new file mode 100644 index 0000000..7e1d20f --- /dev/null +++ b/app/routes/__init__.py @@ -0,0 +1 @@ +# Routes package \ No newline at end of file diff --git a/app/routes/auth.py b/app/routes/auth.py new file mode 100644 index 0000000..f00c3d4 --- /dev/null +++ b/app/routes/auth.py @@ -0,0 +1,33 @@ +""" +Authentication routes +""" + +from flask import Blueprint, render_template, request, redirect, url_for, flash +from app.utils.auth import check_credentials, login_user, logout_user + +auth_bp = Blueprint('auth', __name__) + + +@auth_bp.route('/login', methods=['GET', 'POST']) +def login(): + """Login page and authentication""" + if request.method == 'POST': + username = request.form.get('username') + password = request.form.get('password') + + if check_credentials(username, password): + login_user() + flash('Successfully logged in!') + return redirect(url_for('main.index')) + else: + flash('Invalid username or password.') + + return render_template('login.html') + + +@auth_bp.route('/logout') +def logout(): + """Logout user and redirect to main page""" + logout_user() + flash('You have been logged out.') + return redirect(url_for('main.index')) \ No newline at end of file diff --git a/app/routes/main.py b/app/routes/main.py new file mode 100644 index 0000000..a0f277a --- /dev/null +++ b/app/routes/main.py @@ -0,0 +1,30 @@ +""" +Main application routes +""" + +from flask import Blueprint, render_template, request +from app.models.database import PetPicture +from app.utils.auth import is_authenticated +from app.utils.helpers import get_liked_pictures_from_cookie, add_liked_status_to_pictures + +main_bp = Blueprint('main', __name__) + + +@main_bp.route('/') +def index(): + """Main gallery page - shows all pictures for admins, posted only for public""" + # Get liked pictures from cookie + liked_list = get_liked_pictures_from_cookie(request) + + # Get pictures based on authentication status + if is_authenticated(): + pictures = PetPicture.get_all() + public_view = False + else: + pictures = PetPicture.get_posted() + public_view = True + + # Add liked status to pictures + pictures_with_likes = add_liked_status_to_pictures(pictures, liked_list) + + return render_template("index.html", pictures=pictures_with_likes, public_view=public_view) \ No newline at end of file diff --git a/app/routes/pictures.py b/app/routes/pictures.py new file mode 100644 index 0000000..5fc2cd6 --- /dev/null +++ b/app/routes/pictures.py @@ -0,0 +1,81 @@ +""" +Picture management routes +""" + +import os +from datetime import datetime +from flask import Blueprint, render_template, request, redirect, url_for, flash, send_from_directory, make_response, jsonify, current_app +from werkzeug.utils import secure_filename + +from app.models.database import PetPicture +from app.utils.auth import login_required +from app.utils.helpers import allowed_file, handle_like_action + +pictures_bp = Blueprint('pictures', __name__) + + +@pictures_bp.route('/upload', methods=['GET', 'POST']) +@login_required +def upload(): + """Upload new pet picture""" + if request.method == 'POST': + if 'picture' not in request.files: + flash('No file selected') + return redirect(request.url) + + file = request.files['picture'] + subscriber_name = request.form.get('subscriber_name') + description = request.form.get('description', '').strip() + + if file.filename == '': + flash('No file selected') + return redirect(request.url) + + if not subscriber_name: + flash('Subscriber name is required') + return redirect(request.url) + + if file and allowed_file(file.filename): + filename = secure_filename(file.filename) + timestamp = datetime.now().strftime('%Y%m%d_%H%M%S_') + filename = timestamp + filename + + # Ensure upload directory exists + upload_path = current_app.config['UPLOAD_FOLDER'] + os.makedirs(upload_path, exist_ok=True) + + file.save(os.path.join(upload_path, filename)) + + # Save to database + PetPicture.create(filename, subscriber_name, description, datetime.now()) + + flash('Picture uploaded successfully!') + return redirect(url_for('main.index')) + + flash('Invalid file type') + return redirect(request.url) + + return render_template('upload.html') + + +@pictures_bp.route('/mark_posted/', methods=['POST']) +@login_required +def mark_posted(picture_id): + """Mark picture as posted""" + PetPicture.mark_as_posted(picture_id) + flash('Picture marked as posted!') + return redirect(url_for('main.index')) + + +@pictures_bp.route('/like/', methods=['POST']) +def like_picture(picture_id): + """Handle like/unlike actions""" + return handle_like_action(picture_id, request) + + +@pictures_bp.route('/download/') +def download_file(filename): + """Download original picture file""" + return send_from_directory( + current_app.config['UPLOAD_FOLDER'], filename, as_attachment=True + ) \ No newline at end of file diff --git a/static/uploads/.gitkeep b/app/static/uploads/.gitkeep similarity index 100% rename from static/uploads/.gitkeep rename to app/static/uploads/.gitkeep diff --git a/static/uploads/20250613_164801_IMG_2341.jpeg b/app/static/uploads/20250613_164801_IMG_2341.jpeg similarity index 100% rename from static/uploads/20250613_164801_IMG_2341.jpeg rename to app/static/uploads/20250613_164801_IMG_2341.jpeg diff --git a/app/templates/base.html b/app/templates/base.html new file mode 100644 index 0000000..b42fa9c --- /dev/null +++ b/app/templates/base.html @@ -0,0 +1,134 @@ + + + + + + {% block title %}Pets of Powerwashing{% endblock %} + + + + + + +
+ {% with messages = get_flashed_messages() %} {% if messages %} {% for + message in messages %} + + {% endfor %} {% endif %} {% endwith %} {% block content %}{% endblock %} +
+ + + + + + + diff --git a/app/templates/errors/404.html b/app/templates/errors/404.html new file mode 100644 index 0000000..e30439b --- /dev/null +++ b/app/templates/errors/404.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% block title %}Page Not Found - Pets of Powerwashing{% endblock %} +{% block content %} +
+

404

+

Page Not Found

+

Sorry, the page you're looking for doesn't exist.

+ + Back to Gallery + +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/errors/413.html b/app/templates/errors/413.html new file mode 100644 index 0000000..1d066b8 --- /dev/null +++ b/app/templates/errors/413.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% block title %}File Too Large - Pets of Powerwashing{% endblock %} +{% block content %} +
+

413

+

File Too Large

+

The file you're trying to upload is too large. Please choose a smaller file.

+ + Try Again + +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/errors/500.html b/app/templates/errors/500.html new file mode 100644 index 0000000..24b5951 --- /dev/null +++ b/app/templates/errors/500.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% block title %}Server Error - Pets of Powerwashing{% endblock %} +{% block content %} +
+

500

+

Internal Server Error

+

Something went wrong on our end. Please try again later.

+ + Back to Gallery + +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html new file mode 100644 index 0000000..0db775e --- /dev/null +++ b/app/templates/index.html @@ -0,0 +1,92 @@ +{% extends "base.html" %} {% block title %}Pet Pictures - Pets of Powerwashing{% +endblock %} {% block content %} +
+ {% for picture in pictures %} +
+ +
+

+ From: {{ picture.subscriber_name }} +

+ {% if picture.description %} +

{{ picture.description }}

+ {% endif %} +

Uploaded: {{ picture.uploaded_at }}

+
+
+ +
+ + Download Original + + {% if not public_view %} + {% if not picture.posted %} +
+ +
+ {% else %} +
✓ Posted
+ {% endif %} + {% endif %} +
+
+
+ {% else %} +
+ {% if public_view %} +

No published pet pictures yet.

+

Pictures will appear here once they are marked as posted by an admin.

+ {% else %} +

No pet pictures uploaded yet.

+ + Upload Your First Picture + + {% endif %} +
+ {% endfor %} +
+{% endblock %} diff --git a/app/templates/login.html b/app/templates/login.html new file mode 100644 index 0000000..a019a84 --- /dev/null +++ b/app/templates/login.html @@ -0,0 +1,50 @@ +{% extends "base.html" %} +{% block title %}Login - Pets of Powerwashing{% endblock %} +{% block content %} +
+

Admin Login

+ +
+
+ + +
+ +
+ + +
+ + +
+ + +
+{% endblock %} \ No newline at end of file diff --git a/templates/upload.html b/app/templates/upload.html similarity index 96% rename from templates/upload.html rename to app/templates/upload.html index a1e901b..db9fbfa 100644 --- a/templates/upload.html +++ b/app/templates/upload.html @@ -1,11 +1,11 @@ -{% extends "base.html" %} {% block title %}Upload Pet Picture - Pet Picture -Queue{% endblock %} {% block content %} +{% extends "base.html" %} {% block title %}Upload Pet Picture - Pets of +Powerwashing{% endblock %} {% block content %}

Upload Pet Picture

", methods=["POST"]) -def mark_posted(picture_id): - with get_db() as db: - db.execute("UPDATE pet_pictures SET posted = 1 WHERE id = ?", (picture_id,)) - db.commit() - flash("Picture marked as posted!") - return redirect(url_for("index")) - - -@app.route("/download/") -def download_file(filename): - return send_from_directory( - app.config["UPLOAD_FOLDER"], filename, as_attachment=True - ) +from app import create_app +# Create Flask application using factory pattern +app = create_app() if __name__ == "__main__": - init_db() - app.run(debug=True) + # Development server configuration + debug_mode = os.environ.get('FLASK_ENV') == 'development' + app.run(debug=debug_mode, host='0.0.0.0', port=5000) diff --git a/migrate_session_changes.py b/migrate_session_changes.py new file mode 100755 index 0000000..afadb96 --- /dev/null +++ b/migrate_session_changes.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +""" +Database migration script for session changes +Handles all database schema changes made during this session: +1. Adding likes column (if not exists) +2. Ensuring description column exists +3. Updating any existing records to have default values + +This script is idempotent - can be run multiple times safely. +""" + +import sqlite3 +import sys +import os +from datetime import datetime + + +def get_database_path(): + """Get the correct database path""" + if os.path.exists("pet_pictures.db"): + return "pet_pictures.db" + elif os.path.exists("app/pet_pictures.db"): + return "app/pet_pictures.db" + else: + return "pet_pictures.db" # Default path + + +def check_column_exists(cursor, table_name, column_name): + """Check if a column exists in a table""" + cursor.execute(f"PRAGMA table_info({table_name})") + columns = [column[1] for column in cursor.fetchall()] + return column_name in columns + + +def migrate_database(): + """Main migration function""" + db_path = get_database_path() + print(f"Using database: {db_path}") + + try: + # Connect to the database + db = sqlite3.connect(db_path) + cursor = db.cursor() + + print("Starting database migration...") + + # Check if pet_pictures table exists + cursor.execute(""" + SELECT name FROM sqlite_master + WHERE type='table' AND name='pet_pictures' + """) + + if not cursor.fetchone(): + print("pet_pictures table doesn't exist. Creating it...") + cursor.execute(""" + CREATE TABLE pet_pictures ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + filename TEXT NOT NULL, + subscriber_name TEXT NOT NULL, + description TEXT, + uploaded_at TIMESTAMP NOT NULL, + posted BOOLEAN DEFAULT 0, + likes INTEGER DEFAULT 0 + ) + """) + db.commit() + print("✓ Created pet_pictures table with all columns") + return + + migrations_applied = 0 + + # Migration 1: Add description column if it doesn't exist + if not check_column_exists(cursor, 'pet_pictures', 'description'): + print("Adding description column...") + cursor.execute("ALTER TABLE pet_pictures ADD COLUMN description TEXT") + db.commit() + print("✓ Added description column") + migrations_applied += 1 + else: + print("• Description column already exists") + + # Migration 2: Add likes column if it doesn't exist + if not check_column_exists(cursor, 'pet_pictures', 'likes'): + print("Adding likes column...") + cursor.execute("ALTER TABLE pet_pictures ADD COLUMN likes INTEGER DEFAULT 0") + + # Update existing records to have 0 likes + cursor.execute("UPDATE pet_pictures SET likes = 0 WHERE likes IS NULL") + db.commit() + print("✓ Added likes column and initialized existing records") + migrations_applied += 1 + else: + print("• Likes column already exists") + + # Migration 3: Ensure posted column exists and has correct type + if not check_column_exists(cursor, 'pet_pictures', 'posted'): + print("Adding posted column...") + cursor.execute("ALTER TABLE pet_pictures ADD COLUMN posted BOOLEAN DEFAULT 0") + db.commit() + print("✓ Added posted column") + migrations_applied += 1 + else: + print("• Posted column already exists") + + # Migration 4: Clean up any NULL values in critical columns + print("Cleaning up NULL values...") + cursor.execute(""" + UPDATE pet_pictures + SET likes = 0 + WHERE likes IS NULL + """) + + cursor.execute(""" + UPDATE pet_pictures + SET posted = 0 + WHERE posted IS NULL + """) + + cursor.execute(""" + UPDATE pet_pictures + SET description = '' + WHERE description IS NULL + """) + + db.commit() + print("✓ Cleaned up NULL values") + + # Verify final schema + cursor.execute("PRAGMA table_info(pet_pictures)") + columns = cursor.fetchall() + + print("\nFinal table schema:") + for column in columns: + print(f" {column[1]} {column[2]} {'NOT NULL' if column[3] else 'NULL'} {f'DEFAULT {column[4]}' if column[4] else ''}") + + # Get record count + cursor.execute("SELECT COUNT(*) FROM pet_pictures") + record_count = cursor.fetchone()[0] + + print(f"\nMigration completed successfully!") + print(f"Applied {migrations_applied} migrations") + print(f"Database contains {record_count} pet pictures") + + # Log migration + print(f"Migration completed at: {datetime.now().isoformat()}") + + except sqlite3.Error as e: + print(f"❌ Database error occurred: {e}") + sys.exit(1) + except Exception as e: + print(f"❌ An unexpected error occurred: {e}") + sys.exit(1) + finally: + if 'db' in locals(): + db.close() + + +def verify_migration(): + """Verify that the migration was successful""" + db_path = get_database_path() + + try: + db = sqlite3.connect(db_path) + cursor = db.cursor() + + # Check all required columns exist + required_columns = ['id', 'filename', 'subscriber_name', 'description', 'uploaded_at', 'posted', 'likes'] + cursor.execute("PRAGMA table_info(pet_pictures)") + existing_columns = [column[1] for column in cursor.fetchall()] + + missing_columns = set(required_columns) - set(existing_columns) + if missing_columns: + print(f"❌ Verification failed: Missing columns: {missing_columns}") + return False + + print("✅ Verification successful: All required columns present") + return True + + except sqlite3.Error as e: + print(f"❌ Verification failed with database error: {e}") + return False + finally: + if 'db' in locals(): + db.close() + + +if __name__ == "__main__": + print("=" * 60) + print("Pet Picture Database Migration Script") + print("Session Changes: Adding likes system and ensuring schema consistency") + print("=" * 60) + + # Run migration + migrate_database() + + print("\n" + "=" * 60) + print("Verifying migration...") + + # Verify migration + if verify_migration(): + print("🎉 Migration completed successfully!") + else: + print("⚠️ Migration verification failed") + sys.exit(1) + + print("=" * 60) \ No newline at end of file diff --git a/templates/base.html b/templates/base.html deleted file mode 100644 index 0f036f7..0000000 --- a/templates/base.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - {% block title %}Pet Picture Queue{% endblock %} - - - - - -
- {% with messages = get_flashed_messages() %} {% if messages %} {% for - message in messages %} - - {% endfor %} {% endif %} {% endwith %} {% block content %}{% endblock %} -
- - diff --git a/templates/index.html b/templates/index.html deleted file mode 100644 index 8846c31..0000000 --- a/templates/index.html +++ /dev/null @@ -1,75 +0,0 @@ -{% extends "base.html" %} {% block title %}Pet Pictures - Pet Picture Queue{% -endblock %} {% block content %} -
- {% for picture in pictures %} -
- -
-

- From: {{ picture.subscriber_name }} -

- {% if picture.description %} -

{{ picture.description }}

- {% endif %} -

Uploaded: {{ picture.uploaded_at }}

-
- - Download Original - - {% if not picture.posted %} - - - - {% else %} -
✓ Posted
- {% endif %} -
-
-
- {% else %} -
-

No pet pictures uploaded yet.

- - Upload Your First Picture - -
- {% endfor %} -
-{% endblock %}