""" Auto-export: after admin saves content, export JSON and write a trigger file. A cron job watches the trigger file and runs Nuxt rebuild. """ from __future__ import annotations import logging import os import threading from app.config import settings from app.services.export_service import EXPORT_FUNCTIONS logger = logging.getLogger("auto_export") ROUTE_TO_MODULES: dict[str, list[str]] = { "/api/brand": ["brand"], "/api/about": ["about"], "/api/products": ["products"], "/api/faq": ["faq"], "/api/reviews": ["reviews"], "/api/contact": ["contact"], "/api/seo": ["seo"], "/api/navigation": ["navigation"], "/api/versions": ["versions"], "/api/guides": ["guides"], "/api/site-images": ["images"], "/api/autumn": ["autumn-products"], "/api/winter": ["winter-products"], "/api/winter-camp": ["winter-camp"], "/api/destinations-detail": ["destinations-detail"], "/api/destinations": ["destinations"], "/api/customize": ["customize"], "/api/blog": ["blog"], "/api/stories": ["stories"], "/api/news": ["news"], "/api/pricing": ["pricing"], "/api/qualifications": ["qualifications"], "/api/partners": ["partners"], "/api/gallery": ["gallery"], "/api/selector": ["selector"], "/api/courses": ["courses"], } TRIGGER_FILE = "/tmp/gw-rebuild-trigger" _pending_modules: set[str] = set() _pending_lock = threading.Lock() _debounce_timer: threading.Timer | None = None def _do_export(): """Export pending modules and write trigger file for cron to rebuild.""" global _debounce_timer with _pending_lock: modules = list(_pending_modules) _pending_modules.clear() _debounce_timer = None if not modules: return from app.database import SessionLocal try: db = SessionLocal() try: for mod in modules: fn = EXPORT_FUNCTIONS.get(mod) if fn: fn(db) logger.info(f"Auto-exported: {mod}") finally: db.close() # Write trigger file for cron-based rebuild with open(TRIGGER_FILE, "w") as f: f.write(",".join(modules)) logger.info(f"Trigger file written, cron will rebuild") except Exception as e: logger.error(f"Export failed: {e}") def schedule_export(path: str): """Called after a successful write. Debounces 3s to batch rapid saves.""" global _debounce_timer modules = [] for prefix, mods in ROUTE_TO_MODULES.items(): if path.startswith(prefix): modules = mods break if not modules: return with _pending_lock: _pending_modules.update(modules) if _debounce_timer: _debounce_timer.cancel() _debounce_timer = threading.Timer(3.0, _do_export) _debounce_timer.daemon = True _debounce_timer.start() logger.info(f"Scheduled export for: {modules}")