diff --git a/src/linktools/cli/command.py b/src/linktools/cli/command.py index 062a46eb..7447b317 100644 --- a/src/linktools/cli/command.py +++ b/src/linktools/cli/command.py @@ -789,7 +789,7 @@ def __call__(self, parser, namespace, values, option_string=None): handler.show_level = value environ.set_config("SHOW_LOG_LEVEL", value) - group = parser.add_argument_group(title="log options").add_mutually_exclusive_group() + group = parser.add_argument_group(title="log options") group.add_argument(f"{prefix}{prefix}verbose", action=VerboseAction, nargs=0, const=True, dest=SUPPRESS, help="increase log verbosity") group.add_argument(f"{prefix}{prefix}silent", action=SilentAction, nargs=0, const=True, dest=SUPPRESS, diff --git a/src/linktools/utils/__init__.py b/src/linktools/utils/__init__.py index af7a3f0c..b351e096 100644 --- a/src/linktools/utils/__init__.py +++ b/src/linktools/utils/__init__.py @@ -32,7 +32,8 @@ cast, cast_int as int, cast_bool as bool, coalesce, is_contain, is_empty, get_item, pop_item, get_list_item, - get_md5, get_sha1, get_sha256, make_uuid, gzip_compress, + get_hash, get_file_hash, get_md5, get_file_md5, + make_uuid, gzip_compress, join_path, read_file, write_file, remove_file, clear_directory, get_lan_ip, get_wan_ip, parse_version, get_char_width, diff --git a/src/linktools/utils/_utils.py b/src/linktools/utils/_utils.py index aa4d5b96..53b63be6 100755 --- a/src/linktools/utils/_utils.py +++ b/src/linktools/utils/_utils.py @@ -263,28 +263,31 @@ def get_list_item(obj: Any, *keys: Any, type: "Type[T]" = None, default: "List[T return result -def get_md5(data: Union[str, bytes]) -> str: +def get_hash(data: Union[str, bytes], algorithm: "Literal['md5', 'sha1', 'sha256']" = "md5") -> str: if isinstance(data, str): data = bytes(data, "utf8") - m = hashlib.md5() + m = getattr(hashlib, algorithm)() m.update(data) return m.hexdigest() -def get_sha1(data: Union[str, bytes]) -> str: - if isinstance(data, str): - data = bytes(data, "utf8") - s1 = hashlib.sha1() - s1.update(data) - return s1.hexdigest() +def get_file_hash(path: "PathType", algorithm: "Literal['md5', 'sha1', 'sha256']" = "md5") -> str: + m = getattr(hashlib, algorithm)() + with open(path, "rb") as fd: + while True: + data = fd.read(4096 << 4) + if not data: + break + m.update(data) + return m.hexdigest() -def get_sha256(data: Union[str, bytes]) -> str: - if isinstance(data, str): - data = bytes(data, "utf8") - s1 = hashlib.sha256() - s1.update(data) - return s1.hexdigest() +def get_md5(data: Union[str, bytes]) -> str: + return get_hash(data, algorithm="md5") + + +def get_file_md5(path: "PathType"): + return get_file_hash(path, algorithm="md5") def make_uuid() -> str: