maxapi 0.3__tar.gz → 0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- maxapi-0.5/PKG-INFO +102 -0
- maxapi-0.5/README.md +84 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/bot.py +24 -4
- maxapi-0.5/maxapi/connection/base.py +94 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/context/__init__.py +7 -4
- {maxapi-0.3 → maxapi-0.5}/maxapi/dispatcher.py +23 -10
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/api_path.py +2 -1
- maxapi-0.5/maxapi/enums/chat_status.py +9 -0
- maxapi-0.5/maxapi/enums/upload_type.py +8 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/filters/handler.py +5 -1
- maxapi-0.5/maxapi/loggers.py +5 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/add_admin_chat.py +0 -3
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/add_members_chat.py +0 -3
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/change_info.py +2 -3
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/edit_chat.py +1 -3
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_chat_by_id.py +0 -5
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_chat_by_link.py +0 -4
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_chats.py +0 -2
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_list_admin_chat.py +0 -3
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_me.py +1 -1
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_me_from_chat.py +1 -3
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_members_chat.py +0 -3
- maxapi-0.5/maxapi/methods/get_upload_url.py +35 -0
- maxapi-0.5/maxapi/methods/send_message.py +129 -0
- maxapi-0.5/maxapi/methods/types/getted_upload_url.py +9 -0
- maxapi-0.5/maxapi/methods/types/upload_file_response.py +5 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/__init__.py +5 -1
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/attachment.py +3 -0
- maxapi-0.5/maxapi/types/attachments/upload.py +14 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/callback.py +1 -3
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/chats.py +2 -11
- maxapi-0.5/maxapi/types/command.py +18 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/errors.py +1 -1
- maxapi-0.5/maxapi/types/input_media.py +24 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_callback.py +1 -1
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_created.py +1 -1
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/users.py +1 -5
- maxapi-0.5/maxapi.egg-info/PKG-INFO +102 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi.egg-info/SOURCES.txt +8 -0
- maxapi-0.5/maxapi.egg-info/requires.txt +5 -0
- maxapi-0.5/setup.cfg +31 -0
- maxapi-0.5/setup.py +3 -0
- maxapi-0.3/PKG-INFO +0 -50
- maxapi-0.3/README.md +0 -29
- maxapi-0.3/maxapi/connection/base.py +0 -56
- maxapi-0.3/maxapi/loggers.py +0 -4
- maxapi-0.3/maxapi/methods/send_message.py +0 -65
- maxapi-0.3/maxapi/types/command.py +0 -9
- maxapi-0.3/maxapi.egg-info/PKG-INFO +0 -50
- maxapi-0.3/maxapi.egg-info/requires.txt +0 -5
- maxapi-0.3/setup.cfg +0 -4
- maxapi-0.3/setup.py +0 -20
- {maxapi-0.3 → maxapi-0.5}/maxapi/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/connection/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/context/state_machine.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/attachment.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/button_type.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/chat_permission.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/chat_type.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/http_method.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/intent.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/message_link_type.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/parse_mode.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/sender_action.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/text_style.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/enums/update.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/filters/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/delete_bot_from_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/delete_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/delete_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/delete_pin_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/edit_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_messages.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_pinned_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_updates.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_video.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/pin_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/remove_admin.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/remove_member_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/send_action.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/send_callback.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/added_admin_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/added_members_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/deleted_bot_from_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/deleted_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/deleted_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/deleted_pin_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/edited_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/getted_list_admin_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/getted_members_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/getted_pineed_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/getted_updates.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/pinned_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/removed_admin.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/removed_member_chat.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/sended_action.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/sended_callback.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/sended_message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/audio.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/attachment_button.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/button.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/callback_button.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/chat_button.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/link_button.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/request_contact.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/request_geo_location_button.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/contact.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/file.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/image.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/location.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/share.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/sticker.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/video.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/message.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/bot_added.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/bot_removed.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/bot_started.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/chat_title_changed.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_chat_created.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_edited.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_removed.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/update.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/user_added.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/user_removed.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/utils/__init__.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi/utils/inline_keyboard.py +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi.egg-info/dependency_links.txt +0 -0
- {maxapi-0.3 → maxapi-0.5}/maxapi.egg-info/top_level.txt +0 -0
maxapi-0.5/PKG-INFO
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: maxapi
|
|
3
|
+
Version: 0.5
|
|
4
|
+
Summary: Библиотека для разработки чат-бото с помощью API мессенджера MAX
|
|
5
|
+
Home-page: https://github.com/love-apples/maxapi/tree/main
|
|
6
|
+
Author: Denis
|
|
7
|
+
License: MIT
|
|
8
|
+
Keywords: max,api,bot
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: aiohttp>=3.8.0
|
|
14
|
+
Requires-Dist: fastapi>=0.68.0
|
|
15
|
+
Requires-Dist: magic_filter>=1.0.0
|
|
16
|
+
Requires-Dist: pydantic>=1.8.0
|
|
17
|
+
Requires-Dist: uvicorn>=0.15.0
|
|
18
|
+
|
|
19
|
+
# Асинхронный MAX API
|
|
20
|
+
|
|
21
|
+
[](https://pypi.org/project/maxapi/)
|
|
22
|
+
[](https://pypi.org/project/maxapi/)
|
|
23
|
+
[](https://love-apples/maxapi/blob/main/LICENSE)
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 📦 Установка
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install maxapi
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 🚀 Быстрый старт
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
import asyncio
|
|
39
|
+
import logging
|
|
40
|
+
|
|
41
|
+
from maxapi import Bot, Dispatcher
|
|
42
|
+
from maxapi.types import BotStarted, Command, MessageCreated
|
|
43
|
+
|
|
44
|
+
logging.basicConfig(level=logging.INFO)
|
|
45
|
+
|
|
46
|
+
bot = Bot('тут_ваш_токен')
|
|
47
|
+
dp = Dispatcher()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dp.bot_started()
|
|
51
|
+
async def bot_started(event: BotStarted):
|
|
52
|
+
await event.bot.send_message(
|
|
53
|
+
chat_id=event.chat_id,
|
|
54
|
+
text='Привет! Отправь мне /start'
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@dp.message_created(Command('start'))
|
|
59
|
+
async def hello(event: MessageCreated):
|
|
60
|
+
await event.message.answer(f"Пример чат-бота для MAX 💙")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
async def main():
|
|
64
|
+
await dp.start_polling(bot)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
if __name__ == '__main__':
|
|
68
|
+
asyncio.run(main())
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 📚 Документация
|
|
74
|
+
|
|
75
|
+
В разработке...
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 🧩 Возможности
|
|
80
|
+
|
|
81
|
+
- ✅ Роутеры
|
|
82
|
+
- ✅ Билдер инлайн клавиатур
|
|
83
|
+
- ✅ Простая загрузка медиафайлов
|
|
84
|
+
- ✅ MagicFilter
|
|
85
|
+
- ✅ Внутренние функции моделей
|
|
86
|
+
- ✅ Контекстный менеджер
|
|
87
|
+
- ✅ Поллинг
|
|
88
|
+
- ✅ Вебхук
|
|
89
|
+
- ✅ Логгирование
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
## 💬 Обратная связь и поддержка
|
|
95
|
+
|
|
96
|
+
- MAX: [Чат](https://max.ru/join/IPAok63C3vFqbWTFdutMUtjmrAkGqO56YeAN7iyDfc8)
|
|
97
|
+
- Telegram: [@loveappless](https://t.me/loveappless)
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## 📄 Лицензия
|
|
101
|
+
|
|
102
|
+
Этот проект распространяется под лицензией MIT. См. файл [LICENSE](LICENSE) для подробностей.
|
maxapi-0.5/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Асинхронный MAX API
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/maxapi/)
|
|
4
|
+
[](https://pypi.org/project/maxapi/)
|
|
5
|
+
[](https://love-apples/maxapi/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📦 Установка
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install maxapi
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 🚀 Быстрый старт
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
import asyncio
|
|
21
|
+
import logging
|
|
22
|
+
|
|
23
|
+
from maxapi import Bot, Dispatcher
|
|
24
|
+
from maxapi.types import BotStarted, Command, MessageCreated
|
|
25
|
+
|
|
26
|
+
logging.basicConfig(level=logging.INFO)
|
|
27
|
+
|
|
28
|
+
bot = Bot('тут_ваш_токен')
|
|
29
|
+
dp = Dispatcher()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dp.bot_started()
|
|
33
|
+
async def bot_started(event: BotStarted):
|
|
34
|
+
await event.bot.send_message(
|
|
35
|
+
chat_id=event.chat_id,
|
|
36
|
+
text='Привет! Отправь мне /start'
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dp.message_created(Command('start'))
|
|
41
|
+
async def hello(event: MessageCreated):
|
|
42
|
+
await event.message.answer(f"Пример чат-бота для MAX 💙")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
async def main():
|
|
46
|
+
await dp.start_polling(bot)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
if __name__ == '__main__':
|
|
50
|
+
asyncio.run(main())
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 📚 Документация
|
|
56
|
+
|
|
57
|
+
В разработке...
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 🧩 Возможности
|
|
62
|
+
|
|
63
|
+
- ✅ Роутеры
|
|
64
|
+
- ✅ Билдер инлайн клавиатур
|
|
65
|
+
- ✅ Простая загрузка медиафайлов
|
|
66
|
+
- ✅ MagicFilter
|
|
67
|
+
- ✅ Внутренние функции моделей
|
|
68
|
+
- ✅ Контекстный менеджер
|
|
69
|
+
- ✅ Поллинг
|
|
70
|
+
- ✅ Вебхук
|
|
71
|
+
- ✅ Логгирование
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
## 💬 Обратная связь и поддержка
|
|
77
|
+
|
|
78
|
+
- MAX: [Чат](https://max.ru/join/IPAok63C3vFqbWTFdutMUtjmrAkGqO56YeAN7iyDfc8)
|
|
79
|
+
- Telegram: [@loveappless](https://t.me/loveappless)
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 📄 Лицензия
|
|
83
|
+
|
|
84
|
+
Этот проект распространяется под лицензией MIT. См. файл [LICENSE](LICENSE) для подробностей.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from typing import Any, Dict, List, TYPE_CHECKING
|
|
3
3
|
|
|
4
|
+
from .methods.get_upload_url import GetUploadURL
|
|
4
5
|
from .methods.get_updates import GetUpdates
|
|
5
6
|
from .methods.remove_member_chat import RemoveMemberChat
|
|
6
7
|
from .methods.add_admin_chat import AddAdminChat
|
|
@@ -30,11 +31,13 @@ from .methods.send_message import SendMessage
|
|
|
30
31
|
|
|
31
32
|
from .enums.parse_mode import ParseMode
|
|
32
33
|
from .enums.sender_action import SenderAction
|
|
34
|
+
from .enums.upload_type import UploadType
|
|
33
35
|
|
|
34
36
|
from .types.attachments.attachment import Attachment
|
|
35
37
|
from .types.attachments.image import PhotoAttachmentRequestPayload
|
|
36
38
|
from .types.message import NewMessageLink
|
|
37
|
-
from .types.users import
|
|
39
|
+
from .types.users import ChatAdmin
|
|
40
|
+
from .types.command import BotCommand
|
|
38
41
|
|
|
39
42
|
from .connection.base import BaseConnection
|
|
40
43
|
|
|
@@ -46,12 +49,11 @@ class Bot(BaseConnection):
|
|
|
46
49
|
|
|
47
50
|
def __init__(self, token: str):
|
|
48
51
|
super().__init__()
|
|
52
|
+
|
|
49
53
|
self.bot = self
|
|
50
54
|
|
|
51
55
|
self.__token = token
|
|
52
|
-
self.params = {
|
|
53
|
-
'access_token': self.__token
|
|
54
|
-
}
|
|
56
|
+
self.params = {'access_token': self.__token}
|
|
55
57
|
self.marker_updates = None
|
|
56
58
|
|
|
57
59
|
async def send_message(
|
|
@@ -335,4 +337,22 @@ class Bot(BaseConnection):
|
|
|
335
337
|
):
|
|
336
338
|
return await GetUpdates(
|
|
337
339
|
bot=self,
|
|
340
|
+
).request()
|
|
341
|
+
|
|
342
|
+
async def get_upload_url(
|
|
343
|
+
self,
|
|
344
|
+
type: UploadType
|
|
345
|
+
):
|
|
346
|
+
return await GetUploadURL(
|
|
347
|
+
bot=self,
|
|
348
|
+
type=type
|
|
349
|
+
).request()
|
|
350
|
+
|
|
351
|
+
async def set_my_commands(
|
|
352
|
+
self,
|
|
353
|
+
*commands: BotCommand
|
|
354
|
+
):
|
|
355
|
+
return await ChangeInfo(
|
|
356
|
+
bot=self,
|
|
357
|
+
commands=list(commands)
|
|
338
358
|
).request()
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
import aiohttp
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
from ..types.errors import Error
|
|
8
|
+
from ..enums.http_method import HTTPMethod
|
|
9
|
+
from ..enums.api_path import ApiPath
|
|
10
|
+
from ..enums.upload_type import UploadType
|
|
11
|
+
from ..loggers import logger_bot, logger_connection
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from ..bot import Bot
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class BaseConnection:
|
|
18
|
+
|
|
19
|
+
API_URL = 'https://botapi.max.ru'
|
|
20
|
+
|
|
21
|
+
def __init__(self):
|
|
22
|
+
self.bot: 'Bot' = None
|
|
23
|
+
self.session: aiohttp.ClientSession = None
|
|
24
|
+
|
|
25
|
+
async def request(
|
|
26
|
+
self,
|
|
27
|
+
method: HTTPMethod,
|
|
28
|
+
path: ApiPath,
|
|
29
|
+
model: BaseModel = None,
|
|
30
|
+
is_return_raw: bool = False,
|
|
31
|
+
**kwargs
|
|
32
|
+
):
|
|
33
|
+
|
|
34
|
+
if not self.bot.session:
|
|
35
|
+
self.bot.session = aiohttp.ClientSession(self.bot.API_URL)
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
r = await self.bot.session.request(
|
|
39
|
+
method=method.value,
|
|
40
|
+
url=path.value if isinstance(path, ApiPath) else path,
|
|
41
|
+
**kwargs
|
|
42
|
+
)
|
|
43
|
+
except aiohttp.ClientConnectorDNSError as e:
|
|
44
|
+
return logger_connection.error(f'Ошибка при отправке запроса: {e}')
|
|
45
|
+
|
|
46
|
+
if not r.ok:
|
|
47
|
+
raw = await r.json()
|
|
48
|
+
error = Error(code=r.status, raw=raw)
|
|
49
|
+
logger_bot.error(error)
|
|
50
|
+
return error
|
|
51
|
+
|
|
52
|
+
raw = await r.json()
|
|
53
|
+
|
|
54
|
+
if is_return_raw: return raw
|
|
55
|
+
|
|
56
|
+
model = model(**raw)
|
|
57
|
+
|
|
58
|
+
if hasattr(model, 'message'):
|
|
59
|
+
attr = getattr(model, 'message')
|
|
60
|
+
if hasattr(attr, 'bot'):
|
|
61
|
+
attr.bot = self.bot
|
|
62
|
+
|
|
63
|
+
if hasattr(model, 'bot'):
|
|
64
|
+
model.bot = self.bot
|
|
65
|
+
|
|
66
|
+
return model
|
|
67
|
+
|
|
68
|
+
async def upload_file(
|
|
69
|
+
self,
|
|
70
|
+
url: str,
|
|
71
|
+
path: str,
|
|
72
|
+
type: UploadType
|
|
73
|
+
):
|
|
74
|
+
with open(path, 'rb') as f:
|
|
75
|
+
file_data = f.read()
|
|
76
|
+
|
|
77
|
+
basename = os.path.basename(path)
|
|
78
|
+
name, ext = os.path.splitext(basename)
|
|
79
|
+
|
|
80
|
+
form = aiohttp.FormData()
|
|
81
|
+
form.add_field(
|
|
82
|
+
name='data',
|
|
83
|
+
value=file_data,
|
|
84
|
+
filename=basename,
|
|
85
|
+
content_type=f"{type.value}/{ext.lstrip('.')}"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
async with aiohttp.ClientSession() as session:
|
|
89
|
+
response = await session.post(
|
|
90
|
+
url=url,
|
|
91
|
+
data=form
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
return await response.text()
|
|
@@ -26,11 +26,14 @@ class MemoryContext:
|
|
|
26
26
|
self._context.update(kwargs)
|
|
27
27
|
|
|
28
28
|
async def set_state(self, state: State | str = None):
|
|
29
|
-
self.
|
|
29
|
+
async with self._lock:
|
|
30
|
+
self._state = state
|
|
30
31
|
|
|
31
32
|
async def get_state(self):
|
|
32
|
-
|
|
33
|
+
async with self._lock:
|
|
34
|
+
return self._state
|
|
33
35
|
|
|
34
36
|
async def clear(self):
|
|
35
|
-
self.
|
|
36
|
-
|
|
37
|
+
async with self._lock:
|
|
38
|
+
self._state = None
|
|
39
|
+
self._context = {}
|
|
@@ -3,6 +3,7 @@ from typing import Callable, List
|
|
|
3
3
|
from fastapi import FastAPI, Request
|
|
4
4
|
from fastapi.responses import JSONResponse
|
|
5
5
|
from uvicorn import Config, Server
|
|
6
|
+
from aiohttp import ClientConnectorDNSError
|
|
6
7
|
|
|
7
8
|
from .filters.handler import Handler
|
|
8
9
|
|
|
@@ -41,6 +42,10 @@ class Dispatcher:
|
|
|
41
42
|
self.user_added = Event(update_type=UpdateType.USER_ADDED, router=self)
|
|
42
43
|
self.user_removed = Event(update_type=UpdateType.USER_REMOVED, router=self)
|
|
43
44
|
self.on_started = Event(update_type=UpdateType.ON_STARTED, router=self)
|
|
45
|
+
|
|
46
|
+
async def check_me(self):
|
|
47
|
+
me = await self.bot.get_me()
|
|
48
|
+
logger_dp.info(f'Бот: @{me.username} id={me.user_id}')
|
|
44
49
|
|
|
45
50
|
def include_routers(self, *routers: 'Router'):
|
|
46
51
|
for router in routers:
|
|
@@ -57,6 +62,8 @@ class Dispatcher:
|
|
|
57
62
|
return new_ctx
|
|
58
63
|
|
|
59
64
|
async def handle(self, event_object: UpdateUnion):
|
|
65
|
+
is_handled = False
|
|
66
|
+
|
|
60
67
|
for handler in self.event_handlers:
|
|
61
68
|
|
|
62
69
|
if not handler.update_type == event_object.update_type:
|
|
@@ -66,9 +73,9 @@ class Dispatcher:
|
|
|
66
73
|
if not filter_attrs(event_object, *handler.filters):
|
|
67
74
|
continue
|
|
68
75
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
)
|
|
76
|
+
ids = event_object.get_ids()
|
|
77
|
+
|
|
78
|
+
memory_context = self.get_memory_context(*ids)
|
|
72
79
|
|
|
73
80
|
if not handler.state == await memory_context.get_state() \
|
|
74
81
|
and handler.state:
|
|
@@ -82,18 +89,21 @@ class Dispatcher:
|
|
|
82
89
|
if not key in func_args:
|
|
83
90
|
del kwargs[key]
|
|
84
91
|
|
|
85
|
-
|
|
86
|
-
await handler.func_event(event_object, **kwargs)
|
|
87
|
-
else:
|
|
88
|
-
await handler.func_event(event_object, **kwargs)
|
|
92
|
+
await handler.func_event(event_object, **kwargs)
|
|
89
93
|
|
|
90
|
-
logger_dp.info(f'Обработано: {event_object.update_type}')
|
|
94
|
+
logger_dp.info(f'Обработано: {event_object.update_type} | chat_id: {ids[0]}, user_id: {ids[1]}')
|
|
95
|
+
|
|
96
|
+
is_handled = True
|
|
91
97
|
break
|
|
92
98
|
|
|
99
|
+
if not is_handled:
|
|
100
|
+
logger_dp.info(f'Проигнорировано: {event_object.update_type} | chat_id: {ids[0]}, user_id: {ids[1]}')
|
|
101
|
+
|
|
93
102
|
async def start_polling(self, bot: Bot):
|
|
94
103
|
self.bot = bot
|
|
104
|
+
await self.check_me()
|
|
95
105
|
|
|
96
|
-
logger_dp.info(f'{len(self.event_handlers)}
|
|
106
|
+
logger_dp.info(f'{len(self.event_handlers)} событий на обработку')
|
|
97
107
|
|
|
98
108
|
if self.on_started_func:
|
|
99
109
|
await self.on_started_func()
|
|
@@ -117,12 +127,15 @@ class Dispatcher:
|
|
|
117
127
|
try:
|
|
118
128
|
await self.handle(event)
|
|
119
129
|
except Exception as e:
|
|
120
|
-
logger_dp.error(f"Ошибка при обработке события: {
|
|
130
|
+
logger_dp.error(f"Ошибка при обработке события: {event.update_type}: {e}")
|
|
131
|
+
except ClientConnectorDNSError:
|
|
132
|
+
logger_dp.error(f'Ошибка подключения: {e}')
|
|
121
133
|
except Exception as e:
|
|
122
134
|
logger_dp.error(f'Общая ошибка при обработке событий: {e}')
|
|
123
135
|
|
|
124
136
|
async def handle_webhook(self, bot: Bot, host: str = 'localhost', port: int = 8080):
|
|
125
137
|
self.bot = bot
|
|
138
|
+
await self.check_me()
|
|
126
139
|
|
|
127
140
|
if self.on_started_func:
|
|
128
141
|
await self.on_started_func()
|
|
@@ -5,6 +5,7 @@ from magic_filter import F, MagicFilter
|
|
|
5
5
|
from ..types.command import Command
|
|
6
6
|
from ..context.state_machine import State
|
|
7
7
|
from ..enums.update import UpdateType
|
|
8
|
+
from ..loggers import logger_dp
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class Handler:
|
|
@@ -28,4 +29,7 @@ class Handler:
|
|
|
28
29
|
elif isinstance(arg, State):
|
|
29
30
|
self.state = arg
|
|
30
31
|
elif isinstance(arg, Command):
|
|
31
|
-
self.filters.insert(0, F.message.body.text
|
|
32
|
+
self.filters.insert(0, F.message.body.text.startswith(arg.command))
|
|
33
|
+
else:
|
|
34
|
+
logger_dp.info(f'Обнаружен неизвестный фильтр `{arg}` при '
|
|
35
|
+
f'регистрации функции `{func_event.__name__}`')
|
|
@@ -5,10 +5,8 @@ from typing import Any, Dict, List, TYPE_CHECKING
|
|
|
5
5
|
from collections import Counter
|
|
6
6
|
|
|
7
7
|
from ..types.attachments.image import PhotoAttachmentRequestPayload
|
|
8
|
-
|
|
9
8
|
from ..types.chats import Chat
|
|
10
|
-
|
|
11
|
-
from ..types.users import BotCommand, User
|
|
9
|
+
from ..types.command import Command
|
|
12
10
|
|
|
13
11
|
from ..enums.http_method import HTTPMethod
|
|
14
12
|
from ..enums.api_path import ApiPath
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from ..methods.types.getted_upload_url import GettedUploadUrl
|
|
6
|
+
from ..enums.http_method import HTTPMethod
|
|
7
|
+
from ..enums.api_path import ApiPath
|
|
8
|
+
from ..enums.upload_type import UploadType
|
|
9
|
+
from ..connection.base import BaseConnection
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from ..bot import Bot
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GetUploadURL(BaseConnection):
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
bot: 'Bot',
|
|
20
|
+
type: UploadType
|
|
21
|
+
):
|
|
22
|
+
self.bot = bot
|
|
23
|
+
self.type = type
|
|
24
|
+
|
|
25
|
+
async def request(self) -> GettedUploadUrl:
|
|
26
|
+
params = self.bot.params.copy()
|
|
27
|
+
|
|
28
|
+
params['type'] = self.type.value
|
|
29
|
+
|
|
30
|
+
return await super().request(
|
|
31
|
+
method=HTTPMethod.POST,
|
|
32
|
+
path=ApiPath.UPLOADS,
|
|
33
|
+
model=GettedUploadUrl,
|
|
34
|
+
params=params,
|
|
35
|
+
)
|