Initial commit: Quality App v2 - FG Scan Module with Reports
This commit is contained in:
183
app/__init__.py
Normal file
183
app/__init__.py
Normal file
@@ -0,0 +1,183 @@
|
||||
"""
|
||||
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
|
||||
|
||||
app.register_blueprint(main_bp)
|
||||
app.register_blueprint(quality_bp, url_prefix='/quality')
|
||||
app.register_blueprint(settings_bp, url_prefix='/settings')
|
||||
|
||||
app.logger.info("Blueprints registered: main, quality, settings")
|
||||
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user