142 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
import httpx
 | 
						|
from app.core import config
 | 
						|
from app.core.localizer import localizer
 | 
						|
from app.core.models.chat_models import (
 | 
						|
    PrivateChatListResponse, PrivateChatListData, 
 | 
						|
    PrivateChatHistoryResponse, PrivateChatHistoryData,
 | 
						|
    PrivateMessageSendRequest, PrivateMessageSendResponse
 | 
						|
)
 | 
						|
from uuid import UUID
 | 
						|
 | 
						|
async def get_private_chats(token: str, offset: int = 0, limit: int = 20):
 | 
						|
    """
 | 
						|
    Получает список приватных чатов пользователя.
 | 
						|
 | 
						|
    :param token: Токен доступа пользователя
 | 
						|
    :param offset: Смещение для пагинации
 | 
						|
    :param limit: Количество чатов для загрузки
 | 
						|
    :return: Кортеж (успех: bool, данные: PrivateChatListData | str)
 | 
						|
    """
 | 
						|
    # TODO: Добавить логику обновления токена, как в auth_service.py
 | 
						|
    url = f"{config.BASE_URL}/v1/chat/private/list"
 | 
						|
    headers = {"Authorization": f"Bearer {token}"}
 | 
						|
    params = {"offset": offset, "limit": limit}
 | 
						|
 | 
						|
    try:
 | 
						|
        async with httpx.AsyncClient(http2=True) as client:
 | 
						|
            response = await client.get(url, headers=headers, params=params)
 | 
						|
            print("response.status_code", response.status_code)
 | 
						|
 | 
						|
            if response.status_code == 200:
 | 
						|
                data = response.json()
 | 
						|
                if data.get("status") == "fine":
 | 
						|
                    # Используем Pydantic модель для парсинга ответа
 | 
						|
                    response_model = PrivateChatListResponse(**data)
 | 
						|
                    print("response_model.data", response_model.data)
 | 
						|
                    return True, response_model.data
 | 
						|
                else:
 | 
						|
                    return False, data.get("detail", localizer.translate("Неизвестная ошибка ответа"))
 | 
						|
            
 | 
						|
            elif response.status_code in [401, 403]:
 | 
						|
                error_data = response.json()
 | 
						|
                return False, error_data.get("detail", localizer.translate("Ошибка аутентификации или авторизации"))
 | 
						|
 | 
						|
            elif response.status_code == 422:
 | 
						|
                return False, localizer.translate("Некорректные параметры запроса")
 | 
						|
 | 
						|
            else:
 | 
						|
                return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
 | 
						|
 | 
						|
    except httpx.RequestError as e:
 | 
						|
        return False, f"{localizer.translate('Ошибка сети')}: {e}"
 | 
						|
    except Exception as e:
 | 
						|
        return False, f"{localizer.translate('Произошла ошибка')}: {e}"
 | 
						|
 | 
						|
async def get_chat_history(token: str, chat_id: UUID, before_message_id: int = None, limit: int = 30):
 | 
						|
    """
 | 
						|
    Получает историю сообщений для указанного приватного чата.
 | 
						|
 | 
						|
    :param token: Токен доступа
 | 
						|
    :param chat_id: ID чата
 | 
						|
    :param before_message_id: ID сообщения для пагинации (загрузка более старых)
 | 
						|
    :param limit: Количество сообщений для загрузки
 | 
						|
    :return: Кортеж (успех: bool, данные: PrivateChatHistoryData | str)
 | 
						|
    """
 | 
						|
    url = f"{config.BASE_URL}/v1/chat/private/history"
 | 
						|
    headers = {"Authorization": f"Bearer {token}"}
 | 
						|
    params = {"chat_id": str(chat_id), "limit": limit}
 | 
						|
    if before_message_id:
 | 
						|
        params["before_message_id"] = before_message_id
 | 
						|
 | 
						|
    try:
 | 
						|
        async with httpx.AsyncClient(http2=True) as client:
 | 
						|
            response = await client.get(url, headers=headers, params=params)
 | 
						|
 | 
						|
            if response.status_code == 200:
 | 
						|
                data = response.json()
 | 
						|
                if data.get("status") == "fine":
 | 
						|
                    response_model = PrivateChatHistoryResponse(**data)
 | 
						|
                    return True, response_model.data
 | 
						|
                else:
 | 
						|
                    return False, data.get("detail", "Неизвестная ошибка ответа")
 | 
						|
 | 
						|
            elif response.status_code in [401, 403]:
 | 
						|
                error_data = response.json()
 | 
						|
                return False, error_data.get("detail", "Ошибка аутентификации или доступа")
 | 
						|
            
 | 
						|
            elif response.status_code == 422:
 | 
						|
                return False, "Некорректные параметры запроса"
 | 
						|
            
 | 
						|
            else:
 | 
						|
                return False, f"Ошибка сервера: {response.status_code}"
 | 
						|
 | 
						|
    except httpx.RequestError as e:
 | 
						|
        return False, f"Ошибка сети: {e}"
 | 
						|
    except Exception as e:
 | 
						|
        return False, f"Произошла ошибка: {e}"
 | 
						|
 | 
						|
 | 
						|
async def send_private_message(token: str, payload: "PrivateMessageSendRequest"):
 | 
						|
    """
 | 
						|
    Отправляет приватное сообщение в чат.
 | 
						|
 | 
						|
    :param token: Токен доступа
 | 
						|
    :param payload: Данные сообщения (Pydantic модель PrivateMessageSendRequest)
 | 
						|
    :return: Кортеж (успех: bool, данные: PrivateMessageSendData | str)
 | 
						|
    """
 | 
						|
    url = f"{config.BASE_URL}/v1/chat/private/send"
 | 
						|
    headers = {"Authorization": f"Bearer {token}"}
 | 
						|
    
 | 
						|
    try:
 | 
						|
        async with httpx.AsyncClient(http2=True) as client:
 | 
						|
            response = await client.post(url, headers=headers, json=payload.model_dump(mode='json'))
 | 
						|
 | 
						|
            if response.status_code == 200:
 | 
						|
                data = response.json()
 | 
						|
                if data.get("status") == "fine":
 | 
						|
                    response_model = PrivateMessageSendResponse(**data)
 | 
						|
                    return True, response_model.data
 | 
						|
                else:
 | 
						|
                    return False, data.get("detail", "Неизвестная ошибка ответа")
 | 
						|
 | 
						|
            elif response.status_code in [401, 403, 404]:
 | 
						|
                error_data = response.json()
 | 
						|
                print("error_data", error_data)
 | 
						|
                return False, error_data.get("detail", "Ошибка доступа или чат не найден")
 | 
						|
            
 | 
						|
            elif response.status_code == 422:
 | 
						|
                error_data = response.json()
 | 
						|
                # Может быть список ошибок
 | 
						|
                detail = error_data.get("detail")
 | 
						|
                if isinstance(detail, list):
 | 
						|
                    return False, ", ".join([e.get("msg", "Неизвестная ошибка валидации") for e in detail])
 | 
						|
                return False, detail or "Некорректные данные"
 | 
						|
            
 | 
						|
            else:
 | 
						|
                return False, f"Ошибка сервера: {response.status_code}"
 | 
						|
 | 
						|
    except httpx.RequestError as e:
 | 
						|
        return False, f"Ошибка сети: {e}"
 | 
						|
    except Exception as e:
 | 
						|
        return False, f"Произошла ошибка: {e}"
 |