Немного оптимизировано и поправлен список зависимостей
This commit is contained in:
parent
c481e3e931
commit
b5947e5f47
141
maxapi/bot.py
141
maxapi/bot.py
@ -1,68 +1,69 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any, Dict, List, TYPE_CHECKING, Optional
|
from typing import Any, Dict, List, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from .methods.download_media import DownloadMedia
|
|
||||||
from .methods.get_upload_url import GetUploadURL
|
|
||||||
from .methods.get_updates import GetUpdates
|
|
||||||
from .methods.remove_member_chat import RemoveMemberChat
|
|
||||||
from .methods.add_admin_chat import AddAdminChat
|
|
||||||
from .methods.add_members_chat import AddMembersChat
|
|
||||||
from .methods.get_members_chat import GetMembersChat
|
|
||||||
from .methods.remove_admin import RemoveAdmin
|
|
||||||
from .methods.get_list_admin_chat import GetListAdminChat
|
|
||||||
from .methods.delete_bot_from_chat import DeleteMeFromMessage
|
|
||||||
from .methods.get_me_from_chat import GetMeFromChat
|
|
||||||
from .methods.delete_pin_message import DeletePinMessage
|
|
||||||
from .methods.get_pinned_message import GetPinnedMessage
|
|
||||||
from .methods.pin_message import PinMessage
|
|
||||||
from .methods.delete_chat import DeleteChat
|
|
||||||
from .methods.send_action import SendAction
|
|
||||||
from .methods.edit_chat import EditChat
|
|
||||||
from .methods.get_chat_by_id import GetChatById
|
|
||||||
from .methods.get_chat_by_link import GetChatByLink
|
|
||||||
from .methods.send_callback import SendCallback
|
|
||||||
from .methods.get_video import GetVideo
|
|
||||||
from .methods.delete_message import DeleteMessage
|
|
||||||
from .methods.edit_message import EditMessage
|
|
||||||
from .methods.change_info import ChangeInfo
|
|
||||||
from .methods.get_me import GetMe
|
|
||||||
from .methods.get_messages import GetMessages
|
|
||||||
from .methods.get_chats import GetChats
|
|
||||||
from .methods.send_message import SendMessage
|
|
||||||
|
|
||||||
|
from .connection.base import BaseConnection
|
||||||
from .enums.parse_mode import ParseMode
|
from .enums.parse_mode import ParseMode
|
||||||
from .enums.sender_action import SenderAction
|
from .enums.sender_action import SenderAction
|
||||||
from .enums.upload_type import UploadType
|
from .enums.upload_type import UploadType
|
||||||
|
|
||||||
from .types.message import Message
|
from .methods.add_admin_chat import AddAdminChat
|
||||||
from .types.attachments.attachment import Attachment
|
from .methods.add_members_chat import AddMembersChat
|
||||||
from .types.attachments.image import PhotoAttachmentRequestPayload
|
from .methods.change_info import ChangeInfo
|
||||||
from .types.message import Messages, NewMessageLink
|
from .methods.delete_bot_from_chat import DeleteMeFromMessage
|
||||||
from .types.users import ChatAdmin, User
|
from .methods.delete_chat import DeleteChat
|
||||||
from .types.command import BotCommand
|
from .methods.delete_message import DeleteMessage
|
||||||
|
from .methods.delete_pin_message import DeletePinMessage
|
||||||
|
from .methods.download_media import DownloadMedia
|
||||||
|
from .methods.edit_chat import EditChat
|
||||||
|
from .methods.edit_message import EditMessage
|
||||||
|
from .methods.get_chat_by_id import GetChatById
|
||||||
|
from .methods.get_chat_by_link import GetChatByLink
|
||||||
|
from .methods.get_chats import GetChats
|
||||||
|
from .methods.get_list_admin_chat import GetListAdminChat
|
||||||
|
from .methods.get_me import GetMe
|
||||||
|
from .methods.get_me_from_chat import GetMeFromChat
|
||||||
|
from .methods.get_members_chat import GetMembersChat
|
||||||
|
from .methods.get_messages import GetMessages
|
||||||
|
from .methods.get_pinned_message import GetPinnedMessage
|
||||||
|
from .methods.get_updates import GetUpdates
|
||||||
|
from .methods.get_upload_url import GetUploadURL
|
||||||
|
from .methods.get_video import GetVideo
|
||||||
|
from .methods.pin_message import PinMessage
|
||||||
|
from .methods.remove_admin import RemoveAdmin
|
||||||
|
from .methods.remove_member_chat import RemoveMemberChat
|
||||||
|
from .methods.send_action import SendAction
|
||||||
|
from .methods.send_callback import SendCallback
|
||||||
|
from .methods.send_message import SendMessage
|
||||||
|
|
||||||
from .connection.base import BaseConnection
|
if TYPE_CHECKING:
|
||||||
|
from .types.attachments.attachment import Attachment
|
||||||
|
from .types.attachments.image import PhotoAttachmentRequestPayload
|
||||||
|
from .types.attachments.video import Video
|
||||||
|
from .types.chats import Chat, ChatMember, Chats
|
||||||
|
from .types.command import BotCommand
|
||||||
|
from .types.message import Message, Messages, NewMessageLink
|
||||||
|
from .types.updates import UpdateUnion
|
||||||
|
from .types.users import ChatAdmin, User
|
||||||
|
|
||||||
from .methods.types.added_admin_chat import AddedListAdminChat
|
from .methods.types.added_admin_chat import AddedListAdminChat
|
||||||
from .methods.types.added_members_chat import AddedMembersChat
|
from .methods.types.added_members_chat import AddedMembersChat
|
||||||
from .methods.types.deleted_bot_from_chat import DeletedBotFromChat
|
from .methods.types.deleted_bot_from_chat import DeletedBotFromChat
|
||||||
from .methods.types.deleted_chat import DeletedChat
|
from .methods.types.deleted_chat import DeletedChat
|
||||||
from .methods.types.deleted_message import DeletedMessage
|
from .methods.types.deleted_message import DeletedMessage
|
||||||
from .methods.types.deleted_pin_message import DeletedPinMessage
|
from .methods.types.deleted_pin_message import DeletedPinMessage
|
||||||
from .methods.types.edited_message import EditedMessage
|
from .methods.types.edited_message import EditedMessage
|
||||||
from .methods.types.getted_list_admin_chat import GettedListAdminChat
|
from .methods.types.getted_list_admin_chat import GettedListAdminChat
|
||||||
from .methods.types.getted_members_chat import GettedMembersChat
|
from .methods.types.getted_members_chat import GettedMembersChat
|
||||||
from .methods.types.getted_pineed_message import GettedPin
|
from .methods.types.getted_pineed_message import GettedPin
|
||||||
from .methods.types.getted_upload_url import GettedUploadUrl
|
from .methods.types.getted_upload_url import GettedUploadUrl
|
||||||
from .methods.types.pinned_message import PinnedMessage
|
from .methods.types.pinned_message import PinnedMessage
|
||||||
from .methods.types.removed_admin import RemovedAdmin
|
from .methods.types.removed_admin import RemovedAdmin
|
||||||
from .methods.types.removed_member_chat import RemovedMemberChat
|
from .methods.types.removed_member_chat import RemovedMemberChat
|
||||||
from .methods.types.sended_action import SendedAction
|
from .methods.types.sended_action import SendedAction
|
||||||
from .methods.types.sended_callback import SendedCallback
|
from .methods.types.sended_callback import SendedCallback
|
||||||
from .methods.types.sended_message import SendedMessage
|
from .methods.types.sended_message import SendedMessage
|
||||||
from .types.attachments.video import Video
|
|
||||||
from .types.chats import Chat, ChatMember, Chats
|
|
||||||
from .types.updates import UpdateUnion
|
|
||||||
|
|
||||||
|
|
||||||
class Bot(BaseConnection):
|
class Bot(BaseConnection):
|
||||||
@ -102,6 +103,12 @@ class Bot(BaseConnection):
|
|||||||
self.notify = notify
|
self.notify = notify
|
||||||
self.auto_requests = auto_requests
|
self.auto_requests = auto_requests
|
||||||
|
|
||||||
|
def _resolve_notify(self, notify: Optional[bool]) -> Optional[bool]:
|
||||||
|
return notify if notify is not None else self.notify
|
||||||
|
|
||||||
|
def _resolve_parse_mode(self, mode: Optional[ParseMode]) -> Optional[ParseMode]:
|
||||||
|
return mode if mode is not None else self.parse_mode
|
||||||
|
|
||||||
async def send_message(
|
async def send_message(
|
||||||
self,
|
self,
|
||||||
chat_id: int = None,
|
chat_id: int = None,
|
||||||
@ -133,10 +140,8 @@ class Bot(BaseConnection):
|
|||||||
text=text,
|
text=text,
|
||||||
attachments=attachments,
|
attachments=attachments,
|
||||||
link=link,
|
link=link,
|
||||||
notify=notify if notify \
|
notify=self._resolve_notify(notify),
|
||||||
else self.notify,
|
parse_mode=self._resolve_parse_mode(notify)
|
||||||
parse_mode=parse_mode if parse_mode \
|
|
||||||
else self.parse_mode
|
|
||||||
).request()
|
).request()
|
||||||
|
|
||||||
async def send_action(
|
async def send_action(
|
||||||
@ -187,10 +192,8 @@ class Bot(BaseConnection):
|
|||||||
text=text,
|
text=text,
|
||||||
attachments=attachments,
|
attachments=attachments,
|
||||||
link=link,
|
link=link,
|
||||||
notify=notify if notify \
|
notify=self._resolve_notify(notify),
|
||||||
else self.notify,
|
parse_mode=self._resolve_parse_mode(notify)
|
||||||
parse_mode=parse_mode if parse_mode \
|
|
||||||
else self.parse_mode
|
|
||||||
).request()
|
).request()
|
||||||
|
|
||||||
async def delete_message(
|
async def delete_message(
|
||||||
@ -398,8 +401,7 @@ class Bot(BaseConnection):
|
|||||||
icon=icon,
|
icon=icon,
|
||||||
title=title,
|
title=title,
|
||||||
pin=pin,
|
pin=pin,
|
||||||
notify=notify if notify \
|
notify=self._resolve_notify(notify),
|
||||||
else self.notify,
|
|
||||||
).request()
|
).request()
|
||||||
|
|
||||||
async def get_video(
|
async def get_video(
|
||||||
@ -422,7 +424,7 @@ class Bot(BaseConnection):
|
|||||||
async def send_callback(
|
async def send_callback(
|
||||||
self,
|
self,
|
||||||
callback_id: str,
|
callback_id: str,
|
||||||
message: 'Message' = None,
|
message: Message = None,
|
||||||
notification: str = None
|
notification: str = None
|
||||||
) -> SendedCallback:
|
) -> SendedCallback:
|
||||||
|
|
||||||
@ -462,8 +464,7 @@ class Bot(BaseConnection):
|
|||||||
bot=self,
|
bot=self,
|
||||||
chat_id=chat_id,
|
chat_id=chat_id,
|
||||||
message_id=message_id,
|
message_id=message_id,
|
||||||
notify=notify if notify \
|
notify=self._resolve_notify(notify),
|
||||||
else self.notify,
|
|
||||||
).request()
|
).request()
|
||||||
|
|
||||||
async def delete_pin_message(
|
async def delete_pin_message(
|
||||||
|
@ -113,8 +113,8 @@ class BaseConnection:
|
|||||||
:return: Сырой .text() ответ от сервера после загрузки файла
|
:return: Сырой .text() ответ от сервера после загрузки файла
|
||||||
"""
|
"""
|
||||||
|
|
||||||
with open(path, 'rb') as f:
|
async with aiofiles.open(path, 'rb') as f:
|
||||||
file_data = f.read()
|
file_data = await f.read()
|
||||||
|
|
||||||
basename = os.path.basename(path)
|
basename = os.path.basename(path)
|
||||||
_, ext = os.path.splitext(basename)
|
_, ext = os.path.splitext(basename)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
from typing import Any, Callable, Dict, List
|
from typing import Any, Callable, Dict, List
|
||||||
|
|
||||||
from fastapi import FastAPI, Request
|
from fastapi import FastAPI, Request
|
||||||
@ -22,7 +24,8 @@ from .enums.update import UpdateType
|
|||||||
from .loggers import logger_dp
|
from .loggers import logger_dp
|
||||||
|
|
||||||
|
|
||||||
app = FastAPI()
|
webhook_app = FastAPI()
|
||||||
|
CONNECTION_RETRY_DELAY = 30
|
||||||
|
|
||||||
|
|
||||||
class Dispatcher:
|
class Dispatcher:
|
||||||
@ -39,8 +42,8 @@ class Dispatcher:
|
|||||||
self.filters: List[MagicFilter] = []
|
self.filters: List[MagicFilter] = []
|
||||||
self.middlewares: List[BaseMiddleware] = []
|
self.middlewares: List[BaseMiddleware] = []
|
||||||
|
|
||||||
self.bot = None
|
self.bot: Bot = None
|
||||||
self.on_started_func = None
|
self.on_started_func: Callable = None
|
||||||
|
|
||||||
self.message_created = Event(update_type=UpdateType.MESSAGE_CREATED, router=self)
|
self.message_created = Event(update_type=UpdateType.MESSAGE_CREATED, router=self)
|
||||||
self.bot_added = Event(update_type=UpdateType.BOT_ADDED, router=self)
|
self.bot_added = Event(update_type=UpdateType.BOT_ADDED, router=self)
|
||||||
@ -230,7 +233,8 @@ class Dispatcher:
|
|||||||
for event in processed_events:
|
for event in processed_events:
|
||||||
await self.handle(event)
|
await self.handle(event)
|
||||||
except ClientConnectorError:
|
except ClientConnectorError:
|
||||||
logger_dp.error(f'Ошибка подключения: {e}')
|
logger_dp.error(f'Ошибка подключения, жду {CONNECTION_RETRY_DELAY} секунд')
|
||||||
|
await asyncio.sleep(CONNECTION_RETRY_DELAY)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger_dp.error(f'Общая ошибка при обработке событий: {e}')
|
logger_dp.error(f'Общая ошибка при обработке событий: {e}')
|
||||||
|
|
||||||
@ -246,7 +250,7 @@ class Dispatcher:
|
|||||||
|
|
||||||
await self.__ready(bot)
|
await self.__ready(bot)
|
||||||
|
|
||||||
@app.post('/')
|
@webhook_app.post('/')
|
||||||
async def _(request: Request):
|
async def _(request: Request):
|
||||||
try:
|
try:
|
||||||
event_json = await request.json()
|
event_json = await request.json()
|
||||||
@ -262,7 +266,7 @@ class Dispatcher:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger_dp.error(f"Ошибка при обработке события: {event_json['update_type']}: {e}")
|
logger_dp.error(f"Ошибка при обработке события: {event_json['update_type']}: {e}")
|
||||||
|
|
||||||
config = Config(app=app, host=host, port=port, log_level="critical")
|
config = Config(app=webhook_app, host=host, port=port, log_level="critical")
|
||||||
server = Server(config)
|
server = Server(config)
|
||||||
|
|
||||||
await server.serve()
|
await server.serve()
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from ..methods.types.sended_callback import SendedCallback
|
from ..methods.types.sended_callback import SendedCallback
|
||||||
@ -37,7 +36,7 @@ class SendCallback(BaseConnection):
|
|||||||
self,
|
self,
|
||||||
bot: 'Bot',
|
bot: 'Bot',
|
||||||
callback_id: str,
|
callback_id: str,
|
||||||
message: 'Message' = None,
|
message: Message = None,
|
||||||
notification: str = None
|
notification: str = None
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
@ -25,8 +25,8 @@ if TYPE_CHECKING:
|
|||||||
from ..bot import Bot
|
from ..bot import Bot
|
||||||
|
|
||||||
|
|
||||||
class UploadResponse:
|
RETRY_DELAY = 2
|
||||||
token: str = None
|
ATTEMPTS_COUNT = 5
|
||||||
|
|
||||||
|
|
||||||
class SendMessage(BaseConnection):
|
class SendMessage(BaseConnection):
|
||||||
@ -70,6 +70,9 @@ class SendMessage(BaseConnection):
|
|||||||
att: InputMedia
|
att: InputMedia
|
||||||
):
|
):
|
||||||
|
|
||||||
|
# очень нестабильный метод независящий от модуля
|
||||||
|
# ждем обновлений MAX API
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Загружает файл вложения и формирует объект AttachmentUpload.
|
Загружает файл вложения и формирует объект AttachmentUpload.
|
||||||
|
|
||||||
@ -140,11 +143,11 @@ class SendMessage(BaseConnection):
|
|||||||
json['attachments'].append(att.model_dump())
|
json['attachments'].append(att.model_dump())
|
||||||
|
|
||||||
if not self.link is None: json['link'] = self.link.model_dump()
|
if not self.link is None: json['link'] = self.link.model_dump()
|
||||||
if not self.notify is None: json['notify'] = self.notify
|
json['notify'] = self.notify
|
||||||
if not self.parse_mode is None: json['format'] = self.parse_mode.value
|
if not self.parse_mode is None: json['format'] = self.parse_mode.value
|
||||||
|
|
||||||
response = None
|
response = None
|
||||||
for attempt in range(5):
|
for attempt in range(ATTEMPTS_COUNT):
|
||||||
response = await super().request(
|
response = await super().request(
|
||||||
method=HTTPMethod.POST,
|
method=HTTPMethod.POST,
|
||||||
path=ApiPath.MESSAGES,
|
path=ApiPath.MESSAGES,
|
||||||
@ -155,8 +158,8 @@ class SendMessage(BaseConnection):
|
|||||||
|
|
||||||
if isinstance(response, Error):
|
if isinstance(response, Error):
|
||||||
if response.raw.get('code') == 'attachment.not.ready':
|
if response.raw.get('code') == 'attachment.not.ready':
|
||||||
logger_bot.info(f'Ошибка при отправке загруженного медиа, попытка {attempt+1}, жду 2 секунды')
|
logger_bot.info(f'Ошибка при отправке загруженного медиа, попытка {attempt+1}, жду {RETRY_DELAY} секунды')
|
||||||
await asyncio.sleep(2)
|
await asyncio.sleep(RETRY_DELAY)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
@ -18,6 +18,7 @@ dependencies = [
|
|||||||
"magic_filter>=1.0.0",
|
"magic_filter>=1.0.0",
|
||||||
"pydantic>=1.8.0",
|
"pydantic>=1.8.0",
|
||||||
"uvicorn>=0.15.0",
|
"uvicorn>=0.15.0",
|
||||||
|
"aiofiles==24.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user