from flask import g, request, current_app from flask_babel import get_locale from flask_login import current_user from app.models import Settings from app.utils.timezone import get_timezone_offset_for_timezone def register_context_processors(app): """Register context processors for the application""" # Register permission helpers for templates from app.utils.permissions import init_permission_helpers init_permission_helpers(app) @app.context_processor def inject_settings(): """Inject settings into all templates""" try: from app import db # Check if we have an active database session if db.session.is_active: settings = Settings.get_settings() return {"settings": settings, "currency": settings.currency, "timezone": settings.timezone} except Exception as e: # Log the error but continue with defaults print(f"Warning: Could not inject settings: {e}") # Rollback the failed transaction try: from app import db db.session.rollback() except Exception: pass pass # Return defaults if settings not available return {"settings": None, "currency": "EUR", "timezone": "Europe/Rome"} @app.context_processor def inject_globals(): """Inject global variables into all templates""" try: from app import db # Check if we have an active database session if db.session.is_active: settings = Settings.get_settings() timezone_name = settings.timezone if settings else "Europe/Rome" else: timezone_name = "Europe/Rome" except Exception as e: # Log the error but continue with defaults print(f"Warning: Could not inject globals: {e}") # Rollback the failed transaction try: from app import db db.session.rollback() except Exception: pass timezone_name = "Europe/Rome" # Resolve user-specific timezone, falling back to application timezone user_timezone = timezone_name try: if ( current_user and getattr(current_user, "is_authenticated", False) and getattr(current_user, "timezone", None) ): user_timezone = current_user.timezone except Exception: pass # Determine app version from setup.py (single source of truth) try: from app.config.analytics_defaults import get_version_from_setup import os # Get version from setup.py version_value = get_version_from_setup() # If version is "unknown", fall back to environment variable for dev mode if version_value == "unknown": env_version = os.getenv("APP_VERSION") if env_version: version_value = env_version else: # Last resort: use "dev-0" for development version_value = "dev-0" # Strip any leading 'v' prefix to avoid double 'v' in template (e.g., vv3.5.0) if version_value and version_value.startswith("v"): version_value = version_value[1:] except Exception: # Fallback if anything goes wrong version_value = "dev-0" # Current locale code (e.g., 'en', 'de') try: current_locale = str(get_locale()) except Exception: current_locale = "en" # Normalize to short code for comparisons (e.g., 'en' from 'en_US') short_locale = current_locale.split("_", 1)[0] if current_locale else "en" # Reverse-map normalized locale codes back to config keys for label lookup # 'nb' (used by Flask-Babel) should map back to 'no' (used in LANGUAGES config) display_locale = short_locale if short_locale == "nb": display_locale = "no" available_languages = current_app.config.get("LANGUAGES", {}) or {} current_language_label = available_languages.get(display_locale, short_locale.upper()) # Check if current language is RTL rtl_languages = current_app.config.get("RTL_LANGUAGES", set()) is_rtl = short_locale in rtl_languages return { "app_name": "Time Tracker", "app_version": version_value, "timezone": timezone_name, "timezone_offset": get_timezone_offset_for_timezone(timezone_name), "user_timezone": user_timezone, "current_locale": current_locale, "current_language_code": display_locale, # Use display locale (e.g., 'no' not 'nb') "current_language_label": current_language_label, "is_rtl": is_rtl, "available_languages": available_languages, "config": current_app.config, } @app.before_request def before_request(): """Set up request-specific data""" g.request_start_time = request.start_time if hasattr(request, "start_time") else None