"""Web app factory for CmdForge UI.""" from __future__ import annotations import os import secrets from flask import Flask, render_template, session # Initialize Sentry before importing Flask app (if DSN is configured) _sentry_dsn = os.environ.get("SENTRY_DSN") if _sentry_dsn: try: import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration sentry_sdk.init( dsn=_sentry_dsn, integrations=[FlaskIntegration()], traces_sample_rate=float(os.environ.get("SENTRY_TRACES_RATE", "0.1")), profiles_sample_rate=float(os.environ.get("SENTRY_PROFILES_RATE", "0.1")), environment=os.environ.get("CMDFORGE_ENV", "development"), send_default_pii=False, # Privacy: don't send user IPs, emails, etc. ) except ImportError: pass # sentry-sdk not installed from cmdforge.registry import app as registry_app from . import web_bp from .auth import login, register, logout from .filters import register_filters from .forum import forum_bp from .sessions import SQLiteSessionInterface, cleanup_expired_sessions def create_web_app() -> Flask: app = registry_app.create_app() # Import routes BEFORE registering blueprint from . import routes # noqa: F401 app.register_blueprint(web_bp) app.register_blueprint(forum_bp) # Session configuration app.session_interface = SQLiteSessionInterface(cookie_name="cmdforge_session") app.config["SESSION_COOKIE_NAME"] = "cmdforge_session" app.config["SESSION_COOKIE_SECURE"] = os.environ.get("CMDFORGE_ENV") == "production" app.config["SHOW_ADS"] = os.environ.get("CMDFORGE_SHOW_ADS", "").lower() == "true" # CSRF token generator app.config["CSRF_GENERATOR"] = lambda: secrets.token_urlsafe(32) # Jinja globals def _csrf_token(): token = session.get("csrf_token") if not token: token = app.config["CSRF_GENERATOR"]() session["csrf_token"] = token return token app.jinja_env.globals["csrf_token"] = _csrf_token register_filters(app) cleanup_expired_sessions() # Error handlers @app.errorhandler(404) def not_found_error(error): return render_template("errors/404.html"), 404 @app.errorhandler(500) def internal_error(error): return render_template("errors/500.html"), 500 return app if __name__ == "__main__": create_web_app().run(host="0.0.0.0", port=int(os.environ.get("PORT", 5000)))