from __future__ import annotations import logging import os from logging.handlers import RotatingFileHandler from flask import Flask from flask_compress import Compress from flask_cors import CORS from config import Config from models import db from routes import admin_bp, bp from sockets import socketio def create_app() -> Flask: app = Flask(__name__, template_folder=os.path.join(os.path.dirname(__file__), "..", "templates"), static_folder=os.path.join(os.path.dirname(__file__), "..", "static")) app.config.from_object(Config) os.makedirs(app.config["MEDIA_DIR"], exist_ok=True) # Extensions db.init_app(app) CORS(app, resources={r"/*": {"origins": app.config.get("CORS_ORIGINS", "*")}}) Compress(app) # SocketIO tuning from config socketio.init_app( app, cors_allowed_origins=app.config.get("CORS_ORIGINS", "*"), ping_interval=app.config["SOCKETIO_PING_INTERVAL"], ping_timeout=app.config["SOCKETIO_PING_TIMEOUT"], ) # Blueprints app.register_blueprint(bp) app.register_blueprint(admin_bp) # Logging _configure_logging(app) @app.after_request def _lan_headers(resp): # Keep headers permissive for embedded Chromium/Tizen/WebOS. resp.headers.pop("Content-Security-Policy", None) resp.headers.pop("Cross-Origin-Opener-Policy", None) resp.headers.pop("Cross-Origin-Embedder-Policy", None) # Disable caching for HTML/JS (but media route sets its own cache-control) if resp.mimetype in ("text/html", "application/javascript"): resp.headers["Cache-Control"] = "no-store" return resp return app def _configure_logging(app: Flask) -> None: log_dir = app.config.get("LOG_DIR") or os.path.abspath(os.path.join(app.root_path, "..", "logs")) os.makedirs(log_dir, exist_ok=True) log_path = os.path.abspath(os.path.join(log_dir, "system.log")) handler = RotatingFileHandler(log_path, maxBytes=2_000_000, backupCount=3) fmt = logging.Formatter("%(asctime)s %(levelname)s %(name)s: %(message)s") handler.setFormatter(fmt) handler.setLevel(logging.INFO) app.logger.addHandler(handler) logging.getLogger().addHandler(handler) logging.getLogger().setLevel(logging.INFO)