From 356cd35c5fe65ed2f264a141654585998c3a4d4c Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Sat, 13 Mar 2021 05:12:53 +0300 Subject: [PATCH] better templating --- package/archlinux/PKGBUILD | 2 +- package/share/ahriman/build-status.jinja2 | 110 ++-------------------- package/share/ahriman/repo-index.jinja2 | 60 ++++++++---- package/share/ahriman/search-line.jinja2 | 3 + package/share/ahriman/search.jinja2 | 25 +++++ package/share/ahriman/sorttable.jinja2 | 1 + package/share/ahriman/style.jinja2 | 74 +++++++++++++++ setup.py | 4 + src/ahriman/application/application.py | 4 +- src/ahriman/core/report/html.py | 28 +++--- src/ahriman/core/report/report.py | 9 +- src/ahriman/core/repository.py | 9 +- src/ahriman/core/tree.py | 4 +- src/ahriman/models/package.py | 12 +-- 14 files changed, 193 insertions(+), 152 deletions(-) create mode 100644 package/share/ahriman/search-line.jinja2 create mode 100644 package/share/ahriman/search.jinja2 create mode 100644 package/share/ahriman/sorttable.jinja2 create mode 100644 package/share/ahriman/style.jinja2 diff --git a/package/archlinux/PKGBUILD b/package/archlinux/PKGBUILD index 9d2c8ccd..f80beb08 100644 --- a/package/archlinux/PKGBUILD +++ b/package/archlinux/PKGBUILD @@ -23,7 +23,7 @@ optdepends=('aws-cli: sync to s3' source=("https://github.com/arcan1s/ahriman/releases/download/$pkgver/$pkgname-$pkgver-src.tar.xz" 'ahriman.sysusers' 'ahriman.tmpfiles') -sha512sums=('ef3c5bf73f95a87f226bc7ca90cee990abf8e7d7dacf56ce5ab346e689019a414a1ffe186a38c75bbf2c9fcc7e04822455e704c67fe2e125c5883dee8066f4bc' +sha512sums=('70b2fd83859bdab15037137bf79a599116e52ddf901a401f0a7650f0009770f060e11936f8dd8e57800cd14f1a734ecfd31cde56456506896f7093fd7309034f' '13718afec2c6786a18f0b223ef8e58dccf0688bca4cdbe203f14071f5031ed20120eb0ce38b52c76cfd6e8b6581a9c9eaa2743eb11abbaca637451a84c33f075' '55b20f6da3d66e7bbf2add5d95a3b60632df121717d25a993e56e737d14f51fe063eb6f1b38bd81cc32e05db01c0c1d80aaa720c45cde87f238d8b46cdb8cbc4') backup=('etc/ahriman.ini' diff --git a/package/share/ahriman/build-status.jinja2 b/package/share/ahriman/build-status.jinja2 index e06d8269..1f372597 100644 --- a/package/share/ahriman/build-status.jinja2 +++ b/package/share/ahriman/build-status.jinja2 @@ -3,118 +3,20 @@ {{ repository|e }} - - - - + {% include "style.jinja2" %} + {% include "sorttable.jinja2" %} + {% include "search.jinja2" %}

ahriman {{ version|e }}

-
- -
+ {% include "search-line.jinja2" %}
- +
@@ -126,7 +28,7 @@ {% for package in packages %} - + diff --git a/package/share/ahriman/repo-index.jinja2 b/package/share/ahriman/repo-index.jinja2 index 38879212..952bf78d 100644 --- a/package/share/ahriman/repo-index.jinja2 +++ b/package/share/ahriman/repo-index.jinja2 @@ -2,31 +2,53 @@ {{ repository|e }} + + {% include "style.jinja2" %} + + {% include "sorttable.jinja2" %} + {% include "search.jinja2" %} -

Archlinux custom repository

+
+

Archlinux user repository

- {% if pgp_key is not none %} -

This repository is signed with {{ pgp_key|e }}.

- {% endif %} +
+ {% if pgp_key is not none %} +

This repository is signed with {{ pgp_key|e }} by default.

+ {% endif %} - - $ cat /etc/pacman.conf
- [{{ repository|e }}]
- Server = {{ link_path|e }}
- SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly -
+ + $ cat /etc/pacman.conf
+ [{{ repository|e }}]
+ Server = {{ link_path|e }}
+ SigLevel = Database{% if has_repo_signed %}Required{% else %}Never{% endif %} Package{% if has_package_signed %}Required{% else %}Never{% endif %} TrustedOnly +
+
-

Packages:

-
    - {% for package, package_url in packages.items() %} -
  • {{ package|e }}
  • - {% endfor %} -
+ {% include "search-line.jinja2" %} - {% if homepage is not none %} - - {% endif %} +
+
package base packages
{{ package.version|e }} {{ architecture|e }}
+ + + + + + + {% for package in packages %} + + + + + + {% endfor %} +
packageversionarchitecture
{{ package.version|e }}{{ architecture|e }}
+
+ + {% if homepage is not none %} + + {% endif %} +
diff --git a/package/share/ahriman/search-line.jinja2 b/package/share/ahriman/search-line.jinja2 new file mode 100644 index 00000000..cb685672 --- /dev/null +++ b/package/share/ahriman/search-line.jinja2 @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/package/share/ahriman/search.jinja2 b/package/share/ahriman/search.jinja2 new file mode 100644 index 00000000..a1c80092 --- /dev/null +++ b/package/share/ahriman/search.jinja2 @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/package/share/ahriman/sorttable.jinja2 b/package/share/ahriman/sorttable.jinja2 new file mode 100644 index 00000000..12a1f08a --- /dev/null +++ b/package/share/ahriman/sorttable.jinja2 @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/package/share/ahriman/style.jinja2 b/package/share/ahriman/style.jinja2 new file mode 100644 index 00000000..59e8cda3 --- /dev/null +++ b/package/share/ahriman/style.jinja2 @@ -0,0 +1,74 @@ + \ No newline at end of file diff --git a/setup.py b/setup.py index b385890c..8d45c432 100644 --- a/setup.py +++ b/setup.py @@ -57,6 +57,10 @@ setup( ('share/ahriman', [ 'package/share/ahriman/build-status.jinja2', 'package/share/ahriman/repo-index.jinja2', + 'package/share/ahriman/search.jinja2', + 'package/share/ahriman/search-line.jinja2', + 'package/share/ahriman/sorttable.jinja2', + 'package/share/ahriman/style.jinja2', ]), ], diff --git a/src/ahriman/application/application.py b/src/ahriman/application/application.py index 0109cff3..7f808639 100644 --- a/src/ahriman/application/application.py +++ b/src/ahriman/application/application.py @@ -47,10 +47,10 @@ class Application: return cls(args.architecture, config) def _known_packages(self) -> Set[str]: - known_packages = set() + known_packages: Set[str] = set() # local set for package in self.repository.packages(): - known_packages.update(package.packages) + known_packages.update(package.packages.keys()) known_packages.update(self.repository.pacman.all_packages()) return known_packages diff --git a/src/ahriman/core/report/html.py b/src/ahriman/core/report/html.py index 3cc6bc88..9d98b443 100644 --- a/src/ahriman/core/report/html.py +++ b/src/ahriman/core/report/html.py @@ -20,11 +20,12 @@ import jinja2 import os -from typing import Dict +from typing import Dict, Iterable from ahriman.core.configuration import Configuration from ahriman.core.report.report import Report from ahriman.core.util import package_like +from ahriman.models.package import Package from ahriman.models.sign_settings import SignSettings @@ -32,37 +33,42 @@ class HTML(Report): def __init__(self, architecture: str, config: Configuration) -> None: Report.__init__(self, architecture, config) + self.architecture = architecture section = config.get_section_name('html', architecture) self.report_path = config.get(section, 'path') - self.link_path = config.get(section, 'link_path') self.template_path = config.get(section, 'template_path') # base template vars - self.sign_targets = [SignSettings.from_option(opt) for opt in config.getlist('sign', 'target')] - self.pgp_key = config.get('sign', 'key', fallback=None) self.homepage = config.get(section, 'homepage', fallback=None) self.repository = config.get('repository', 'name') - def generate(self, path: str) -> None: + sign_section = config.get_section_name('sign', architecture) + self.sign_targets = [SignSettings.from_option(opt) for opt in config.getlist(sign_section, 'target')] + self.pgp_key = config.get(sign_section, 'key') if self.sign_targets else None + + def generate(self, packages: Iterable[Package]) -> None: # idea comes from https://stackoverflow.com/a/38642558 templates_dir, template_name = os.path.split(self.template_path) loader = jinja2.FileSystemLoader(searchpath=templates_dir) environment = jinja2.Environment(loader=loader) template = environment.get_template(template_name) - packages: Dict[str, str] = {} - for fn in sorted(os.listdir(path)): - if not package_like(fn): - continue - packages[fn] = f'{self.link_path}/{fn}' + content = [ + { + 'filename': filename, + 'name': package, + 'version': base.version + } for base in packages for package, filename in base.packages.items() + ] html = template.render( + architecture=self.architecture, homepage=self.homepage, link_path=self.link_path, has_package_signed=SignSettings.SignPackages in self.sign_targets, has_repo_signed=SignSettings.SignRepository in self.sign_targets, - packages=packages, + packages=content, pgp_key=self.pgp_key, repository=self.repository) diff --git a/src/ahriman/core/report/report.py b/src/ahriman/core/report/report.py index 47e3f92a..46716364 100644 --- a/src/ahriman/core/report/report.py +++ b/src/ahriman/core/report/report.py @@ -19,8 +19,11 @@ # import logging +from typing import Iterable + from ahriman.core.configuration import Configuration from ahriman.core.exceptions import ReportFailed +from ahriman.models.package import Package from ahriman.models.report_settings import ReportSettings @@ -32,7 +35,7 @@ class Report: self.config = config @staticmethod - def run(architecture: str, config: Configuration, target: str, path: str) -> None: + def run(architecture: str, config: Configuration, target: str, packages: Iterable[Package]) -> None: provider = ReportSettings.from_option(target) if provider == ReportSettings.HTML: from ahriman.core.report.html import HTML @@ -41,10 +44,10 @@ class Report: report = Report(architecture, config) try: - report.generate(path) + report.generate(packages) except Exception: report.logger.exception('report generation failed', exc_info=True) raise ReportFailed() - def generate(self, path: str) -> None: + def generate(self, packages: Iterable[Package]) -> None: pass \ No newline at end of file diff --git a/src/ahriman/core/repository.py b/src/ahriman/core/repository.py index ee92d981..1f7f3baf 100644 --- a/src/ahriman/core/repository.py +++ b/src/ahriman/core/repository.py @@ -114,11 +114,12 @@ class Repository: except Exception: self.logger.exception(f'could not remove {package}', exc_info=True) + requested = set(packages) for local in self.packages(): if local.base in packages: - to_remove = local.packages - elif local.packages.intersection(packages): - to_remove = local.packages.intersection(packages) + to_remove = set(local.packages.keys()) + elif requested.intersection(local.packages.keys()): + to_remove = requested.intersection(local.packages.keys()) else: to_remove = set() self.web.remove(local.base, to_remove) @@ -131,7 +132,7 @@ class Repository: if targets is None: targets = self.config.getlist('report', 'target') for target in targets: - Report.run(self.architecture, self.config, target, self.paths.repository) + Report.run(self.architecture, self.config, target, self.packages()) def process_sync(self, targets: Optional[Iterable[str]]) -> None: if targets is None: diff --git a/src/ahriman/core/tree.py b/src/ahriman/core/tree.py index e09bf748..7b573c93 100644 --- a/src/ahriman/core/tree.py +++ b/src/ahriman/core/tree.py @@ -61,8 +61,8 @@ class Leaf: :param packages: :return: true if any of packages is dependency of the leaf, false otherwise ''' - for package in packages: - if package.package.packages.intersection(self.dependencies): + for leaf in packages: + if self.dependencies.intersection(leaf.package.packages.keys()): return False return True diff --git a/src/ahriman/models/package.py b/src/ahriman/models/package.py index 76b0483e..6b1a3123 100644 --- a/src/ahriman/models/package.py +++ b/src/ahriman/models/package.py @@ -24,9 +24,9 @@ import os import shutil import tempfile -from dataclasses import dataclass, field +from dataclasses import dataclass from srcinfo.parse import parse_srcinfo -from typing import List, Optional, Set, Type +from typing import Dict, List, Optional, Set, Type from ahriman.core.alpm.pacman import Pacman from ahriman.core.exceptions import InvalidPackageInfo @@ -38,7 +38,7 @@ class Package: base: str version: str aur_url: str - packages: Set[str] = field(default_factory=set) + packages: Dict[str, str] # map of package name to archive name @property def git_url(self) -> str: @@ -82,12 +82,12 @@ class Package: @classmethod def from_archive(cls: Type[Package], path: str, pacman: Pacman, aur_url: str) -> Package: package = pacman.handle.load_pkg(path) - return cls(package.base, package.version, aur_url, {package.name}) + return cls(package.base, package.version, aur_url, {package.name: os.path.basename(path)}) @classmethod def from_aur(cls: Type[Package], name: str, aur_url: str)-> Package: package = aur.info(name) - return cls(package.package_base, package.version, aur_url, {package.name}) + return cls(package.package_base, package.version, aur_url, {package.name: ''}) @classmethod def from_build(cls: Type[Package], path: str, aur_url: str) -> Package: @@ -95,7 +95,7 @@ class Package: src_info, errors = parse_srcinfo(fn.read()) if errors: raise InvalidPackageInfo(errors) - packages = set(src_info['packages'].keys()) + packages = {key: '' for key in src_info['packages'].keys()} version = cls.full_version(src_info.get('epoch'), src_info['pkgver'], src_info['pkgrel']) return cls(src_info['pkgbase'], version, aur_url, packages)