From 8c0586a592192d037656a587a59540db90c3579c Mon Sep 17 00:00:00 2001 From: themanyfaceddemon Date: Mon, 26 Aug 2024 16:36:49 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BE=D1=80=D1=82=D0=B8=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=BE=D0=B2?= =?UTF-8?q?=20=D0=B2=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DMBotNetwork/client.py | 238 +++++++++++++++++++++-------------------- 1 file changed, 121 insertions(+), 117 deletions(-) diff --git a/DMBotNetwork/client.py b/DMBotNetwork/client.py index caf0262..64de9fa 100644 --- a/DMBotNetwork/client.py +++ b/DMBotNetwork/client.py @@ -33,31 +33,48 @@ def __init_subclass__(cls, **kwargs): if callable(getattr(cls, method)) and method.startswith("net_"): cls._net_methods[method[4:]] = getattr(cls, method) + # Сеттеры и геттеры @classmethod - async def request_method(cls, spec_type: str, **kwargs) -> None: - """Запрашивает выполнение метода на сервере. + def set_host(cls, host: str) -> None: + cls._host = host - Args: - spec_type (str): Указание метода, который нужно вызвать. + @classmethod + def get_host(cls) -> Optional[str]: + return cls._host - Raises: - ConnectionError: Если соединение с сервером не установлено. - """ - if not cls._writer: - raise ConnectionError("Not connected to server") + @classmethod + def set_port(cls, port: int) -> None: + cls._port = port - request_data = { - "action": "net", - "type": spec_type, - **kwargs - } + @classmethod + def get_port(cls) -> Optional[int]: + return cls._port - try: - await cls._send_data(request_data) - - except Exception as e: - logger.error(f"Error requesting method 'net.{spec_type}'. kwargs: '{kwargs}'. Error: {e}") + @classmethod + def set_login(cls, login: str) -> None: + cls._login = login + + @classmethod + def get_login(cls) -> Optional[str]: + return cls._login + @classmethod + def set_password(cls, password: str) -> None: + cls._password = password + + @classmethod + def get_password(cls) -> Optional[str]: + return cls._password + + @classmethod + def set_server_file_path(cls, path: Path) -> None: + cls._server_file_path = path + + @classmethod + def get_server_file_path(cls) -> Optional[Path]: + return cls._server_file_path + + # Основные методы взаимодействия с сервером @classmethod async def connect(cls) -> None: """Устанавливает соединение с сервером.""" @@ -72,34 +89,36 @@ async def connect(cls) -> None: logger.error(f"Error creating connect task: {e}") @classmethod - async def _call_method(cls, metods_dict: Dict[str, Any], method_name: str, **kwargs) -> Any: - """Вызывает зарегистрированный метод по его имени. + async def request_method(cls, spec_type: str, **kwargs) -> None: + """Запрашивает выполнение метода на сервере. Args: - metods_dict (Dict[str, Any]): Словарь, из которого будут вызываться методы. - method_name (str): Имя метода для вызова. + spec_type (str): Указание метода, который нужно вызвать. - Returns: - Any: Результат выполнения метода, если найден, иначе None. + Raises: + ConnectionError: Если соединение с сервером не установлено. """ - method = metods_dict.get(method_name) - if method is None: - logger.error(f"Net method {method_name} not found.") - return None + if not cls._writer: + raise ConnectionError("Not connected to server") - sig = inspect.signature(method) - valid_kwargs = {k: v for k, v in kwargs.items() if k in sig.parameters} + request_data = { + "action": "net", + "type": spec_type, + **kwargs + } try: - if inspect.iscoroutinefunction(method): - return await method(cls, **valid_kwargs) - else: - return method(cls, **valid_kwargs) + await cls._send_data(request_data) except Exception as e: - logger.error(f"Error calling method {method_name}: {e}") - return None + logger.error(f"Error requesting method 'net.{spec_type}'. kwargs: '{kwargs}'. Error: {e}") + + @classmethod + async def close_connection(cls) -> None: + """Закрывает соединение с сервером.""" + await cls._close() + # Вспомогательные методы работы с соединением @classmethod async def _connect_and_listen(cls) -> None: """Управляет процессом подключения и прослушивания сообщений в фоне.""" @@ -114,35 +133,6 @@ async def _connect_and_listen(cls) -> None: cls._is_connected = False await cls._close() - @classmethod - async def close_connection(cls) -> None: - """Закрывает соединение с сервером.""" - await cls._close() - - @classmethod - async def _close(cls) -> None: - """Закрывает соединение с сервером.""" - if not cls._is_connected: - logger.warning("Attempted to close connection, but no connection was established.") - return - - cls._is_connected = False - - if cls._writer: - try: - cls._writer.close() - await cls._writer.wait_closed() - - except Exception as e: - logger.error(f"Error closing connection: {e}") - - if cls._listen_task: - cls._listen_task.cancel() - try: - await cls._listen_task - except asyncio.CancelledError: - pass - @classmethod async def _send_data(cls, data: Any) -> None: """Отправляет данные на сервер. @@ -204,18 +194,30 @@ async def _receive_data(cls) -> Any: return None @classmethod - async def _authenticate(cls) -> None: - """Аутентифицирует клиента на сервере. - """ - try: - await cls._send_data({ - "login": cls._login, - "password": cls._password - }) + async def _close(cls) -> None: + """Закрывает соединение с сервером.""" + if not cls._is_connected: + logger.warning("Attempted to close connection, but no connection was established.") + return - except Exception as e: - logger.error(f"Error during authentication: {e}") + cls._is_connected = False + if cls._writer: + try: + cls._writer.close() + await cls._writer.wait_closed() + + except Exception as e: + logger.error(f"Error closing connection: {e}") + + if cls._listen_task: + cls._listen_task.cancel() + try: + await cls._listen_task + except asyncio.CancelledError: + pass + + # Обработка сообщений от сервера @classmethod async def listen_for_messages(cls) -> None: """Слушает входящие сообщения от сервера и обрабатывает их.""" @@ -257,6 +259,49 @@ async def _action_processor(cls, action_type, server_data: dict) -> None: else: logger.warning(f"Unexpected action type from server: {action_type}") + @classmethod + async def _call_method(cls, metods_dict: Dict[str, Any], method_name: str, **kwargs) -> Any: + """Вызывает зарегистрированный метод по его имени. + + Args: + metods_dict (Dict[str, Any]): Словарь, из которого будут вызываться методы. + method_name (str): Имя метода для вызова. + + Returns: + Any: Результат выполнения метода, если найден, иначе None. + """ + method = metods_dict.get(method_name) + if method is None: + logger.error(f"Net method {method_name} not found.") + return None + + sig = inspect.signature(method) + valid_kwargs = {k: v for k, v in kwargs.items() if k in sig.parameters} + + try: + if inspect.iscoroutinefunction(method): + return await method(cls, **valid_kwargs) + else: + return method(cls, **valid_kwargs) + + except Exception as e: + logger.error(f"Error calling method {method_name}: {e}") + return None + + @classmethod + async def _authenticate(cls) -> None: + """Аутентифицирует клиента на сервере. + """ + try: + await cls._send_data({ + "login": cls._login, + "password": cls._password + }) + + except Exception as e: + logger.error(f"Error during authentication: {e}") + + # Логирование @classmethod def log_processor(cls, server_data: dict) -> None: log_methods = { @@ -275,44 +320,3 @@ def log_processor(cls, server_data: dict) -> None: else: logger.warning(f"Unknown log_type: {log_type}. Message: {msg}") - - # Сеттеры и геттеры - @classmethod - def set_host(cls, host: str) -> None: - cls._host = host - - @classmethod - def get_host(cls) -> Optional[str]: - return cls._host - - @classmethod - def set_port(cls, port: int) -> None: - cls._port = port - - @classmethod - def get_port(cls) -> Optional[int]: - return cls._port - - @classmethod - def set_login(cls, login: str) -> None: - cls._login = login - - @classmethod - def get_login(cls) -> Optional[str]: - return cls._login - - @classmethod - def set_password(cls, password: str) -> None: - cls._password = password - - @classmethod - def get_password(cls) -> Optional[str]: - return cls._password - - @classmethod - def set_server_file_path(cls, path: Path) -> None: - cls._server_file_path = path - - @classmethod - def get_server_file_path(cls) -> Optional[Path]: - return cls._server_file_path