From 3e4185913b584f5cc9a54f16f3c223861e11ec18 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Thu, 16 Apr 2026 17:14:23 +0200 Subject: Introduce a new marco - %e and migrate the project from GitHub to Codeberg --- src/etoolkit/__init__.py | 6 +++--- src/etoolkit/__main__.py | 18 +++++++++--------- src/etoolkit/etoolkit.py | 19 +++++++++++-------- 3 files changed, 23 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/etoolkit/__init__.py b/src/etoolkit/__init__.py index 4cf5d6e..fc32b61 100644 --- a/src/etoolkit/__init__.py +++ b/src/etoolkit/__init__.py @@ -1,5 +1,5 @@ # etoolkit -# Copyright (C) 2021-2024 Simeon Simeonov +# Copyright (C) 2021-2026 Simeon Simeonov # 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 @@ -18,11 +18,11 @@ from .etoolkit import EtoolkitInstance, EtoolkitInstanceError __author__ = 'Simeon Simeonov' -__version__ = '2.1.0' +__version__ = '2.2.0' __license__ = 'GPL3' -def int_or_str(value): +def int_or_str(value: int | str) -> int | str: """Returns int value of value when possible""" try: return int(value) diff --git a/src/etoolkit/__main__.py b/src/etoolkit/__main__.py index a2f2f20..cef3d42 100644 --- a/src/etoolkit/__main__.py +++ b/src/etoolkit/__main__.py @@ -1,5 +1,5 @@ # etoolkit -# Copyright (C) 2021-2024 Simeon Simeonov +# Copyright (C) 2021-2026 Simeon Simeonov # 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 @@ -50,7 +50,7 @@ class EtoolkitCLIHandler: a part of the etoolkit API """ - def __init__(self, args: argparse.Namespace, config_dict: dict): + def __init__(self, args: argparse.Namespace, config_dict: dict) -> None: """ :param args: The parsed argparse arguments sent by the caller :type args: argparse.Namespace @@ -69,7 +69,7 @@ class EtoolkitCLIHandler: self._password_from_env = os.environ.get('ETOOLKIT_MASTER_PASSWORD') - def decrypt_value(self): + def decrypt_value(self) -> None: """ Interactive method for decrypting value(s) @@ -110,7 +110,7 @@ class EtoolkitCLIHandler: break return - def encrypt_value(self): + def encrypt_value(self) -> None: """ Interactive method for encrypting value(s) @@ -155,7 +155,7 @@ class EtoolkitCLIHandler: break return - def generate_master_password_hash(self): + def generate_master_password_hash(self) -> None: """ Interactive method for generating password hash @@ -168,7 +168,7 @@ class EtoolkitCLIHandler: ) print(f'Master password hash: {phash}') - def list(self): + def list(self) -> None: """Lists all instances defined in the config file""" for instance_name in sorted( @@ -179,7 +179,7 @@ class EtoolkitCLIHandler: ): print(instance_name) - def load_instance(self): + def load_instance(self) -> None: """Loads a single specified instance from the config file""" inst = etoolkit.EtoolkitInstance( @@ -208,7 +208,7 @@ class EtoolkitCLIHandler: os.environ.get('SHELL', 'bash').split(), check=False ) - def reencrypt(self): + def reencrypt(self) -> None: """ Interactive method that prints new configuration data (JSON) to stdout @@ -277,7 +277,7 @@ class EtoolkitCLIHandler: ) -def main(inargs=None): +def main(inargs: list = None) -> None: """main entry point""" parser = argparse.ArgumentParser( diff --git a/src/etoolkit/etoolkit.py b/src/etoolkit/etoolkit.py index a933a01..f5ce2a6 100644 --- a/src/etoolkit/etoolkit.py +++ b/src/etoolkit/etoolkit.py @@ -1,5 +1,5 @@ # etoolkit -# Copyright (C) 2021-2024 Simeon Simeonov +# Copyright (C) 2021-2026 Simeon Simeonov # 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 @@ -19,6 +19,7 @@ import base64 import getpass import hashlib import os +from collections.abc import Callable from cryptography.exceptions import InvalidTag from cryptography.hazmat.primitives.ciphers.aead import AESGCM @@ -33,7 +34,7 @@ class EtoolkitInstanceError(Exception): class EtoolkitInstance: """A basic class representing a single instance""" - def __init__(self, name: str, data: dict): + def __init__(self, name: str, data: dict) -> None: """ :param name: Instance name :type name: str @@ -76,14 +77,14 @@ class EtoolkitInstance: ] @property - def master_password(self) -> str: + def master_password(self) -> str | None: """master_password-property""" if self._master_password is not None: return self._master_password return None if self._parent is None else self._parent.master_password @master_password.setter - def master_password(self, value): + def master_password(self, value: str) -> None: """master_password-property setter""" self._master_password = value if self._parent is not None and self._parent.master_password is None: @@ -95,7 +96,7 @@ class EtoolkitInstance: return self._master_password_hash @master_password_hash.setter - def master_password_hash(self, value): + def master_password_hash(self, value: str) -> None: """master_password_hash-property setter""" self._master_password_hash = value @@ -105,12 +106,12 @@ class EtoolkitInstance: return self._name @property - def prompt_func(self): + def prompt_func(self) -> Callable[[str, bool], str]: """prompt_func-property""" return self._prompt_func @prompt_func.setter - def prompt_func(self, value): + def prompt_func(self, value: Callable[[str, bool], str]) -> None: """prompt_func-property setter""" self._prompt_func = value if self._parent is not None and self._parent.prompt_func is None: @@ -294,7 +295,7 @@ class EtoolkitInstance: ) @staticmethod - def parse_value(value, macros: dict): + def parse_value(value: object, macros: dict) -> object: """ Returns the value with all macros replaced by their values @@ -412,6 +413,8 @@ class EtoolkitInstance: if not value: # perhaps unset instead of skipping? continue + if isinstance(value, str) and '%e' in value: + macros['%e'] = os.environ.get(key, '') if isinstance(value, str) and '%p' in value: macros['%p'] = ( self._parent.get_environ().get(key, '') -- cgit v1.3