Coverage for kpoisk_bot/handlers.py: 57%
44 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-19 21:13 +0000
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-19 21:13 +0000
1import logging
2from typing import Any
4from aiogram import Router, html
5from aiogram.filters import CommandStart
6from aiogram.types import (
7 ChosenInlineResult,
8 InlineQuery,
9 InlineQueryResultArticle,
10 InputTextMessageContent,
11 Message,
12)
13from httpx import HTTPError
14from kinopoisk_unofficial_api_client import Client
15from kinopoisk_unofficial_api_client.api.films import (
16 get_api_v2_1_films_search_by_keyword,
17 get_api_v2_2_films_id,
18)
20from .config import TOP_RESULTS_COUNT
21from .format import FilmFormatter
24router = Router()
27@router.message(CommandStart())
28async def command_start_handler(message: Message) -> None:
29 """
30 This handler receives messages with `/start` command
31 """
32 await message.answer(f"Hello, {html.bold(message.from_user.full_name)}!")
35@router.message()
36async def search_handler(message: Message, api_client: Client) -> Any:
37 if message.text is None:
38 return
39 try:
40 results = await get_api_v2_1_films_search_by_keyword.asyncio(
41 client=api_client, keyword=message.text, page=1
42 )
43 for content in map(
44 lambda film: FilmFormatter(film).as_text_message(),
45 results.films[:TOP_RESULTS_COUNT],
46 ):
47 await message.reply(
48 content.message_text,
49 link_preview_options=content.link_preview_options,
50 entities=content.entities,
51 parse_mode=content.parse_mode,
52 )
53 except HTTPError as e:
54 # But not all the types is supported to be copied so need to handle it
55 logging.error(e)
58@router.inline_query()
59async def inline_handler(query: InlineQuery, api_client: Client) -> Any:
60 if not query.query:
61 return await query.answer(
62 [
63 InlineQueryResultArticle(
64 id="EMPTY",
65 title="Наберите название фильма, чтобы найти его в КиноПоиске",
66 input_message_content=InputTextMessageContent(
67 message_text="Этот бот поможет вам найти фильм в КиноПоиске"
68 ),
69 )
70 ]
71 )
73 try:
74 api_result = await get_api_v2_1_films_search_by_keyword.asyncio(
75 client=api_client, keyword=query.query, page=1
76 )
77 results = [
78 FilmFormatter(film).as_inline()
79 for film in api_result.films[:TOP_RESULTS_COUNT]
80 ]
81 return await query.answer(results)
82 except (HTTPError, TypeError) as e:
83 logging.error(e)
84 return await query.answer(
85 [
86 InlineQueryResultArticle(
87 id="ERROR",
88 title="Упс, что-то пошло не так",
89 input_message_content=InputTextMessageContent(
90 message_text="Что-то пошло не так :("
91 ),
92 )
93 ]
94 )
97@router.chosen_inline_result()
98async def chosen_inline_handler(result: ChosenInlineResult, api_client: Client) -> Any:
99 if result.result_id == "ERROR" or result.result_id == "EMPTY":
100 return
102 film = await get_api_v2_2_films_id.asyncio(
103 id=int(result.result_id), client=api_client
104 )
105 formatter = FilmFormatter(film)
106 as_message = formatter.as_text_message()
107 await result.bot.edit_message_text(
108 inline_message_id=result.inline_message_id,
109 text=as_message.message_text,
110 parse_mode=as_message.parse_mode,
111 entities=as_message.entities,
112 link_preview_options=as_message.link_preview_options,
113 )
114 await result.bot.edit_message_reply_markup(
115 inline_message_id=result.inline_message_id,
116 reply_markup=formatter.create_result_markup(),
117 )