search patch
This commit is contained in:
parent
86d5e03157
commit
5306640238
26
app/core/models/search_models.py
Normal file
26
app/core/models/search_models.py
Normal file
@ -0,0 +1,26 @@
|
||||
from uuid import UUID
|
||||
from datetime import datetime
|
||||
from typing import Optional, List, Any
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class UserSearchResult(BaseModel):
|
||||
user_id: UUID
|
||||
login: str
|
||||
full_name: Optional[str] = None
|
||||
custom_name: Optional[str] = None
|
||||
created_at: datetime = Field(..., description="Дата регистрации")
|
||||
profile: Optional[Any] = Field(None, description="Модель как у /profile/{user_id}")
|
||||
|
||||
|
||||
class SearchData(BaseModel):
|
||||
users: List[UserSearchResult]
|
||||
groups: List[Any] = []
|
||||
channels: List[Any] = []
|
||||
messages: List[Any] = []
|
||||
|
||||
|
||||
class SearchResponse(BaseModel):
|
||||
status: str
|
||||
data: SearchData
|
||||
|
||||
42
app/core/services/search_service.py
Normal file
42
app/core/services/search_service.py
Normal file
@ -0,0 +1,42 @@
|
||||
import httpx
|
||||
from app.core import config
|
||||
from app.core.localizer import localizer
|
||||
from app.core.http_client import authorized_get
|
||||
from app.core.models.search_models import SearchResponse, SearchData
|
||||
|
||||
|
||||
async def search_by_query(login: str, token: str, query: str):
|
||||
"""
|
||||
Поиск по строке: пользователи (префикс), далее можно расширить под группы/каналы/сообщения.
|
||||
|
||||
:return: tuple (ok: bool, data: SearchData | str)
|
||||
"""
|
||||
url = f"{config.BASE_URL}/v1/feed/search"
|
||||
headers = {"Authorization": f"Bearer {token}"}
|
||||
params = {"query": query}
|
||||
|
||||
try:
|
||||
response = await authorized_get(url, login=login, access_token=token, headers=headers, params=params)
|
||||
|
||||
print("response.status_code", response.status_code)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "fine":
|
||||
model = SearchResponse(**data)
|
||||
return True, model.data
|
||||
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("Недостаточно прав или неавторизован"))
|
||||
|
||||
if response.status_code == 422:
|
||||
return False, localizer.translate("Некорректные параметры запроса")
|
||||
|
||||
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}"
|
||||
|
||||
@ -20,6 +20,7 @@ from app.ui.views.chat_view import ChatView
|
||||
from app.core.services.chat_service import get_chat_history, send_private_message
|
||||
from app.core.models.chat_models import PrivateMessageSendRequest, MessageItem
|
||||
from uuid import UUID
|
||||
from app.core.services.search_service import search_by_query
|
||||
|
||||
class YobbleHomeView(QWidget):
|
||||
REQUIRED_PERMISSIONS = {
|
||||
@ -271,6 +272,8 @@ class YobbleHomeView(QWidget):
|
||||
self.search_input.setPlaceholderText("Поиск…")
|
||||
self.search_input.hide()
|
||||
top_bar_layout.addWidget(self.search_input, 1)
|
||||
# Запуск поиска по Enter
|
||||
self.search_input.returnPressed.connect(self.on_search_submit)
|
||||
|
||||
# Новые кнопки справа
|
||||
self.search_button = QPushButton("🔍")
|
||||
@ -664,6 +667,38 @@ class YobbleHomeView(QWidget):
|
||||
self.search_button.show()
|
||||
self.notification_button.show()
|
||||
|
||||
def on_search_submit(self):
|
||||
"""Обработчик Enter в поле поиска."""
|
||||
query = (self.search_input.text() or "").strip()
|
||||
if len(query) < 1:
|
||||
self.show_notification(localizer.translate("Введите минимум 1 символ"), is_error=True)
|
||||
return
|
||||
# Запускаем асинхронный поиск
|
||||
asyncio.ensure_future(self._do_search(query))
|
||||
|
||||
async def _do_search(self, query: str):
|
||||
"""Вызов серверного поиска и показ краткого результата."""
|
||||
# Получаем текущие учётные данные
|
||||
login = self.username
|
||||
token = await get_current_access_token()
|
||||
if not token:
|
||||
self.show_notification(localizer.translate("Не найден токен авторизации"), is_error=True)
|
||||
return
|
||||
|
||||
ok, data_or_error = await search_by_query(login, token, query)
|
||||
if not ok:
|
||||
self.show_notification(str(data_or_error), is_error=True)
|
||||
return
|
||||
|
||||
data = data_or_error
|
||||
users_cnt = len(getattr(data, 'users', []) or [])
|
||||
groups_cnt = len(getattr(data, 'groups', []) or [])
|
||||
channels_cnt = len(getattr(data, 'channels', []) or [])
|
||||
messages_cnt = len(getattr(data, 'messages', []) or [])
|
||||
self.show_notification(
|
||||
localizer.translate(f"Найдено: пользователи {users_cnt}, беседы {groups_cnt}, паблики {channels_cnt}, сообщения {messages_cnt}")
|
||||
)
|
||||
|
||||
def handle_notification_click(self):
|
||||
"""Пустышка для кнопки уведомлений."""
|
||||
show_themed_messagebox(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user