Project_Manager/app/__init__.py
2026-06-26 18:21:22 +02:00

85 lines
2.7 KiB
Python

"""App-Factory für den Projekt-Hub.
Erzeugt die Flask-App, lädt die Config, bindet die Extensions und registriert
die Blueprints der einzelnen Mini-App-Module. Jedes neue Modul wird hier per
register_blueprint(...) eingebunden und über die zentrale Navigations-Registry
in der Navigation sichtbar gemacht — Kern bleibt unangetastet.
"""
import os
from flask import Flask, redirect, url_for
from .config import get_config
from .extensions import db, migrate, login_manager, mail, limiter, csrf
# --- Zentrale Navigations-Registry ---------------------------------------
# Jedes Modul trägt hier einen Eintrag bei (Label, Endpoint, Icon). base.html
# rendert daraus die gemeinsame Navigation. Neues Modul = neuer Eintrag.
NAV_MODULES = [
{"label": "Projekte", "endpoint": "projects.index", "icon": "📁"},
]
def create_app(config_name: str | None = None) -> Flask:
app = Flask(
__name__,
instance_relative_config=True,
instance_path=os.path.join(os.path.dirname(os.path.dirname(__file__)), "instance"),
)
app.config.from_object(get_config(config_name))
# instance/-Ordner sicherstellen (SQLite-Datei landet hier).
os.makedirs(app.instance_path, exist_ok=True)
# Relativen sqlite-Pfad in den instance/-Ordner umbiegen.
uri = app.config.get("SQLALCHEMY_DATABASE_URI", "")
if uri.startswith("sqlite:///") and not uri.startswith("sqlite:////"):
db_name = uri.replace("sqlite:///", "", 1)
abs_path = os.path.join(app.instance_path, db_name)
app.config["SQLALCHEMY_DATABASE_URI"] = f"sqlite:///{abs_path}"
_init_extensions(app)
_register_blueprints(app)
_register_context(app)
@app.route("/")
def index():
return redirect(url_for("projects.index"))
return app
def _init_extensions(app: Flask) -> None:
db.init_app(app)
migrate.init_app(app, db)
login_manager.init_app(app)
mail.init_app(app)
limiter.init_app(app)
csrf.init_app(app)
# Modelle importieren, damit SQLAlchemy/Alembic sie kennen (Autogenerate).
from . import models # noqa: F401
from .projects import models as project_models # noqa: F401
from .models import User
@login_manager.user_loader
def load_user(user_id):
return db.session.get(User, int(user_id))
def _register_blueprints(app: Flask) -> None:
from .auth import bp as auth_bp
from .projects import bp as projects_bp
app.register_blueprint(auth_bp)
app.register_blueprint(projects_bp)
def _register_context(app: Flask) -> None:
@app.context_processor
def inject_nav():
# Navigations-Registry in allen Templates verfügbar machen.
return {"nav_modules": NAV_MODULES}