import asyncio from fastapi import APIRouter from loguru import logger from .crud import db from .tasks import wait_for_paid_invoices from .views import castle_generic_router from .views_api import castle_api_router castle_ext: APIRouter = APIRouter(prefix="/castle", tags=["Castle"]) castle_ext.include_router(castle_generic_router) castle_ext.include_router(castle_api_router) castle_static_files = [ { "path": "/castle/static", "name": "castle_static", } ] scheduled_tasks: list[asyncio.Task] = [] def castle_stop(): """Clean up background tasks on extension shutdown""" for task in scheduled_tasks: try: task.cancel() except Exception as ex: logger.warning(ex) def castle_start(): """Initialize Castle extension background tasks""" from lnbits.tasks import create_permanent_unique_task from .fava_client import init_fava_client from .models import CastleSettings from .tasks import wait_for_account_sync # Initialize Fava client with default settings # (Will be re-initialized if admin updates settings) defaults = CastleSettings() try: init_fava_client( fava_url=defaults.fava_url, ledger_slug=defaults.fava_ledger_slug, timeout=defaults.fava_timeout ) logger.info(f"Fava client initialized: {defaults.fava_url}/{defaults.fava_ledger_slug}") except Exception as e: logger.error(f"Failed to initialize Fava client: {e}") logger.warning("Castle will not function without Fava. Please configure Fava settings.") # Start background tasks task = create_permanent_unique_task("ext_castle", wait_for_paid_invoices) scheduled_tasks.append(task) # Start account sync task (runs hourly) sync_task = create_permanent_unique_task("ext_castle_account_sync", wait_for_account_sync) scheduled_tasks.append(sync_task) logger.info("Castle account sync task started (runs hourly)") __all__ = ["castle_ext", "castle_static_files", "db", "castle_start", "castle_stop"]