Skip to content

Commit

Permalink
Сортировка методов в клиенте
Browse files Browse the repository at this point in the history
  • Loading branch information
themanyfaceddemon committed Aug 26, 2024
1 parent e6f7d74 commit 8c0586a
Showing 1 changed file with 121 additions and 117 deletions.
238 changes: 121 additions & 117 deletions DMBotNetwork/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
"""Устанавливает соединение с сервером."""
Expand All @@ -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:
"""Управляет процессом подключения и прослушивания сообщений в фоне."""
Expand All @@ -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:
"""Отправляет данные на сервер.
Expand Down Expand Up @@ -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:
"""Слушает входящие сообщения от сервера и обрабатывает их."""
Expand Down Expand Up @@ -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 = {
Expand All @@ -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

0 comments on commit 8c0586a

Please sign in to comment.