Compare commits
2 Commits
54e4d3542e
...
22b6fd272f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22b6fd272f | ||
|
|
6f8bc0e762 |
@ -105,7 +105,7 @@ class MainController(QStackedWidget):
|
||||
# return
|
||||
|
||||
token = session['access_token']
|
||||
success, data = await get_private_chats(token=token, offset=0, limit=50)
|
||||
success, data = await get_private_chats(login=username, token=token, offset=0, limit=50)
|
||||
|
||||
if success:
|
||||
# Отправляем данные в основной поток через сигнал
|
||||
@ -113,3 +113,5 @@ class MainController(QStackedWidget):
|
||||
else:
|
||||
# Отправляем ошибку в основной поток через сигнал
|
||||
self.notification_requested.emit(f"Не удалось загрузить чаты: {data}", True)
|
||||
print("data", data)
|
||||
|
||||
|
||||
92
app/core/http_client.py
Normal file
92
app/core/http_client.py
Normal file
@ -0,0 +1,92 @@
|
||||
import httpx
|
||||
from contextvars import ContextVar
|
||||
from typing import Dict, Any, Optional
|
||||
|
||||
# Connection pool & timeouts
|
||||
limits = httpx.Limits(max_connections=200, max_keepalive_connections=50)
|
||||
timeout = httpx.Timeout(connect=5.0, read=10.0, write=5.0, pool=5.0)
|
||||
|
||||
# Keep a client per event loop/context to avoid cross-loop issues
|
||||
_client_ctx: ContextVar[httpx.AsyncClient | None] = ContextVar("http_client_ctx", default=None)
|
||||
|
||||
def get_client() -> httpx.AsyncClient:
|
||||
client = _client_ctx.get()
|
||||
if client is None or client.is_closed:
|
||||
transport = httpx.AsyncHTTPTransport(http2=True)
|
||||
client = httpx.AsyncClient(transport=transport, limits=limits, timeout=timeout)
|
||||
_client_ctx.set(client)
|
||||
return client
|
||||
|
||||
async def aclose_client():
|
||||
client = _client_ctx.get()
|
||||
if client is not None and not client.is_closed:
|
||||
await client.aclose()
|
||||
_client_ctx.set(None)
|
||||
|
||||
# --- Authorized helpers with auto-refresh on 401 ---
|
||||
async def authorized_get(
|
||||
url: str,
|
||||
*,
|
||||
login: Optional[str] = None,
|
||||
access_token: Optional[str] = None,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
) -> httpx.Response:
|
||||
hdrs = dict(headers or {})
|
||||
if access_token:
|
||||
hdrs["Authorization"] = f"Bearer {access_token}"
|
||||
|
||||
resp = await get_client().get(url, headers=hdrs, params=params)
|
||||
if resp.status_code != 401 or not login or not access_token:
|
||||
return resp
|
||||
|
||||
# Try refresh flow lazily to avoid import cycle at import time
|
||||
from app.core.database import get_session, logout
|
||||
from app.core.services.auth_service import refresh_token as do_refresh
|
||||
|
||||
session = get_session(login)
|
||||
if not session or not session.get("refresh_token"):
|
||||
return resp
|
||||
|
||||
ok, data = await do_refresh(access_token, session["refresh_token"])
|
||||
if ok:
|
||||
new_access = data["access_token"]
|
||||
hdrs["Authorization"] = f"Bearer {new_access}"
|
||||
return await get_client().get(url, headers=hdrs, params=params)
|
||||
|
||||
logout(access_token)
|
||||
return resp
|
||||
|
||||
async def authorized_post(
|
||||
url: str,
|
||||
*,
|
||||
login: Optional[str] = None,
|
||||
access_token: Optional[str] = None,
|
||||
headers: Optional[Dict[str, str]] = None,
|
||||
params: Optional[Dict[str, Any]] = None,
|
||||
json: Any = None,
|
||||
data: Any = None,
|
||||
) -> httpx.Response:
|
||||
hdrs = dict(headers or {})
|
||||
if access_token:
|
||||
hdrs["Authorization"] = f"Bearer {access_token}"
|
||||
|
||||
resp = await get_client().post(url, headers=hdrs, params=params, json=json, data=data)
|
||||
if resp.status_code != 401 or not login or not access_token:
|
||||
return resp
|
||||
|
||||
from app.core.database import get_session, logout
|
||||
from app.core.services.auth_service import refresh_token as do_refresh
|
||||
|
||||
session = get_session(login)
|
||||
if not session or not session.get("refresh_token"):
|
||||
return resp
|
||||
|
||||
ok, data = await do_refresh(access_token, session["refresh_token"])
|
||||
if ok:
|
||||
new_access = data["access_token"]
|
||||
hdrs["Authorization"] = f"Bearer {new_access}"
|
||||
return await get_client().post(url, headers=hdrs, params=params, json=json, data=data)
|
||||
|
||||
logout(access_token)
|
||||
return resp
|
||||
@ -3,62 +3,61 @@ import asyncio
|
||||
from app.core import config
|
||||
from app.core.database import add_session, logout, get_session
|
||||
from app.core.localizer import localizer
|
||||
from app.core.http_client import get_client, authorized_get
|
||||
|
||||
|
||||
async def login(login, password):
|
||||
"""
|
||||
Отправляет запрос на аутентификацию и в случае успеха сохраняет сессию.
|
||||
Логин пользователя по логину и паролю.
|
||||
|
||||
:param login: Логин пользователя
|
||||
:param password: Пароль пользователя
|
||||
:return: Кортеж (успех: bool, сообщение: str)
|
||||
:return: tuple (ok: bool, message: str)
|
||||
"""
|
||||
url = f"{config.BASE_URL}/v1/auth/login"
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(http2=True) as client:
|
||||
response = await client.post(url, json={"login": login, "password": password})
|
||||
response = await get_client().post(url, json={"login": login, "password": password})
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "fine":
|
||||
token_data = data["data"]
|
||||
add_session(
|
||||
login=login,
|
||||
access_token=token_data["access_token"],
|
||||
refresh_token=token_data["refresh_token"],
|
||||
user_id=token_data["user_id"]
|
||||
)
|
||||
return True, localizer.translate("Успешный вход")
|
||||
else:
|
||||
return False, data.get("detail", localizer.translate("Неизвестная ошибка ответа"))
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "fine":
|
||||
token_data = data["data"]
|
||||
add_session(
|
||||
login=login,
|
||||
access_token=token_data["access_token"],
|
||||
refresh_token=token_data["refresh_token"],
|
||||
user_id=token_data.get("user_id"),
|
||||
)
|
||||
return True, localizer.translate("Вход выполнен успешно")
|
||||
return False, data.get("detail", localizer.translate("Неизвестная ошибка"))
|
||||
|
||||
elif response.status_code in [401]:
|
||||
error_data = response.json()
|
||||
return False, error_data.get("detail", localizer.translate("Неверный логин или пароль"))
|
||||
if response.status_code == 401:
|
||||
error_data = response.json()
|
||||
return False, error_data.get("detail", localizer.translate("Неверный логин или пароль"))
|
||||
|
||||
elif response.status_code in [403]:
|
||||
error_data = response.json()
|
||||
return False, error_data.get("detail", localizer.translate("Учетная запись пользователя отключена"))
|
||||
if response.status_code == 403:
|
||||
error_data = response.json()
|
||||
return False, error_data.get("detail", localizer.translate("Доступ запрещен"))
|
||||
|
||||
elif response.status_code == 422:
|
||||
return False, localizer.translate("Некорректные данные для входа")
|
||||
if response.status_code == 422:
|
||||
return False, localizer.translate("Некорректные входные данные")
|
||||
|
||||
else:
|
||||
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
||||
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
||||
|
||||
except httpx.RequestError as e:
|
||||
return False, f"{localizer.translate('Ошибка сети')}: {e}"
|
||||
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
||||
except Exception as e:
|
||||
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
||||
|
||||
|
||||
async def register(login, password, invite=None):
|
||||
"""
|
||||
Отправляет запрос на регистрацию нового пользователя.
|
||||
Регистрация нового пользователя.
|
||||
|
||||
:param login: Логин
|
||||
:param password: Пароль
|
||||
:param invite: Инвайт-код (опционально)
|
||||
:return: Кортеж (успех: bool, сообщение: str)
|
||||
:return: tuple (ok: bool, message: str)
|
||||
"""
|
||||
url = f"{config.BASE_URL}/v1/auth/register"
|
||||
payload = {"login": login, "password": password}
|
||||
@ -66,116 +65,90 @@ async def register(login, password, invite=None):
|
||||
payload["invite"] = invite
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(http2=True) as client:
|
||||
response = await client.post(url, json=payload)
|
||||
response = await get_client().post(url, json=payload)
|
||||
|
||||
if response.status_code == 201:
|
||||
return True, localizer.translate("Регистрация прошла успешно!")
|
||||
if response.status_code == 201:
|
||||
return True, localizer.translate("Регистрация прошла успешно!")
|
||||
|
||||
error_data = response.json()
|
||||
error_message = error_data.get("detail", localizer.translate("Произошла ошибка"))
|
||||
error_data = response.json()
|
||||
error_message = error_data.get("detail", localizer.translate("Произошла ошибка"))
|
||||
|
||||
if response.status_code == 409:
|
||||
return False, localizer.translate("Этот логин уже занят.")
|
||||
elif response.status_code == 400:
|
||||
return False, localizer.translate("Неверный инвайт-код.")
|
||||
elif response.status_code == 403:
|
||||
return False, localizer.translate("Регистрация в данный момент отключена.")
|
||||
elif response.status_code == 422:
|
||||
return False, localizer.translate("Данные не прошли валидацию. Проверьте длину логина и пароля.")
|
||||
else:
|
||||
return False, f"{localizer.translate('Ошибка сервера')} ({response.status_code}): {error_message}"
|
||||
if response.status_code == 409:
|
||||
return False, localizer.translate("Пользователь уже существует.")
|
||||
if response.status_code == 400:
|
||||
return False, localizer.translate("Некорректный запрос.")
|
||||
if response.status_code == 403:
|
||||
return False, localizer.translate("Регистрация по приглашению отключена.")
|
||||
if response.status_code == 422:
|
||||
return False, localizer.translate("Некорректные входные данные. Проверьте логин и пароль.")
|
||||
|
||||
return False, f"{localizer.translate('Ошибка сервера')} ({response.status_code}): {error_message}"
|
||||
|
||||
except httpx.RequestError as e:
|
||||
return False, f"{localizer.translate('Ошибка сети')}: {e}"
|
||||
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
||||
except Exception as e:
|
||||
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
||||
|
||||
|
||||
async def refresh_token(access_token: str, refresh_token: str):
|
||||
"""
|
||||
Обновляет токен доступа, используя токен обновления.
|
||||
Обновление пары токенов по refresh_token.
|
||||
|
||||
:param access_token: Истекший токен доступа
|
||||
:param refresh_token: Токен обновления
|
||||
:return: Кортеж (успех: bool, данные: dict | str)
|
||||
:param access_token: Текущий access token
|
||||
:param refresh_token: Refresh token
|
||||
:return: tuple (ok: bool, data: dict | str)
|
||||
"""
|
||||
url = f"{config.BASE_URL}/v1/auth/token/refresh"
|
||||
payload = {"access_token": access_token, "refresh_token": refresh_token}
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(http2=True) as client:
|
||||
response = await client.post(url, json=payload)
|
||||
response = await get_client().post(url, json=payload)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "fine":
|
||||
token_data = data["data"]
|
||||
# Обновляем сессию с новыми токенами
|
||||
add_session(
|
||||
login=None, # Логин не требуется для обновления
|
||||
access_token=token_data["access_token"],
|
||||
refresh_token=token_data["refresh_token"],
|
||||
update_existing=True
|
||||
)
|
||||
return True, token_data
|
||||
else:
|
||||
return False, data.get("detail", localizer.translate("Unknown error"))
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "fine":
|
||||
token_data = data["data"]
|
||||
add_session(
|
||||
login=None,
|
||||
access_token=token_data["access_token"],
|
||||
refresh_token=token_data["refresh_token"],
|
||||
update_existing=True,
|
||||
)
|
||||
return True, token_data
|
||||
return False, data.get("detail", localizer.translate("Неизвестная ошибка"))
|
||||
|
||||
elif response.status_code == 401:
|
||||
return False, localizer.translate("Refresh token is invalid or expired")
|
||||
if response.status_code == 401:
|
||||
return False, localizer.translate("Refresh token недействителен или истек")
|
||||
|
||||
else:
|
||||
return False, f"{localizer.translate('Server error')}: {response.status_code}"
|
||||
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
||||
|
||||
except httpx.RequestError as e:
|
||||
return False, f"{localizer.translate('Network error')}: {e}"
|
||||
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
||||
except Exception as e:
|
||||
return False, f"{localizer.translate('An error occurred')}: {e}"
|
||||
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
||||
|
||||
|
||||
async def get_user_role(access_token: str, login: str):
|
||||
"""
|
||||
Получает роль и права пользователя по токену доступа.
|
||||
В случае истечения срока действия токена, пытается его обновить.
|
||||
Получение роли пользователя. При 401 выполняется автообновление токена внутри authorized_get.
|
||||
"""
|
||||
url = f"{config.BASE_URL}/v1/user/role"
|
||||
headers = {"Authorization": f"Bearer {access_token}"}
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(http2=True) as client:
|
||||
response = await client.get(url, headers=headers)
|
||||
response = await authorized_get(url, login=login, access_token=access_token, headers=headers)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
return (True, data['data']) if data.get("status") == "fine" else (False, data.get("detail", localizer.translate("Unknown error")))
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
return (True, data['data']) if data.get("status") == "fine" else (False, data.get("detail", localizer.translate("Неизвестная ошибка")))
|
||||
|
||||
elif response.status_code == 401:
|
||||
# Токен истек, пытаемся обновить
|
||||
session = get_session(login)
|
||||
if not session or not session['refresh_token']:
|
||||
return False, localizer.translate("No refresh token found")
|
||||
if response.status_code == 401:
|
||||
return False, localizer.translate("Сессия истекла, войдите снова")
|
||||
|
||||
refresh_success, refresh_data = await refresh_token(access_token, session['refresh_token'])
|
||||
|
||||
if refresh_success:
|
||||
# Повторяем запрос с новым токеном
|
||||
new_access_token = refresh_data['access_token']
|
||||
headers["Authorization"] = f"Bearer {new_access_token}"
|
||||
response = await client.get(url, headers=headers)
|
||||
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
return (True, data['data']) if data.get("status") == "fine" else (False, localizer.translate("Failed to get role after refresh"))
|
||||
|
||||
# Если обновление не удалось, выходим из системы
|
||||
logout(access_token)
|
||||
return False, localizer.translate("Session expired, please log in again")
|
||||
|
||||
else:
|
||||
return False, f"{localizer.translate('Server error')}: {response.status_code}"
|
||||
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
||||
|
||||
except httpx.RequestError as e:
|
||||
return False, f"{localizer.translate('Network error')}: {e}"
|
||||
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
||||
except Exception as e:
|
||||
return False, f"{localizer.translate('An error occurred')}: {e}"
|
||||
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
||||
|
||||
|
||||
@ -7,60 +7,49 @@ from app.core.models.chat_models import (
|
||||
PrivateMessageSendRequest, PrivateMessageSendResponse
|
||||
)
|
||||
from uuid import UUID
|
||||
from app.core.http_client import get_client, authorized_get, authorized_post
|
||||
|
||||
async def get_private_chats(token: str, offset: int = 0, limit: int = 20):
|
||||
"""
|
||||
Получает список приватных чатов пользователя.
|
||||
|
||||
:param token: Токен доступа пользователя
|
||||
:param offset: Смещение для пагинации
|
||||
:param limit: Количество чатов для загрузки
|
||||
:return: Кортеж (успех: bool, данные: PrivateChatListData | str)
|
||||
async def get_private_chats(login: str, token: str, offset: int = 0, limit: int = 20):
|
||||
"""
|
||||
Получить список приватных чатов.
|
||||
|
||||
:param token: Bearer токен
|
||||
:param offset: Смещение
|
||||
:param limit: Количество
|
||||
:return: tuple (ok: bool, data: 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)
|
||||
response = await authorized_get(url, login=login, access_token=token, headers=headers, params=params)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "fine":
|
||||
response_model = PrivateChatListResponse(**data)
|
||||
return True, response_model.data
|
||||
return False, data.get("detail", localizer.translate("Неизвестная ошибка"))
|
||||
|
||||
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("Неизвестная ошибка ответа"))
|
||||
if response.status_code in [401, 403]:
|
||||
error_data = response.json()
|
||||
return False, error_data.get("detail", localizer.translate("Недостаточно прав или неавторизован"))
|
||||
|
||||
elif response.status_code in [401, 403]:
|
||||
error_data = response.json()
|
||||
return False, error_data.get("detail", localizer.translate("Ошибка аутентификации или авторизации"))
|
||||
if response.status_code == 422:
|
||||
return False, localizer.translate("Некорректные параметры запроса")
|
||||
|
||||
elif response.status_code == 422:
|
||||
return False, localizer.translate("Некорректные параметры запроса")
|
||||
|
||||
else:
|
||||
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
||||
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
||||
|
||||
except httpx.RequestError as e:
|
||||
return False, f"{localizer.translate('Ошибка сети')}: {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)
|
||||
async def get_chat_history(login: str, token: str, chat_id: UUID, before_message_id: int = None, limit: int = 30):
|
||||
"""
|
||||
История сообщений приватного чата.
|
||||
"""
|
||||
url = f"{config.BASE_URL}/v1/chat/private/history"
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
@ -69,73 +58,61 @@ async def get_chat_history(token: str, chat_id: UUID, before_message_id: int = N
|
||||
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)
|
||||
response = await authorized_get(url, login=login, access_token=token, 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", "Неизвестная ошибка ответа")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "fine":
|
||||
response_model = PrivateChatHistoryResponse(**data)
|
||||
return True, response_model.data
|
||||
return False, data.get("detail", localizer.translate("Неизвестная ошибка"))
|
||||
|
||||
elif response.status_code in [401, 403]:
|
||||
error_data = response.json()
|
||||
return False, error_data.get("detail", "Ошибка аутентификации или доступа")
|
||||
if 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, "Некорректные параметры запроса"
|
||||
if response.status_code == 422:
|
||||
return False, localizer.translate("Некорректные параметры запроса")
|
||||
|
||||
else:
|
||||
return False, f"Ошибка сервера: {response.status_code}"
|
||||
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
||||
|
||||
except httpx.RequestError as e:
|
||||
return False, f"Ошибка сети: {e}"
|
||||
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
||||
except Exception as e:
|
||||
return False, f"Произошла ошибка: {e}"
|
||||
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
||||
|
||||
|
||||
async def send_private_message(token: str, payload: "PrivateMessageSendRequest"):
|
||||
async def send_private_message(login: str, 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'))
|
||||
response = await authorized_post(url, login=login, access_token=token, 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", "Неизвестная ошибка ответа")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "fine":
|
||||
response_model = PrivateMessageSendResponse(**data)
|
||||
return True, response_model.data
|
||||
return False, data.get("detail", localizer.translate("Неизвестная ошибка"))
|
||||
|
||||
elif response.status_code in [401, 403, 404]:
|
||||
error_data = response.json()
|
||||
print("error_data", error_data)
|
||||
return False, error_data.get("detail", "Ошибка доступа или чат не найден")
|
||||
if response.status_code in [401, 403, 404]:
|
||||
error_data = response.json()
|
||||
return False, error_data.get("detail", localizer.translate("Недостаточно прав или ресурс не найден"))
|
||||
|
||||
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 "Некорректные данные"
|
||||
if response.status_code == 422:
|
||||
error_data = response.json()
|
||||
detail = error_data.get("detail")
|
||||
if isinstance(detail, list):
|
||||
return False, ", ".join([e.get("msg", localizer.translate("Некорректные параметры")) for e in detail])
|
||||
return False, detail or localizer.translate("Некорректный запрос")
|
||||
|
||||
else:
|
||||
return False, f"Ошибка сервера: {response.status_code}"
|
||||
return False, f"{localizer.translate('Ошибка сервера')}: {response.status_code}"
|
||||
|
||||
except httpx.RequestError as e:
|
||||
return False, f"Ошибка сети: {e}"
|
||||
return False, f"{localizer.translate('Сетевая ошибка')}: {e}"
|
||||
except Exception as e:
|
||||
return False, f"Произошла ошибка: {e}"
|
||||
return False, f"{localizer.translate('Произошла ошибка')}: {e}"
|
||||
|
||||
@ -489,7 +489,7 @@ class YobbleHomeView(QWidget):
|
||||
return
|
||||
|
||||
self.show_notification("Загрузка истории...", is_error=False, duration=1000)
|
||||
success, data = await get_chat_history(token, chat_id)
|
||||
success, data = await get_chat_history(self.username, token, chat_id)
|
||||
|
||||
if success:
|
||||
if self.chat_view:
|
||||
@ -532,7 +532,7 @@ class YobbleHomeView(QWidget):
|
||||
self.show_notification("Ошибка: сессия не найдена.", is_error=True)
|
||||
return
|
||||
|
||||
success, data = await send_private_message(token, payload)
|
||||
success, data = await send_private_message(self.username, token, payload)
|
||||
|
||||
if success:
|
||||
# В случае успеха, создаем объект сообщения и добавляем в чат
|
||||
@ -791,3 +791,4 @@ class YobbleHomeView(QWidget):
|
||||
);
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user