Add channel search and subscription
This commit is contained in:
@@ -752,6 +752,37 @@ def parse_chat_id(value: Any) -> int:
|
||||
return int(text)
|
||||
|
||||
|
||||
def is_channel_link_query(value: str) -> bool:
|
||||
text = value.strip()
|
||||
lower = text.lower()
|
||||
return (
|
||||
"://max.ru/" in lower
|
||||
or "://web.max.ru/" in lower
|
||||
or "/join/" in lower
|
||||
or lower.startswith("join/")
|
||||
or lower.startswith("@")
|
||||
)
|
||||
|
||||
|
||||
def channel_search_result(
|
||||
chat: Any,
|
||||
user_map: dict[str, Any] | None = None,
|
||||
me_id: int | None = None,
|
||||
*,
|
||||
subscribed: bool,
|
||||
chat_url: str | None = None,
|
||||
) -> dict[str, Any]:
|
||||
user_map = user_map or {}
|
||||
return {
|
||||
"externalId": clean_id(getattr(chat, "id", None)),
|
||||
"title": resolve_chat_title(chat, user_map, me_id),
|
||||
"avatarUrl": resolve_chat_avatar(chat, user_map, me_id),
|
||||
"chatUrl": chat_url or f"pymax://chat/{chat.id}",
|
||||
"isSubscribed": subscribed,
|
||||
"description": first_text(getattr(chat, "description", None), getattr(chat, "about", None)),
|
||||
}
|
||||
|
||||
|
||||
def validate_send_path(raw: str) -> pathlib.Path:
|
||||
path = pathlib.Path(raw)
|
||||
resolved = path.resolve(strict=True)
|
||||
@@ -877,6 +908,58 @@ async def resolve_chat_url(request: web.Request) -> web.Response:
|
||||
return json_response({"success": True, "chatUrl": f"pymax://chat/{chat_id}", "error": None})
|
||||
|
||||
|
||||
@route_errors
|
||||
async def channels_search(request: web.Request) -> web.Response:
|
||||
data = await read_json(request)
|
||||
query = str(data.get("query") or "").strip()
|
||||
if not query:
|
||||
return json_response([])
|
||||
|
||||
client = await runtime.get_client()
|
||||
lower_query = query.lower()
|
||||
chats = await fetch_chat_pages(client, CHAT_FETCH_LIMIT)
|
||||
channel_chats = [chat for chat in chats if normalize_chat_kind(chat) == "Channel"]
|
||||
me_id = get_me_user_id(client)
|
||||
user_map = await build_user_map(client, channel_chats)
|
||||
results = [
|
||||
channel_search_result(chat, user_map, me_id, subscribed=True)
|
||||
for chat in channel_chats
|
||||
if lower_query in resolve_chat_title(chat, user_map, me_id).lower()
|
||||
]
|
||||
|
||||
if is_channel_link_query(query) and not any(result.get("chatUrl") == query for result in results):
|
||||
try:
|
||||
resolved = await asyncio.wait_for(client.resolve_group_by_link(query), timeout=10)
|
||||
except Exception:
|
||||
resolved = None
|
||||
if resolved is not None:
|
||||
results.insert(0, channel_search_result(resolved, subscribed=False, chat_url=query))
|
||||
elif not any(result.get("externalId") == query for result in results):
|
||||
results.insert(0, {
|
||||
"externalId": query,
|
||||
"title": query,
|
||||
"avatarUrl": None,
|
||||
"chatUrl": query,
|
||||
"isSubscribed": False,
|
||||
"description": "Канал MAX по ссылке или invite-токену",
|
||||
})
|
||||
|
||||
return json_response(results[:20])
|
||||
|
||||
|
||||
@route_errors
|
||||
async def channels_join(request: web.Request) -> web.Response:
|
||||
data = await read_json(request)
|
||||
link = str(data.get("link") or data.get("chatUrl") or "").strip()
|
||||
if not link:
|
||||
return json_response({"success": False, "error": "link is required"}, status=400)
|
||||
|
||||
client = await runtime.get_client()
|
||||
chat = await client.join_channel(link)
|
||||
result = await normalize_chat_update(client, chat, include_history=True)
|
||||
return json_response(result)
|
||||
|
||||
|
||||
@route_errors
|
||||
async def chat_presence(_request: web.Request) -> web.Response:
|
||||
return json_response({"isTyping": False, "statusText": None, "updatedAt": utc_now()})
|
||||
@@ -936,6 +1019,8 @@ def create_app() -> web.Application:
|
||||
app.router.add_get("/updates", updates)
|
||||
app.router.add_post("/chat/history", chat_history)
|
||||
app.router.add_post("/chat/resolve-url", resolve_chat_url)
|
||||
app.router.add_post("/channels/search", channels_search)
|
||||
app.router.add_post("/channels/join", channels_join)
|
||||
app.router.add_post("/chat/presence", chat_presence)
|
||||
app.router.add_post("/chat/clear-history", disabled_action)
|
||||
app.router.add_post("/chat/delete", disabled_action)
|
||||
|
||||
Reference in New Issue
Block a user