migration of jinja tempaltes to bootstrap (#30)

This commit is contained in:
2021-09-05 05:27:58 +03:00
committed by GitHub
parent f49894107a
commit 19ba2ba8e5
25 changed files with 313 additions and 412 deletions

View File

@ -188,7 +188,7 @@ def _set_key_import_parser(root: SubParserAction) -> argparse.ArgumentParser:
parser = root.add_parser("key-import", help="import PGP key",
description="import PGP key from public sources to repository user",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("--key-server", help="key server for key import", default="keys.gnupg.net")
parser.add_argument("--key-server", help="key server for key import", default="pgp.mit.edu")
parser.add_argument("key", help="PGP key to import from public server")
parser.set_defaults(handler=handlers.KeyImport, architecture=[""], lock=None, no_report=True)
return parser

View File

@ -24,7 +24,7 @@ import logging
from logging.config import fileConfig
from pathlib import Path
from typing import Dict, List, Optional, Type
from typing import Any, Dict, List, Optional, Type
class Configuration(configparser.RawConfigParser):
@ -41,6 +41,8 @@ class Configuration(configparser.RawConfigParser):
ARCHITECTURE_SPECIFIC_SECTIONS = ["build", "html", "rsync", "s3", "sign", "web"]
_UNSET = object()
def __init__(self) -> None:
"""
default constructor. In the most cases must not be called directly
@ -109,15 +111,21 @@ class Configuration(configparser.RawConfigParser):
return []
return raw.split()
def getpath(self, section: str, key: str) -> Path:
def getpath(self, section: str, key: str, fallback: Any = _UNSET) -> Path:
"""
helper to generate absolute configuration path for relative settings value
:param section: section name
:param key: key name
:param fallback: optional fallback value
:return: absolute path according to current path configuration
"""
value = Path(self.get(section, key))
if self.path is None or value.is_absolute():
try:
value = Path(self.get(section, key))
except (configparser.NoOptionError, configparser.NoSectionError):
if fallback is self._UNSET:
raise
value = fallback
if self.path is None or not isinstance(value, Path) or value.is_absolute():
return value
return self.path.parent / value

View File

@ -54,6 +54,9 @@ class Email(Report, JinjaTemplate):
Report.__init__(self, architecture, configuration)
JinjaTemplate.__init__(self, "email", configuration)
self.full_template_path = configuration.getpath("email", "full_template_path", fallback=None)
self.template_path = configuration.getpath("email", "template_path")
# base smtp settings
self.host = configuration.get("email", "host")
self.no_empty_report = configuration.getboolean("email", "no_empty_report", fallback=True)
@ -100,6 +103,9 @@ class Email(Report, JinjaTemplate):
"""
if self.no_empty_report and not built_packages:
return
text = self.make_html(built_packages, False)
attachments = {"index.html": self.make_html(packages, True)}
text = self.make_html(built_packages, self.template_path)
if self.full_template_path is not None:
attachments = {"index.html": self.make_html(packages, self.full_template_path)}
else:
attachments = {}
self._send(text, attachments)

View File

@ -41,6 +41,7 @@ class HTML(Report, JinjaTemplate):
JinjaTemplate.__init__(self, "html", configuration)
self.report_path = configuration.getpath("html", "path")
self.template_path = configuration.getpath("html", "template_path")
def generate(self, packages: Iterable[Package], built_packages: Iterable[Package]) -> None:
"""
@ -48,5 +49,5 @@ class HTML(Report, JinjaTemplate):
:param packages: list of packages to generate report
:param built_packages: list of packages which has just been built
"""
html = self.make_html(packages, True)
html = self.make_html(packages, self.template_path)
self.report_path.write_text(html)

View File

@ -19,6 +19,7 @@
#
import jinja2
from pathlib import Path
from typing import Callable, Dict, Iterable
from ahriman.core.configuration import Configuration
@ -59,7 +60,6 @@ class JinjaTemplate:
:ivar name: repository name
:ivar default_pgp_key: default PGP key
:ivar sign_targets: targets to sign enabled in configuration
:ivar template_path: path to directory with jinja templates
"""
def __init__(self, section: str, configuration: Configuration) -> None:
@ -69,7 +69,6 @@ class JinjaTemplate:
:param configuration: configuration instance
"""
self.link_path = configuration.get(section, "link_path")
self.template_path = configuration.getpath(section, "template_path")
# base template vars
self.homepage = configuration.get(section, "homepage", fallback=None)
@ -77,16 +76,16 @@ class JinjaTemplate:
self.sign_targets, self.default_pgp_key = GPG.sign_options(configuration)
def make_html(self, packages: Iterable[Package], extended_report: bool) -> str:
def make_html(self, packages: Iterable[Package], template_path: Path) -> str:
"""
generate report for the specified packages
:param packages: list of packages to generate report
:param extended_report: include additional blocks to the report
:param template_path: path to jinja template
"""
# idea comes from https://stackoverflow.com/a/38642558
loader = jinja2.FileSystemLoader(searchpath=self.template_path.parent)
loader = jinja2.FileSystemLoader(searchpath=template_path.parent)
environment = jinja2.Environment(loader=loader, autoescape=True)
template = environment.get_template(self.template_path.name)
template = environment.get_template(template_path.name)
content = [
{
@ -107,7 +106,6 @@ class JinjaTemplate:
comparator: Callable[[Dict[str, str]], str] = lambda item: item["filename"]
return template.render(
extended_report=extended_report,
homepage=self.homepage,
link_path=self.link_path,
has_package_signed=SignSettings.Packages in self.sign_targets,

View File

@ -58,6 +58,21 @@ class BuildStatusEnum(Enum):
return "success"
return "inactive"
def bootstrap_color(self) -> str:
"""
converts itself to bootstrap color
:return: bootstrap color
"""
if self == BuildStatusEnum.Pending:
return "warning"
if self == BuildStatusEnum.Building:
return "warning"
if self == BuildStatusEnum.Failed:
return "danger"
if self == BuildStatusEnum.Success:
return "success"
return "secondary"
class BuildStatus:
"""

View File

@ -44,6 +44,7 @@ class IndexView(BaseView):
* licenses, sorted list of strings
* packages, sorted list of strings
* status, string based on enum value
* status_color, string based on enum value
* timestamp, pretty printed datetime, string
* version, string
* web_url, string
@ -70,6 +71,7 @@ class IndexView(BaseView):
"licenses": package.licenses,
"packages": list(sorted(package.packages)),
"status": status.status.value,
"status_color": status.status.bootstrap_color(),
"timestamp": pretty_datetime(status.timestamp),
"version": package.version,
"web_url": package.web_url