import os import logging from datetime import datetime from flask import Flask, render_template from flask_sqlalchemy import SQLAlchemy from sqlalchemy.orm import DeclarativeBase from werkzeug.middleware.proxy_fix import ProxyFix from flask_login import LoginManager from flask_wtf.csrf import CSRFProtect # Set up logging logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) # Define base class for SQLAlchemy models class Base(DeclarativeBase): pass # Initialize extensions db = SQLAlchemy(model_class=Base) csrf = CSRFProtect() login_manager = LoginManager() # Create Flask application app = Flask(__name__) # Configure application app.secret_key = os.environ.get("SESSION_SECRET", "dev-secret-key") app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1) # Configure database app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DATABASE_URL", "sqlite:///forrum.db") app.config["SQLALCHEMY_ENGINE_OPTIONS"] = { "pool_recycle": 300, "pool_pre_ping": True, } # Initialize extensions with app db.init_app(app) csrf.init_app(app) login_manager.init_app(app) # Configure login manager login_manager.login_view = "auth.login" login_manager.login_message = "Please log in to access this page." login_manager.login_message_category = "info" # Import models (must be after db initialization but before create_all) from models import User # Register blueprints with app.app_context(): from routes.auth import auth_bp from routes.forum import forum_bp from routes.user import user_bp from routes.admin import admin_bp from routes.cadmin import cadmin_bp app.register_blueprint(auth_bp) app.register_blueprint(forum_bp) app.register_blueprint(user_bp) app.register_blueprint(admin_bp) app.register_blueprint(cadmin_bp) # Create database tables db.create_all() # Import utility functions from utils import format_datetime # Add template filters app.jinja_env.filters['format_datetime'] = format_datetime # Context processor for template variables @app.context_processor def utility_processor(): return { 'now': datetime.utcnow } # User loader for Flask-Login @login_manager.user_loader def load_user(user_id): return User.query.get(int(user_id)) # Error handlers @app.errorhandler(404) def page_not_found(e): return render_template('errors/404.html'), 404 @app.errorhandler(403) def forbidden(e): return render_template('errors/403.html'), 403 @app.errorhandler(500) def internal_server_error(e): return render_template('errors/500.html'), 500 # Ensure required directories exist upload_dir = os.path.join(app.static_folder, 'uploads') avatar_dir = os.path.join(upload_dir, 'avatars') if not os.path.exists(upload_dir): os.makedirs(upload_dir) if not os.path.exists(avatar_dir): os.makedirs(avatar_dir) logger.debug("Application initialized successfully")