""" Quality App v2 - Flask Application Factory Robust, modular application with login, dashboard, and multiple modules """ from flask import Flask from datetime import datetime, timedelta import os import logging from logging.handlers import RotatingFileHandler def create_app(config=None): """ Application factory function Creates and configures the Flask application """ app = Flask(__name__) # Load configuration if config is None: from app.config import Config config = Config app.config.from_object(config) # Setup logging setup_logging(app) logger = logging.getLogger(__name__) logger.info("=" * 80) logger.info("Flask App Initialization Started") logger.info("=" * 80) # Configure session app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=8) app.config['SESSION_COOKIE_SECURE'] = False # Set True in production with HTTPS app.config['SESSION_COOKIE_HTTPONLY'] = True app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' # Initialize database connection logger.info("Initializing database connection...") from app.database import init_db, close_db init_db(app) app.teardown_appcontext(close_db) # Register blueprints logger.info("Registering blueprints...") register_blueprints(app) # Register error handlers logger.info("Registering error handlers...") register_error_handlers(app) # Add template globals app.jinja_env.globals['now'] = datetime.now # Add context processor for app name @app.context_processor def inject_app_settings(): """Inject app settings into all templates""" try: from app.database import get_db conn = get_db() cursor = conn.cursor() cursor.execute( "SELECT setting_value FROM application_settings WHERE setting_key = %s", ('app_name',) ) result = cursor.fetchone() cursor.close() app_name = result[0] if result else 'Quality App v2' except: app_name = 'Quality App v2' return {'app_name': app_name} # Add before_request handlers register_request_handlers(app) # Initialize backup scheduler logger.info("Initializing backup scheduler...") try: from app.scheduler import init_scheduler init_scheduler(app) except Exception as e: logger.error(f"Failed to initialize backup scheduler: {e}") logger.info("=" * 80) logger.info("Flask App Initialization Completed Successfully") logger.info("=" * 80) return app def setup_logging(app): """Configure application logging""" log_dir = app.config.get('LOG_DIR', '/app/data/logs') # Create log directory if it doesn't exist if not os.path.exists(log_dir): os.makedirs(log_dir, exist_ok=True) # Configure rotating file handler log_file = os.path.join(log_dir, 'app.log') handler = RotatingFileHandler( log_file, maxBytes=10485760, # 10MB backupCount=10 ) # Create formatter formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) handler.setFormatter(formatter) # Set logging level log_level = app.config.get('LOG_LEVEL', 'INFO') handler.setLevel(getattr(logging, log_level)) # Add handler to app logger app.logger.addHandler(handler) app.logger.setLevel(getattr(logging, log_level)) def register_blueprints(app): """Register application blueprints""" from app.routes import main_bp from app.modules.quality.routes import quality_bp from app.modules.settings.routes import settings_bp from app.modules.warehouse.routes import warehouse_bp from app.modules.warehouse.boxes_routes import boxes_bp app.register_blueprint(main_bp) app.register_blueprint(quality_bp, url_prefix='/quality') app.register_blueprint(settings_bp, url_prefix='/settings') app.register_blueprint(warehouse_bp, url_prefix='/warehouse') app.register_blueprint(boxes_bp) app.logger.info("Blueprints registered: main, quality, settings, warehouse, boxes") def register_error_handlers(app): """Register error handlers""" @app.errorhandler(404) def page_not_found(e): from flask import render_template return render_template('errors/404.html'), 404 @app.errorhandler(500) def internal_error(e): from flask import render_template app.logger.error(f"Internal error: {e}") return render_template('errors/500.html'), 500 @app.errorhandler(403) def forbidden(e): from flask import render_template return render_template('errors/403.html'), 403 def register_request_handlers(app): """Register before/after request handlers""" @app.before_request def before_request(): """Handle pre-request logic""" from flask import session, request, redirect, url_for # Skip authentication check for login and static files if request.endpoint and ( request.endpoint in ['static', 'main.login', 'main.index'] or request.path.startswith('/static/') ): return None # Check if user is logged in if 'user_id' not in session: return redirect(url_for('main.login')) return None @app.after_request def after_request(response): """Handle post-request logic""" return response