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.
Files changed (134) hide show
  1. maxapi-0.5/PKG-INFO +102 -0
  2. maxapi-0.5/README.md +84 -0
  3. {maxapi-0.3 → maxapi-0.5}/maxapi/bot.py +24 -4
  4. maxapi-0.5/maxapi/connection/base.py +94 -0
  5. {maxapi-0.3 → maxapi-0.5}/maxapi/context/__init__.py +7 -4
  6. {maxapi-0.3 → maxapi-0.5}/maxapi/dispatcher.py +23 -10
  7. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/api_path.py +2 -1
  8. maxapi-0.5/maxapi/enums/chat_status.py +9 -0
  9. maxapi-0.5/maxapi/enums/upload_type.py +8 -0
  10. {maxapi-0.3 → maxapi-0.5}/maxapi/filters/handler.py +5 -1
  11. maxapi-0.5/maxapi/loggers.py +5 -0
  12. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/add_admin_chat.py +0 -3
  13. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/add_members_chat.py +0 -3
  14. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/change_info.py +2 -3
  15. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/edit_chat.py +1 -3
  16. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_chat_by_id.py +0 -5
  17. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_chat_by_link.py +0 -4
  18. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_chats.py +0 -2
  19. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_list_admin_chat.py +0 -3
  20. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_me.py +1 -1
  21. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_me_from_chat.py +1 -3
  22. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_members_chat.py +0 -3
  23. maxapi-0.5/maxapi/methods/get_upload_url.py +35 -0
  24. maxapi-0.5/maxapi/methods/send_message.py +129 -0
  25. maxapi-0.5/maxapi/methods/types/getted_upload_url.py +9 -0
  26. maxapi-0.5/maxapi/methods/types/upload_file_response.py +5 -0
  27. {maxapi-0.3 → maxapi-0.5}/maxapi/types/__init__.py +5 -1
  28. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/attachment.py +3 -0
  29. maxapi-0.5/maxapi/types/attachments/upload.py +14 -0
  30. {maxapi-0.3 → maxapi-0.5}/maxapi/types/callback.py +1 -3
  31. {maxapi-0.3 → maxapi-0.5}/maxapi/types/chats.py +2 -11
  32. maxapi-0.5/maxapi/types/command.py +18 -0
  33. {maxapi-0.3 → maxapi-0.5}/maxapi/types/errors.py +1 -1
  34. maxapi-0.5/maxapi/types/input_media.py +24 -0
  35. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_callback.py +1 -1
  36. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_created.py +1 -1
  37. {maxapi-0.3 → maxapi-0.5}/maxapi/types/users.py +1 -5
  38. maxapi-0.5/maxapi.egg-info/PKG-INFO +102 -0
  39. {maxapi-0.3 → maxapi-0.5}/maxapi.egg-info/SOURCES.txt +8 -0
  40. maxapi-0.5/maxapi.egg-info/requires.txt +5 -0
  41. maxapi-0.5/setup.cfg +31 -0
  42. maxapi-0.5/setup.py +3 -0
  43. maxapi-0.3/PKG-INFO +0 -50
  44. maxapi-0.3/README.md +0 -29
  45. maxapi-0.3/maxapi/connection/base.py +0 -56
  46. maxapi-0.3/maxapi/loggers.py +0 -4
  47. maxapi-0.3/maxapi/methods/send_message.py +0 -65
  48. maxapi-0.3/maxapi/types/command.py +0 -9
  49. maxapi-0.3/maxapi.egg-info/PKG-INFO +0 -50
  50. maxapi-0.3/maxapi.egg-info/requires.txt +0 -5
  51. maxapi-0.3/setup.cfg +0 -4
  52. maxapi-0.3/setup.py +0 -20
  53. {maxapi-0.3 → maxapi-0.5}/maxapi/__init__.py +0 -0
  54. {maxapi-0.3 → maxapi-0.5}/maxapi/connection/__init__.py +0 -0
  55. {maxapi-0.3 → maxapi-0.5}/maxapi/context/state_machine.py +0 -0
  56. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/__init__.py +0 -0
  57. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/attachment.py +0 -0
  58. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/button_type.py +0 -0
  59. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/chat_permission.py +0 -0
  60. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/chat_type.py +0 -0
  61. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/http_method.py +0 -0
  62. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/intent.py +0 -0
  63. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/message_link_type.py +0 -0
  64. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/parse_mode.py +0 -0
  65. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/sender_action.py +0 -0
  66. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/text_style.py +0 -0
  67. {maxapi-0.3 → maxapi-0.5}/maxapi/enums/update.py +0 -0
  68. {maxapi-0.3 → maxapi-0.5}/maxapi/filters/__init__.py +0 -0
  69. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/__init__.py +0 -0
  70. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/delete_bot_from_chat.py +0 -0
  71. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/delete_chat.py +0 -0
  72. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/delete_message.py +0 -0
  73. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/delete_pin_message.py +0 -0
  74. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/edit_message.py +0 -0
  75. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_messages.py +0 -0
  76. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_pinned_message.py +0 -0
  77. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_updates.py +0 -0
  78. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/get_video.py +0 -0
  79. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/pin_message.py +0 -0
  80. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/remove_admin.py +0 -0
  81. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/remove_member_chat.py +0 -0
  82. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/send_action.py +0 -0
  83. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/send_callback.py +0 -0
  84. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/__init__.py +0 -0
  85. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/added_admin_chat.py +0 -0
  86. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/added_members_chat.py +0 -0
  87. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/deleted_bot_from_chat.py +0 -0
  88. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/deleted_chat.py +0 -0
  89. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/deleted_message.py +0 -0
  90. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/deleted_pin_message.py +0 -0
  91. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/edited_message.py +0 -0
  92. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/getted_list_admin_chat.py +0 -0
  93. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/getted_members_chat.py +0 -0
  94. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/getted_pineed_message.py +0 -0
  95. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/getted_updates.py +0 -0
  96. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/pinned_message.py +0 -0
  97. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/removed_admin.py +0 -0
  98. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/removed_member_chat.py +0 -0
  99. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/sended_action.py +0 -0
  100. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/sended_callback.py +0 -0
  101. {maxapi-0.3 → maxapi-0.5}/maxapi/methods/types/sended_message.py +0 -0
  102. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/__init__.py +0 -0
  103. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/audio.py +0 -0
  104. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/__init__.py +0 -0
  105. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/attachment_button.py +0 -0
  106. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/button.py +0 -0
  107. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/callback_button.py +0 -0
  108. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/chat_button.py +0 -0
  109. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/link_button.py +0 -0
  110. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/request_contact.py +0 -0
  111. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/buttons/request_geo_location_button.py +0 -0
  112. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/contact.py +0 -0
  113. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/file.py +0 -0
  114. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/image.py +0 -0
  115. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/location.py +0 -0
  116. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/share.py +0 -0
  117. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/sticker.py +0 -0
  118. {maxapi-0.3 → maxapi-0.5}/maxapi/types/attachments/video.py +0 -0
  119. {maxapi-0.3 → maxapi-0.5}/maxapi/types/message.py +0 -0
  120. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/__init__.py +0 -0
  121. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/bot_added.py +0 -0
  122. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/bot_removed.py +0 -0
  123. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/bot_started.py +0 -0
  124. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/chat_title_changed.py +0 -0
  125. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_chat_created.py +0 -0
  126. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_edited.py +0 -0
  127. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/message_removed.py +0 -0
  128. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/update.py +0 -0
  129. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/user_added.py +0 -0
  130. {maxapi-0.3 → maxapi-0.5}/maxapi/types/updates/user_removed.py +0 -0
  131. {maxapi-0.3 → maxapi-0.5}/maxapi/utils/__init__.py +0 -0
  132. {maxapi-0.3 → maxapi-0.5}/maxapi/utils/inline_keyboard.py +0 -0
  133. {maxapi-0.3 → maxapi-0.5}/maxapi.egg-info/dependency_links.txt +0 -0
  134. {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
+ [![PyPI version](https://img.shields.io/pypi/v/maxapi.svg)](https://pypi.org/project/maxapi/)
22
+ [![Python Version](https://img.shields.io/pypi/pyversions/maxapi.svg)](https://pypi.org/project/maxapi/)
23
+ [![License](https://img.shields.io/github/license/love-apples/maxapi.svg)](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
+ [![PyPI version](https://img.shields.io/pypi/v/maxapi.svg)](https://pypi.org/project/maxapi/)
4
+ [![Python Version](https://img.shields.io/pypi/pyversions/maxapi.svg)](https://pypi.org/project/maxapi/)
5
+ [![License](https://img.shields.io/github/license/love-apples/maxapi.svg)](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 BotCommand, ChatAdmin
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._state = state
29
+ async with self._lock:
30
+ self._state = state
30
31
 
31
32
  async def get_state(self):
32
- return self._state
33
+ async with self._lock:
34
+ return self._state
33
35
 
34
36
  async def clear(self):
35
- self._state = None
36
- self._context = {}
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
- memory_context = self.get_memory_context(
70
- *event_object.get_ids()
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
- if kwargs:
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)} event handlers started')
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"Ошибка при обработке события: {events['update_type']}: {e}")
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()
@@ -10,4 +10,5 @@ class ApiPath(str, Enum):
10
10
  ACTIONS = '/actions'
11
11
  PIN = '/pin'
12
12
  MEMBERS = '/members'
13
- ADMINS = '/admins'
13
+ ADMINS = '/admins'
14
+ UPLOADS = '/uploads'
@@ -0,0 +1,9 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ChatStatus(str, Enum):
5
+ ACTIVE = 'active'
6
+ REMOVED = 'removed'
7
+ LEFT = 'left'
8
+ CLOSED = 'closed'
9
+ SUSPENDED = 'suspended'
@@ -0,0 +1,8 @@
1
+ from enum import Enum
2
+
3
+
4
+ class UploadType(str, Enum):
5
+ IMAGE = 'image'
6
+ VIDEO = 'video'
7
+ AUDIO = 'audio'
8
+ FILE = 'file'
@@ -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 == arg.command)
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__}`')
@@ -0,0 +1,5 @@
1
+ import logging
2
+
3
+ logger_bot = logging.getLogger('bot')
4
+ logger_connection = logging.getLogger('connection')
5
+ logger_dp = logging.getLogger('dispatcher')
@@ -1,6 +1,3 @@
1
-
2
-
3
- from re import findall
4
1
  from typing import TYPE_CHECKING, List
5
2
 
6
3
  from .types.added_admin_chat import AddedListAdminChat
@@ -1,6 +1,3 @@
1
-
2
-
3
- from re import findall
4
1
  from typing import TYPE_CHECKING, List
5
2
 
6
3
  from ..methods.types.added_members_chat import AddedMembersChat
@@ -1,8 +1,7 @@
1
-
2
-
3
1
  from typing import Any, Dict, List, TYPE_CHECKING
4
2
 
5
- from ..types.users import BotCommand, User
3
+ from ..types.users import User
4
+ from ..types.command import BotCommand
6
5
 
7
6
  from ..enums.http_method import HTTPMethod
8
7
  from ..enums.api_path import ApiPath
@@ -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
@@ -1,12 +1,7 @@
1
-
2
-
3
- from re import findall
4
1
  from typing import TYPE_CHECKING
5
2
 
6
3
  from ..types.chats import Chat
7
4
 
8
- from ..types.users import User
9
-
10
5
  from ..enums.http_method import HTTPMethod
11
6
  from ..enums.api_path import ApiPath
12
7
 
@@ -1,12 +1,8 @@
1
-
2
-
3
1
  from re import findall
4
2
  from typing import TYPE_CHECKING
5
3
 
6
4
  from ..types.chats import Chat
7
5
 
8
- from ..types.users import User
9
-
10
6
  from ..enums.http_method import HTTPMethod
11
7
  from ..enums.api_path import ApiPath
12
8
 
@@ -4,8 +4,6 @@ from typing import TYPE_CHECKING
4
4
 
5
5
  from ..types.chats import Chats
6
6
 
7
- from ..types.users import User
8
-
9
7
  from ..enums.http_method import HTTPMethod
10
8
  from ..enums.api_path import ApiPath
11
9
 
@@ -1,6 +1,3 @@
1
-
2
-
3
- from re import findall
4
1
  from typing import TYPE_CHECKING
5
2
 
6
3
  from ..methods.types.getted_list_admin_chat import GettedListAdminChat
@@ -20,7 +20,7 @@ class GetMe(BaseConnection):
20
20
  def __init__(self, bot: 'Bot'):
21
21
  self.bot = bot
22
22
 
23
- async def request(self) -> Chats:
23
+ async def request(self) -> User:
24
24
  return await super().request(
25
25
  method=HTTPMethod.GET,
26
26
  path=ApiPath.ME,
@@ -2,9 +2,7 @@
2
2
 
3
3
  from typing import TYPE_CHECKING
4
4
 
5
- from ..types.chats import ChatMember, Chats
6
-
7
- from ..types.users import User
5
+ from ..types.chats import ChatMember
8
6
 
9
7
  from ..enums.http_method import HTTPMethod
10
8
  from ..enums.api_path import ApiPath
@@ -1,6 +1,3 @@
1
-
2
-
3
- from re import findall
4
1
  from typing import TYPE_CHECKING, List
5
2
 
6
3
  from ..methods.types.getted_members_chat import GettedMembersChat
@@ -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
+ )