68 lines
2.2 KiB
Python
68 lines
2.2 KiB
Python
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)
|