94 lines
2.4 KiB
Python
Executable File
94 lines
2.4 KiB
Python
Executable File
"""Flask application factory."""
|
|
|
|
import os
|
|
from datetime import UTC, datetime
|
|
|
|
from flask import Flask, g
|
|
from flask_cors import CORS
|
|
|
|
|
|
def create_app(config_name: str | None = None) -> Flask:
|
|
"""Create Flask application."""
|
|
from customer_portal.config import config
|
|
|
|
app = Flask(__name__)
|
|
|
|
# Load config
|
|
config_name = config_name or os.getenv("FLASK_ENV", "default")
|
|
app.config.from_object(config[config_name])
|
|
|
|
# Extensions
|
|
CORS(app)
|
|
|
|
# Initialize Flask-Mail
|
|
from customer_portal.services.email import mail
|
|
|
|
mail.init_app(app)
|
|
|
|
# Initialize database
|
|
from customer_portal.models import close_db, create_tables, init_db
|
|
|
|
init_db(app.config["SQLALCHEMY_DATABASE_URI"])
|
|
|
|
# Create tables on first request (development)
|
|
with app.app_context():
|
|
create_tables()
|
|
|
|
# Teardown - close db session
|
|
app.teardown_appcontext(close_db)
|
|
|
|
# Register Jinja2 filters
|
|
from customer_portal.web.filters import register_filters
|
|
|
|
register_filters(app)
|
|
|
|
# Context processor for templates
|
|
@app.context_processor
|
|
def inject_globals():
|
|
from customer_portal.models import get_db
|
|
from customer_portal.models.settings import (
|
|
DEFAULT_BRANDING_CONFIG,
|
|
PortalSettings,
|
|
)
|
|
|
|
# Get branding config (with fallback to defaults)
|
|
branding = DEFAULT_BRANDING_CONFIG.copy()
|
|
try:
|
|
db = get_db()
|
|
branding = PortalSettings.get_branding(db)
|
|
except Exception:
|
|
pass # Use defaults if DB not available
|
|
|
|
return {
|
|
"now": lambda: datetime.now(UTC),
|
|
"branding": branding,
|
|
}
|
|
|
|
# Make g.customer available in templates
|
|
@app.before_request
|
|
def load_customer():
|
|
g.customer = None
|
|
|
|
# Blueprints
|
|
from customer_portal.web.routes import (
|
|
admin,
|
|
api,
|
|
auth,
|
|
bookings,
|
|
invoices,
|
|
main,
|
|
profile,
|
|
videos,
|
|
)
|
|
|
|
app.register_blueprint(main.bp)
|
|
app.register_blueprint(auth.bp, url_prefix="/auth")
|
|
app.register_blueprint(api.bp, url_prefix="/api")
|
|
app.register_blueprint(admin.bp, url_prefix="/admin")
|
|
app.register_blueprint(bookings.bp, url_prefix="/bookings")
|
|
app.register_blueprint(invoices.bp, url_prefix="/invoices")
|
|
app.register_blueprint(profile.bp, url_prefix="/profile")
|
|
app.register_blueprint(videos.bp, url_prefix="/videos")
|
|
|
|
return app
|