# ========================================================================== # # # # KVMD - The main Pi-KVM daemon. # # # # Copyright (C) 2018-2021 Maxim Devaev # # # # 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 . # # # # ========================================================================== # import re from typing import List from typing import Set from typing import Mapping from typing import Sequence from typing import Callable from typing import TypeVar from typing import NoReturn from typing import Union from typing import Any # ===== class ValidatorError(ValueError): pass # ===== _RetvalSeqT = TypeVar("_RetvalSeqT", bound=Sequence) # ===== def raise_error(arg: Any, name: str, hide: bool=False) -> NoReturn: arg_str = " " if not hide: arg_str = (f" {arg!r} " if isinstance(arg, (str, bytes)) else f" '{arg}' ") raise ValidatorError(f"The argument{arg_str}is not a valid {name}") def check_not_none(arg: Any, name: str) -> Any: if arg is None: raise ValidatorError(f"Empty argument is not a valid {name}") return arg def check_not_none_string(arg: Any, name: str, strip: bool=True) -> str: arg = str(check_not_none(arg, name)) if strip: arg = arg.strip() return arg def check_in_list(arg: Any, name: str, variants: Union[Sequence, Mapping, Set]) -> Any: if arg not in variants: raise_error(arg, name) return arg def check_string_in_list( arg: Any, name: str, variants: Union[Sequence[str], Mapping[str, Any], Set[str]], lower: bool=True, ) -> str: arg = check_not_none_string(arg, name) if lower: arg = arg.lower() return check_in_list(arg, name, variants) def check_re_match(arg: Any, name: str, pattern: str, strip: bool=True, hide: bool=False) -> str: arg = check_not_none_string(arg, name, strip=strip) if re.match(pattern, arg, flags=re.MULTILINE) is None: raise_error(arg, name, hide=hide) return arg def check_len(arg: _RetvalSeqT, name: str, limit: int) -> _RetvalSeqT: if len(arg) > limit: raise_error(arg, name) return arg def check_any(arg: Any, name: str, validators: List[Callable[[Any], Any]]) -> Any: # pylint: disable=inconsistent-return-statements for validator in validators: try: return validator(arg) except Exception: pass raise_error(arg, name)