# HG changeset patch # User Goffi # Date 1588343199 -7200 # Node ID 8ec5ddb4e75905c2df6458cf53b3b33aa67cccc1 # Parent 1649bbe8d07e06f73fd862f17ed4cb47be2d6e73 tools (common/template): list themes and parse their browser data, available through new `getThemesData` method diff -r 1649bbe8d07e -r 8ec5ddb4e759 sat/tools/common/template.py --- a/sat/tools/common/template.py Wed Apr 29 13:53:00 2020 +0200 +++ b/sat/tools/common/template.py Fri May 01 16:26:39 2020 +0200 @@ -1,7 +1,6 @@ #!/usr/bin/env python3 - -# SAT: a jabber client +# SAT: an XMPP client # Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org) # This program is free software: you can redistribute it and/or modify @@ -20,22 +19,24 @@ """Template generation""" import os.path +import time +import re +import json +from pathlib import Path from collections import namedtuple +from xml.sax.saxutils import quoteattr +from babel import support +from babel import Locale +from babel.core import UnknownLocaleError +import pygments +from pygments import lexers +from pygments import formatters from sat.core.constants import Const as C from sat.core.i18n import _ from sat.core import exceptions from sat.tools import config from sat.tools.common import date_utils from sat.core.log import getLogger -from xml.sax.saxutils import quoteattr -import time -import re -from babel import support -from babel import Locale -from babel.core import UnknownLocaleError -import pygments -from pygments import lexers -from pygments import formatters log = getLogger(__name__) @@ -57,19 +58,21 @@ "pip install jinja2" ) +from lxml import etree from jinja2 import Markup as safe from jinja2 import is_undefined from jinja2 import utils from jinja2 import TemplateNotFound from jinja2 import contextfilter from jinja2.loaders import split_template_path -from lxml import etree HTML_EXT = ("html", "xhtml") RE_ATTR_ESCAPE = re.compile(r"[^a-z_-]") SITE_RESERVED_NAMES = ("sat",) TPL_RESERVED_CHARS = r"()/." RE_TPL_RESERVED_CHARS = re.compile("[" + TPL_RESERVED_CHARS + "]") +BROWSER_DIR = "_browser" +BROWSER_META_FILE = "browser_meta.json" TemplateData = namedtuple("TemplateData", ['site', 'theme', 'path']) @@ -350,6 +353,8 @@ self.sites_paths = { "": os.path.dirname(sat_templates.__file__), } + self.sites_themes = { + } conf = config.parseMainConf() public_sites = config.getConfig(conf, None, "sites_path_public_dict", {}) sites_data = [public_sites] @@ -372,6 +377,27 @@ normalised[name] = path self.sites_paths.update(normalised) + for site, site_path in self.sites_paths.items(): + tpl_path = Path(site_path) / C.TEMPLATE_TPL_DIR + for p in tpl_path.iterdir(): + if not p.is_dir(): + continue + log.debug(f"theme found for {site or 'default site'}: {p.name}") + theme_data = self.sites_themes.setdefault(site, {})[p.name] = {'path': p} + browser_path = p / BROWSER_DIR + if browser_path.is_dir(): + theme_data['browser_path'] = browser_path + browser_meta_path = browser_path / BROWSER_META_FILE + if browser_meta_path.is_file(): + try: + with browser_meta_path.open() as f: + theme_data['browser_meta'] = json.load(f) + except Exception as e: + log.error( + f"Can't parse browser metadata at {browser_meta_path}: {e}" + ) + continue + self.env = Environment( loader=TemplateLoader(sites_paths=self.sites_paths, trusted=trusted), autoescape=jinja2.select_autoescape(["html", "xhtml", "xml"]), @@ -516,6 +542,12 @@ raise exceptions.NotFound return theme, os.path.join(site_root_dir, C.TEMPLATE_TPL_DIR, theme) + def getThemesData(self, site_name): + try: + return self.sites_themes[site_name] + except KeyError: + raise exceptions.NotFound(f"no theme found for {site_name}") + def getStaticPath(self, template_data, filename): """Retrieve path of a static file if it exists with current theme or default