Правки по mypy
This commit is contained in:
parent
2cd3d64bb8
commit
7d2826c4b5
131
maxapi/bot.py
131
maxapi/bot.py
@ -1,7 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
||||
from typing import Any, Dict, List, Optional, Union, TYPE_CHECKING
|
||||
|
||||
from .client.default import DefaultConnectionProperties
|
||||
|
||||
from .types.input_media import InputMedia, InputMediaBuffer
|
||||
|
||||
@ -82,6 +84,7 @@ class Bot(BaseConnection):
|
||||
parse_mode: Optional[ParseMode] = None,
|
||||
notify: Optional[bool] = None,
|
||||
auto_requests: bool = True,
|
||||
default_connection: Optional[DefaultConnectionProperties] = None
|
||||
):
|
||||
|
||||
"""
|
||||
@ -91,22 +94,24 @@ class Bot(BaseConnection):
|
||||
:param parse_mode: Форматирование по умолчанию
|
||||
:param notify: Отключение уведомлений при отправке сообщений (по умолчанию игнорируется) (не работает на стороне MAX)
|
||||
:param auto_requests: Автоматическое заполнение полей chat и from_user в Update
|
||||
:param default_connection: Настройки aiohttp
|
||||
с помощью API запросов если они не заложены как полноценные объекты в Update (по умолчанию True, при False chat и from_user в некоторых событиях будут выдавать None)
|
||||
"""
|
||||
|
||||
super().__init__()
|
||||
|
||||
self.bot = self
|
||||
self.default_connection = default_connection or DefaultConnectionProperties()
|
||||
|
||||
self.__token = token
|
||||
self.params = {'access_token': self.__token}
|
||||
self.params: Dict[str, Any] = {'access_token': self.__token}
|
||||
self.marker_updates = None
|
||||
|
||||
self.parse_mode = parse_mode
|
||||
self.notify = notify
|
||||
self.auto_requests = auto_requests
|
||||
|
||||
self._me: User = None
|
||||
self._me: User | None = None
|
||||
|
||||
@property
|
||||
def me(self):
|
||||
@ -120,11 +125,11 @@ class Bot(BaseConnection):
|
||||
|
||||
async def send_message(
|
||||
self,
|
||||
chat_id: int = None,
|
||||
user_id: int = None,
|
||||
text: str = None,
|
||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
||||
link: NewMessageLink = None,
|
||||
chat_id: Optional[int] = None,
|
||||
user_id: Optional[int] = None,
|
||||
text: Optional[str] = None,
|
||||
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||
link: Optional[NewMessageLink] = None,
|
||||
notify: Optional[bool] = None,
|
||||
parse_mode: Optional[ParseMode] = None
|
||||
) -> SendedMessage:
|
||||
@ -152,11 +157,11 @@ class Bot(BaseConnection):
|
||||
link=link,
|
||||
notify=self._resolve_notify(notify),
|
||||
parse_mode=self._resolve_parse_mode(parse_mode)
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def send_action(
|
||||
self,
|
||||
chat_id: int = None,
|
||||
chat_id: Optional[int] = None,
|
||||
action: SenderAction = SenderAction.TYPING_ON
|
||||
) -> SendedAction:
|
||||
|
||||
@ -173,14 +178,14 @@ class Bot(BaseConnection):
|
||||
bot=self,
|
||||
chat_id=chat_id,
|
||||
action=action
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def edit_message(
|
||||
self,
|
||||
message_id: str,
|
||||
text: str = None,
|
||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
||||
link: NewMessageLink = None,
|
||||
text: Optional[str] = None,
|
||||
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||
link: Optional[NewMessageLink] = None,
|
||||
notify: Optional[bool] = None,
|
||||
parse_mode: Optional[ParseMode] = None
|
||||
) -> EditedMessage:
|
||||
@ -206,7 +211,7 @@ class Bot(BaseConnection):
|
||||
link=link,
|
||||
notify=self._resolve_notify(notify),
|
||||
parse_mode=self._resolve_parse_mode(parse_mode)
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def delete_message(
|
||||
self,
|
||||
@ -224,7 +229,7 @@ class Bot(BaseConnection):
|
||||
return await DeleteMessage(
|
||||
bot=self,
|
||||
message_id=message_id,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def delete_chat(
|
||||
self,
|
||||
@ -242,14 +247,14 @@ class Bot(BaseConnection):
|
||||
return await DeleteChat(
|
||||
bot=self,
|
||||
chat_id=chat_id,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_messages(
|
||||
self,
|
||||
chat_id: int = None,
|
||||
message_ids: List[str] = None,
|
||||
from_time: datetime | int = None,
|
||||
to_time: datetime | int = None,
|
||||
chat_id: Optional[int] = None,
|
||||
message_ids: Optional[List[str]] = None,
|
||||
from_time: Optional[Union[datetime, int]] = None,
|
||||
to_time: Optional[Union[datetime, int]] = None,
|
||||
count: int = 50,
|
||||
) -> Messages:
|
||||
|
||||
@ -272,7 +277,7 @@ class Bot(BaseConnection):
|
||||
from_time=from_time,
|
||||
to_time=to_time,
|
||||
count=count
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_message(
|
||||
self,
|
||||
@ -299,7 +304,7 @@ class Bot(BaseConnection):
|
||||
:return: Объект пользователя бота
|
||||
"""
|
||||
|
||||
return await GetMe(self).request()
|
||||
return await GetMe(self).fetch()
|
||||
|
||||
async def get_pin_message(
|
||||
self,
|
||||
@ -317,14 +322,14 @@ class Bot(BaseConnection):
|
||||
return await GetPinnedMessage(
|
||||
bot=self,
|
||||
chat_id=chat_id
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def change_info(
|
||||
self,
|
||||
name: str = None,
|
||||
description: str = None,
|
||||
commands: List[BotCommand] = None,
|
||||
photo: Dict[str, Any] = None
|
||||
name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
commands: Optional[List[BotCommand]] = None,
|
||||
photo: Optional[Dict[str, Any]] = None
|
||||
) -> User:
|
||||
|
||||
"""
|
||||
@ -344,12 +349,12 @@ class Bot(BaseConnection):
|
||||
description=description,
|
||||
commands=commands,
|
||||
photo=photo
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_chats(
|
||||
self,
|
||||
count: int = 50,
|
||||
marker: int = None
|
||||
marker: Optional[int] = None
|
||||
) -> Chats:
|
||||
|
||||
"""
|
||||
@ -365,7 +370,7 @@ class Bot(BaseConnection):
|
||||
bot=self,
|
||||
count=count,
|
||||
marker=marker
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_chat_by_link(
|
||||
self,
|
||||
@ -380,7 +385,7 @@ class Bot(BaseConnection):
|
||||
:return: Объект чата
|
||||
"""
|
||||
|
||||
return await GetChatByLink(bot=self, link=link).request()
|
||||
return await GetChatByLink(bot=self, link=link).fetch()
|
||||
|
||||
async def get_chat_by_id(
|
||||
self,
|
||||
@ -395,14 +400,14 @@ class Bot(BaseConnection):
|
||||
:return: Объект чата
|
||||
"""
|
||||
|
||||
return await GetChatById(bot=self, id=id).request()
|
||||
return await GetChatById(bot=self, id=id).fetch()
|
||||
|
||||
async def edit_chat(
|
||||
self,
|
||||
chat_id: int,
|
||||
icon: PhotoAttachmentRequestPayload = None,
|
||||
title: str = None,
|
||||
pin: str = None,
|
||||
icon: Optional[PhotoAttachmentRequestPayload] = None,
|
||||
title: Optional[str] = None,
|
||||
pin: Optional[str] = None,
|
||||
notify: Optional[bool] = None,
|
||||
) -> Chat:
|
||||
|
||||
@ -425,7 +430,7 @@ class Bot(BaseConnection):
|
||||
title=title,
|
||||
pin=pin,
|
||||
notify=self._resolve_notify(notify),
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_video(
|
||||
self,
|
||||
@ -443,13 +448,13 @@ class Bot(BaseConnection):
|
||||
return await GetVideo(
|
||||
bot=self,
|
||||
video_token=video_token
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def send_callback(
|
||||
self,
|
||||
callback_id: str,
|
||||
message: Message = None,
|
||||
notification: str = None
|
||||
message: Optional[Message] = None,
|
||||
notification: Optional[str] = None
|
||||
) -> SendedCallback:
|
||||
|
||||
"""
|
||||
@ -467,7 +472,7 @@ class Bot(BaseConnection):
|
||||
callback_id=callback_id,
|
||||
message=message,
|
||||
notification=notification
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def pin_message(
|
||||
self,
|
||||
@ -491,7 +496,7 @@ class Bot(BaseConnection):
|
||||
chat_id=chat_id,
|
||||
message_id=message_id,
|
||||
notify=self._resolve_notify(notify),
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def delete_pin_message(
|
||||
self,
|
||||
@ -509,7 +514,7 @@ class Bot(BaseConnection):
|
||||
return await DeletePinMessage(
|
||||
bot=self,
|
||||
chat_id=chat_id,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_me_from_chat(
|
||||
self,
|
||||
@ -527,7 +532,7 @@ class Bot(BaseConnection):
|
||||
return await GetMeFromChat(
|
||||
bot=self,
|
||||
chat_id=chat_id,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def delete_me_from_chat(
|
||||
self,
|
||||
@ -545,7 +550,7 @@ class Bot(BaseConnection):
|
||||
return await DeleteMeFromMessage(
|
||||
bot=self,
|
||||
chat_id=chat_id,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_list_admin_chat(
|
||||
self,
|
||||
@ -563,13 +568,13 @@ class Bot(BaseConnection):
|
||||
return await GetListAdminChat(
|
||||
bot=self,
|
||||
chat_id=chat_id,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def add_list_admin_chat(
|
||||
self,
|
||||
chat_id: int,
|
||||
admins: List[ChatAdmin],
|
||||
marker: int = None
|
||||
marker: Optional[int] = None
|
||||
) -> AddedListAdminChat:
|
||||
|
||||
"""
|
||||
@ -587,7 +592,7 @@ class Bot(BaseConnection):
|
||||
chat_id=chat_id,
|
||||
admins=admins,
|
||||
marker=marker,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def remove_admin(
|
||||
self,
|
||||
@ -608,14 +613,14 @@ class Bot(BaseConnection):
|
||||
bot=self,
|
||||
chat_id=chat_id,
|
||||
user_id=user_id,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_chat_members(
|
||||
self,
|
||||
chat_id: int,
|
||||
user_ids: List[int] = None,
|
||||
marker: int = None,
|
||||
count: int = None,
|
||||
user_ids: Optional[List[int]] = None,
|
||||
marker: Optional[int] = None,
|
||||
count: Optional[int] = None,
|
||||
) -> GettedMembersChat:
|
||||
|
||||
"""
|
||||
@ -635,13 +640,13 @@ class Bot(BaseConnection):
|
||||
user_ids=user_ids,
|
||||
marker=marker,
|
||||
count=count,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_chat_member(
|
||||
self,
|
||||
chat_id: int,
|
||||
user_id: int,
|
||||
) -> GettedMembersChat:
|
||||
) -> Optional[ChatMember]:
|
||||
|
||||
"""
|
||||
Получает участника чата.
|
||||
@ -659,11 +664,13 @@ class Bot(BaseConnection):
|
||||
|
||||
if members.members:
|
||||
return members.members[0]
|
||||
|
||||
return None
|
||||
|
||||
async def add_chat_members(
|
||||
self,
|
||||
chat_id: int,
|
||||
user_ids: List[str],
|
||||
user_ids: List[int],
|
||||
) -> AddedMembersChat:
|
||||
|
||||
"""
|
||||
@ -679,7 +686,7 @@ class Bot(BaseConnection):
|
||||
bot=self,
|
||||
chat_id=chat_id,
|
||||
user_ids=user_ids,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def kick_chat_member(
|
||||
self,
|
||||
@ -703,11 +710,11 @@ class Bot(BaseConnection):
|
||||
chat_id=chat_id,
|
||||
user_id=user_id,
|
||||
block=block,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_updates(
|
||||
self,
|
||||
) -> UpdateUnion:
|
||||
) -> Dict:
|
||||
|
||||
"""
|
||||
Получает обновления для бота.
|
||||
@ -717,7 +724,7 @@ class Bot(BaseConnection):
|
||||
|
||||
return await GetUpdates(
|
||||
bot=self,
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def get_upload_url(
|
||||
self,
|
||||
@ -735,7 +742,7 @@ class Bot(BaseConnection):
|
||||
return await GetUploadURL(
|
||||
bot=self,
|
||||
type=type
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def set_my_commands(
|
||||
self,
|
||||
@ -753,7 +760,7 @@ class Bot(BaseConnection):
|
||||
return await ChangeInfo(
|
||||
bot=self,
|
||||
commands=list(commands)
|
||||
).request()
|
||||
).fetch()
|
||||
|
||||
async def download_file(
|
||||
self,
|
||||
@ -777,4 +784,4 @@ class Bot(BaseConnection):
|
||||
path=path,
|
||||
media_url=url,
|
||||
media_token=token
|
||||
).request()
|
||||
).fetch()
|
10
maxapi/client/default.py
Normal file
10
maxapi/client/default.py
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
from aiohttp import ClientTimeout
|
||||
|
||||
|
||||
class DefaultConnectionProperties:
|
||||
|
||||
def __init__(self, timeout: int = 5 * 30, sock_connect: int = 30, **kwargs):
|
||||
self.timeout = ClientTimeout(total=timeout, sock_connect=sock_connect)
|
||||
self.kwargs = kwargs
|
@ -1,7 +1,9 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import mimetypes
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, Optional
|
||||
from uuid import uuid4
|
||||
|
||||
import aiofiles
|
||||
@ -18,7 +20,7 @@ from ..enums.http_method import HTTPMethod
|
||||
from ..enums.api_path import ApiPath
|
||||
from ..enums.upload_type import UploadType
|
||||
|
||||
from ..loggers import logger_bot, logger_connection
|
||||
from ..loggers import logger_bot
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..bot import Bot
|
||||
@ -36,15 +38,15 @@ class BaseConnection:
|
||||
|
||||
API_URL = 'https://botapi.max.ru'
|
||||
|
||||
def __init__(self):
|
||||
self.bot: 'Bot' = None
|
||||
self.session: ClientSession = None
|
||||
def __init__(self) -> None:
|
||||
self.bot: Optional[Bot] = None
|
||||
self.session: Optional[ClientSession] = None
|
||||
|
||||
async def request(
|
||||
self,
|
||||
method: HTTPMethod,
|
||||
path: ApiPath,
|
||||
model: BaseModel = None,
|
||||
path: ApiPath | str,
|
||||
model: BaseModel | Any = None,
|
||||
is_return_raw: bool = False,
|
||||
**kwargs
|
||||
):
|
||||
@ -64,8 +66,14 @@ class BaseConnection:
|
||||
- dict (если is_return_raw=True)
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
|
||||
if not self.bot.session:
|
||||
self.bot.session = ClientSession(self.bot.API_URL)
|
||||
self.bot.session = ClientSession(
|
||||
base_url=self.bot.API_URL,
|
||||
timeout=self.bot.default_connection.timeout,
|
||||
**self.bot.default_connection.kwargs
|
||||
)
|
||||
|
||||
try:
|
||||
r = await self.bot.session.request(
|
||||
@ -90,7 +98,7 @@ class BaseConnection:
|
||||
|
||||
if is_return_raw: return raw
|
||||
|
||||
model = model(**raw)
|
||||
model = model(**raw) # type: ignore
|
||||
|
||||
if hasattr(model, 'message'):
|
||||
attr = getattr(model, 'message')
|
||||
|
@ -1,6 +1,6 @@
|
||||
import asyncio
|
||||
|
||||
from typing import Any, Dict
|
||||
from typing import Any, Dict, Optional, Union
|
||||
|
||||
from ..context.state_machine import State, StatesGroup
|
||||
|
||||
@ -19,7 +19,7 @@ class MemoryContext:
|
||||
self.chat_id = chat_id
|
||||
self.user_id = user_id
|
||||
self._context: Dict[str, Any] = {}
|
||||
self._state: State | None = None
|
||||
self._state: State | str | None = None
|
||||
self._lock = asyncio.Lock()
|
||||
|
||||
async def get_data(self) -> dict[str, Any]:
|
||||
@ -58,7 +58,7 @@ class MemoryContext:
|
||||
async with self._lock:
|
||||
self._context.update(kwargs)
|
||||
|
||||
async def set_state(self, state: State | str = None):
|
||||
async def set_state(self, state: Optional[Union[State, str]] = None):
|
||||
|
||||
"""
|
||||
Устанавливает новое состояние.
|
||||
|
@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from typing import Any, Callable, Dict, List, TYPE_CHECKING
|
||||
from typing import Any, Callable, Dict, List, TYPE_CHECKING, Optional, cast
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.responses import JSONResponse
|
||||
@ -45,7 +45,7 @@ class Dispatcher:
|
||||
применение middleware, фильтров и вызов соответствующих обработчиков.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self) -> None:
|
||||
|
||||
"""
|
||||
Инициализация диспетчера.
|
||||
@ -53,12 +53,12 @@ class Dispatcher:
|
||||
|
||||
self.event_handlers: List[Handler] = []
|
||||
self.contexts: List[MemoryContext] = []
|
||||
self.routers: List[Router] = []
|
||||
self.routers: List[Router | Dispatcher] = []
|
||||
self.filters: List[MagicFilter] = []
|
||||
self.middlewares: List[BaseMiddleware] = []
|
||||
|
||||
self.bot: Bot = None
|
||||
self.on_started_func: Callable = None
|
||||
self.bot: Optional[Bot] = None
|
||||
self.on_started_func: Optional[Callable] = None
|
||||
|
||||
self.message_created = Event(update_type=UpdateType.MESSAGE_CREATED, router=self)
|
||||
self.bot_added = Event(update_type=UpdateType.BOT_ADDED, router=self)
|
||||
@ -249,18 +249,18 @@ class Dispatcher:
|
||||
|
||||
while True:
|
||||
try:
|
||||
events = await self.bot.get_updates()
|
||||
events: Dict = await self.bot.get_updates() # type: ignore
|
||||
|
||||
if isinstance(events, Error):
|
||||
logger_dp.info(f'Ошибка при получении обновлений: {events}, жду {GET_UPDATES_RETRY_DELAY} секунд')
|
||||
await asyncio.sleep(GET_UPDATES_RETRY_DELAY)
|
||||
continue
|
||||
|
||||
self.bot.marker_updates = events.get('marker')
|
||||
|
||||
self.bot.marker_updates = events.get('marker') # type: ignore
|
||||
|
||||
processed_events = await process_update_request(
|
||||
events=events,
|
||||
bot=self.bot
|
||||
bot=self.bot # type: ignore
|
||||
)
|
||||
|
||||
for event in processed_events:
|
||||
@ -270,7 +270,7 @@ class Dispatcher:
|
||||
logger_dp.error(f'Ошибка подключения, жду {CONNECTION_RETRY_DELAY} секунд')
|
||||
await asyncio.sleep(CONNECTION_RETRY_DELAY)
|
||||
except Exception as e:
|
||||
logger_dp.error(f'Общая ошибка при обработке событий: {e}')
|
||||
logger_dp.error(f'Общая ошибка при обработке событий: {e.__class__} - {e}')
|
||||
|
||||
async def handle_webhook(self, bot: Bot, host: str = '0.0.0.0', port: int = 8080):
|
||||
|
||||
@ -289,7 +289,7 @@ class Dispatcher:
|
||||
|
||||
event_object = await process_update_webhook(
|
||||
event_json=event_json,
|
||||
bot=self.bot
|
||||
bot=self.bot # type: ignore
|
||||
)
|
||||
|
||||
await self.handle(event_object)
|
||||
|
@ -16,4 +16,5 @@ class AttachmentType(str, Enum):
|
||||
STICKER = 'sticker'
|
||||
CONTACT = 'contact'
|
||||
INLINE_KEYBOARD = 'inline_keyboard'
|
||||
LOCATION = 'location'
|
||||
LOCATION = 'location'
|
||||
SHARE = 'share'
|
@ -1,3 +1,11 @@
|
||||
|
||||
class MaxConnection(BaseException):
|
||||
...
|
||||
|
||||
|
||||
class MaxUploadFileFailed(BaseException):
|
||||
...
|
||||
|
||||
|
||||
class MaxIconParamsException(BaseException):
|
||||
...
|
@ -1,4 +1,4 @@
|
||||
from typing import TYPE_CHECKING, List
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional
|
||||
|
||||
from .types.added_admin_chat import AddedListAdminChat
|
||||
from ..types.users import ChatAdmin
|
||||
@ -30,14 +30,14 @@ class AddAdminChat(BaseConnection):
|
||||
bot: 'Bot',
|
||||
chat_id: int,
|
||||
admins: List[ChatAdmin],
|
||||
marker: int = None
|
||||
marker: Optional[int] = None
|
||||
):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
self.admins = admins
|
||||
self.marker = marker
|
||||
|
||||
async def request(self) -> AddedListAdminChat:
|
||||
async def fetch(self) -> AddedListAdminChat:
|
||||
|
||||
"""
|
||||
Выполняет HTTP POST запрос для добавления администраторов в чат.
|
||||
@ -48,7 +48,9 @@ class AddAdminChat(BaseConnection):
|
||||
AddedListAdminChat: Результат операции с информацией об успешности.
|
||||
"""
|
||||
|
||||
json = {}
|
||||
assert self.bot is not None
|
||||
|
||||
json: Dict[str, Any] = {}
|
||||
|
||||
json['admins'] = [admin.model_dump() for admin in self.admins]
|
||||
json['marker'] = self.marker
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import TYPE_CHECKING, List
|
||||
from typing import TYPE_CHECKING, Any, Dict, List
|
||||
|
||||
from ..methods.types.added_members_chat import AddedMembersChat
|
||||
|
||||
@ -34,7 +34,7 @@ class AddMembersChat(BaseConnection):
|
||||
self.chat_id = chat_id
|
||||
self.user_ids = user_ids
|
||||
|
||||
async def request(self) -> AddedMembersChat:
|
||||
async def fetch(self) -> AddedMembersChat:
|
||||
|
||||
"""
|
||||
Отправляет POST-запрос на добавление пользователей в чат.
|
||||
@ -45,7 +45,9 @@ class AddMembersChat(BaseConnection):
|
||||
AddedMembersChat: Результат операции с информацией об успешности добавления.
|
||||
"""
|
||||
|
||||
json = {}
|
||||
assert self.bot is not None
|
||||
|
||||
json: Dict[str, Any] = {}
|
||||
|
||||
json['user_ids'] = self.user_ids
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Any, Dict, List, TYPE_CHECKING
|
||||
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
||||
|
||||
from ..types.users import User
|
||||
from ..types.command import BotCommand
|
||||
@ -29,10 +29,10 @@ class ChangeInfo(BaseConnection):
|
||||
def __init__(
|
||||
self,
|
||||
bot: 'Bot',
|
||||
name: str = None,
|
||||
description: str = None,
|
||||
commands: List[BotCommand] = None,
|
||||
photo: Dict[str, Any] = None
|
||||
name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
commands: Optional[List[BotCommand]] = None,
|
||||
photo: Optional[Dict[str, Any]] = None
|
||||
):
|
||||
self.bot = bot
|
||||
self.name = name
|
||||
@ -40,7 +40,7 @@ class ChangeInfo(BaseConnection):
|
||||
self.commands = commands
|
||||
self.photo = photo
|
||||
|
||||
async def request(self) -> User:
|
||||
async def fetch(self) -> User:
|
||||
|
||||
"""Отправляет запрос на изменение информации о боте.
|
||||
|
||||
@ -48,7 +48,9 @@ class ChangeInfo(BaseConnection):
|
||||
User: Объект с обновленными данными бота
|
||||
"""
|
||||
|
||||
json = {}
|
||||
assert self.bot is not None
|
||||
|
||||
json: Dict[str, Any] = {}
|
||||
|
||||
if self.name: json['name'] = self.name
|
||||
if self.description: json['description'] = self.description
|
||||
|
@ -30,7 +30,7 @@ class DeleteMeFromMessage(BaseConnection):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
|
||||
async def request(self) -> DeletedBotFromChat:
|
||||
async def fetch(self) -> DeletedBotFromChat:
|
||||
|
||||
"""
|
||||
Отправляет DELETE-запрос для удаления бота из чата.
|
||||
@ -39,6 +39,7 @@ class DeleteMeFromMessage(BaseConnection):
|
||||
DeletedBotFromChat: Результат операции удаления.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.DELETE,
|
||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ME,
|
||||
|
@ -29,7 +29,7 @@ class DeleteChat(BaseConnection):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
|
||||
async def request(self) -> DeletedChat:
|
||||
async def fetch(self) -> DeletedChat:
|
||||
|
||||
"""
|
||||
Отправляет DELETE-запрос для удаления указанного чата.
|
||||
@ -38,6 +38,7 @@ class DeleteChat(BaseConnection):
|
||||
DeletedChat: Результат операции удаления чата.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.DELETE,
|
||||
path=ApiPath.CHATS.value + '/' + str(self.chat_id),
|
||||
|
@ -29,7 +29,7 @@ class DeleteMessage(BaseConnection):
|
||||
self.bot = bot
|
||||
self.message_id = message_id
|
||||
|
||||
async def request(self) -> DeletedMessage:
|
||||
async def fetch(self) -> DeletedMessage:
|
||||
|
||||
"""
|
||||
Выполняет DELETE-запрос для удаления сообщения.
|
||||
@ -40,6 +40,7 @@ class DeleteMessage(BaseConnection):
|
||||
DeletedMessage: Результат операции удаления сообщения.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
params['message_id'] = self.message_id
|
||||
|
@ -19,18 +19,18 @@ class DeletePinMessage(BaseConnection):
|
||||
|
||||
Args:
|
||||
bot (Bot): Экземпляр бота для выполнения запроса.
|
||||
chat_id (str): Идентификатор чата, из которого нужно удалить закреплённое сообщение.
|
||||
chat_id (int): Идентификатор чата, из которого нужно удалить закреплённое сообщение.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
bot: 'Bot',
|
||||
chat_id: str,
|
||||
chat_id: int,
|
||||
):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
|
||||
async def request(self) -> DeletedPinMessage:
|
||||
async def fetch(self) -> DeletedPinMessage:
|
||||
|
||||
"""
|
||||
Выполняет DELETE-запрос для удаления закреплённого сообщения.
|
||||
@ -38,7 +38,7 @@ class DeletePinMessage(BaseConnection):
|
||||
Returns:
|
||||
DeletedPinMessage: Результат операции удаления закреплённого сообщения.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.DELETE,
|
||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.PIN,
|
||||
|
@ -36,7 +36,7 @@ class DownloadMedia(BaseConnection):
|
||||
self.media_url = media_url
|
||||
self.media_token = media_token
|
||||
|
||||
async def request(self) -> int:
|
||||
async def fetch(self) -> int:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для скачивания медиафайла
|
||||
|
@ -1,9 +1,11 @@
|
||||
|
||||
|
||||
from logging import getLogger
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||
from collections import Counter
|
||||
|
||||
from ..exceptions.max import MaxIconParamsException
|
||||
|
||||
from ..types.attachments.image import PhotoAttachmentRequestPayload
|
||||
from ..types.chats import Chat
|
||||
|
||||
@ -37,10 +39,10 @@ class EditChat(BaseConnection):
|
||||
self,
|
||||
bot: 'Bot',
|
||||
chat_id: int,
|
||||
icon: PhotoAttachmentRequestPayload = None,
|
||||
title: str = None,
|
||||
pin: str = None,
|
||||
notify: bool = True,
|
||||
icon: Optional[PhotoAttachmentRequestPayload] = None,
|
||||
title: Optional[str] = None,
|
||||
pin: Optional[str] = None,
|
||||
notify: Optional[bool] = None,
|
||||
):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
@ -49,7 +51,7 @@ class EditChat(BaseConnection):
|
||||
self.pin = pin
|
||||
self.notify = notify
|
||||
|
||||
async def request(self) -> Chat:
|
||||
async def fetch(self) -> Chat:
|
||||
|
||||
"""
|
||||
Выполняет PATCH-запрос для обновления параметров чата.
|
||||
@ -62,7 +64,8 @@ class EditChat(BaseConnection):
|
||||
Chat: Обновлённый объект чата.
|
||||
"""
|
||||
|
||||
json = {}
|
||||
assert self.bot is not None
|
||||
json: Dict[str, Any] = {}
|
||||
|
||||
if self.icon:
|
||||
dump = self.icon.model_dump()
|
||||
@ -70,7 +73,8 @@ class EditChat(BaseConnection):
|
||||
|
||||
if not None in counter or \
|
||||
not counter[None] == 2:
|
||||
return logger.error(
|
||||
|
||||
raise MaxIconParamsException(
|
||||
'Все атрибуты модели Icon являются взаимоисключающими | '
|
||||
'https://dev.max.ru/docs-api/methods/PATCH/chats/-chatId-'
|
||||
)
|
||||
|
@ -1,6 +1,8 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import List, TYPE_CHECKING, Optional
|
||||
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
||||
|
||||
from ..utils.message import process_input_media
|
||||
|
||||
from .types.edited_message import EditedMessage
|
||||
from ..types.message import NewMessageLink
|
||||
@ -37,10 +39,10 @@ class EditMessage(BaseConnection):
|
||||
self,
|
||||
bot: Bot,
|
||||
message_id: str,
|
||||
text: str = None,
|
||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
||||
link: NewMessageLink = None,
|
||||
notify: bool = True,
|
||||
text: Optional[str] = None,
|
||||
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||
link: Optional[NewMessageLink] = None,
|
||||
notify: Optional[bool] = None,
|
||||
parse_mode: Optional[ParseMode] = None
|
||||
):
|
||||
self.bot = bot
|
||||
@ -51,7 +53,7 @@ class EditMessage(BaseConnection):
|
||||
self.notify = notify
|
||||
self.parse_mode = parse_mode
|
||||
|
||||
async def request(self) -> EditedMessage:
|
||||
async def fetch(self) -> EditedMessage:
|
||||
|
||||
"""
|
||||
Выполняет PUT-запрос для обновления сообщения.
|
||||
@ -62,15 +64,31 @@ class EditMessage(BaseConnection):
|
||||
EditedMessage: Обновлённое сообщение.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
json = {}
|
||||
json: Dict[str, Any] = {}
|
||||
|
||||
params['message_id'] = self.message_id
|
||||
|
||||
if not self.text is None: json['text'] = self.text
|
||||
if self.attachments: json['attachments'] = \
|
||||
[att.model_dump() for att in self.attachments]
|
||||
|
||||
if self.attachments:
|
||||
|
||||
for att in self.attachments:
|
||||
|
||||
if isinstance(att, InputMedia) or isinstance(att, InputMediaBuffer):
|
||||
input_media = await process_input_media(
|
||||
base_connection=self,
|
||||
bot=self.bot,
|
||||
att=att
|
||||
)
|
||||
json['attachments'].append(
|
||||
input_media.model_dump()
|
||||
)
|
||||
else:
|
||||
json['attachments'].append(att.model_dump())
|
||||
|
||||
if not self.link is None: json['link'] = self.link.model_dump()
|
||||
if not self.notify is None: json['notify'] = self.notify
|
||||
if not self.parse_mode is None: json['format'] = self.parse_mode.value
|
||||
|
@ -30,7 +30,7 @@ class GetChatById(BaseConnection):
|
||||
self.bot = bot
|
||||
self.id = id
|
||||
|
||||
async def request(self) -> Chat:
|
||||
async def fetch(self) -> Chat:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения данных чата.
|
||||
@ -39,6 +39,7 @@ class GetChatById(BaseConnection):
|
||||
Chat: Объект чата с полной информацией.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.GET,
|
||||
path=ApiPath.CHATS.value + '/' + str(self.id),
|
||||
|
@ -40,7 +40,7 @@ class GetChatByLink(BaseConnection):
|
||||
if not self.link:
|
||||
return
|
||||
|
||||
async def request(self) -> Chat:
|
||||
async def fetch(self) -> Chat:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения данных чата по ссылке.
|
||||
@ -49,6 +49,7 @@ class GetChatByLink(BaseConnection):
|
||||
Chat: Объект с информацией о чате.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.GET,
|
||||
path=ApiPath.CHATS.value + '/' + self.link[-1],
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from ..types.chats import Chats
|
||||
|
||||
@ -32,13 +32,13 @@ class GetChats(BaseConnection):
|
||||
self,
|
||||
bot: 'Bot',
|
||||
count: int = 50,
|
||||
marker: int = None
|
||||
marker: Optional[int] = None
|
||||
):
|
||||
self.bot = bot
|
||||
self.count = count
|
||||
self.marker = marker
|
||||
|
||||
async def request(self) -> Chats:
|
||||
async def fetch(self) -> Chats:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения списка чатов.
|
||||
@ -46,7 +46,7 @@ class GetChats(BaseConnection):
|
||||
Returns:
|
||||
Chats: Объект с данными по списку чатов.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
params['count'] = self.count
|
||||
|
@ -34,7 +34,7 @@ class GetListAdminChat(BaseConnection):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
|
||||
async def request(self) -> GettedListAdminChat:
|
||||
async def fetch(self) -> GettedListAdminChat:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения списка администраторов указанного чата.
|
||||
@ -42,7 +42,7 @@ class GetListAdminChat(BaseConnection):
|
||||
Returns:
|
||||
GettedListAdminChat: Объект с информацией о администраторах чата.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.GET,
|
||||
path=ApiPath.CHATS.value + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ADMINS,
|
||||
|
@ -24,7 +24,7 @@ class GetMe(BaseConnection):
|
||||
def __init__(self, bot: 'Bot'):
|
||||
self.bot = bot
|
||||
|
||||
async def request(self) -> User:
|
||||
async def fetch(self) -> User:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения данных о боте.
|
||||
@ -32,7 +32,7 @@ class GetMe(BaseConnection):
|
||||
Returns:
|
||||
User: Объект пользователя с полной информацией.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.GET,
|
||||
path=ApiPath.ME,
|
||||
|
@ -34,7 +34,7 @@ class GetMeFromChat(BaseConnection):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
|
||||
async def request(self) -> ChatMember:
|
||||
async def fetch(self) -> ChatMember:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения информации о боте в указанном чате.
|
||||
@ -42,7 +42,7 @@ class GetMeFromChat(BaseConnection):
|
||||
Returns:
|
||||
ChatMember: Информация о боте как участнике чата.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.GET,
|
||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.MEMBERS + ApiPath.ME,
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import TYPE_CHECKING, List
|
||||
from typing import TYPE_CHECKING, List, Optional
|
||||
|
||||
from ..methods.types.getted_members_chat import GettedMembersChat
|
||||
|
||||
@ -27,7 +27,7 @@ class GetMembersChat(BaseConnection):
|
||||
Attributes:
|
||||
bot (Bot): Экземпляр бота.
|
||||
chat_id (int): Идентификатор чата.
|
||||
user_ids (List[str] | None): Список ID пользователей для фильтра.
|
||||
user_ids (List[int] | None): Список ID пользователей для фильтра.
|
||||
marker (int | None): Позиция для пагинации.
|
||||
count (int | None): Максимальное количество участников.
|
||||
"""
|
||||
@ -36,9 +36,9 @@ class GetMembersChat(BaseConnection):
|
||||
self,
|
||||
bot: 'Bot',
|
||||
chat_id: int,
|
||||
user_ids: List[str] = None,
|
||||
marker: int = None,
|
||||
count: int = None,
|
||||
user_ids: Optional[List[int]] = None,
|
||||
marker: Optional[int] = None,
|
||||
count: Optional[int] = None,
|
||||
|
||||
):
|
||||
self.bot = bot
|
||||
@ -47,7 +47,7 @@ class GetMembersChat(BaseConnection):
|
||||
self.marker = marker
|
||||
self.count = count
|
||||
|
||||
async def request(self) -> GettedMembersChat:
|
||||
async def fetch(self) -> GettedMembersChat:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения участников чата с опциональной фильтрацией.
|
||||
@ -57,12 +57,12 @@ class GetMembersChat(BaseConnection):
|
||||
Returns:
|
||||
GettedMembersChat: Объект с данными по участникам чата.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
if self.user_ids:
|
||||
self.user_ids = [str(user_id) for user_id in self.user_ids]
|
||||
params['user_ids'] = ','.join(self.user_ids)
|
||||
params['user_ids'] = ','.join([str(user_id) for user_id in self.user_ids])
|
||||
|
||||
if self.marker: params['marker'] = self.marker
|
||||
if self.count: params['marker'] = self.count
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, List
|
||||
from typing import TYPE_CHECKING, List, Optional, Union
|
||||
|
||||
from ..types.message import Messages
|
||||
from ..enums.http_method import HTTPMethod
|
||||
@ -36,10 +36,10 @@ class GetMessages(BaseConnection):
|
||||
def __init__(
|
||||
self,
|
||||
bot: 'Bot',
|
||||
chat_id: int,
|
||||
message_ids: List[str] = None,
|
||||
from_time: datetime | int = None,
|
||||
to_time: datetime | int = None,
|
||||
chat_id: Optional[int] = None,
|
||||
message_ids: Optional[List[str]] = None,
|
||||
from_time: Optional[Union[datetime, int]] = None,
|
||||
to_time: Optional[Union[datetime, int]] = None,
|
||||
count: int = 50,
|
||||
):
|
||||
self.bot = bot
|
||||
@ -49,7 +49,7 @@ class GetMessages(BaseConnection):
|
||||
self.to_time = to_time
|
||||
self.count = count
|
||||
|
||||
async def request(self) -> Messages:
|
||||
async def fetch(self) -> Messages:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения сообщений с учётом параметров фильтрации.
|
||||
@ -59,7 +59,7 @@ class GetMessages(BaseConnection):
|
||||
Returns:
|
||||
Messages: Объект с полученными сообщениями.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
if self.chat_id: params['chat_id'] = self.chat_id
|
||||
|
@ -29,7 +29,7 @@ class GetPinnedMessage(BaseConnection):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
|
||||
async def request(self) -> GettedPin:
|
||||
async def fetch(self) -> GettedPin:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения закреплённого сообщения.
|
||||
@ -37,7 +37,7 @@ class GetPinnedMessage(BaseConnection):
|
||||
Returns:
|
||||
GettedPin: Объект с информацией о закреплённом сообщении.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.GET,
|
||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + ApiPath.PIN,
|
||||
|
@ -1,4 +1,5 @@
|
||||
from typing import TYPE_CHECKING
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING, Dict
|
||||
|
||||
from ..types.updates import UpdateUnion
|
||||
|
||||
@ -28,13 +29,13 @@ class GetUpdates(BaseConnection):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
bot: 'Bot',
|
||||
bot: Bot,
|
||||
limit: int = 100,
|
||||
):
|
||||
self.bot = bot
|
||||
self.limit = limit
|
||||
|
||||
async def request(self) -> UpdateUnion:
|
||||
async def fetch(self) -> Dict:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения обновлений с указанным лимитом.
|
||||
@ -44,7 +45,7 @@ class GetUpdates(BaseConnection):
|
||||
Returns:
|
||||
UpdateUnion: Объединённый тип данных обновлений.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
params['limit'] = self.limit
|
||||
|
@ -33,7 +33,7 @@ class GetUploadURL(BaseConnection):
|
||||
self.bot = bot
|
||||
self.type = type
|
||||
|
||||
async def request(self) -> GettedUploadUrl:
|
||||
async def fetch(self) -> GettedUploadUrl:
|
||||
|
||||
"""
|
||||
Выполняет POST-запрос для получения URL загрузки файла.
|
||||
@ -43,7 +43,7 @@ class GetUploadURL(BaseConnection):
|
||||
Returns:
|
||||
GettedUploadUrl: Результат с URL для загрузки.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
params['type'] = self.type.value
|
||||
|
@ -30,7 +30,7 @@ class GetVideo(BaseConnection):
|
||||
self.bot = bot
|
||||
self.video_token = video_token
|
||||
|
||||
async def request(self) -> Video:
|
||||
async def fetch(self) -> Video:
|
||||
|
||||
"""
|
||||
Выполняет GET-запрос для получения данных видео по токену.
|
||||
@ -38,7 +38,7 @@ class GetVideo(BaseConnection):
|
||||
Returns:
|
||||
Video: Объект с информацией о видео.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.GET,
|
||||
path=ApiPath.VIDEOS.value + '/' + self.video_token,
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||
|
||||
from .types.pinned_message import PinnedMessage
|
||||
|
||||
@ -35,14 +35,14 @@ class PinMessage(BaseConnection):
|
||||
bot: 'Bot',
|
||||
chat_id: int,
|
||||
message_id: str,
|
||||
notify: bool = True
|
||||
notify: Optional[bool] = None
|
||||
):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
self.message_id = message_id
|
||||
self.notify = notify
|
||||
|
||||
async def request(self) -> PinnedMessage:
|
||||
async def fetch(self) -> PinnedMessage:
|
||||
|
||||
"""
|
||||
Выполняет PUT-запрос для закрепления сообщения в чате.
|
||||
@ -52,8 +52,8 @@ class PinMessage(BaseConnection):
|
||||
Returns:
|
||||
PinnedMessage: Объект с информацией о закреплённом сообщении.
|
||||
"""
|
||||
|
||||
json = {}
|
||||
assert self.bot is not None
|
||||
json: Dict[str, Any] = {}
|
||||
|
||||
json['message_id'] = self.message_id
|
||||
json['notify'] = self.notify
|
||||
|
@ -38,7 +38,7 @@ class RemoveAdmin(BaseConnection):
|
||||
self.chat_id = chat_id
|
||||
self.user_id = user_id
|
||||
|
||||
async def request(self) -> RemovedAdmin:
|
||||
async def fetch(self) -> RemovedAdmin:
|
||||
|
||||
"""
|
||||
Выполняет DELETE-запрос для отмены прав администратора в чате.
|
||||
@ -46,11 +46,11 @@ class RemoveAdmin(BaseConnection):
|
||||
Returns:
|
||||
RemovedAdmin: Объект с результатом отмены прав администратора.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await super().request(
|
||||
method=HTTPMethod.DELETE,
|
||||
path=ApiPath.CHATS + '/' + str(self.chat_id) + \
|
||||
ApiPath.MEMBERS + ApiPath.ADMINS + '/' + str(self.user_id),
|
||||
model=RemovedAdmin,
|
||||
params=self.bot.params,
|
||||
)
|
||||
)
|
@ -43,7 +43,7 @@ class RemoveMemberChat(BaseConnection):
|
||||
self.user_id = user_id
|
||||
self.block = block
|
||||
|
||||
async def request(self) -> RemovedMemberChat:
|
||||
async def fetch(self) -> RemovedMemberChat:
|
||||
|
||||
"""
|
||||
Выполняет DELETE-запрос для удаления пользователя из чата.
|
||||
@ -54,6 +54,7 @@ class RemoveMemberChat(BaseConnection):
|
||||
RemovedMemberChat: Результат удаления участника.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
params['chat_id'] = self.chat_id
|
||||
|
@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||
|
||||
from ..methods.types.sended_action import SendedAction
|
||||
|
||||
@ -34,14 +34,14 @@ class SendAction(BaseConnection):
|
||||
def __init__(
|
||||
self,
|
||||
bot: 'Bot',
|
||||
chat_id: int = None,
|
||||
chat_id: Optional[int] = None,
|
||||
action: SenderAction = SenderAction.TYPING_ON
|
||||
):
|
||||
self.bot = bot
|
||||
self.chat_id = chat_id
|
||||
self.action = action
|
||||
|
||||
async def request(self) -> SendedAction:
|
||||
async def fetch(self) -> SendedAction:
|
||||
|
||||
"""
|
||||
Выполняет POST-запрос для отправки действия в указанный чат.
|
||||
@ -49,8 +49,9 @@ class SendAction(BaseConnection):
|
||||
Returns:
|
||||
SendedAction: Результат выполнения запроса.
|
||||
"""
|
||||
assert self.bot is not None
|
||||
|
||||
json = {}
|
||||
json: Dict[str, Any] = {}
|
||||
|
||||
json['action'] = self.action.value
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
||||
|
||||
from ..methods.types.sended_callback import SendedCallback
|
||||
|
||||
@ -36,15 +36,15 @@ class SendCallback(BaseConnection):
|
||||
self,
|
||||
bot: 'Bot',
|
||||
callback_id: str,
|
||||
message: Message = None,
|
||||
notification: str = None
|
||||
message: Optional[Message] = None,
|
||||
notification: Optional[str] = None
|
||||
):
|
||||
self.bot = bot
|
||||
self.callback_id = callback_id
|
||||
self.message = message
|
||||
self.notification = notification
|
||||
|
||||
async def request(self) -> SendedCallback:
|
||||
async def fetch(self) -> SendedCallback:
|
||||
|
||||
"""
|
||||
Выполняет POST-запрос для отправки callback-ответа.
|
||||
@ -55,11 +55,12 @@ class SendCallback(BaseConnection):
|
||||
SendedCallback: Объект с результатом отправки callback.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
params['callback_id'] = self.callback_id
|
||||
|
||||
json = {}
|
||||
json: Dict[str, Any] = {}
|
||||
|
||||
if self.message: json['message'] = self.message.model_dump()
|
||||
if self.notification: json['notification'] = self.notification
|
||||
|
@ -1,10 +1,14 @@
|
||||
|
||||
|
||||
import asyncio
|
||||
from typing import List, TYPE_CHECKING, Optional
|
||||
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
||||
|
||||
from json import loads as json_loads
|
||||
|
||||
from ..utils.message import process_input_media
|
||||
|
||||
from ..exceptions.max import MaxUploadFileFailed
|
||||
|
||||
from .types.sended_message import SendedMessage
|
||||
from ..types.attachments.upload import AttachmentPayload, AttachmentUpload
|
||||
from ..types.errors import Error
|
||||
@ -39,7 +43,7 @@ class SendMessage(BaseConnection):
|
||||
chat_id (int, optional): Идентификатор чата, куда отправлять сообщение.
|
||||
user_id (int, optional): Идентификатор пользователя, если нужно отправить личное сообщение.
|
||||
text (str, optional): Текст сообщения.
|
||||
attachments (List[Attachment | InputMedia], optional): Список вложений к сообщению.
|
||||
attachments (List[Attachment | InputMedia | InputMediaBuffer], optional): Список вложений к сообщению.
|
||||
link (NewMessageLink, optional): Связь с другим сообщением (например, ответ или пересылка).
|
||||
notify (bool, optional): Отправлять ли уведомление о сообщении. По умолчанию True.
|
||||
parse_mode (ParseMode, optional): Режим разбора текста (например, Markdown, HTML).
|
||||
@ -48,12 +52,12 @@ class SendMessage(BaseConnection):
|
||||
def __init__(
|
||||
self,
|
||||
bot: 'Bot',
|
||||
chat_id: int = None,
|
||||
user_id: int = None,
|
||||
text: str = None,
|
||||
attachments: List[Attachment | InputMedia] = None,
|
||||
link: NewMessageLink = None,
|
||||
notify: bool = True,
|
||||
chat_id: Optional[int] = None,
|
||||
user_id: Optional[int] = None,
|
||||
text: Optional[str] = None,
|
||||
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||
link: Optional[NewMessageLink] = None,
|
||||
notify: Optional[bool] = None,
|
||||
parse_mode: Optional[ParseMode] = None
|
||||
):
|
||||
self.bot = bot
|
||||
@ -65,59 +69,7 @@ class SendMessage(BaseConnection):
|
||||
self.notify = notify
|
||||
self.parse_mode = parse_mode
|
||||
|
||||
async def __process_input_media(
|
||||
self,
|
||||
att: InputMedia | InputMediaBuffer
|
||||
):
|
||||
|
||||
# очень нестабильный метод независящий от модуля
|
||||
# ждем обновлений MAX API
|
||||
|
||||
"""
|
||||
Загружает файл вложения и формирует объект AttachmentUpload.
|
||||
|
||||
Args:
|
||||
att (InputMedia): Объект вложения для загрузки.
|
||||
|
||||
Returns:
|
||||
AttachmentUpload: Загруженное вложение с токеном.
|
||||
"""
|
||||
|
||||
upload = await self.bot.get_upload_url(att.type)
|
||||
|
||||
if isinstance(att, InputMedia):
|
||||
upload_file_response = await self.upload_file(
|
||||
url=upload.url,
|
||||
path=att.path,
|
||||
type=att.type,
|
||||
)
|
||||
elif isinstance(att, InputMediaBuffer):
|
||||
upload_file_response = await self.upload_file_buffer(
|
||||
url=upload.url,
|
||||
buffer=att.buffer,
|
||||
type=att.type,
|
||||
)
|
||||
|
||||
if att.type in (UploadType.VIDEO, UploadType.AUDIO):
|
||||
token = upload.token
|
||||
|
||||
elif att.type == UploadType.FILE:
|
||||
json_r = json_loads(upload_file_response)
|
||||
token = json_r['token']
|
||||
|
||||
elif att.type == UploadType.IMAGE:
|
||||
json_r = json_loads(upload_file_response)
|
||||
json_r_keys = list(json_r['photos'].keys())
|
||||
token = json_r['photos'][json_r_keys[0]]['token']
|
||||
|
||||
return AttachmentUpload(
|
||||
type=att.type,
|
||||
payload=AttachmentPayload(
|
||||
token=token
|
||||
)
|
||||
)
|
||||
|
||||
async def request(self) -> SendedMessage:
|
||||
async def fetch(self) -> Optional[SendedMessage | Error]:
|
||||
|
||||
"""
|
||||
Отправляет сообщение с вложениями (если есть), с обработкой задержки готовности вложений.
|
||||
@ -128,9 +80,10 @@ class SendMessage(BaseConnection):
|
||||
SendedMessage или Error
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
params = self.bot.params.copy()
|
||||
|
||||
json = {'attachments': []}
|
||||
json: Dict[str, Any] = {'attachments': []}
|
||||
|
||||
if self.chat_id: params['chat_id'] = self.chat_id
|
||||
elif self.user_id: params['user_id'] = self.user_id
|
||||
@ -142,7 +95,11 @@ class SendMessage(BaseConnection):
|
||||
for att in self.attachments:
|
||||
|
||||
if isinstance(att, InputMedia) or isinstance(att, InputMediaBuffer):
|
||||
input_media = await self.__process_input_media(att)
|
||||
input_media = await process_input_media(
|
||||
base_connection=self,
|
||||
bot=self.bot,
|
||||
att=att
|
||||
)
|
||||
json['attachments'].append(
|
||||
input_media.model_dump()
|
||||
)
|
||||
|
@ -3,5 +3,5 @@ from pydantic import BaseModel
|
||||
|
||||
|
||||
class GettedUploadUrl(BaseModel):
|
||||
url: Optional[str] = None
|
||||
url: str
|
||||
token: Optional[str] = None
|
@ -32,35 +32,35 @@ from .input_media import InputMedia
|
||||
from .input_media import InputMediaBuffer
|
||||
|
||||
__all__ = [
|
||||
CommandStart,
|
||||
OpenAppButton,
|
||||
Message,
|
||||
Attachment,
|
||||
InputMediaBuffer,
|
||||
MessageButton,
|
||||
UpdateUnion,
|
||||
InputMedia,
|
||||
BotCommand,
|
||||
CallbackButton,
|
||||
ChatButton,
|
||||
LinkButton,
|
||||
RequestContactButton,
|
||||
RequestGeoLocationButton,
|
||||
Command,
|
||||
PhotoAttachmentPayload,
|
||||
OtherAttachmentPayload,
|
||||
ContactAttachmentPayload,
|
||||
ButtonsPayload,
|
||||
StickerAttachmentPayload,
|
||||
BotAdded,
|
||||
BotRemoved,
|
||||
BotStarted,
|
||||
ChatTitleChanged,
|
||||
MessageCallback,
|
||||
MessageChatCreated,
|
||||
MessageCreated,
|
||||
MessageEdited,
|
||||
MessageRemoved,
|
||||
UserAdded,
|
||||
UserRemoved
|
||||
]
|
||||
'CommandStart',
|
||||
'OpenAppButton',
|
||||
'Message',
|
||||
'Attachment',
|
||||
'InputMediaBuffer',
|
||||
'MessageButton',
|
||||
'UpdateUnion',
|
||||
'InputMedia',
|
||||
'BotCommand',
|
||||
'CallbackButton',
|
||||
'ChatButton',
|
||||
'LinkButton',
|
||||
'RequestContactButton',
|
||||
'RequestGeoLocationButton',
|
||||
'Command',
|
||||
'PhotoAttachmentPayload',
|
||||
'OtherAttachmentPayload',
|
||||
'ContactAttachmentPayload',
|
||||
'ButtonsPayload',
|
||||
'StickerAttachmentPayload',
|
||||
'BotAdded',
|
||||
'BotRemoved',
|
||||
'BotStarted',
|
||||
'ChatTitleChanged',
|
||||
'MessageCallback',
|
||||
'MessageChatCreated',
|
||||
'MessageCreated',
|
||||
'MessageEdited',
|
||||
'MessageRemoved',
|
||||
'UserAdded',
|
||||
'UserRemoved',
|
||||
]
|
||||
|
@ -112,33 +112,33 @@ class Attachment(BaseModel):
|
||||
bot: Optional[Any] = Field(default=None, exclude=True)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
bot: Optional[Bot]
|
||||
bot: Optional[Bot] # type: ignore
|
||||
|
||||
class Config:
|
||||
use_enum_values = True
|
||||
|
||||
async def download(
|
||||
self,
|
||||
path: str
|
||||
):
|
||||
# async def download(
|
||||
# self,
|
||||
# path: str
|
||||
# ):
|
||||
|
||||
"""
|
||||
Скачивает медиа, сохраняя по определенному пути
|
||||
# """
|
||||
# Скачивает медиа, сохраняя по определенному пути
|
||||
|
||||
:param path: Путь сохранения медиа
|
||||
# :param path: Путь сохранения медиа
|
||||
|
||||
:return: Числовой статус
|
||||
"""
|
||||
# :return: Числовой статус
|
||||
# """
|
||||
|
||||
if not hasattr(self.payload, 'token') or \
|
||||
not hasattr(self.payload, 'url'):
|
||||
raise NotAvailableForDownload()
|
||||
# if not hasattr(self.payload, 'token') or \
|
||||
# not hasattr(self.payload, 'url'):
|
||||
# raise NotAvailableForDownload()
|
||||
|
||||
elif not self.payload.token or not self.payload.url:
|
||||
raise NotAvailableForDownload(f'Медиа типа `{self.type}` недоступно для скачивания')
|
||||
# elif not self.payload.token or not self.payload.url:
|
||||
# raise NotAvailableForDownload(f'Медиа типа `{self.type}` недоступно для скачивания')
|
||||
|
||||
return await self.bot.download_file(
|
||||
path=path,
|
||||
url=self.payload.url,
|
||||
token=self.payload.token,
|
||||
)
|
||||
# return await self.bot.download_file(
|
||||
# path=path,
|
||||
# url=self.payload.url,
|
||||
# token=self.payload.token,
|
||||
# )
|
@ -1,4 +1,6 @@
|
||||
from typing import Literal, Optional
|
||||
from typing import Optional
|
||||
|
||||
from ...enums.attachment import AttachmentType
|
||||
|
||||
from .attachment import Attachment
|
||||
|
||||
@ -13,5 +15,5 @@ class Audio(Attachment):
|
||||
transcription (Optional[str]): Транскрипция аудио (если есть).
|
||||
"""
|
||||
|
||||
type: Literal['audio'] = 'audio'
|
||||
type: AttachmentType = AttachmentType.AUDIO
|
||||
transcription: Optional[str] = None
|
@ -1,4 +1,4 @@
|
||||
from typing import Literal
|
||||
from ...enums.attachment import AttachmentType
|
||||
|
||||
from .attachment import Attachment
|
||||
|
||||
@ -12,4 +12,4 @@ class Contact(Attachment):
|
||||
type (Literal['contact']): Тип вложения, всегда 'contact'.
|
||||
"""
|
||||
|
||||
type: Literal['contact'] = 'contact'
|
||||
type: AttachmentType = AttachmentType.CONTACT
|
@ -1,4 +1,6 @@
|
||||
from typing import Literal, Optional
|
||||
from typing import Optional
|
||||
|
||||
from ...enums.attachment import AttachmentType
|
||||
|
||||
from .attachment import Attachment
|
||||
|
||||
@ -14,6 +16,6 @@ class File(Attachment):
|
||||
size (Optional[int]): Размер файла в байтах.
|
||||
"""
|
||||
|
||||
type: Literal['file'] = 'file'
|
||||
type: AttachmentType = AttachmentType.FILE
|
||||
filename: Optional[str] = None
|
||||
size: Optional[int] = None
|
@ -1,7 +1,9 @@
|
||||
from typing import Literal, Optional
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from .attachment import Attachment
|
||||
from ...enums.attachment import AttachmentType
|
||||
|
||||
|
||||
class PhotoAttachmentRequestPayload(BaseModel):
|
||||
@ -29,4 +31,4 @@ class Image(Attachment):
|
||||
type (Literal['image']): Тип вложения, всегда 'image'.
|
||||
"""
|
||||
|
||||
type: Literal['image'] = 'image'
|
||||
type: AttachmentType = AttachmentType.IMAGE
|
@ -1,4 +1,6 @@
|
||||
from typing import Literal, Optional
|
||||
from typing import Optional
|
||||
|
||||
from ...enums.attachment import AttachmentType
|
||||
|
||||
from .attachment import Attachment
|
||||
|
||||
@ -14,6 +16,6 @@ class Location(Attachment):
|
||||
longitude (Optional[float]): Долгота.
|
||||
"""
|
||||
|
||||
type: Literal['location'] = 'location'
|
||||
type: AttachmentType = AttachmentType.LOCATION
|
||||
latitude: Optional[float] = None
|
||||
longitude: Optional[float] = None
|
@ -1,4 +1,6 @@
|
||||
from typing import Literal, Optional
|
||||
from typing import Optional
|
||||
|
||||
from ...enums.attachment import AttachmentType
|
||||
|
||||
from .attachment import Attachment
|
||||
|
||||
@ -15,7 +17,7 @@ class Share(Attachment):
|
||||
image_url (Optional[str]): URL изображения для предпросмотра.
|
||||
"""
|
||||
|
||||
type: Literal['share'] = 'share'
|
||||
type: AttachmentType = AttachmentType.SHARE
|
||||
title: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
image_url: Optional[str] = None
|
||||
|
@ -1,4 +1,6 @@
|
||||
from typing import Literal, Optional
|
||||
from typing import Optional
|
||||
|
||||
from ...enums.attachment import AttachmentType
|
||||
|
||||
from .attachment import Attachment
|
||||
|
||||
@ -14,6 +16,6 @@ class Sticker(Attachment):
|
||||
height (Optional[int]): Высота стикера в пикселях.
|
||||
"""
|
||||
|
||||
type: Literal['sticker'] = 'sticker'
|
||||
type: AttachmentType = AttachmentType.STICKER
|
||||
width: Optional[int] = None
|
||||
height: Optional[int] = None
|
@ -1,6 +1,8 @@
|
||||
from typing import TYPE_CHECKING, Any, Literal, Optional
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ...enums.attachment import AttachmentType
|
||||
|
||||
from .attachment import Attachment
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -59,7 +61,7 @@ class Video(Attachment):
|
||||
bot (Optional[Any]): Ссылка на экземпляр бота, не сериализуется.
|
||||
"""
|
||||
|
||||
type: Optional[Literal['video']] = 'video'
|
||||
type: AttachmentType = AttachmentType.VIDEO
|
||||
token: Optional[str] = None
|
||||
urls: Optional[VideoUrl] = None
|
||||
thumbnail: VideoThumbnail
|
||||
@ -69,4 +71,4 @@ class Video(Attachment):
|
||||
bot: Optional[Any] = Field(default=None, exclude=True)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
bot: Optional['Bot']
|
||||
bot: Optional['Bot'] # type: ignore
|
||||
|
@ -70,11 +70,11 @@ class InputMediaBuffer:
|
||||
Класс для представления медиафайла из буфера.
|
||||
|
||||
Attributes:
|
||||
buffer (BytesIO): Буфер с содержимым файла.
|
||||
buffer (bytes): Буфер с содержимым файла.
|
||||
type (UploadType): Тип файла, определенный по содержимому.
|
||||
"""
|
||||
|
||||
def __init__(self, buffer: BytesIO):
|
||||
def __init__(self, buffer: bytes):
|
||||
"""
|
||||
Инициализирует объект медиафайла из буфера.
|
||||
|
||||
@ -84,7 +84,7 @@ class InputMediaBuffer:
|
||||
self.buffer = buffer
|
||||
self.type = self.__detect_file_type(buffer)
|
||||
|
||||
def __detect_file_type(self, buffer: BytesIO) -> UploadType:
|
||||
def __detect_file_type(self, buffer: bytes) -> UploadType:
|
||||
try:
|
||||
matches = puremagic.magic_string(buffer)
|
||||
if matches:
|
||||
|
@ -89,7 +89,7 @@ class MessageBody(BaseModel):
|
||||
|
||||
mid: str
|
||||
seq: int
|
||||
text: str = None
|
||||
text: Optional[str] = None
|
||||
attachments: Optional[
|
||||
List[
|
||||
Union[
|
||||
@ -103,7 +103,7 @@ class MessageBody(BaseModel):
|
||||
Location
|
||||
]
|
||||
]
|
||||
] = Field(default_factory=list)
|
||||
] = Field(default_factory=list) # type: ignore
|
||||
|
||||
markup: Optional[
|
||||
List[
|
||||
@ -111,7 +111,7 @@ class MessageBody(BaseModel):
|
||||
MarkupLink, MarkupElement
|
||||
]
|
||||
]
|
||||
] = Field(default_factory=list)
|
||||
] = Field(default_factory=list) # type: ignore
|
||||
|
||||
|
||||
class MessageStat(BaseModel):
|
||||
@ -164,19 +164,19 @@ class Message(BaseModel):
|
||||
recipient: Recipient
|
||||
timestamp: int
|
||||
link: Optional[LinkedMessage] = None
|
||||
body: Optional[MessageBody] = None
|
||||
body: MessageBody
|
||||
stat: Optional[MessageStat] = None
|
||||
url: Optional[str] = None
|
||||
bot: Optional[Any] = Field(default=None, exclude=True)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
bot: Optional[Bot]
|
||||
bot: Optional[Bot] # type: ignore
|
||||
|
||||
async def answer(
|
||||
self,
|
||||
text: str = None,
|
||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
||||
link: NewMessageLink = None,
|
||||
text: Optional[str] = None,
|
||||
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||
link: Optional[NewMessageLink] = None,
|
||||
notify: Optional[bool] = None,
|
||||
parse_mode: Optional[ParseMode] = None
|
||||
):
|
||||
@ -195,6 +195,7 @@ class Message(BaseModel):
|
||||
Any: Результат выполнения метода send_message бота.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await self.bot.send_message(
|
||||
chat_id=self.recipient.chat_id,
|
||||
user_id=self.recipient.user_id,
|
||||
@ -207,8 +208,8 @@ class Message(BaseModel):
|
||||
|
||||
async def reply(
|
||||
self,
|
||||
text: str = None,
|
||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
||||
text: Optional[str] = None,
|
||||
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||
notify: Optional[bool] = None,
|
||||
parse_mode: Optional[ParseMode] = None
|
||||
):
|
||||
@ -226,6 +227,7 @@ class Message(BaseModel):
|
||||
Any: Результат выполнения метода send_message бота.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await self.bot.send_message(
|
||||
chat_id=self.recipient.chat_id,
|
||||
user_id=self.recipient.user_id,
|
||||
@ -242,8 +244,8 @@ class Message(BaseModel):
|
||||
async def forward(
|
||||
self,
|
||||
chat_id,
|
||||
user_id: int = None,
|
||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
||||
user_id: Optional[int] = None,
|
||||
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||
notify: Optional[bool] = None,
|
||||
parse_mode: Optional[ParseMode] = None
|
||||
):
|
||||
@ -262,6 +264,7 @@ class Message(BaseModel):
|
||||
Any: Результат выполнения метода send_message бота.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await self.bot.send_message(
|
||||
chat_id=chat_id,
|
||||
user_id=user_id,
|
||||
@ -276,9 +279,9 @@ class Message(BaseModel):
|
||||
|
||||
async def edit(
|
||||
self,
|
||||
text: str = None,
|
||||
attachments: List[Attachment | InputMedia | InputMediaBuffer] = None,
|
||||
link: NewMessageLink = None,
|
||||
text: Optional[str] = None,
|
||||
attachments: Optional[List[Attachment | InputMedia | InputMediaBuffer]] = None,
|
||||
link: Optional[NewMessageLink] = None,
|
||||
notify: bool = True,
|
||||
parse_mode: Optional[ParseMode] = None
|
||||
):
|
||||
@ -297,6 +300,7 @@ class Message(BaseModel):
|
||||
Any: Результат выполнения метода edit_message бота.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await self.bot.edit_message(
|
||||
message_id=self.body.mid,
|
||||
text=text,
|
||||
@ -331,6 +335,7 @@ class Message(BaseModel):
|
||||
Any: Результат выполнения метода pin_message бота.
|
||||
"""
|
||||
|
||||
assert self.bot is not None
|
||||
return await self.bot.pin_message(
|
||||
chat_id=self.recipient.chat_id,
|
||||
message_id=self.body.mid,
|
||||
@ -352,7 +357,7 @@ class Messages(BaseModel):
|
||||
bot: Optional[Any] = Field(default=None, exclude=True)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
bot: Optional[Bot]
|
||||
bot: Optional[Bot] # type: ignore
|
||||
|
||||
|
||||
class NewMessageLink(BaseModel):
|
||||
|
@ -2,6 +2,8 @@ from typing import List, Optional, TYPE_CHECKING, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from ...types.attachments.location import Location
|
||||
|
||||
from .update import Update
|
||||
|
||||
from ...enums.parse_mode import ParseMode
|
||||
@ -49,10 +51,11 @@ class MessageForCallback(BaseModel):
|
||||
File,
|
||||
Image,
|
||||
Sticker,
|
||||
Share
|
||||
Share,
|
||||
Location
|
||||
]
|
||||
]
|
||||
] = Field(default_factory=list)
|
||||
] = Field(default_factory=list) # type: ignore
|
||||
link: Optional[NewMessageLink] = None
|
||||
notify: Optional[bool] = True
|
||||
format: Optional[ParseMode] = None
|
||||
@ -86,9 +89,9 @@ class MessageCallback(Update):
|
||||
|
||||
async def answer(
|
||||
self,
|
||||
notification: str = None,
|
||||
new_text: str = None,
|
||||
link: NewMessageLink = None,
|
||||
notification: Optional[str] = None,
|
||||
new_text: Optional[str] = None,
|
||||
link: Optional[NewMessageLink] = None,
|
||||
notify: bool = True,
|
||||
format: Optional[ParseMode] = None,
|
||||
):
|
||||
@ -115,6 +118,7 @@ class MessageCallback(Update):
|
||||
message.notify = notify
|
||||
message.format = format
|
||||
|
||||
assert self.bot is not None
|
||||
return await self.bot.send_callback(
|
||||
callback_id=self.callback.callback_id,
|
||||
message=message,
|
||||
|
72
maxapi/utils/message.py
Normal file
72
maxapi/utils/message.py
Normal file
@ -0,0 +1,72 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
from json import loads
|
||||
|
||||
from ..types.input_media import InputMedia, InputMediaBuffer
|
||||
from ..enums.upload_type import UploadType
|
||||
from ..exceptions.max import MaxUploadFileFailed
|
||||
from ..types.attachments.upload import AttachmentPayload, AttachmentUpload
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..bot import Bot
|
||||
from ..connection.base import BaseConnection
|
||||
|
||||
|
||||
async def process_input_media(
|
||||
base_connection: BaseConnection,
|
||||
bot: Bot,
|
||||
att: InputMedia | InputMediaBuffer
|
||||
):
|
||||
|
||||
# очень нестабильный метод независящий от модуля
|
||||
# ждем обновлений MAX API
|
||||
|
||||
"""
|
||||
Загружает файл вложения и формирует объект AttachmentUpload.
|
||||
|
||||
Args:
|
||||
att (InputMedia): Объект вложения для загрузки.
|
||||
|
||||
Returns:
|
||||
AttachmentUpload: Загруженное вложение с токеном.
|
||||
"""
|
||||
|
||||
upload = await bot.get_upload_url(att.type)
|
||||
|
||||
if isinstance(att, InputMedia):
|
||||
upload_file_response = await base_connection.upload_file(
|
||||
url=upload.url,
|
||||
path=att.path,
|
||||
type=att.type,
|
||||
)
|
||||
elif isinstance(att, InputMediaBuffer):
|
||||
upload_file_response = await base_connection.upload_file_buffer(
|
||||
url=upload.url,
|
||||
buffer=att.buffer,
|
||||
type=att.type,
|
||||
)
|
||||
|
||||
if att.type in (UploadType.VIDEO, UploadType.AUDIO):
|
||||
if upload.token is None:
|
||||
assert bot.session is not None
|
||||
await bot.session.close()
|
||||
raise MaxUploadFileFailed('По неизвестной причине token не был получен')
|
||||
|
||||
token = upload.token
|
||||
|
||||
elif att.type == UploadType.FILE:
|
||||
json_r = loads(upload_file_response)
|
||||
token = json_r['token']
|
||||
|
||||
elif att.type == UploadType.IMAGE:
|
||||
json_r = loads(upload_file_response)
|
||||
json_r_keys = list(json_r['photos'].keys())
|
||||
token = json_r['photos'][json_r_keys[0]]['token']
|
||||
|
||||
return AttachmentUpload(
|
||||
type=att.type,
|
||||
payload=AttachmentPayload(
|
||||
token=token
|
||||
)
|
||||
)
|
@ -46,7 +46,7 @@ MemoryContext(chat_id: int, user_id: int)
|
||||
|
||||
---
|
||||
|
||||
### `async def set_state(state: State | str = None)`
|
||||
### `async def set_state(state: Optional[Union[State, str]] = None)`
|
||||
|
||||
Устанавливает новое состояние пользователя или сбрасывает его.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user