import os from flask import Flask from .extensions import db, login_manager from .models import User from .cli import init_db_command def create_app(): app = Flask(__name__, instance_relative_config=True) # Basic config # Flask ships with SECRET_KEY=None by default, so setdefault() won't override it. app.config["SECRET_KEY"] = os.environ.get("SECRET_KEY") or "dev-secret-change-me" app.config.setdefault( "SQLALCHEMY_DATABASE_URI", os.environ.get("DATABASE_URL", "sqlite:///" + os.path.join(app.instance_path, "signage.sqlite")), ) app.config.setdefault("SQLALCHEMY_TRACK_MODIFICATIONS", False) app.config.setdefault("UPLOAD_FOLDER", os.path.join(app.root_path, "static", "uploads")) app.config.setdefault("MAX_CONTENT_LENGTH", 500 * 1024 * 1024) # 500MB os.makedirs(app.instance_path, exist_ok=True) os.makedirs(app.config["UPLOAD_FOLDER"], exist_ok=True) # Init extensions db.init_app(app) login_manager.init_app(app) login_manager.login_view = "auth.login" # Lightweight migration(s) for SQLite DBs created before new columns existed. # This avoids requiring Alembic for this small project. with app.app_context(): try: uri = app.config.get("SQLALCHEMY_DATABASE_URI", "") or "" if uri.startswith("sqlite:"): cols = [r[1] for r in db.session.execute(db.text("PRAGMA table_info(user)")).fetchall()] if "email" not in cols: db.session.execute(db.text("ALTER TABLE user ADD COLUMN email VARCHAR(255)")) # Best-effort unique index (SQLite doesn't support adding unique constraints after the fact). db.session.execute(db.text("CREATE UNIQUE INDEX IF NOT EXISTS ix_user_email ON user (email)")) db.session.commit() except Exception: db.session.rollback() @login_manager.user_loader def load_user(user_id: str): return db.session.get(User, int(user_id)) # CLI app.cli.add_command(init_db_command) # Blueprints from .routes.auth import bp as auth_bp from .routes.admin import bp as admin_bp from .routes.company import bp as company_bp from .routes.display import bp as display_bp from .routes.api import bp as api_bp app.register_blueprint(auth_bp) app.register_blueprint(admin_bp) app.register_blueprint(company_bp) app.register_blueprint(display_bp) app.register_blueprint(api_bp) # Home from flask import redirect, url_for from flask_login import current_user @app.get("/") def index(): if not current_user.is_authenticated: return redirect(url_for("auth.login")) if current_user.is_admin: return redirect(url_for("admin.dashboard")) return redirect(url_for("company.dashboard")) return app