diff --git a/src/ahriman/application/ahriman.py b/src/ahriman/application/ahriman.py index 700ef539..e1879057 100644 --- a/src/ahriman/application/ahriman.py +++ b/src/ahriman/application/ahriman.py @@ -86,7 +86,7 @@ def _parser() -> argparse.ArgumentParser: action="store_true") parser.add_argument("--wait-timeout", help="wait for lock to be free. Negative value will lead to " "immediate application run even if there is lock file. " - "In case of zero value, tthe application will wait infinitely", + "In case of zero value, the application will wait infinitely", type=int, default=-1) parser.add_argument("-V", "--version", action="version", version=__version__) diff --git a/src/ahriman/application/application/application_packages.py b/src/ahriman/application/application/application_packages.py index 7aa3884f..2a6f9572 100644 --- a/src/ahriman/application/application/application_packages.py +++ b/src/ahriman/application/application/application_packages.py @@ -117,7 +117,6 @@ class ApplicationPackages(ApplicationProperties): Raises: UnknownPackageError: if specified package is unknown or doesn't exist """ - dst = self.repository.paths.packages / Path(source).name # URL is path, is not it? # timeout=None to suppress pylint warns. Also suppress bandit warnings try: response = requests.get(source, stream=True, timeout=None) # nosec @@ -125,6 +124,7 @@ class ApplicationPackages(ApplicationProperties): except Exception: raise UnknownPackageError(source) + dst = self.repository.paths.packages / Path(source).name # URL is path, is not it? with dst.open("wb") as local_file: for chunk in response.iter_content(chunk_size=1024): local_file.write(chunk) diff --git a/src/ahriman/application/handlers/handler.py b/src/ahriman/application/handlers/handler.py index 28744aaf..c5c61be2 100644 --- a/src/ahriman/application/handlers/handler.py +++ b/src/ahriman/application/handlers/handler.py @@ -94,10 +94,13 @@ class Handler: """ try: configuration = Configuration.from_path(args.configuration, architecture) + log_handler = Log.handler(args.log_handler) Log.load(configuration, log_handler, quiet=args.quiet, report=args.report) + with Lock(args, architecture, configuration): cls.run(args, architecture, configuration, report=args.report) + return True except ExitCode: return False @@ -128,8 +131,7 @@ class Handler: raise MultipleArchitecturesError(args.command) with Pool(len(architectures)) as pool: - result = pool.starmap( - cls.call, [(args, architecture) for architecture in architectures]) + result = pool.starmap(cls.call, [(args, architecture) for architecture in architectures]) else: result = [cls.call(args, architectures.pop())] diff --git a/src/ahriman/application/handlers/patch.py b/src/ahriman/application/handlers/patch.py index 7fcfcdb0..30c2ec13 100644 --- a/src/ahriman/application/handlers/patch.py +++ b/src/ahriman/application/handlers/patch.py @@ -51,16 +51,17 @@ class Patch(Handler): application = Application(architecture, configuration, report=report) application.on_start() - if args.action == Action.Update and args.variable is not None: - patch = Patch.patch_create_from_function(args.variable, args.patch) - Patch.patch_set_create(application, args.package, patch) - elif args.action == Action.Update and args.variable is None: - package_base, patch = Patch.patch_create_from_diff(args.package, architecture, args.track) - Patch.patch_set_create(application, package_base, patch) - elif args.action == Action.List: - Patch.patch_set_list(application, args.package, args.variable, args.exit_code) - elif args.action == Action.Remove: - Patch.patch_set_remove(application, args.package, args.variable) + match args.action: + case Action.Update if args.variable is not None: + patch = Patch.patch_create_from_function(args.variable, args.patch) + Patch.patch_set_create(application, args.package, patch) + case Action.Update: + package_base, patch = Patch.patch_create_from_diff(args.package, architecture, args.track) + Patch.patch_set_create(application, package_base, patch) + case Action.List: + Patch.patch_set_list(application, args.package, args.variable, args.exit_code) + case Action.Remove: + Patch.patch_set_remove(application, args.package, args.variable) @staticmethod def patch_create_from_diff(sources_dir: Path, architecture: str, track: list[str]) -> tuple[str, PkgbuildPatch]: diff --git a/src/ahriman/application/handlers/service_updates.py b/src/ahriman/application/handlers/service_updates.py index 1a27b3f2..96e2f550 100644 --- a/src/ahriman/application/handlers/service_updates.py +++ b/src/ahriman/application/handlers/service_updates.py @@ -48,7 +48,7 @@ class ServiceUpdates(Handler): application = Application(architecture, configuration, report=report) remote = Package.from_aur("ahriman", application.repository.pacman, None) - release = remote.version.rsplit("-", 1)[-1] # we don't store pkgrel locally, so we just append it + _, release = remote.version.rsplit("-", 1) # we don't store pkgrel locally, so we just append it local_version = f"{__version__}-{release}" # technically we would like to compare versions, but it is fine to raise an exception in case if locally diff --git a/src/ahriman/application/handlers/status_update.py b/src/ahriman/application/handlers/status_update.py index ef3ebecf..803ca8e5 100644 --- a/src/ahriman/application/handlers/status_update.py +++ b/src/ahriman/application/handlers/status_update.py @@ -46,13 +46,14 @@ class StatusUpdate(Handler): # we are using reporter here client = Application(architecture, configuration, report=True).repository.reporter - if args.action == Action.Update and args.package: - # update packages statuses - for package in args.package: - client.package_update(package, args.status) - elif args.action == Action.Update: - # update service status - client.status_update(args.status) - elif args.action == Action.Remove: - for package in args.package: - client.package_remove(package) + match args.action: + case Action.Update if args.package: + # update packages statuses + for package in args.package: + client.package_update(package, args.status) + case Action.Update: + # update service status + client.status_update(args.status) + case Action.Remove: + for package in args.package: + client.package_remove(package) diff --git a/src/ahriman/application/handlers/users.py b/src/ahriman/application/handlers/users.py index d8cd4238..92a33b70 100644 --- a/src/ahriman/application/handlers/users.py +++ b/src/ahriman/application/handlers/users.py @@ -49,18 +49,19 @@ class Users(Handler): """ database = SQLite.load(configuration) - if args.action == Action.Update: - user = Users.user_create(args) - # if password is left blank we are not going to require salt to be set - salt = configuration.get("auth", "salt", fallback="") if user.password else "" - database.user_update(user.hash_password(salt)) - elif args.action == Action.List: - users = database.user_list(args.username, args.role) - Users.check_if_empty(args.exit_code, not users) - for user in users: - UserPrinter(user).print(verbose=True) - elif args.action == Action.Remove: - database.user_remove(args.username) + match args.action: + case Action.Update: + user = Users.user_create(args) + # if password is left blank we are not going to require salt to be set + salt = configuration.get("auth", "salt", fallback="") if user.password else "" + database.user_update(user.hash_password(salt)) + case Action.List: + users = database.user_list(args.username, args.role) + Users.check_if_empty(args.exit_code, not users) + for user in users: + UserPrinter(user).print(verbose=True) + case Action.Remove: + database.user_remove(args.username) @staticmethod def user_create(args: argparse.Namespace) -> User: diff --git a/src/ahriman/core/alpm/pacman.py b/src/ahriman/core/alpm/pacman.py index 461a980e..6fb56540 100644 --- a/src/ahriman/core/alpm/pacman.py +++ b/src/ahriman/core/alpm/pacman.py @@ -49,6 +49,16 @@ class Pacman(LazyLogging): self.__create_handle_fn: Callable[[], Handle] = lambda: self.__create_handle( architecture, configuration, refresh_database=refresh_database) + @cached_property + def handle(self) -> Handle: + """ + pyalpm handle + + Returns: + Handle: generated pyalpm handle instance + """ + return self.__create_handle_fn() + def __create_handle(self, architecture: str, configuration: Configuration, *, refresh_database: PacmanSynchronization) -> Handle: """ @@ -79,16 +89,6 @@ class Pacman(LazyLogging): return handle - @cached_property - def handle(self) -> Handle: - """ - pyalpm handle - - Returns: - Handle: generated pyalpm handle instance - """ - return self.__create_handle_fn() - def database_copy(self, handle: Handle, database: DB, pacman_root: Path, paths: RepositoryPaths, *, use_ahriman_cache: bool) -> None: """ @@ -116,7 +116,7 @@ class Pacman(LazyLogging): src = repository_database(pacman_root) if not src.is_file(): self.logger.warning("repository %s is set to be used, however, no working copy was found", database.name) - return # database for some reasons deos not exist + return # database for some reason deos not exist self.logger.info("copy pacman database from operating system root to ahriman's home") shutil.copy(src, dst) paths.chown(dst) diff --git a/src/ahriman/core/auth/auth.py b/src/ahriman/core/auth/auth.py index e9316ce0..da3763c1 100644 --- a/src/ahriman/core/auth/auth.py +++ b/src/ahriman/core/auth/auth.py @@ -74,14 +74,15 @@ class Auth(LazyLogging): Returns: Auth: authorization module according to current settings """ - provider = AuthSettings.from_option(configuration.get("auth", "target", fallback="disabled")) - if provider == AuthSettings.Configuration: - from ahriman.core.auth.mapping import Mapping - return Mapping(configuration, database) - if provider == AuthSettings.OAuth: - from ahriman.core.auth.oauth import OAuth - return OAuth(configuration, database) - return Auth(configuration) + match AuthSettings.from_option(configuration.get("auth", "target", fallback="disabled")): + case AuthSettings.Configuration: + from ahriman.core.auth.mapping import Mapping + return Mapping(configuration, database) + case AuthSettings.OAuth: + from ahriman.core.auth.oauth import OAuth + return OAuth(configuration, database) + case _: + return Auth(configuration) async def check_credentials(self, username: str | None, password: str | None) -> bool: """ diff --git a/src/ahriman/core/auth/oauth.py b/src/ahriman/core/auth/oauth.py index a12c5386..55ec7be4 100644 --- a/src/ahriman/core/auth/oauth.py +++ b/src/ahriman/core/auth/oauth.py @@ -28,8 +28,8 @@ from ahriman.models.auth_settings import AuthSettings class OAuth(Mapping): """ - OAuth's user authorization. - It is required to create application first and put application credentials. + User authorization implementation via OAuth. It is required to create application first and put application + credentials. Attributes: client_id(str): application client id diff --git a/src/ahriman/core/configuration/schema.py b/src/ahriman/core/configuration/schema.py index 1dfc833d..4bbc1bdd 100644 --- a/src/ahriman/core/configuration/schema.py +++ b/src/ahriman/core/configuration/schema.py @@ -266,6 +266,11 @@ CONFIGURATION_SCHEMA: ConfigurationSchema = { "required": True, "path_exists": True, }, + "timeout": { + "type": "integer", + "coerce": "integer", + "min": 0, + }, "unix_socket": { "type": "path", "coerce": "absolute_path", diff --git a/src/ahriman/core/configuration/validator.py b/src/ahriman/core/configuration/validator.py index bf146de2..e7499bc3 100644 --- a/src/ahriman/core/configuration/validator.py +++ b/src/ahriman/core/configuration/validator.py @@ -136,13 +136,13 @@ class Validator(RootValidator): The rule's arguments are validated against this schema: {"type": "list", "schema": {"type": "string"}} """ - url = urlparse(value) # it probably will never rise exceptions on parse - if not url.scheme: - self._error(field, f"Url scheme is not set for {value}") - if not url.netloc and url.scheme not in ("file",): - self._error(field, f"Location must be set for url {value} of scheme {url.scheme}") - if constraint and url.scheme not in constraint: - self._error(field, f"Url {value} scheme must be one of {constraint}") + match urlparse(value): # it probably will never rise exceptions on parse + case url if not url.scheme: + self._error(field, f"Url scheme is not set for {value}") + case url if not url.netloc and url.scheme not in ("file",): + self._error(field, f"Location must be set for url {value} of scheme {url.scheme}") + case url if constraint and url.scheme not in constraint: + self._error(field, f"Url {value} scheme must be one of {constraint}") def _validate_path_exists(self, constraint: bool, field: str, value: Path) -> None: """ @@ -157,7 +157,8 @@ class Validator(RootValidator): The rule's arguments are validated against this schema: {"type": "boolean"} """ - if constraint and not value.exists(): - self._error(field, f"Path {value} must exist") - if not constraint and value.exists(): - self._error(field, f"Path {value} must not exist") + match value.exists(): + case True if not constraint: + self._error(field, f"Path {value} must not exist") + case False if constraint: + self._error(field, f"Path {value} must exist") diff --git a/src/ahriman/core/report/report.py b/src/ahriman/core/report/report.py index b4d5862d..392837fb 100644 --- a/src/ahriman/core/report/report.py +++ b/src/ahriman/core/report/report.py @@ -80,23 +80,24 @@ class Report(LazyLogging): Report: client according to current settings """ section, provider_name = configuration.gettype(target, architecture) - provider = ReportSettings.from_option(provider_name) - if provider == ReportSettings.HTML: - from ahriman.core.report.html import HTML - return HTML(architecture, configuration, section) - if provider == ReportSettings.Email: - from ahriman.core.report.email import Email - return Email(architecture, configuration, section) - if provider == ReportSettings.Console: - from ahriman.core.report.console import Console - return Console(architecture, configuration, section) - if provider == ReportSettings.Telegram: - from ahriman.core.report.telegram import Telegram - return Telegram(architecture, configuration, section) - if provider == ReportSettings.RemoteCall: - from ahriman.core.report.remote_call import RemoteCall - return RemoteCall(architecture, configuration, section) - return Report(architecture, configuration) # should never happen + match ReportSettings.from_option(provider_name): + case ReportSettings.HTML: + from ahriman.core.report.html import HTML + return HTML(architecture, configuration, section) + case ReportSettings.Email: + from ahriman.core.report.email import Email + return Email(architecture, configuration, section) + case ReportSettings.Console: + from ahriman.core.report.console import Console + return Console(architecture, configuration, section) + case ReportSettings.Telegram: + from ahriman.core.report.telegram import Telegram + return Telegram(architecture, configuration, section) + case ReportSettings.RemoteCall: + from ahriman.core.report.remote_call import RemoteCall + return RemoteCall(architecture, configuration, section) + case _: + return Report(architecture, configuration) # should never happen def generate(self, packages: list[Package], result: Result) -> None: """ diff --git a/src/ahriman/core/repository/repository.py b/src/ahriman/core/repository/repository.py index dbedc455..90f519d4 100644 --- a/src/ahriman/core/repository/repository.py +++ b/src/ahriman/core/repository/repository.py @@ -40,7 +40,7 @@ class Repository(Executor, UpdateHandler): Examples: This class along with traits provides access to local repository actions, e.g. remove packages, update packages, - sync local repository to remote, generate report, etc:: + sync local repository to remote, generate report, etc.:: >>> from ahriman.core.configuration import Configuration >>> from ahriman.core.database import SQLite diff --git a/src/ahriman/core/sign/gpg.py b/src/ahriman/core/sign/gpg.py index 99fd15ec..30f26373 100644 --- a/src/ahriman/core/sign/gpg.py +++ b/src/ahriman/core/sign/gpg.py @@ -33,7 +33,7 @@ class GPG(SyncHttpClient): Attributes: configuration(Configuration): configuration instance default_key(str | None): default PGP key ID to use - targets(set[SignSettings]): list of targets to sign (repository, package etc) + targets(set[SignSettings]): list of targets to sign (repository, package etc.) """ _check_output = check_output @@ -116,7 +116,7 @@ class GPG(SyncHttpClient): download key from public PGP server Args: - server(str): public PGP server which will be used to download the key + server(str): public PGP server which will be used to download data key(str): key ID to download Returns: @@ -163,7 +163,7 @@ class GPG(SyncHttpClient): import key to current user and sign it locally Args: - server(str): public PGP server which will be used to download the key + server(str): public PGP server which will be used to download data key(str): key ID to import """ key_body = self.key_download(server, key) diff --git a/src/ahriman/core/status/watcher.py b/src/ahriman/core/status/watcher.py index 9816c4ea..d2ec7cad 100644 --- a/src/ahriman/core/status/watcher.py +++ b/src/ahriman/core/status/watcher.py @@ -113,7 +113,7 @@ class Watcher(LazyLogging): Args: log_record_id(LogRecordId): log record id - created(float): log created record + created(float): log created timestamp record(str): log record """ if self._last_log_record_id != log_record_id: diff --git a/src/ahriman/core/tree.py b/src/ahriman/core/tree.py index 49ee6149..e1550b06 100644 --- a/src/ahriman/core/tree.py +++ b/src/ahriman/core/tree.py @@ -92,7 +92,7 @@ class Tree: dependency tree implementation Attributes: - leaves[list[Leaf]): list of tree leaves + leaves(list[Leaf]): list of tree leaves Examples: The most important feature here is to generate tree levels one by one which can be achieved by using class diff --git a/src/ahriman/core/upload/github.py b/src/ahriman/core/upload/github.py index 19062036..5002b2a6 100644 --- a/src/ahriman/core/upload/github.py +++ b/src/ahriman/core/upload/github.py @@ -31,11 +31,11 @@ from ahriman.models.package import Package class Github(HttpUpload): """ - upload files to github releases + upload files to GitHub releases Attributes: - github_owner(str): github repository owner - github_repository(str): github repository name + github_owner(str): GitHub repository owner + github_repository(str): GitHub repository name """ def __init__(self, architecture: str, configuration: Configuration, section: str) -> None: @@ -100,7 +100,7 @@ class Github(HttpUpload): def files_remove(self, release: dict[str, Any], local_files: dict[Path, str], remote_files: dict[str, str]) -> None: """ - remove files from github + remove files from GitHub Args: release(dict[str, Any]): release object @@ -115,7 +115,7 @@ class Github(HttpUpload): def files_upload(self, release: dict[str, Any], local_files: dict[Path, str], remote_files: dict[str, str]) -> None: """ - upload files to github + upload files to GitHub Args: release(dict[str, Any]): release object @@ -133,7 +133,7 @@ class Github(HttpUpload): create empty release Returns: - dict[str, Any]: github API release object for the new release + dict[str, Any]: GitHub API release object for the new release """ url = f"https://api.github.com/repos/{self.github_owner}/{self.github_repository}/releases" response = self.make_request("POST", url, json={"tag_name": self.architecture, "name": self.architecture}) @@ -145,7 +145,7 @@ class Github(HttpUpload): get release object if any Returns: - dict[str, Any] | None: github API release object if release found and None otherwise + dict[str, Any] | None: GitHub API release object if release found and None otherwise """ url = f"https://api.github.com/repos/{self.github_owner}/{self.github_repository}/releases/tags/{self.architecture}" try: diff --git a/src/ahriman/core/upload/upload.py b/src/ahriman/core/upload/upload.py index ce443b87..83df31ae 100644 --- a/src/ahriman/core/upload/upload.py +++ b/src/ahriman/core/upload/upload.py @@ -80,20 +80,21 @@ class Upload(LazyLogging): Upload: client according to current settings """ section, provider_name = configuration.gettype(target, architecture) - provider = UploadSettings.from_option(provider_name) - if provider == UploadSettings.Rsync: - from ahriman.core.upload.rsync import Rsync - return Rsync(architecture, configuration, section) - if provider == UploadSettings.S3: - from ahriman.core.upload.s3 import S3 - return S3(architecture, configuration, section) - if provider == UploadSettings.Github: - from ahriman.core.upload.github import Github - return Github(architecture, configuration, section) - if provider == UploadSettings.RemoteService: - from ahriman.core.upload.remote_service import RemoteService - return RemoteService(architecture, configuration, section) - return Upload(architecture, configuration) # should never happen + match UploadSettings.from_option(provider_name): + case UploadSettings.Rsync: + from ahriman.core.upload.rsync import Rsync + return Rsync(architecture, configuration, section) + case UploadSettings.S3: + from ahriman.core.upload.s3 import S3 + return S3(architecture, configuration, section) + case UploadSettings.GitHub: + from ahriman.core.upload.github import Github + return Github(architecture, configuration, section) + case UploadSettings.RemoteService: + from ahriman.core.upload.remote_service import RemoteService + return RemoteService(architecture, configuration, section) + case _: + return Upload(architecture, configuration) # should never happen def run(self, path: Path, built_packages: list[Package]) -> None: """ diff --git a/src/ahriman/core/upload/upload_trigger.py b/src/ahriman/core/upload/upload_trigger.py index 75caa759..0ccdfe15 100644 --- a/src/ahriman/core/upload/upload_trigger.py +++ b/src/ahriman/core/upload/upload_trigger.py @@ -99,6 +99,11 @@ class UploadTrigger(Trigger): "type": "string", "allowed": ["ahriman", "remote-service"], }, + "timeout": { + "type": "integer", + "coerce": "integer", + "min": 0, + }, }, }, "s3": { diff --git a/src/ahriman/core/util.py b/src/ahriman/core/util.py index c1791c80..37872d3a 100644 --- a/src/ahriman/core/util.py +++ b/src/ahriman/core/util.py @@ -334,7 +334,7 @@ def pretty_size(size: float | None, level: int = 0) -> str: Args: size(float | None): size to convert - level(int, optional): represents current units, 0 is B, 1 is KiB, etc (Default value = 0) + level(int, optional): represents current units, 0 is B, 1 is KiB, etc. (Default value = 0) Returns: str: pretty printable size as string @@ -343,15 +343,17 @@ def pretty_size(size: float | None, level: int = 0) -> str: OptionError: if size is more than 1TiB """ def str_level() -> str: - if level == 0: - return "B" - if level == 1: - return "KiB" - if level == 2: - return "MiB" - if level == 3: - return "GiB" - raise OptionError(level) # must never happen actually + match level: + case 0: + return "B" + case 1: + return "KiB" + case 2: + return "MiB" + case 3: + return "GiB" + case _: + raise OptionError(level) # must never happen actually if size is None: return "" @@ -389,7 +391,7 @@ def srcinfo_property(key: str, srcinfo: dict[str, Any], package_srcinfo: dict[st returned Args: - key(str): key to extract from srcinfo + key(str): key to extract srcinfo(dict[str, Any]): root structure of SRCINFO package_srcinfo(dict[str, Any]): package specific SRCINFO default(Any, optional): the default value for the specified key (Default value = None) @@ -408,7 +410,7 @@ def srcinfo_property_list(key: str, srcinfo: dict[str, Any], package_srcinfo: di append it at the end of result Args: - key(str): key to extract from srcinfo + key(str): key to extract srcinfo(dict[str, Any]): root structure of SRCINFO package_srcinfo(dict[str, Any]): package specific SRCINFO architecture(str | None, optional): package architecture if set (Default value = None) @@ -424,9 +426,9 @@ def srcinfo_property_list(key: str, srcinfo: dict[str, Any], package_srcinfo: di def trim_package(package_name: str) -> str: """ - remove version bound and description from package name. Pacman allows to specify version bound (=, <=, >= etc) for - packages in dependencies and also allows to specify description (via :); this function removes trailing parts and - return exact package name + remove version bound and description from package name. Pacman allows to specify version bound (=, <=, >= etc.) for + packages in dependencies and also allows to specify description (via ``:``); this function removes trailing parts + and return exact package name Args: package_name(str): source package name diff --git a/src/ahriman/models/auth_settings.py b/src/ahriman/models/auth_settings.py index c036be54..f308be1f 100644 --- a/src/ahriman/models/auth_settings.py +++ b/src/ahriman/models/auth_settings.py @@ -44,9 +44,7 @@ class AuthSettings(str, Enum): Returns: bool: False in case if authorization is disabled and True otherwise """ - if self == AuthSettings.Disabled: - return False - return True + return self != AuthSettings.Disabled @staticmethod def from_option(value: str) -> AuthSettings: @@ -59,8 +57,10 @@ class AuthSettings(str, Enum): Returns: AuthSettings: parsed value """ - if value.lower() in ("configuration", "mapping"): - return AuthSettings.Configuration - if value.lower() in ("oauth", "oauth2"): - return AuthSettings.OAuth - return AuthSettings.Disabled + match value.lower(): + case "configuration" | "mapping": + return AuthSettings.Configuration + case "oauth" | "oauth2": + return AuthSettings.OAuth + case _: + return AuthSettings.Disabled diff --git a/src/ahriman/models/remote_source.py b/src/ahriman/models/remote_source.py index 5d7cfaa1..c10bc9e5 100644 --- a/src/ahriman/models/remote_source.py +++ b/src/ahriman/models/remote_source.py @@ -64,7 +64,7 @@ class RemoteSource: @property def pkgbuild_dir(self) -> Path | None: """ - get path to directory with package sources (PKGBUILD etc) + get path to directory with package sources (PKGBUILD etc.) Returns: Path | None: path to directory with package sources based on settings if available diff --git a/src/ahriman/models/report_settings.py b/src/ahriman/models/report_settings.py index 7b086636..f4f03048 100644 --- a/src/ahriman/models/report_settings.py +++ b/src/ahriman/models/report_settings.py @@ -53,14 +53,16 @@ class ReportSettings(str, Enum): Returns: ReportSettings: parsed value """ - if value.lower() in ("html",): - return ReportSettings.HTML - if value.lower() in ("email",): - return ReportSettings.Email - if value.lower() in ("console",): - return ReportSettings.Console - if value.lower() in ("telegram",): - return ReportSettings.Telegram - if value.lower() in ("ahriman", "remote-call",): - return ReportSettings.RemoteCall - return ReportSettings.Disabled + match value.lower(): + case "html": + return ReportSettings.HTML + case "email": + return ReportSettings.Email + case "console": + return ReportSettings.Console + case "telegram": + return ReportSettings.Telegram + case "ahriman" | "remote-call": + return ReportSettings.RemoteCall + case _: + return ReportSettings.Disabled diff --git a/src/ahriman/models/repository_paths.py b/src/ahriman/models/repository_paths.py index 20282fc6..b7fbd4f1 100644 --- a/src/ahriman/models/repository_paths.py +++ b/src/ahriman/models/repository_paths.py @@ -32,8 +32,8 @@ class RepositoryPaths: repository paths holder. For the most operations with paths you want to use this object Attributes: - root(Path): repository root (i.e. ahriman home) architecture(str): repository architecture + root(Path): repository root (i.e. ahriman home) Examples: This class can be used in order to access the repository tree structure:: diff --git a/src/ahriman/models/sign_settings.py b/src/ahriman/models/sign_settings.py index 73dd51d9..c9222a4e 100644 --- a/src/ahriman/models/sign_settings.py +++ b/src/ahriman/models/sign_settings.py @@ -47,8 +47,10 @@ class SignSettings(str, Enum): Returns: SignSettings: parsed value """ - if value.lower() in ("package", "packages", "sign-package"): - return SignSettings.Packages - if value.lower() in ("repository", "sign-repository"): - return SignSettings.Repository - return SignSettings.Disabled + match value.lower(): + case "package" | "packages" | "sign-package": + return SignSettings.Packages + case "repository" | "sign-repository": + return SignSettings.Repository + case _: + return SignSettings.Disabled diff --git a/src/ahriman/models/smtp_ssl_settings.py b/src/ahriman/models/smtp_ssl_settings.py index e7eac78b..5a079095 100644 --- a/src/ahriman/models/smtp_ssl_settings.py +++ b/src/ahriman/models/smtp_ssl_settings.py @@ -47,8 +47,10 @@ class SmtpSSLSettings(str, Enum): Returns: SmtpSSLSettings: parsed value """ - if value.lower() in ("ssl", "ssl/tls"): - return SmtpSSLSettings.SSL - if value.lower() in ("starttls",): - return SmtpSSLSettings.STARTTLS - return SmtpSSLSettings.Disabled + match value.lower(): + case "ssl" | "ssl/tls": + return SmtpSSLSettings.SSL + case "starttls": + return SmtpSSLSettings.STARTTLS + case _: + return SmtpSSLSettings.Disabled diff --git a/src/ahriman/models/upload_settings.py b/src/ahriman/models/upload_settings.py index 02f7a738..6a2cd034 100644 --- a/src/ahriman/models/upload_settings.py +++ b/src/ahriman/models/upload_settings.py @@ -30,14 +30,14 @@ class UploadSettings(str, Enum): Disabled(UploadSettings): (class attribute) no sync will be performed, required for testing purpose Rsync(UploadSettings): (class attribute) sync via rsync S3(UploadSettings): (class attribute) sync to Amazon S3 - Github(UploadSettings): (class attribute) sync to github releases page + GitHub(UploadSettings): (class attribute) sync to GitHub releases page RemoteService(UploadSettings): (class attribute) sync to another ahriman instance """ Disabled = "disabled" # for testing purpose Rsync = "rsync" S3 = "s3" - Github = "github" + GitHub = "github" RemoteService = "remote-service" @staticmethod @@ -51,12 +51,14 @@ class UploadSettings(str, Enum): Returns: UploadSettings: parsed value """ - if value.lower() in ("rsync",): - return UploadSettings.Rsync - if value.lower() in ("s3",): - return UploadSettings.S3 - if value.lower() in ("github",): - return UploadSettings.Github - if value.lower() in ("ahriman", "remote-service",): - return UploadSettings.RemoteService - return UploadSettings.Disabled + match value.lower(): + case "rsync": + return UploadSettings.Rsync + case "s3": + return UploadSettings.S3 + case "github": + return UploadSettings.GitHub + case "ahriman" | "remote-service": + return UploadSettings.RemoteService + case _: + return UploadSettings.Disabled diff --git a/src/ahriman/web/middlewares/auth_handler.py b/src/ahriman/web/middlewares/auth_handler.py index f2bc0a35..ab741945 100644 --- a/src/ahriman/web/middlewares/auth_handler.py +++ b/src/ahriman/web/middlewares/auth_handler.py @@ -102,6 +102,7 @@ def _auth_handler(allow_read_only: bool) -> MiddlewareType: permission = UserAccess.Unauthorized if isinstance(handler_instance, StaticResource) else UserAccess.Full else: permission = UserAccess.Full + if permission == UserAccess.Unauthorized: # explicit if elif else for better code coverage pass elif allow_read_only and UserAccess.Read.permits(permission): diff --git a/src/ahriman/web/views/base.py b/src/ahriman/web/views/base.py index 6fd89913..1ca1e440 100644 --- a/src/ahriman/web/views/base.py +++ b/src/ahriman/web/views/base.py @@ -107,7 +107,7 @@ class BaseView(View, CorsViewMixin): get non-empty value from request parameters Args: - extractor(Callable[[str], T | None]): function to get value by the specified key + extractor(Callable[[str], T | None]): function to get value key(str): key to extract value Returns: diff --git a/tests/ahriman/application/handlers/test_handler_service_updates.py b/tests/ahriman/application/handlers/test_handler_service_updates.py index e6be1e33..f09f6caf 100644 --- a/tests/ahriman/application/handlers/test_handler_service_updates.py +++ b/tests/ahriman/application/handlers/test_handler_service_updates.py @@ -28,7 +28,7 @@ def test_run(args: argparse.Namespace, configuration: Configuration, repository: """ must run command """ - package_ahriman.version = "0.0.0" + package_ahriman.version = "0.0.0-1" args = _default_args(args) mocker.patch("ahriman.core.repository.Repository.load", return_value=repository) package_mock = mocker.patch("ahriman.models.package.Package.from_aur", return_value=package_ahriman) diff --git a/tests/ahriman/models/test_upload_settings.py b/tests/ahriman/models/test_upload_settings.py index 02e82fed..f8d0b089 100644 --- a/tests/ahriman/models/test_upload_settings.py +++ b/tests/ahriman/models/test_upload_settings.py @@ -18,8 +18,8 @@ def test_from_option_valid() -> None: assert UploadSettings.from_option("s3") == UploadSettings.S3 assert UploadSettings.from_option("S3") == UploadSettings.S3 - assert UploadSettings.from_option("github") == UploadSettings.Github - assert UploadSettings.from_option("GitHub") == UploadSettings.Github + assert UploadSettings.from_option("github") == UploadSettings.GitHub + assert UploadSettings.from_option("GitHub") == UploadSettings.GitHub assert UploadSettings.from_option("remote-service") == UploadSettings.RemoteService assert UploadSettings.from_option("Remote-Service") == UploadSettings.RemoteService