from __future__ import annotations import os import os.path import typing import jinja2 import quart.templating import quart_trio import capport.comm.hub import capport.config import capport.utils.ipneigh class DispatchingJinjaLoader(quart.templating.DispatchingJinjaLoader): app: MyQuartApp def __init__(self, app: MyQuartApp) -> None: super().__init__(app) def get_source( self, environment: typing.Any, template: str, ) -> tuple[str, str | None, typing.Callable | None]: if self.app.custom_loader: try: return self.app.custom_loader.get_source(environment, template) except jinja2.TemplateNotFound: pass return super().get_source(environment, template) def list_templates(self) -> list[str]: result = set() if self.app.custom_loader: result.update(self.app.custom_loader.list_templates()) result.update(super().list_templates()) return list(result) class MyQuartApp(quart_trio.QuartTrio): my_nc: capport.utils.ipneigh.NeighborController | None = None my_hub: capport.comm.hub.Hub | None = None my_config: capport.config.Config custom_loader: jinja2.FileSystemLoader | None = None def __init__(self, import_name: str, **kwargs) -> None: self.my_config = capport.config.Config.load_default_once() kwargs.setdefault('template_folder', os.path.join(os.path.dirname(__file__), 'templates')) cust_templ = os.path.join('custom', 'templates') if os.path.exists(cust_templ): self.custom_loader = jinja2.FileSystemLoader(os.fspath(cust_templ)) cust_static = os.path.abspath(os.path.join('custom', 'static')) if os.path.exists(cust_static): static_folder = cust_static else: static_folder = os.path.join(os.path.dirname(__file__), 'static') kwargs.setdefault('static_folder', static_folder) super().__init__(import_name, **kwargs) self.debug = self.my_config.debug self.secret_key = self.my_config.cookie_secret def create_global_jinja_loader(self) -> DispatchingJinjaLoader: """Create and return a global (not blueprint specific) Jinja loader.""" return DispatchingJinjaLoader(self)