82 lines
2.5 KiB
Python
82 lines
2.5 KiB
Python
"""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)))
|