PySPlusthon 0.5.3__py3-none-any.whl

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 (284) hide show
  1. PySPlusthon/__init__.py +3 -0
  2. PySPlusthon/client/__init__.py +1 -0
  3. PySPlusthon/client/attachments/__init__.py +29 -0
  4. PySPlusthon/client/attachments/get_file.py +22 -0
  5. PySPlusthon/client/attachments/send_animation.py +71 -0
  6. PySPlusthon/client/attachments/send_audio.py +54 -0
  7. PySPlusthon/client/attachments/send_contact.py +47 -0
  8. PySPlusthon/client/attachments/send_document.py +63 -0
  9. PySPlusthon/client/attachments/send_location.py +45 -0
  10. PySPlusthon/client/attachments/send_media_group.py +88 -0
  11. PySPlusthon/client/attachments/send_photo.py +67 -0
  12. PySPlusthon/client/attachments/send_sticker.py +51 -0
  13. PySPlusthon/client/attachments/send_video.py +56 -0
  14. PySPlusthon/client/attachments/send_voice.py +52 -0
  15. PySPlusthon/client/attachments/upload_file.py +82 -0
  16. PySPlusthon/client/chats/__init__.py +43 -0
  17. PySPlusthon/client/chats/ban_chat_member.py +24 -0
  18. PySPlusthon/client/chats/delete_chat_photo.py +32 -0
  19. PySPlusthon/client/chats/get_chat.py +69 -0
  20. PySPlusthon/client/chats/get_chat_administrators.py +18 -0
  21. PySPlusthon/client/chats/get_chat_history.py +39 -0
  22. PySPlusthon/client/chats/get_chat_member.py +16 -0
  23. PySPlusthon/client/chats/get_chat_members.py +29 -0
  24. PySPlusthon/client/chats/get_chat_members_count.py +21 -0
  25. PySPlusthon/client/chats/join_chat.py +31 -0
  26. PySPlusthon/client/chats/leave_chat.py +22 -0
  27. PySPlusthon/client/chats/pin_chat_message.py +31 -0
  28. PySPlusthon/client/chats/promote_chat_member.py +64 -0
  29. PySPlusthon/client/chats/restrict_chat_member.py +25 -0
  30. PySPlusthon/client/chats/set_chat_description.py +23 -0
  31. PySPlusthon/client/chats/set_chat_photo.py +33 -0
  32. PySPlusthon/client/chats/set_chat_title.py +23 -0
  33. PySPlusthon/client/chats/unban_chat_member.py +24 -0
  34. PySPlusthon/client/chats/unpin_all_chat_messages.py +38 -0
  35. PySPlusthon/client/chats/unpin_chat_message.py +33 -0
  36. PySPlusthon/client/client.py +223 -0
  37. PySPlusthon/client/invite_links/__init__.py +7 -0
  38. PySPlusthon/client/invite_links/create_chat_invite_link.py +14 -0
  39. PySPlusthon/client/invite_links/export_chat_invite_link.py +21 -0
  40. PySPlusthon/client/invite_links/revoke_chat_invite_link.py +23 -0
  41. PySPlusthon/client/messages/__init__.py +21 -0
  42. PySPlusthon/client/messages/answer_callback_query.py +12 -0
  43. PySPlusthon/client/messages/copy_message.py +43 -0
  44. PySPlusthon/client/messages/delete_message.py +29 -0
  45. PySPlusthon/client/messages/edit_message_caption.py +40 -0
  46. PySPlusthon/client/messages/edit_message_reply_markup.py +17 -0
  47. PySPlusthon/client/messages/edit_message_text.py +40 -0
  48. PySPlusthon/client/messages/forward_message.py +35 -0
  49. PySPlusthon/client/messages/send_message.py +39 -0
  50. PySPlusthon/client/stickers/__init__.py +9 -0
  51. PySPlusthon/client/stickers/add_sticker_to_set.py +15 -0
  52. PySPlusthon/client/stickers/create_new_sticker_set.py +16 -0
  53. PySPlusthon/client/stickers/delete_sticker_from_set.py +10 -0
  54. PySPlusthon/client/stickers/get_sticker_set.py +11 -0
  55. PySPlusthon/client/stickers/upload_sticker_file.py +16 -0
  56. PySPlusthon/client/updates/__init__.py +8 -0
  57. PySPlusthon/client/updates/delete_webhook.py +9 -0
  58. PySPlusthon/client/updates/get_updates.py +14 -0
  59. PySPlusthon/client/updates/get_webhook_info.py +10 -0
  60. PySPlusthon/client/updates/set_webhook.py +10 -0
  61. PySPlusthon/client/users/__init__.py +6 -0
  62. PySPlusthon/client/users/ask_review.py +14 -0
  63. PySPlusthon/client/users/get_me.py +16 -0
  64. PySPlusthon/conditions/__init__.py +43 -0
  65. PySPlusthon/conditions/all.py +6 -0
  66. PySPlusthon/conditions/animation.py +7 -0
  67. PySPlusthon/conditions/at_state.py +18 -0
  68. PySPlusthon/conditions/audio.py +7 -0
  69. PySPlusthon/conditions/author.py +13 -0
  70. PySPlusthon/conditions/caption.py +7 -0
  71. PySPlusthon/conditions/channel.py +11 -0
  72. PySPlusthon/conditions/channel_chat_created.py +7 -0
  73. PySPlusthon/conditions/chat.py +14 -0
  74. PySPlusthon/conditions/click.py +24 -0
  75. PySPlusthon/conditions/command.py +23 -0
  76. PySPlusthon/conditions/condition.py +88 -0
  77. PySPlusthon/conditions/contact.py +7 -0
  78. PySPlusthon/conditions/content.py +7 -0
  79. PySPlusthon/conditions/delete_chat_photo.py +7 -0
  80. PySPlusthon/conditions/document.py +7 -0
  81. PySPlusthon/conditions/entities.py +7 -0
  82. PySPlusthon/conditions/equals.py +14 -0
  83. PySPlusthon/conditions/forward.py +7 -0
  84. PySPlusthon/conditions/group.py +11 -0
  85. PySPlusthon/conditions/group_chat_created.py +7 -0
  86. PySPlusthon/conditions/is_admin.py +17 -0
  87. PySPlusthon/conditions/is_instance.py +10 -0
  88. PySPlusthon/conditions/is_joined.py +61 -0
  89. PySPlusthon/conditions/left_chat_member.py +7 -0
  90. PySPlusthon/conditions/location.py +7 -0
  91. PySPlusthon/conditions/media.py +7 -0
  92. PySPlusthon/conditions/media_group.py +7 -0
  93. PySPlusthon/conditions/new_chat_members.py +7 -0
  94. PySPlusthon/conditions/new_chat_photo.py +7 -0
  95. PySPlusthon/conditions/new_chat_title.py +7 -0
  96. PySPlusthon/conditions/number.py +12 -0
  97. PySPlusthon/conditions/photo.py +7 -0
  98. PySPlusthon/conditions/pinned_message.py +7 -0
  99. PySPlusthon/conditions/poll.py +7 -0
  100. PySPlusthon/conditions/private.py +11 -0
  101. PySPlusthon/conditions/regex.py +17 -0
  102. PySPlusthon/conditions/reply.py +7 -0
  103. PySPlusthon/conditions/sticker.py +7 -0
  104. PySPlusthon/conditions/supergroup_chat_created.py +7 -0
  105. PySPlusthon/conditions/text.py +7 -0
  106. PySPlusthon/conditions/video.py +7 -0
  107. PySPlusthon/conditions/voice.py +7 -0
  108. PySPlusthon/dispatcher/__init__.py +5 -0
  109. PySPlusthon/dispatcher/chain.py +165 -0
  110. PySPlusthon/dispatcher/dispatcher.py +124 -0
  111. PySPlusthon/dispatcher/logging_chain.py +36 -0
  112. PySPlusthon/dispatcher/monitoring_chain.py +19 -0
  113. PySPlusthon/dispatcher/printing_chain.py +21 -0
  114. PySPlusthon/enums/__init__.py +7 -0
  115. PySPlusthon/enums/chat_member_status.py +9 -0
  116. PySPlusthon/enums/chat_type.py +9 -0
  117. PySPlusthon/enums/message_media_type.py +16 -0
  118. PySPlusthon/enums/name_enum.py +13 -0
  119. PySPlusthon/enums/peer_type.py +8 -0
  120. PySPlusthon/enums/poll_type.py +8 -0
  121. PySPlusthon/enums/transaction_status.py +10 -0
  122. PySPlusthon/errors/__init__.py +11 -0
  123. PySPlusthon/errors/dispatching_errors/__init__.py +2 -0
  124. PySPlusthon/errors/dispatching_errors/break_dispatching.py +2 -0
  125. PySPlusthon/errors/dispatching_errors/continue_dispatching.py +2 -0
  126. PySPlusthon/errors/rpc_errors/__init__.py +8 -0
  127. PySPlusthon/errors/rpc_errors/bad_request_error.py +6 -0
  128. PySPlusthon/errors/rpc_errors/flood_error.py +6 -0
  129. PySPlusthon/errors/rpc_errors/forbidden_error.py +6 -0
  130. PySPlusthon/errors/rpc_errors/internal_error.py +6 -0
  131. PySPlusthon/errors/rpc_errors/not_found_error.py +6 -0
  132. PySPlusthon/errors/rpc_errors/rpc_error.py +23 -0
  133. PySPlusthon/errors/rpc_errors/too_many_requests.py +10 -0
  134. PySPlusthon/errors/rpc_errors/unauthorized_error.py +6 -0
  135. PySPlusthon/event_handlers/__init__.py +12 -0
  136. PySPlusthon/event_handlers/callback_query_handler.py +16 -0
  137. PySPlusthon/event_handlers/command_handler.py +46 -0
  138. PySPlusthon/event_handlers/connect_handler.py +19 -0
  139. PySPlusthon/event_handlers/disconnect_handler.py +18 -0
  140. PySPlusthon/event_handlers/edited_message_handler.py +16 -0
  141. PySPlusthon/event_handlers/error_handler.py +15 -0
  142. PySPlusthon/event_handlers/event_handler.py +53 -0
  143. PySPlusthon/event_handlers/initialize_handler.py +18 -0
  144. PySPlusthon/event_handlers/message_handler.py +16 -0
  145. PySPlusthon/event_handlers/shipping_query_handler.py +16 -0
  146. PySPlusthon/event_handlers/shutdown_handler.py +18 -0
  147. PySPlusthon/event_handlers/update_handler.py +16 -0
  148. PySPlusthon/network/__init__.py +1 -0
  149. PySPlusthon/network/httpconnection.py +74 -0
  150. PySPlusthon/objects/__init__.py +43 -0
  151. PySPlusthon/objects/animation.py +44 -0
  152. PySPlusthon/objects/audio.py +36 -0
  153. PySPlusthon/objects/callback_query.py +37 -0
  154. PySPlusthon/objects/chat.py +118 -0
  155. PySPlusthon/objects/chat_member.py +53 -0
  156. PySPlusthon/objects/chat_permissions.py +26 -0
  157. PySPlusthon/objects/chat_photo.py +24 -0
  158. PySPlusthon/objects/contact.py +18 -0
  159. PySPlusthon/objects/date.py +35 -0
  160. PySPlusthon/objects/document.py +36 -0
  161. PySPlusthon/objects/edited_message.py +27 -0
  162. PySPlusthon/objects/entity.py +21 -0
  163. PySPlusthon/objects/file.py +21 -0
  164. PySPlusthon/objects/forward_origin.py +22 -0
  165. PySPlusthon/objects/inline_keyboard.py +65 -0
  166. PySPlusthon/objects/inline_keyboard_button.py +30 -0
  167. PySPlusthon/objects/input_media.py +44 -0
  168. PySPlusthon/objects/input_media_photo.py +14 -0
  169. PySPlusthon/objects/input_media_video.py +14 -0
  170. PySPlusthon/objects/invite_link.py +32 -0
  171. PySPlusthon/objects/list.py +24 -0
  172. PySPlusthon/objects/location.py +14 -0
  173. PySPlusthon/objects/message.py +478 -0
  174. PySPlusthon/objects/message_id.py +31 -0
  175. PySPlusthon/objects/object.py +154 -0
  176. PySPlusthon/objects/order_info.py +19 -0
  177. PySPlusthon/objects/photo.py +31 -0
  178. PySPlusthon/objects/poll.py +34 -0
  179. PySPlusthon/objects/poll_option.py +16 -0
  180. PySPlusthon/objects/reply_keyboard.py +79 -0
  181. PySPlusthon/objects/reply_keyboard_button.py +27 -0
  182. PySPlusthon/objects/reply_keyboard_remove.py +10 -0
  183. PySPlusthon/objects/reply_markup.py +12 -0
  184. PySPlusthon/objects/shipping_address.py +22 -0
  185. PySPlusthon/objects/shipping_query.py +20 -0
  186. PySPlusthon/objects/sticker.py +54 -0
  187. PySPlusthon/objects/sticker_set.py +29 -0
  188. PySPlusthon/objects/transaction.py +25 -0
  189. PySPlusthon/objects/update.py +33 -0
  190. PySPlusthon/objects/user.py +60 -0
  191. PySPlusthon/objects/video.py +45 -0
  192. PySPlusthon/objects/voice.py +31 -0
  193. PySPlusthon/objects/webhook_info.py +16 -0
  194. PySPlusthon/proto/__init__.py +2 -0
  195. PySPlusthon/proto/enums_pb2.py +46 -0
  196. PySPlusthon/proto/enums_pb2.pyi +99 -0
  197. PySPlusthon/proto/enums_pb2_grpc.py +24 -0
  198. PySPlusthon/proto/requests/__init__.py +209 -0
  199. PySPlusthon/proto/requests/abacus_pb2.py +40 -0
  200. PySPlusthon/proto/requests/abacus_pb2.pyi +31 -0
  201. PySPlusthon/proto/requests/abacus_pb2_grpc.py +24 -0
  202. PySPlusthon/proto/requests/auth_pb2.py +49 -0
  203. PySPlusthon/proto/requests/auth_pb2.pyi +67 -0
  204. PySPlusthon/proto/requests/auth_pb2_grpc.py +24 -0
  205. PySPlusthon/proto/requests/configs_pb2.py +37 -0
  206. PySPlusthon/proto/requests/configs_pb2.pyi +15 -0
  207. PySPlusthon/proto/requests/configs_pb2_grpc.py +24 -0
  208. PySPlusthon/proto/requests/files_pb2.py +40 -0
  209. PySPlusthon/proto/requests/files_pb2.pyi +34 -0
  210. PySPlusthon/proto/requests/files_pb2_grpc.py +24 -0
  211. PySPlusthon/proto/requests/groups_pb2.py +82 -0
  212. PySPlusthon/proto/requests/groups_pb2.pyi +213 -0
  213. PySPlusthon/proto/requests/groups_pb2_grpc.py +24 -0
  214. PySPlusthon/proto/requests/messaging_pb2.py +56 -0
  215. PySPlusthon/proto/requests/messaging_pb2.pyi +119 -0
  216. PySPlusthon/proto/requests/messaging_pb2_grpc.py +24 -0
  217. PySPlusthon/proto/requests/presence_pb2.py +40 -0
  218. PySPlusthon/proto/requests/presence_pb2.pyi +24 -0
  219. PySPlusthon/proto/requests/presence_pb2_grpc.py +24 -0
  220. PySPlusthon/proto/requests/request_pb2.py +42 -0
  221. PySPlusthon/proto/requests/request_pb2.pyi +35 -0
  222. PySPlusthon/proto/requests/request_pb2_grpc.py +24 -0
  223. PySPlusthon/proto/requests/users_pb2.py +43 -0
  224. PySPlusthon/proto/requests/users_pb2.pyi +34 -0
  225. PySPlusthon/proto/requests/users_pb2_grpc.py +24 -0
  226. PySPlusthon/proto/responses/__init__.py +6 -0
  227. PySPlusthon/proto/responses/abacus_pb2.py +37 -0
  228. PySPlusthon/proto/responses/abacus_pb2.pyi +14 -0
  229. PySPlusthon/proto/responses/abacus_pb2_grpc.py +24 -0
  230. PySPlusthon/proto/responses/auth_pb2.py +42 -0
  231. PySPlusthon/proto/responses/auth_pb2.pyi +40 -0
  232. PySPlusthon/proto/responses/auth_pb2_grpc.py +24 -0
  233. PySPlusthon/proto/responses/files_pb2.py +39 -0
  234. PySPlusthon/proto/responses/files_pb2.pyi +27 -0
  235. PySPlusthon/proto/responses/files_pb2_grpc.py +24 -0
  236. PySPlusthon/proto/responses/groups_pb2.py +59 -0
  237. PySPlusthon/proto/responses/groups_pb2.pyi +90 -0
  238. PySPlusthon/proto/responses/groups_pb2_grpc.py +24 -0
  239. PySPlusthon/proto/responses/messaging_pb2.py +44 -0
  240. PySPlusthon/proto/responses/messaging_pb2.pyi +37 -0
  241. PySPlusthon/proto/responses/messaging_pb2_grpc.py +24 -0
  242. PySPlusthon/proto/responses/users_pb2.py +41 -0
  243. PySPlusthon/proto/responses/users_pb2.pyi +28 -0
  244. PySPlusthon/proto/responses/users_pb2_grpc.py +24 -0
  245. PySPlusthon/proto/structs/__init__.py +7 -0
  246. PySPlusthon/proto/structs/collections_pb2.py +54 -0
  247. PySPlusthon/proto/structs/collections_pb2.pyi +79 -0
  248. PySPlusthon/proto/structs/collections_pb2_grpc.py +24 -0
  249. PySPlusthon/proto/structs/files_pb2.py +52 -0
  250. PySPlusthon/proto/structs/files_pb2.pyi +93 -0
  251. PySPlusthon/proto/structs/files_pb2_grpc.py +24 -0
  252. PySPlusthon/proto/structs/groups_pb2.py +49 -0
  253. PySPlusthon/proto/structs/groups_pb2.pyi +144 -0
  254. PySPlusthon/proto/structs/groups_pb2_grpc.py +24 -0
  255. PySPlusthon/proto/structs/messaging_pb2.py +81 -0
  256. PySPlusthon/proto/structs/messaging_pb2.pyi +296 -0
  257. PySPlusthon/proto/structs/messaging_pb2_grpc.py +24 -0
  258. PySPlusthon/proto/structs/peers_pb2.py +47 -0
  259. PySPlusthon/proto/structs/peers_pb2.pyi +56 -0
  260. PySPlusthon/proto/structs/peers_pb2_grpc.py +24 -0
  261. PySPlusthon/proto/structs/set_updates_pb2.py +37 -0
  262. PySPlusthon/proto/structs/set_updates_pb2.pyi +15 -0
  263. PySPlusthon/proto/structs/set_updates_pb2_grpc.py +24 -0
  264. PySPlusthon/proto/structs/users_pb2.py +54 -0
  265. PySPlusthon/proto/structs/users_pb2.pyi +122 -0
  266. PySPlusthon/proto/structs/users_pb2_grpc.py +24 -0
  267. PySPlusthon/proto/updates/__init__.py +1 -0
  268. PySPlusthon/proto/updates/messaging_pb2.py +38 -0
  269. PySPlusthon/proto/updates/messaging_pb2.pyi +26 -0
  270. PySPlusthon/proto/updates/messaging_pb2_grpc.py +24 -0
  271. PySPlusthon/proto/ws_pb2.py +52 -0
  272. PySPlusthon/proto/ws_pb2.pyi +76 -0
  273. PySPlusthon/proto/ws_pb2_grpc.py +24 -0
  274. PySPlusthon/smart_call.py +73 -0
  275. PySPlusthon/states/__init__.py +3 -0
  276. PySPlusthon/states/state.py +11 -0
  277. PySPlusthon/states/state_group.py +13 -0
  278. PySPlusthon/states/state_machine.py +83 -0
  279. PySPlusthon/sync_support.py +48 -0
  280. pysplusthon-0.5.3.dist-info/METADATA +65 -0
  281. pysplusthon-0.5.3.dist-info/RECORD +284 -0
  282. pysplusthon-0.5.3.dist-info/WHEEL +5 -0
  283. pysplusthon-0.5.3.dist-info/licenses/LICENSE +19 -0
  284. pysplusthon-0.5.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def new_chat_members(event) -> bool:
