diff --git a/package/share/ahriman/repo-index.jinja2 b/package/share/ahriman/repo-index.jinja2 index 754d1e26..de74ceea 100644 --- a/package/share/ahriman/repo-index.jinja2 +++ b/package/share/ahriman/repo-index.jinja2 @@ -33,12 +33,14 @@ package version + installed size {% for package in packages %} {{ package.name|e }} {{ package.version|e }} + {{ package.installed_size|e }} {% endfor %} diff --git a/src/ahriman/core/report/html.py b/src/ahriman/core/report/html.py index e6a65e34..6ea46a52 100644 --- a/src/ahriman/core/report/html.py +++ b/src/ahriman/core/report/html.py @@ -25,6 +25,7 @@ from typing import Callable, Dict, Iterable from ahriman.core.configuration import Configuration from ahriman.core.report.report import Report from ahriman.models.package import Package +from ahriman.models.package_desciption import PackageDescription from ahriman.models.sign_settings import SignSettings @@ -38,7 +39,7 @@ class HTML(Report): link_path - prefix fo packages to download, string, required has_package_signed - True in case if package sign enabled, False otherwise, required has_repo_signed - True in case if repository database sign enabled, False otherwise, required - packages - sorted list of packages properties: filename, name, version. Required + packages - sorted list of packages properties: filename, installed_size, name, version. Required pgp_key - default PGP key ID, string, optional repository - repository name, string, required @@ -84,10 +85,11 @@ class HTML(Report): content = [ { - 'filename': filename, + 'filename': properties.filename, + 'installed_size': PackageDescription.size_to_str(properties.installed_size), 'name': package, 'version': base.version - } for base in packages for package, filename in base.packages.items() + } for base in packages for package, properties in base.packages.items() ] comparator: Callable[[Dict[str, str]], str] = lambda item: item['filename'] diff --git a/src/ahriman/models/package.py b/src/ahriman/models/package.py index 748e43ca..8e99f738 100644 --- a/src/ahriman/models/package.py +++ b/src/ahriman/models/package.py @@ -32,6 +32,7 @@ from typing import Dict, List, Optional, Set, Type from ahriman.core.alpm.pacman import Pacman from ahriman.core.exceptions import InvalidPackageInfo from ahriman.core.util import check_output +from ahriman.models.package_desciption import PackageDescription @dataclass @@ -40,14 +41,14 @@ class Package: package properties representation :ivar aurl_url: AUR root url :ivar base: package base name - :ivar packages: map of package names to archive name + :ivar packages: map of package names to their properties. Filled only on load from archive :ivar version: package full version ''' base: str version: str aur_url: str - packages: Dict[str, str] + packages: Dict[str, PackageDescription] @property def git_url(self) -> str: @@ -110,7 +111,8 @@ class Package: :return: package properties ''' package = pacman.handle.load_pkg(path) - return cls(package.base, package.version, aur_url, {package.name: os.path.basename(path)}) + properties = PackageDescription(os.path.basename(path), package.isize) + return cls(package.base, package.version, aur_url, {package.name: properties}) @classmethod def from_aur(cls: Type[Package], name: str, aur_url: str) -> Package: @@ -121,7 +123,7 @@ class Package: :return: package properties ''' 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: PackageDescription()}) @classmethod def from_build(cls: Type[Package], path: str, aur_url: str) -> Package: @@ -135,7 +137,7 @@ class Package: src_info, errors = parse_srcinfo(fn.read()) if errors: raise InvalidPackageInfo(errors) - packages = {key: '' for key in src_info['packages'].keys()} + packages = {key: PackageDescription() 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) diff --git a/src/ahriman/models/package_desciption.py b/src/ahriman/models/package_desciption.py new file mode 100644 index 00000000..4ad0b299 --- /dev/null +++ b/src/ahriman/models/package_desciption.py @@ -0,0 +1,57 @@ +# +# Copyright (c) 2021 Evgenii Alekseev. +# +# This file is part of ahriman +# (see https://github.com/arcan1s/ahriman). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +from dataclasses import dataclass +from typing import Optional + +from ahriman.core.exceptions import InvalidOption + + +@dataclass +class PackageDescription: + ''' + package specific properties + ''' + filename: Optional[str] = None + installed_size: Optional[int] = None + + @staticmethod + def size_to_str(size: Optional[float], level: int = 0) -> str: + ''' + convert size to string + :param size: size to convert + :param level: represents current units, 0 is B, 1 is KiB etc + :return: pretty printable size as string + ''' + def str_level() -> str: + if level == 0: + return 'B' + elif level == 1: + return 'KiB' + elif level == 2: + return 'MiB' + elif level == 3: + return 'GiB' + raise InvalidOption(level) + + if size is None: + return '' + elif size < 1024: + return f'{round(size, 2)} {str_level()}' + return PackageDescription.size_to_str(size / 1024, level + 1)