from .apikey import apikey_generator from .exception import config_exception from .exception import not_ready_exception from .exception import validator_exception from .validator import nick_validator from .validator import apikey_validator from .validator import password_validator class user: """ This represents user in the system. It would be stored in the config file. Creating new must be done by builders, which checks content with validators. User class is immutable. """ def __init__(self, nick: str, password: str, apikey: str) -> None: """ This create new user, and require all parameters of it. Parameters: nick (str): Nick of the user password (str): Password of the user apikey (str): ApiKey of the user """ self.__nick = nick self.__password = password self.__apikey = apikey self.__result = None @property def nick(self) -> str: """ It returns nick of the user. """ return self.__nick @property def password(self) -> str: """ It returns password of the user. """ return self.__password @property def apikey(self) -> str: """ It returns apikey of the user. """ return self.__apikey def __str__(self) -> str: """ This create dump of the user. Returns: (str): Dump of the user """ target = "User:\n" target = target + "Nick: \"" + str(self.nick) + "\"\n" target = target + "Password: \"" + str(self.password) + "\"\n" target = target + "ApiKey: \"" + str(self.apikey) + "\"\n" return target class user_factory: """ This class is responsible for generating new users. It make avairable creating user step by step, and it is responsible for generating ApiKey. """ def __init__(self, target: user | None = None) -> None: """ This create new user factory. When user had been provided, then it is used to initialize nick, ApiKey and password of the factory. Parameters target (user | None): User to initialize factory (default = None) """ self.__nick = None self.__password = None self.__apikey = None self.__result = None if target is not None: self.__nick = target.nick self.__password = target.password self.__apikey = target.apikey @property def apikey(self) -> str: """ This return factory ApiKey. """ if self.__apikey is None: self.__apikey = apikey_generator() return self.__apikey @property def nick(self) -> str | None: """ This return nick of the factory. """ return self.__nick @property def password(self) -> str | None: """ This return password of the factory. """ return self.__password @nick.setter def nick(self, target: str) -> None: """ This set new nick, and validate it. """ if nick_validator(target).invalid: raise validator_exception("user.nick") self.__nick = target @password.setter def password(self, target: str) -> None: """ This set new password, and validate it. """ if password_validator(target).invalid: raise validator_exception("user.password") self.__password = target @property def ready(self) -> bool: """ This check that factory is ready or not. """ if self.__nick is None: return False if self.__password is None: return False return True @property def result(self) -> user: """ This create new user. Factory must be ready, to do it. """ if not self.ready: raise not_ready_exception(self) if self.__result is not None: return self.__result self.__result = user( self.nick, self.password, self.apikey ) return self.__result class user_builder: """ This create new user builder. User builder is responsble for loading users from dicts, which would be provided from config file. """ def __init__(self, target: dict): """ This create new user builder. Parameters: target (dict): Target dict to load user from """ self.__target = target self.__result = None @property def nick(self) -> str: """ This return nick from dict. """ if not "nick" in self.__target: return "" return self.__target["nick"] @property def password(self) -> str: """ This return password from dict. """ if not "password" in self.__target: return "" return self.__target["password"] @property def apikey(self) -> str: """ This return ApiKey from dict. """ if not "apikey" in self.__target: return "" return self.__target["apikey"] def check(self) -> None | str: """ This validate all properties, nick, password and ApiKey. All must be valid, if any is not valid or is not provided, then it return error. When all is valid, return None, when anything is wrong, then return it as string. Returns: (None): When all is valid (str): Content of the error """ if not "nick" in self.__target: return "User not contain nick." if nick_validator(self.nick).invalid: return "User nick \"" + self.nick + "\" is invalid." if not "password" in self.__target: return self.nick + " not contain password." if password_validator(self.password).invalid: return self.nick + " has invalid password." if not "apikey" in self.__target: return self.nick + " not contain apikey." if apikey_validator(self.apikey).invalid: return self.nick + " has invalid apikey." return None @property def result(self) -> user: """ Ready user form dict. """ if self.__result is not None: return self.__result check = self.check() if check is not None: raise config_exception("User config contain error. " + check) self.__result = user( self.nick, self.password, self.apikey ) return self.__result class user_exporter: """ This export user to dict, which could be safe into config file. """ def __init__(self, target: user) -> None: """ This initialize new exporter. Parameters: target (user): Target user to export """ self.__target = target @property def target(self) -> user: """ Target user to export. """ return self.__target @property def result(self) -> dict: """ Exported user as dict. """ return { "nick": self.target.nick, "password": self.target.password, "apikey": self.target.apikey }