7
+ return bool(event.new_chat_members)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def new_chat_photo(event) -> bool:
7
+ return bool(event.new_chat_photo)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def new_chat_title(event) -> bool:
7
+ return bool(event.new_chat_title)
@@ -0,0 +1,12 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def number(event) -> bool:
7
+ try:
8
+ int(event.content)
9
+ except ValueError:
10
+ return False
11
+ else:
12
+ return True
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def photo(event) -> bool:
7
+ return bool(event.photo)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def pinned_message(event) -> bool:
7
+ return bool(event.pinned_message)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def poll(event) -> bool:
7
+ return bool(event.poll)
@@ -0,0 +1,11 @@
1
+ from .condition import create
2
+ from ..objects import Message, CallbackQuery
3
+ from ..enums import ChatType
4
+
5
+
6
+ @create(can_process=(Message, CallbackQuery))
7
+ def private(event) -> bool:
8
+ if isinstance(event, Message):
9
+ return event.chat.type == ChatType.PRIVATE
10
+ elif isinstance(event, CallbackQuery):
11
+ return event.message.chat.type == ChatType.PRIVATE
@@ -0,0 +1,17 @@
1
+ from re import compile
2
+
3
+ from .condition import Condition
4
+ from ..objects import Message, CallbackQuery
5
+
6
+
7
+ class Regex(Condition):
8
+ def __init__(self, pattern, flags=0):
9
+ super().__init__(can_process=(Message, CallbackQuery))
10
+ self.pattern = compile(pattern, flags)
11
+
12
+ async def process(self, client, event) -> bool:
13
+ if isinstance(event, Message):
14
+ event = event.content
15
+ elif isinstance(event, CallbackQuery):
16
+ event = event.data
17
+ return bool(list(self.pattern.finditer(event)) or None)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def reply(event) -> bool:
7
+ return bool(event.reply_to_message)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def sticker(event) -> bool:
7
+ return bool(event.sticker)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def supergroup_chat_created(event) -> bool:
7
+ return bool(event.supergroup_chat_created)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def text(event) -> bool:
7
+ return bool(event.text)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def video(event) -> bool:
7
+ return bool(event.video)
@@ -0,0 +1,7 @@
1
+ from .condition import create
2
+ from ..objects import Message
3
+
4
+
5
+ @create(can_process=Message)
6
+ def voice(event) -> bool:
7
+ return bool(event.voice)
@@ -0,0 +1,5 @@
1
+ from .chain import Chain
2
+ from .dispatcher import Dispatcher
3
+ from .printing_chain import PrintingChain
4
+ from .logging_chain import LoggingChain
5
+ from .monitoring_chain import MonitoringChain
@@ -0,0 +1,165 @@
1
+ from ..event_handlers import (
2
+ ConnectHandler,
3
+ InitializeHandler,
4
+ EventHandler,
5
+ ErrorHandler,
6
+ UpdateHandler,
7
+ MessageHandler,
8
+ EditedMessageHandler,
9
+ CommandHandler,
10
+ CallbackQueryHandler,
11
+ ShippingQueryHandler,
12
+ ShutdownHandler,
13
+ DisconnectHandler
14
+ )
15
+
16
+
17
+ class Chain:
18
+
19
+ def __init__(self, name, condition=None, *chains):
20
+ self.name = name
21
+ self.condition = condition
22
+ self.chains = list(chains)
23
+ self.children = []
24
+ for attribute_name in dir(self):
25
+ attribute = getattr(self, attribute_name)
26
+ if isinstance(attribute, EventHandler):
27
+ attribute.self = self
28
+ self.add_event_handler(attribute)
29
+
30
+ async def check(self, client, event):
31
+ if self.condition is None:
32
+ return True
33
+ return await self.condition(client, event)
34
+
35
+ @staticmethod
36
+ def create_event_handler(event_handler, *args, **kwargs):
37
+ def decorator(callback):
38
+ return event_handler(callback, *args, **kwargs)
39
+ return decorator
40
+
41
+ def add_event_handler(self, event_handler, *args, **kwargs):
42
+ if isinstance(event_handler, type):
43
+ def decorator(callback):
44
+ event_handler_instance = event_handler(callback, *args, **kwargs)
45
+ self.add_event_handler(event_handler_instance)
46
+ return event_handler_instance
47
+ return decorator
48
+ self.children.append(event_handler)
49
+
50
+ @classmethod
51
+ def connect_handler(cls):
52
+ return cls.create_event_handler(ConnectHandler)
53
+
54
+ def on_connect(self):
55
+ return self.add_event_handler(ConnectHandler)
56
+
57
+ @classmethod
58
+ def initialize_handler(cls):
59
+ return cls.create_event_handler(InitializeHandler)
60
+
61
+ def on_initialize(self):
62
+ return self.add_event_handler(InitializeHandler)
63
+
64
+ @classmethod
65
+ def event_handler(cls, condition=None):
66
+ return cls.create_event_handler(EventHandler, condition)
67
+
68
+ def on_event(self, condition=None):
69
+ return self.add_event_handler(EventHandler, condition)
70
+
71
+ @classmethod
72
+ def error_handler(cls, condition=None):
73
+ return cls.create_event_handler(ErrorHandler, condition)
74
+
75
+ def on_error(self, condition=None):
76
+ return self.add_event_handler(ErrorHandler, condition)
77
+
78
+ @classmethod
79
+ def update_handler(cls, condition=None):
80
+ return cls.create_event_handler(UpdateHandler, condition)
81
+
82
+ def on_update(self, condition=None):
83
+ return self.add_event_handler(UpdateHandler, condition)
84
+
85
+ @classmethod
86
+ def message_handler(cls, condition=None):
87
+ return cls.create_event_handler(MessageHandler, condition)
88
+
89
+ def on_message(self, condition=None):
90
+ return self.add_event_handler(MessageHandler, condition)
91
+
92
+ @classmethod
93
+ def edited_message_handler(cls, condition=None):
94
+ return cls.create_event_handler(EditedMessageHandler, condition)
95
+
96
+ def on_edited_message(self, condition=None):
97
+ return self.add_event_handler(EditedMessageHandler, condition)
98
+
99
+ @classmethod
100
+ def command_handler(cls, condition=None, name=None, prefix="/", min_arguments=None, max_arguments=None):
101
+ return cls.create_event_handler(CommandHandler, condition, name, prefix, min_arguments, max_arguments)
102
+
103
+ def on_command(self, condition=None, name=None, prefix="/", min_arguments=None, max_arguments=None):
104
+ return self.add_event_handler(CommandHandler, condition, name, prefix, min_arguments, max_arguments)
105
+
106
+ @classmethod
107
+ def callback_query_handler(cls, condition=None):
108
+ return cls.create_event_handler(CallbackQueryHandler, condition)
109
+
110
+ def on_callback_query(self, condition=None):
111
+ return self.add_event_handler(CallbackQueryHandler, condition)
112
+
113
+ @classmethod
114
+ def pre_checkout_query_handler(cls, condition=None):
115
+ return cls.create_event_handler(PreCheckoutQueryHandler, condition)
116
+
117
+ def on_pre_checkout_query(self, condition=None):
118
+ return self.add_event_handler(PreCheckoutQueryHandler, condition)
119
+
120
+ @classmethod
121
+ def shipping_query_handler(cls, condition=None):
122
+ return cls.create_event_handler(ShippingQueryHandler, condition)
123
+
124
+ def on_shipping_query(self, condition=None):
125
+ return self.add_event_handler(ShippingQueryHandler, condition)
126
+
127
+ @classmethod
128
+ def shutdown_handler(cls):
129
+ return cls.create_event_handler(ShutdownHandler)
130
+
131
+ def on_shutdown(self):
132
+ return self.add_event_handler(ShutdownHandler)
133
+
134
+ @classmethod
135
+ def disconnect_handler(cls):
136
+ return cls.create_event_handler(DisconnectHandler)
137
+
138
+ def on_disconnect(self):
139
+ return self.add_event_handler(DisconnectHandler)
140
+
141
+ def remove_event_handler(self, event_handler):
142
+ self.children.remove(event_handler)
143
+
144
+ def add(self, *chains):
145
+ self.children.extend(chains)
146
+
147
+ def include(self, *chains):
148
+ self.chains.extend(chains)
149
+
150
+ def get(self, name):
151
+ for chain in self.chains:
152
+ if chain.name == name:
153
+ return chain
154
+ raise ValueError(f"Chain \"{name}\" does not exist")
155
+
156
+ def delete(self, name):
157
+ for i, c in enumerate(self.chains):
158
+ if c.name == name:
159
+ del self.chains[i]
160
+ return
161
+ for i, c in enumerate(self.children):
162
+ if isinstance(c, Chain) and c.name == name:
163
+ del self.children[i]
164
+ return
165
+ raise ValueError(f"Chain \"{name}\" does not exist")
@@ -0,0 +1,124 @@
1
+ from asyncio import Queue, get_running_loop
2
+ from concurrent.futures import ThreadPoolExecutor
3
+ from os import cpu_count
4
+
5
+ from .chain import Chain
6
+ from ..errors import ContinueDispatching, BreakDispatching
7
+ from ..event_handlers import EventHandler
8
+ from ..objects import Update
9
+
10
+
11
+ def is_subclass(cls, super_cls):
12
+ if not isinstance(cls, type):
13
+ return False
14
+ return issubclass(cls, super_cls)
15
+
16
+
17
+ class Dispatcher:
18
+ reasonable_sync_workers = min(32, (cpu_count() or 1) + 4)
19
+ reasonable_async_workers = reasonable_sync_workers * 5
20
+
21
+ def __init__(
22
+ self,
23
+ *clients,
24
+ async_workers: int = None,
25
+ sync_workers: int = None,
26
+ use_concurrency: bool = True
27
+ ):
28
+ self.clients = clients
29
+ self.event_loop = None
30
+ self.events_queue = Queue()
31
+ self.is_started = False
32
+ self.async_workers_count = async_workers or self.reasonable_async_workers
33
+ self.async_workers = []
34
+ self.sync_workers_count = sync_workers or self.reasonable_sync_workers
35
+ self.sync_workers = None
36
+ self.use_concurrency = use_concurrency
37
+
38
+ async def start(self):
39
+ if self.is_started:
40
+ raise RuntimeError("Dispatcher is already started")
41
+ self.event_loop = get_running_loop()
42
+ self.is_started = True
43
+ if self.use_concurrency:
44
+ self.async_workers = [self.event_loop.create_task(self.worker()) for _ in range(self.async_workers_count)]
45
+ self.sync_workers = ThreadPoolExecutor(self.sync_workers_count, thread_name_prefix="Event Handler")
46
+
47
+ async def stop(self):
48
+ if not self.is_started:
49
+ raise RuntimeError("Dispatcher is already stopped")
50
+ self.is_started = False
51
+ if self.use_concurrency:
52
+ for _ in self.async_workers:
53
+ self.events_queue.put_nowait(None)
54
+ for async_worker in self.async_workers:
55
+ await async_worker
56
+ self.async_workers.clear()
57
+ self.sync_workers.shutdown()
58
+
59
+ async def propagate_chain(self, chain, client, event):
60
+ for child in chain.children:
61
+ if isinstance(child, Chain):
62
+ try:
63
+ if not await child.check(client, event):
64
+ continue
65
+ except ContinueDispatching:
66
+ continue
67
+ except BreakDispatching:
68
+ break
69
+ except Exception as error:
70
+ await self.dispatch_event(client, error)
71
+ continue
72
+ await self.propagate_chain(child, client, event)
73
+ break
74
+
75
+ elif isinstance(child, EventHandler):
76
+ if not isinstance(event, child.can_handle) and not is_subclass(event, child.can_handle):
77
+ continue
78
+
79
+ try:
80
+ if not await child.check(client, event):
81
+ continue
82
+ await child.handle(client=client, event=event)
83
+ break
84
+ except ContinueDispatching:
85
+ continue
86
+ except BreakDispatching:
87
+ break
88
+ except Exception as error:
89
+ await self.dispatch_event(client, error)
90
+ break
91
+
92
+ for child in chain.chains:
93
+ try:
94
+ if not await child.check(client, event):
95
+ continue
96
+ except ContinueDispatching:
97
+ continue
98
+ except BreakDispatching:
99
+ break
100
+ except Exception as error:
101
+ await self.dispatch_event(client, error)
102
+ continue
103
+
104
+ await self.propagate_chain(child, client, event)
105
+
106
+ async def worker(self):
107
+ while True:
108
+ item = await self.events_queue.get()
109
+ if item is None:
110
+ break
111
+ client, event = item
112
+ await self.propagate_chain(client, client, event)
113
+
114
+ async def dispatch_event(self, client, event):
115
+ if self.is_started:
116
+ if self.use_concurrency:
117
+ self.events_queue.put_nowait((client, event))
118
+ else:
119
+ await self.propagate_chain(client, client, event)
120
+
121
+ async def dispatch_raw_update(self, client, update):
122
+ update = Update.wrap(update).get_effective_update()
123
+ update.bind(client)
124
+ await self.dispatch_event(client, update)
@@ -0,0 +1,36 @@
1
+ from logging import getLogger
2
+
3
+ from .chain import Chain
4
+
5
+
6
+ class LoggingChain(Chain):
7
+
8
+ def __init__(self, name="logging", condition=None, logger=None):
9
+ super().__init__(name, condition)
10
+ self.log = logger or getLogger(self.name)
11
+
12
+ @Chain.error_handler()
13
+ def log_error(self, error):
14
+ self.log.exception(error)
15
+
16
+ @Chain.connect_handler()
17
+ def log_connect(self, client):
18
+ self.log.info(f"{client} connected")
19
+
20
+ @Chain.initialize_handler()
21
+ def log_initialize(self, client):
22
+ sync_workers = client.dispatcher.sync_workers_count
23
+ async_workers = client.dispatcher.async_workers_count
24
+ self.log.info(f"{client} initialized (sync workers: {sync_workers} - async workers: {async_workers})")
25
+
26
+ @Chain.shutdown_handler()
27
+ def log_shutdown(self, client):
28
+ self.log.info(f"{client} shutting down")
29
+
30
+ @Chain.disconnect_handler()
31
+ def log_disconnect(self, client):
32
+ self.log.info(f"{client} disconnected")
33
+
34
+ @Chain.event_handler()
35
+ def log_event(self, event):
36
+ self.log.info(event)
@@ -0,0 +1,19 @@
1
+ from sys import stdout
2
+
3
+ from .chain import Chain
4
+
5
+
6
+ class MonitoringChain(Chain):
7
+ def __init__(self, name="monitoring", condition=None, stream=None):
8
+ super().__init__(name, condition)
9
+ self.stream = stream or stdout
10
+
11
+ @Chain.message_handler()
12
+ def monitor_message(self, message):
13
+ if not message.author:
14
+ return
15
+ self.stream.write(f"{message.author.full_name}: {message.content}\n")
16
+
17
+ @Chain.callback_query_handler()
18
+ def monitor_callback_query(self, callback_query):
19
+ self.stream.write(f"{callback_query.author.full_name}: [{callback_query.data}]\n")
@@ -0,0 +1,21 @@
1
+ from traceback import print_exception
2
+
3
+ from .chain import Chain
4
+
5
+
6
+ class PrintingChain(Chain):
7
+
8
+ def __init__(self, name="printing", condition=None):
9
+ super().__init__(name, condition)
10
+
11
+ @Chain.error_handler()
12
+ def print_error(self, error):
13
+ print_exception(None, error, error.__traceback__)
14
+
15
+ @Chain.initialize_handler()
16
+ def print_ready(self, client):
17
+ print(f"---{client} is ready---")
18
+
19
+ @Chain.shutdown_handler()
20
+ def print_stopped(self, client):
21
+ print(f"---{client} has stopped---")
@@ -0,0 +1,7 @@
1
+ from .name_enum import NameEnum
2
+ from .chat_type import ChatType
3
+ from .message_media_type import MessageMediaType
4
+ from .chat_member_status import ChatMemberStatus
5
+ from .transaction_status import TransactionStatus
6
+ from .poll_type import PollType
7
+ from .peer_type import PeerType
@@ -0,0 +1,9 @@
1
+ from enum import auto
2
+
3
+ from .name_enum import NameEnum
4
+
5
+
6
+ class ChatMemberStatus(NameEnum):
7
+ MEMBER = auto()
8
+ ADMINISTRATOR = auto()
9
+ CREATOR = auto()
@@ -0,0 +1,9 @@
1
+ from enum import auto
2
+
3
+ from .name_enum import NameEnum
4
+
5
+
6
+ class ChatType(NameEnum):
7
+ PRIVATE = auto()
8
+ GROUP = auto()
9
+ CHANNEL = auto()
@@ -0,0 +1,16 @@
1
+ from enum import auto
2
+
3
+ from .name_enum import NameEnum
4
+
5
+
6
+ class MessageMediaType(NameEnum):
7
+ PHOTO = auto()
8
+ VOICE = auto()
9
+ AUDIO = auto()
10
+ VIDEO = auto()
11
+ ANIMATION = auto()
12
+ CONTACT = auto()
13
+ LOCATION = auto()
14
+ STICKER = auto()
15
+ DOCUMENT = auto()
16
+ POLL = auto()
@@ -0,0 +1,13 @@
1
+ from enum import Enum
2
+
3
+
4
+ class NameEnum(Enum):
5
+ @staticmethod
6
+ def _generate_next_value_(name, start, count, last_values):
7
+ return name.lower()
8
+
9
+ def __repr__(self):
10
+ return super().__str__()
11
+
12
+ def __eq__(self, other):
13
+ return self.value == other
@@ -0,0 +1,8 @@
1
+ from enum import auto
2
+
3
+ from .name_enum import NameEnum
4
+
5
+
6
+ class PeerType(NameEnum):
7
+ USER = auto()
8
+ CHANNEL = auto()
@@ -0,0 +1,8 @@
1
+ from enum import auto
2
+
3
+ from .name_enum import NameEnum
4
+
5
+
6
+ class PollType(NameEnum):
7
+ REGULAR = auto()
8
+ QUIZ = auto()
@@ -0,0 +1,10 @@
1
+ from enum import auto
2
+
3
+ from .name_enum import NameEnum
4
+
5
+
6
+ class TransactionStatus(NameEnum):
7
+ PENDING = auto()
8
+ PAID = auto()
9
+ FAILED = auto()
10
+ REJECTED = auto()
@@ -0,0 +1,11 @@
1
+ from .dispatching_errors import BreakDispatching, ContinueDispatching
2
+ from .rpc_errors import (
3
+ BadRequestError,
4
+ FloodError,
5
+ ForbiddenError,
6
+ InternalError,
7
+ NotFoundError,
8
+ RPCError,
9
+ UnauthorizedError,
10
+ TooManyRequestsError
11
+ )
@@ -0,0 +1,2 @@
1
+ from .break_dispatching import BreakDispatching
2
+ from .continue_dispatching import ContinueDispatching
@@ -0,0 +1,2 @@
1
+ class BreakDispatching(Exception):
2
+ pass
@@ -0,0 +1,2 @@
1
+ class ContinueDispatching(Exception):
2
+ pass
@@ -0,0 +1,8 @@
1
+ from .bad_request_error import BadRequestError
2
+ from .flood_error import FloodError
3
+ from .forbidden_error import ForbiddenError
4
+ from .internal_error import InternalError
5
+ from .not_found_error import NotFoundError
6
+ from .rpc_error import RPCError
7
+ from .too_many_requests import TooManyRequestsError
8
+ from .unauthorized_error import UnauthorizedError
@@ -0,0 +1,6 @@
1
+ from .rpc_error import RPCError
2
+
3
+
4
+ class BadRequestError(RPCError):
5
+ name = "Bad Request"
6
+ code = 400
@@ -0,0 +1,6 @@
1
+ from .rpc_error import RPCError
2
+
3
+
4
+ class FloodError(RPCError):
5
+ name = "Flood"
6
+ code = 420