spluspy 2.0.5__tar.gz → 2.0.7__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 (313) hide show
  1. spluspy-2.0.7/.gitignore +50 -0
  2. {spluspy-2.0.5 → spluspy-2.0.7}/CHANGELOG.md +30 -0
  3. {spluspy-2.0.5 → spluspy-2.0.7}/Dockerfile +3 -2
  4. {spluspy-2.0.5 → spluspy-2.0.7}/MANIFEST.in +1 -1
  5. {spluspy-2.0.5 → spluspy-2.0.7}/PKG-INFO +366 -45
  6. {spluspy-2.0.5 → spluspy-2.0.7}/README.md +363 -44
  7. {spluspy-2.0.5 → spluspy-2.0.7}/examples/01_hello_bot.py +1 -2
  8. {spluspy-2.0.5 → spluspy-2.0.7}/examples/02_echo_bot.py +1 -1
  9. {spluspy-2.0.5 → spluspy-2.0.7}/examples/04_private_only.py +3 -4
  10. {spluspy-2.0.5 → spluspy-2.0.7}/examples/05_group_only.py +3 -4
  11. {spluspy-2.0.5 → spluspy-2.0.7}/examples/06_regex_bot.py +6 -7
  12. {spluspy-2.0.5 → spluspy-2.0.7}/examples/07_user_filter.py +5 -6
  13. {spluspy-2.0.5 → spluspy-2.0.7}/examples/09_inline_keyboard.py +8 -9
  14. {spluspy-2.0.5 → spluspy-2.0.7}/examples/10_reply_keyboard.py +7 -8
  15. {spluspy-2.0.5 → spluspy-2.0.7}/examples/11_message_actions.py +10 -12
  16. spluspy-2.0.7/examples/12_media_bot.py +36 -0
  17. {spluspy-2.0.5 → spluspy-2.0.7}/examples/13_fsm_bot.py +12 -13
  18. {spluspy-2.0.5 → spluspy-2.0.7}/examples/14_plugin_bot.py +7 -5
  19. {spluspy-2.0.5 → spluspy-2.0.7}/examples/15_middleware_bot.py +2 -2
  20. {spluspy-2.0.5 → spluspy-2.0.7}/pyproject.toml +2 -1
  21. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/__init__.py +28 -2
  22. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/__version__.py +1 -1
  23. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/account.py +1 -1
  24. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/buttons.py +1 -1
  25. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/chats.py +1 -1
  26. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/messages.py +3 -3
  27. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/updates.py +2 -2
  28. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/uploads.py +1 -1
  29. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/users.py +1 -1
  30. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/__init__.py +3 -3
  31. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/album.py +1 -1
  32. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/callbackquery.py +1 -1
  33. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/chataction.py +1 -1
  34. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/inlinequery.py +1 -1
  35. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/messagedeleted.py +1 -1
  36. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/messageedited.py +1 -1
  37. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/messageread.py +1 -1
  38. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/newmessage.py +2 -2
  39. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/raw.py +1 -1
  40. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/userupdate.py +1 -1
  41. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/sessions/sqlite.py +5 -0
  42. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/conversation.py +1 -1
  43. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/message.py +1 -1
  44. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/utils.py +2 -2
  45. spluspy-2.0.7/spluspy/admin.py +285 -0
  46. spluspy-2.0.7/spluspy/afk.py +202 -0
  47. spluspy-2.0.7/spluspy/client/client.py +3344 -0
  48. spluspy-2.0.7/spluspy/client/conversation.py +294 -0
  49. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/compat.py +3 -3
  50. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/config.py +2 -2
  51. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/base.py +6 -14
  52. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/filters/__init__.py +2 -0
  53. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/filters/filters.py +36 -0
  54. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/fsm/state.py +9 -0
  55. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/middleware/base.py +26 -6
  56. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/middleware/rate_limit.py +6 -1
  57. spluspy-2.0.7/spluspy/mirror.py +207 -0
  58. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/models/bot.py +8 -44
  59. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/models/chat.py +4 -4
  60. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/models/media.py +11 -11
  61. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/models/message.py +15 -80
  62. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/models/objects.py +6 -6
  63. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/models/user.py +1 -1
  64. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/network/__init__.py +10 -0
  65. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/network/client.py +38 -10
  66. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/network/mtproto.py +41 -0
  67. spluspy-2.0.7/spluspy/network/protocols.py +104 -0
  68. spluspy-2.0.7/spluspy/network/spluspy_adapter.py +465 -0
  69. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/network/transport.py +6 -62
  70. spluspy-2.0.7/spluspy/py.typed +0 -0
  71. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/scheduler/__init__.py +2 -2
  72. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/scheduler/scheduler.py +140 -2
  73. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/session/sqlite.py +12 -15
  74. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/session/string.py +22 -3
  75. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/storage/base.py +9 -2
  76. spluspy-2.0.7/spluspy/storage/entity_cache.py +280 -0
  77. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/storage/sqlite.py +6 -0
  78. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/utils/__init__.py +6 -0
  79. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/utils/batch.py +1 -1
  80. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/utils/cache.py +54 -3
  81. spluspy-2.0.7/spluspy/utils/chat_lock.py +96 -0
  82. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/utils/file_transfer.py +85 -15
  83. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/utils/logger.py +282 -284
  84. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/utils/rate_limiter.py +4 -4
  85. spluspy-2.0.7/spluspy/utils/resolver.py +372 -0
  86. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_client.py +33 -21
  87. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_filters.py +3 -3
  88. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_fsm_enhanced.py +12 -12
  89. spluspy-2.0.7/tests/test_resolver.py +411 -0
  90. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_storage.py +12 -0
  91. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_types.py +6 -6
  92. spluspy-2.0.5/debug_client.py +0 -829
  93. spluspy-2.0.5/examples/12_media_bot.py +0 -38
  94. spluspy-2.0.5/spluspy/.mimocode/.cron-lock +0 -1
  95. spluspy-2.0.5/spluspy/client/client.py +0 -1844
  96. spluspy-2.0.5/spluspy/client/conversation.py +0 -80
  97. spluspy-2.0.5/spluspy/network/spluspy_adapter.py +0 -306
  98. spluspy-2.0.5/spluspy/network/telethon_adapter.py +0 -153
  99. spluspy-2.0.5/tempCodeRunnerFile.py +0 -6
  100. spluspy-2.0.5/test_handlers.py +0 -85
  101. spluspy-2.0.5/tests/.vscode/PythonImportHelper-v2-Completion.json +0 -843
  102. spluspy-2.0.5/tests/test_storage_backends.py +0 -52
  103. {spluspy-2.0.5 → spluspy-2.0.7}/CONTRIBUTING.md +0 -0
  104. {spluspy-2.0.5 → spluspy-2.0.7}/LICENSE +0 -0
  105. {spluspy-2.0.5 → spluspy-2.0.7}/README.rst +0 -0
  106. {spluspy-2.0.5 → spluspy-2.0.7}/examples/03_command_bot.py +0 -0
  107. {spluspy-2.0.5 → spluspy-2.0.7}/examples/08_combined_filters.py +0 -0
  108. {spluspy-2.0.5 → spluspy-2.0.7}/examples/16_scheduler_bot.py +0 -0
  109. {spluspy-2.0.5 → spluspy-2.0.7}/examples/17_conversation.py +0 -0
  110. {spluspy-2.0.5 → spluspy-2.0.7}/examples/18_chat_management.py +0 -0
  111. {spluspy-2.0.5 → spluspy-2.0.7}/examples/19_event_types.py +0 -0
  112. {spluspy-2.0.5 → spluspy-2.0.7}/examples/20_sync_bot.py +0 -0
  113. {spluspy-2.0.5 → spluspy-2.0.7}/examples/21_album_handler.py +0 -0
  114. {spluspy-2.0.5 → spluspy-2.0.7}/examples/22_download_bot.py +0 -0
  115. {spluspy-2.0.5 → spluspy-2.0.7}/examples/23_url_button.py +0 -0
  116. {spluspy-2.0.5 → spluspy-2.0.7}/examples/24_string_session.py +0 -0
  117. {spluspy-2.0.5 → spluspy-2.0.7}/examples/25_error_handling.py +0 -0
  118. {spluspy-2.0.5 → spluspy-2.0.7}/examples/25_working_bot.py +0 -0
  119. {spluspy-2.0.5 → spluspy-2.0.7}/examples/26_message_entities.py +0 -0
  120. {spluspy-2.0.5 → spluspy-2.0.7}/examples/27_search_messages.py +0 -0
  121. {spluspy-2.0.5 → spluspy-2.0.7}/examples/28_poll_bot.py +0 -0
  122. {spluspy-2.0.5 → spluspy-2.0.7}/examples/29_dice_bot.py +0 -0
  123. {spluspy-2.0.5 → spluspy-2.0.7}/examples/30_cache_bot.py +0 -0
  124. {spluspy-2.0.5 → spluspy-2.0.7}/examples/31_reaction_bot.py +0 -0
  125. {spluspy-2.0.5 → spluspy-2.0.7}/examples/32_mark_read_bot.py +0 -0
  126. {spluspy-2.0.5 → spluspy-2.0.7}/examples/33_context_manager.py +0 -0
  127. {spluspy-2.0.5 → spluspy-2.0.7}/examples/34_user_info.py +0 -0
  128. {spluspy-2.0.5 → spluspy-2.0.7}/examples/35_chat_info.py +0 -0
  129. {spluspy-2.0.5 → spluspy-2.0.7}/examples/36_forward_copy.py +0 -0
  130. {spluspy-2.0.5 → spluspy-2.0.7}/examples/37_admin_bot.py +0 -0
  131. {spluspy-2.0.5 → spluspy-2.0.7}/examples/38_media_filters.py +0 -0
  132. {spluspy-2.0.5 → spluspy-2.0.7}/examples/39_status_bot.py +0 -0
  133. {spluspy-2.0.5 → spluspy-2.0.7}/examples/40_delete_detection.py +0 -0
  134. {spluspy-2.0.5 → spluspy-2.0.7}/examples/41_read_detection.py +0 -0
  135. {spluspy-2.0.5 → spluspy-2.0.7}/examples/42_raw_events.py +0 -0
  136. {spluspy-2.0.5 → spluspy-2.0.7}/examples/43_poll_handler.py +0 -0
  137. {spluspy-2.0.5 → spluspy-2.0.7}/examples/44_reaction_handler.py +0 -0
  138. {spluspy-2.0.5 → spluspy-2.0.7}/examples/45_typing_handler.py +0 -0
  139. {spluspy-2.0.5 → spluspy-2.0.7}/examples/46_get_messages.py +0 -0
  140. {spluspy-2.0.5 → spluspy-2.0.7}/examples/47_iter_messages.py +0 -0
  141. {spluspy-2.0.5 → spluspy-2.0.7}/examples/48_get_members.py +0 -0
  142. {spluspy-2.0.5 → spluspy-2.0.7}/examples/49_resolve_username.py +0 -0
  143. {spluspy-2.0.5 → spluspy-2.0.7}/examples/50_invoke.py +0 -0
  144. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/__init__.py +0 -0
  145. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/_updates/__init__.py +0 -0
  146. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/_updates/entitycache.py +0 -0
  147. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/_updates/messagebox.py +0 -0
  148. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/_updates/session.py +0 -0
  149. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/__init__.py +0 -0
  150. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/auth.py +0 -0
  151. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/bots.py +0 -0
  152. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/dialogs.py +0 -0
  153. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/downloads.py +0 -0
  154. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/messageparse.py +0 -0
  155. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/soroushclient.py +0 -0
  156. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/client/telegrambaseclient.py +0 -0
  157. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/crypto/__init__.py +0 -0
  158. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/crypto/aes.py +0 -0
  159. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/crypto/aesctr.py +0 -0
  160. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/crypto/authkey.py +0 -0
  161. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/crypto/cdndecrypter.py +0 -0
  162. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/crypto/factorization.py +0 -0
  163. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/crypto/libssl.py +0 -0
  164. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/crypto/rsa.py +0 -0
  165. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/custom.py +0 -0
  166. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/errors/__init__.py +0 -0
  167. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/errors/common.py +0 -0
  168. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/errors/rpcbaseerrors.py +0 -0
  169. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/errors/rpcerrorlist.py +0 -0
  170. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/events/common.py +0 -0
  171. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/extensions/__init__.py +0 -0
  172. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/extensions/binaryreader.py +0 -0
  173. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/extensions/html.py +0 -0
  174. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/extensions/markdown.py +0 -0
  175. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/extensions/messagepacker.py +0 -0
  176. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/functions.py +0 -0
  177. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/helpers.py +0 -0
  178. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/hints.py +0 -0
  179. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/__init__.py +0 -0
  180. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/authenticator.py +0 -0
  181. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/__init__.py +0 -0
  182. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/connection.py +0 -0
  183. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/http.py +0 -0
  184. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/tcpabridged.py +0 -0
  185. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/tcpfull.py +0 -0
  186. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/tcpintermediate.py +0 -0
  187. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/tcpmtproxy.py +0 -0
  188. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/tcpobfuscated.py +0 -0
  189. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/connection/websocket.py +0 -0
  190. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/mtprotoplainsender.py +0 -0
  191. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/mtprotosender.py +0 -0
  192. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/mtprotostate.py +0 -0
  193. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/network/requeststate.py +0 -0
  194. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/password.py +0 -0
  195. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/requestiter.py +0 -0
  196. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/sessions/__init__.py +0 -0
  197. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/sessions/abstract.py +0 -0
  198. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/sessions/memory.py +0 -0
  199. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/sessions/string.py +0 -0
  200. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/sync.py +0 -0
  201. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/__init__.py +0 -0
  202. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/alltlobjects.py +0 -0
  203. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/core/__init__.py +0 -0
  204. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/core/gzippacked.py +0 -0
  205. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/core/messagecontainer.py +0 -0
  206. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/core/rpcresult.py +0 -0
  207. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/core/tlmessage.py +0 -0
  208. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/__init__.py +0 -0
  209. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/adminlogevent.py +0 -0
  210. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/button.py +0 -0
  211. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/chatgetter.py +0 -0
  212. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/dialog.py +0 -0
  213. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/draft.py +0 -0
  214. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/file.py +0 -0
  215. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/forward.py +0 -0
  216. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/inlinebuilder.py +0 -0
  217. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/inlineresult.py +0 -0
  218. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/inlineresults.py +0 -0
  219. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/inputsizedfile.py +0 -0
  220. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/messagebutton.py +0 -0
  221. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/participantpermissions.py +0 -0
  222. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/qrlogin.py +0 -0
  223. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/sendergetter.py +0 -0
  224. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/custom/types.py +0 -0
  225. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/__init__.py +0 -0
  226. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/account.py +0 -0
  227. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/auth.py +0 -0
  228. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/bots.py +0 -0
  229. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/channels.py +0 -0
  230. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/chatlists.py +0 -0
  231. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/conference.py +0 -0
  232. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/contacts.py +0 -0
  233. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/folders.py +0 -0
  234. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/help.py +0 -0
  235. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/langpack.py +0 -0
  236. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/messages.py +0 -0
  237. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/payments.py +0 -0
  238. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/phone.py +0 -0
  239. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/photos.py +0 -0
  240. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/premium.py +0 -0
  241. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/stats.py +0 -0
  242. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/stories.py +0 -0
  243. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/thirdParty.py +0 -0
  244. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/updates.py +0 -0
  245. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/upload.py +0 -0
  246. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/functions/users.py +0 -0
  247. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/patched/__init__.py +0 -0
  248. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/tlobject.py +0 -0
  249. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/__init__.py +0 -0
  250. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/account.py +0 -0
  251. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/auth.py +0 -0
  252. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/bots.py +0 -0
  253. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/channels.py +0 -0
  254. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/chatlists.py +0 -0
  255. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/conference.py +0 -0
  256. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/contacts.py +0 -0
  257. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/help.py +0 -0
  258. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/messages.py +0 -0
  259. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/payments.py +0 -0
  260. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/phone.py +0 -0
  261. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/photos.py +0 -0
  262. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/premium.py +0 -0
  263. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/stats.py +0 -0
  264. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/stickers.py +0 -0
  265. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/storage.py +0 -0
  266. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/stories.py +0 -0
  267. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/thirdParty.py +0 -0
  268. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/update.py +0 -0
  269. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/updates.py +0 -0
  270. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/upload.py +0 -0
  271. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/tl/types/users.py +0 -0
  272. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/types.py +0 -0
  273. {spluspy-2.0.5/spluspy/spluspy2 → spluspy-2.0.7/spluspy/_engine}/version.py +0 -0
  274. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/cli.py +0 -0
  275. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/client/__init__.py +0 -0
  276. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/errors/__init__.py +0 -0
  277. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/errors/exceptions.py +0 -0
  278. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/__init__.py +0 -0
  279. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/album.py +0 -0
  280. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/callback.py +0 -0
  281. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/chat_action.py +0 -0
  282. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/edited.py +0 -0
  283. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/inline.py +0 -0
  284. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/message.py +0 -0
  285. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/message_deleted.py +0 -0
  286. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/message_read.py +0 -0
  287. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/events/user_update.py +0 -0
  288. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/fsm/__init__.py +0 -0
  289. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/middleware/__init__.py +0 -0
  290. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/models/__init__.py +0 -0
  291. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/models/enums.py +0 -0
  292. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/network/connection.py +0 -0
  293. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/network/http_client.py +0 -0
  294. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/plugins/__init__.py +0 -0
  295. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/plugins/loader.py +0 -0
  296. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/session/__init__.py +0 -0
  297. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/session/base.py +0 -0
  298. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/session/memory.py +0 -0
  299. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/storage/__init__.py +0 -0
  300. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/storage/memory.py +0 -0
  301. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/storage/postgres.py +0 -0
  302. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/storage/redis.py +0 -0
  303. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/sync/__init__.py +0 -0
  304. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/sync/client.py +0 -0
  305. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/utils/helpers.py +0 -0
  306. {spluspy-2.0.5 → spluspy-2.0.7}/spluspy/utils/version_check.py +0 -0
  307. {spluspy-2.0.5 → spluspy-2.0.7}/tests/__init__.py +0 -0
  308. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_fsm.py +0 -0
  309. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_middleware.py +0 -0
  310. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_rate_limiter.py +0 -0
  311. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_scheduler.py +0 -0
  312. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_session.py +0 -0
  313. {spluspy-2.0.5 → spluspy-2.0.7}/tests/test_utils.py +0 -0
@@ -0,0 +1,50 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ *.egg-info/
7
+ *.egg
8
+ dist/
9
+ build/
10
+ *.whl
11
+
12
+ # Virtual environments
13
+ venv/
14
+ .venv/
15
+ env/
16
+
17
+ # IDE
18
+ .vscode/
19
+ .idea/
20
+ *.swp
21
+ *.swo
22
+ *~
23
+
24
+ # Testing
25
+ .pytest_cache/
26
+ .coverage
27
+ htmlcov/
28
+ .mypy_cache/
29
+
30
+ # Logs
31
+ *.log
32
+ logs/
33
+
34
+ # Database files
35
+ *.sqlite
36
+ *.sqlite3
37
+
38
+ # Environment
39
+ .env
40
+ .env.*
41
+
42
+ # OS
43
+ Thumbs.db
44
+ Desktop.ini
45
+ .DS_Store
46
+
47
+ # Temporary files
48
+ tempCodeRunnerFile.py
49
+ *.tmp
50
+ *.bak
@@ -5,6 +5,36 @@ All notable changes to SplusPy will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [2.0.7] - 2026-07-11
9
+
10
+ ### Changed
11
+ - Version bump to 2.0.7
12
+
13
+ ## [2.0.6] - 2026-07-11
14
+
15
+ ### Fixed
16
+ - Fixed missing `Union` import in `batch.py` that caused `NameError` at runtime
17
+ - Fixed missing `copy_messages` method call in sync wrapper that caused `AttributeError`
18
+ - Removed unused `SplusConnectionError` import in `client.py`
19
+ - Fixed deprecated `asyncio.get_event_loop()` replaced with `asyncio.get_running_loop()` in network client
20
+ - Fixed FSM `on_enter`/`on_leave` hooks that were registered but never invoked
21
+ - Fixed `RateLimitMiddleware` that incremented counter but didn't actually rate-limit updates
22
+
23
+ ### Removed
24
+ - Removed unused `HttpTransport` class from transport module
25
+ - Removed duplicate `test_storage_backends.py` (merged TTL test into `test_storage.py`)
26
+
27
+ ### Changed
28
+ - Renamed `FloodWait` in `rate_limiter.py` to `FloodWaitState` to avoid confusion with `errors.FloodWait`
29
+ - Moved inline `import inspect` and `import re` to module-level imports in `client.py`
30
+ - Added `FloodWaitState` docstring clarification in rate limiter
31
+
32
+ ### Documentation
33
+ - Fixed README.md project structure: `types/` corrected to `models/`
34
+ - Fixed README.md FSM example that accessed data after `reset()`
35
+ - Fixed Dockerfile `COPY bot.py` that failed when file doesn't exist
36
+ - Added docstring for `Regex` filter side effect (`pattern_match`)
37
+
8
38
  ## [3.0.0] - 2026-07-10
9
39
 
10
40
  ### Added
@@ -14,8 +14,9 @@ COPY spluspy/ spluspy/
14
14
  # Install the package
15
15
  RUN pip install --no-cache-dir ".[all]"
16
16
 
17
- # Copy bot script if present
18
- COPY bot.py ./
17
+ # Copy bot script (pass as build arg)
18
+ ARG BOT_SCRIPT=bot.py
19
+ COPY ${BOT_SCRIPT} ./
19
20
 
20
21
  # Run the bot
21
22
  CMD ["python", "bot.py"]
@@ -2,6 +2,6 @@ include LICENSE
2
2
  include README.md
3
3
  include README.rst
4
4
  include pyproject.toml
5
- recursive-include spluspy *.py *.pyi
5
+ recursive-include spluspy *.py *.pyi py.typed
6
6
  recursive-include tests *.py
7
7
  recursive-include examples *.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spluspy
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: A modern async Python library for interacting with Soroush Plus
5
5
  Project-URL: Homepage, https://github.com/Itskillmaster/spluspy
6
6
  Project-URL: Documentation, https://github.com/Itskillmaster/spluspy#readme
@@ -36,6 +36,7 @@ Requires-Dist: pytest-cov>=4.0; extra == 'all'
36
36
  Requires-Dist: pytest>=7.0; extra == 'all'
37
37
  Requires-Dist: redis>=4.0; extra == 'all'
38
38
  Requires-Dist: ruff>=0.1.0; extra == 'all'
39
+ Requires-Dist: uvloop>=0.19.0; (sys_platform != 'win32') and extra == 'all'
39
40
  Provides-Extra: dev
40
41
  Requires-Dist: black>=23.0; extra == 'dev'
41
42
  Requires-Dist: mypy>=1.0; extra == 'dev'
@@ -50,6 +51,7 @@ Requires-Dist: redis>=4.0; extra == 'redis'
50
51
  Provides-Extra: speed
51
52
  Requires-Dist: cryptg; extra == 'speed'
52
53
  Requires-Dist: orjson>=3.9.0; extra == 'speed'
54
+ Requires-Dist: uvloop>=0.19.0; (sys_platform != 'win32') and extra == 'speed'
53
55
  Description-Content-Type: text/markdown
54
56
 
55
57
  <div align="center">
@@ -101,10 +103,20 @@ Built from the ground up with clean architecture, it's designed to feel like [Te
101
103
  | **Scheduler** | Built-in task scheduler |
102
104
  | **Multiple Storage Backends** | Memory, SQLite, Redis, PostgreSQL |
103
105
  | **Rate Limiting** | Token bucket algorithm with flood wait handling |
106
+ | **AFK Auto-Reply** | Smart auto-responder with per-chat rate limiting |
107
+ | **Chat Administration** | Ban, mute, pin, purge — high-level admin API |
108
+ | **Message Mirroring** | Real-time message cloning between chats |
109
+ | **Batch Operations** | Send, delete, forward multiple messages at once |
110
+ | **File Transfer with Progress** | Upload/download with progress tracking |
104
111
  | **Professional Logging** | Structured, namespaced loggers |
105
112
  | **Type Hints Everywhere** | Full type safety |
106
113
  | **Clean Architecture** | SOLID principles, modular design |
107
114
 
115
+ ### Requirements
116
+
117
+ - Python 3.10+
118
+ - No external API keys needed (built-in Soroush Plus credentials)
119
+
108
120
  ### Installation
109
121
 
110
122
  ```bash
@@ -308,9 +320,9 @@ async def process_form(client, message):
308
320
  await ctx.set_state(Form.age)
309
321
  await message.reply("How old are you?")
310
322
  elif state == Form.age:
311
- await ctx.set_data(age=message.text)
323
+ data = await ctx.get_data()
312
324
  await ctx.reset()
313
- await message.reply(f"Registered! Name: {(await ctx.get_data()).get('name')}")
325
+ await message.reply(f"Registered! Name: {data.get('name')}, Age: {message.text}")
314
326
  ```
315
327
 
316
328
  #### Advanced FSM: State Routing with Decorators
@@ -435,6 +447,94 @@ value = cache.get("key")
435
447
  stats = cache.stats() # {'hits': 42, 'misses': 3}
436
448
  ```
437
449
 
450
+ ### AFK Auto-Reply
451
+
452
+ ```python
453
+ from spluspy import Client, filters
454
+ from spluspy.afk import AfkManager
455
+
456
+ bot = Client("my_account")
457
+ afk = AfkManager(bot, message="I'm currently AFK. Back soon!")
458
+
459
+ @bot.on_message(filters.command("afk"))
460
+ async def set_afk(client, message):
461
+ afk.set_afk(True, reason="Lunch break")
462
+ await message.reply("I'm now AFK!")
463
+
464
+ @bot.on_message(filters.command("back"))
465
+ async def unset_afk(client, message):
466
+ afk.set_afk(False)
467
+ await message.reply(f"Back! Sent {afk.total_replies} auto-replies.")
468
+
469
+ @bot.on_message(filters.private & filters.incoming)
470
+ async def auto_reply(client, message):
471
+ if afk.is_afk:
472
+ await afk.handle(message)
473
+ ```
474
+
475
+ ### Chat Administration
476
+
477
+ ```python
478
+ from spluspy.admin import ChatAdmin
479
+
480
+ admin = ChatAdmin(bot)
481
+
482
+ await admin.ban_user(chat_id, user_id)
483
+ await admin.unban_user(chat_id, user_id)
484
+ await admin.mute_user(chat_id, user_id)
485
+ await admin.unmute_user(chat_id, user_id)
486
+ await admin.pin_message(chat_id, message)
487
+ await admin.unpin_message(chat_id, message)
488
+ await admin.unpin_all(chat_id)
489
+ await admin.purge_messages(chat_id, limit=100)
490
+
491
+ # Bulk actions
492
+ await admin.bulk_action(chat_id, "ban", [user_id1, user_id2, user_id3])
493
+
494
+ # Admin log
495
+ events = await admin.get_admin_log(chat_id, limit=50)
496
+ ```
497
+
498
+ ### Message Mirroring
499
+
500
+ ```python
501
+ from spluspy.mirror import MessageMirror
502
+
503
+ mirror = MessageMirror(bot)
504
+
505
+ # Add a mirroring route
506
+ mirror.add_route(
507
+ source=-1001234567890,
508
+ targets=[-1009876543210, -1001112223334],
509
+ strip_forward=True,
510
+ strip_sender=False,
511
+ add_prefix="[Mirror]"
512
+ )
513
+
514
+ # Or build incrementally
515
+ mirror.add_source(-1001234567890)
516
+ mirror.add_target(-1009876543210)
517
+
518
+ await mirror.start()
519
+ ```
520
+
521
+ ### Scheduler
522
+
523
+ ```python
524
+ from spluspy.scheduler.scheduler import MessageScheduler
525
+
526
+ scheduler = MessageScheduler(bot)
527
+
528
+ # Send a message every hour
529
+ scheduler.schedule_interval("hourly_greeting", chat_id, "Hello!", interval=3600)
530
+
531
+ # Send a message after a delay
532
+ scheduler.schedule_once("reminder", chat_id, "Don't forget!", delay=300)
533
+
534
+ # Cancel a scheduled task
535
+ scheduler.cancel("hourly_greeting")
536
+ ```
537
+
438
538
  ### Chat Management
439
539
 
440
540
  ```python
@@ -511,25 +611,46 @@ await message.download(progress=tracker)
511
611
  # Run a bot
512
612
  spluspy run bot.py
513
613
 
614
+ # Run with custom session name
615
+ spluspy run bot.py --session my_bot
616
+
514
617
  # Get session info
515
- spluspy session-info
618
+ spluspy session-info my_session.session
516
619
 
517
620
  # Show version
518
621
  spluspy version
519
622
 
520
- # Validate session
521
- spluspy validate
623
+ # Validate a bot script for syntax errors
624
+ spluspy validate bot.py
522
625
  ```
523
626
 
524
627
  ### Docker
525
628
 
526
629
  ```dockerfile
527
630
  FROM python:3.12-slim
631
+
528
632
  WORKDIR /app
529
- COPY requirements.txt .
530
- RUN pip install spluspy
531
- COPY . .
532
- CMD ["spluspy", "run", "bot.py"]
633
+
634
+ # Install system dependencies
635
+ RUN apt-get update && apt-get install -y --no-install-recommends \
636
+ gcc \
637
+ && rm -rf /var/lib/apt/lists/*
638
+
639
+ # Install spluspy
640
+ RUN pip install --no-cache-dir spluspy[all]
641
+
642
+ # Copy your bot script
643
+ COPY bot.py .
644
+
645
+ # Run the bot
646
+ CMD ["python", "bot.py"]
647
+ ```
648
+
649
+ Build and run:
650
+
651
+ ```bash
652
+ docker build -t my-spluspy-bot .
653
+ docker run -v ./sessions:/app/sessions my-spluspy-bot
533
654
  ```
534
655
 
535
656
  ### Project Structure
@@ -541,8 +662,13 @@ spluspy/
541
662
  ├── cli.py # CLI entry point
542
663
  ├── config.py # Configuration
543
664
  ├── compat.py # Compatibility layer
665
+ ├── afk.py # AFK auto-responder
666
+ ├── admin.py # Chat administration
667
+ ├── mirror.py # Message mirroring engine
544
668
  ├── client/ # Client and conversation API
545
- ├── types/ # Domain models (Message, User, Chat, Media, etc.)
669
+ │ ├── client.py # Main Client class
670
+ │ └── conversation.py # Conversation API
671
+ ├── models/ # Domain models (Message, User, Chat, Media, etc.)
546
672
  ├── events/ # Event types and builders
547
673
  ├── filters/ # Composable message filters
548
674
  ├── errors/ # Custom exception hierarchy
@@ -554,7 +680,34 @@ spluspy/
554
680
  ├── fsm/ # Finite state machine
555
681
  ├── scheduler/ # Task scheduler
556
682
  ├── utils/ # Logger, cache, helpers
557
- └── sync/ # Synchronous client wrapper
683
+ ├── sync/ # Synchronous client wrapper
684
+ └── _engine/ # Low-level MTProto engine
685
+ ```
686
+
687
+ ### Error Hierarchy
688
+
689
+ ```
690
+ SplusPyError
691
+ ├── SoroushPlusAPIError
692
+ │ ├── RPCError
693
+ │ │ ├── FloodWait
694
+ │ │ ├── Unauthorized
695
+ │ │ ├── BadRequest
696
+ │ │ │ ├── ChatNotFound
697
+ │ │ │ ├── UserNotFound
698
+ │ │ │ └── MessageNotFound
699
+ │ │ └── ...
700
+ │ ├── SessionExpiredError
701
+ │ └── SessionError
702
+ ├── AuthError
703
+ ├── ValidationError
704
+ ├── JoinChatError
705
+ │ ├── InvalidInviteLinkError
706
+ │ ├── InviteLinkExpiredError
707
+ │ ├── ChatFullError
708
+ │ ├── ChatDeactivatedError
709
+ │ └── MembershipRequiredError
710
+ └── FloodWaitError (rate limiter)
558
711
  ```
559
712
 
560
713
  ---
@@ -579,10 +732,20 @@ spluspy/
579
732
  | **زمان‌بند (Scheduler)** | زمان‌بندی داخلی وظایف |
580
733
  | **بک‌اندهای ذخیره‌سازی متعدد** | حافظه، SQLite، Redis، PostgreSQL |
581
734
  | **محدودیت نرخ (Rate Limiting)** | الگوریتم سطل توکن با مدیریت انتظار سیلاب |
735
+ | **پاسخ خودکار AFK** | پاسخگوی هوشمند با محدودیت نرخ به ازای هر چت |
736
+ | **مدیریت چت** | مسدود کردن، بی‌صدا کردن، سنجاق، پاکسازی — API مدیریتی |
737
+ | **آینه‌سازی پیام** | کلون کردن پیام و رسانه به صورت بلادرنگ بین چت‌ها |
738
+ | **عملیات دسته‌ای** | ارسال، حذف، فوروارد چندین پیام به صورت همزمان |
739
+ | **انتقال فایل با پیشرفت** | آپلود/دانلود با ردیابی پیشرفت |
582
740
  | **لاگ حرفه‌ای** | لاگرهای ساختاریافته و فضای نام‌دار |
583
741
  | **نوع‌نویسی در همه جا** | ایمنی کامل نوع |
584
742
  | **معماری تمیز** | اصول SOLID، طراحی ماژولار |
585
743
 
744
+ ### پیش‌نیازها
745
+
746
+ - پایتون 3.10 به بالا
747
+ - نیازی به کلید API خارجی نیست (کلیدهای سروش پلاس به صورت داخلی)
748
+
586
749
  ### نصب
587
750
 
588
751
  ```bash
@@ -786,9 +949,9 @@ async def process_form(client, message):
786
949
  await ctx.set_state(Form.age)
787
950
  await message.reply("سن شما چقدر است؟")
788
951
  elif state == Form.age:
789
- await ctx.set_data(age=message.text)
952
+ data = await ctx.get_data()
790
953
  await ctx.reset()
791
- await message.reply(f"ثبت شد! نام: {(await ctx.get_data()).get('name')}")
954
+ await message.reply(f"ثبت شد! نام: {data.get('name')}, سن: {message.text}")
792
955
  ```
793
956
 
794
957
  #### FSM پیشرفته: مسیریابی وضعیت با دکوراتور
@@ -908,22 +1071,97 @@ async def limited_handler(client, message):
908
1071
  from spluspy.utils import LRUCache
909
1072
 
910
1073
  cache = LRUCache(maxsize=1000, ttl=300) # TTL ۵ دقیقه‌ای
911
- cache.set("کلید", "مقدار")
912
- مقدار = cache.get("کلید")
913
- آمار = cache.stats() # {'hits': 42, 'misses': 3}
1074
+ cache.set("key", "value")
1075
+ value = cache.get("key")
1076
+ stats = cache.stats() # {'hits': 42, 'misses': 3}
1077
+ ```
1078
+
1079
+ ### پاسخ خودکار AFK
1080
+
1081
+ ```python
1082
+ from spluspy import Client, filters
1083
+ from spluspy.afk import AfkManager
1084
+
1085
+ bot = Client("my_account")
1086
+ afk = AfkManager(bot, message="الان AFK هستم. زود برمی‌گردم!")
1087
+
1088
+ @bot.on_message(filters.command("afk"))
1089
+ async def set_afk(client, message):
1090
+ afk.set_afk(True, reason="ناهار")
1091
+ await message.reply("الان AFK هستم!")
1092
+
1093
+ @bot.on_message(filters.command("back"))
1094
+ async def unset_afk(client, message):
1095
+ afk.set_afk(False)
1096
+ await message.reply(f"برگشتم! {afk.total_replies} پاسخ خودکار ارسال شد.")
1097
+
1098
+ @bot.on_message(filters.private & filters.incoming)
1099
+ async def auto_reply(client, message):
1100
+ if afk.is_afk:
1101
+ await afk.handle(message)
914
1102
  ```
915
1103
 
916
1104
  ### مدیریت چت
917
1105
 
918
1106
  ```python
919
- await bot.ban_user(chat_id, user_id) # مسدود کردن
920
- await bot.unban_user(chat_id, user_id) # رفع مسدودیت
921
- await bot.mute_user(chat_id, user_id) # بی‌صدا کردن
922
- await bot.unmute_user(chat_id, user_id) # رفع بی‌صدایی
923
- await bot.pin_message(chat_id, message) # سنجاق کردن
924
- await bot.unpin_message(chat_id, message) # رفع سنجاق
925
- await bot.join_chat(chat_id) # پیوستن به چت
926
- await bot.leave_chat(chat_id) # ترک چت
1107
+ from spluspy.admin import ChatAdmin
1108
+
1109
+ admin = ChatAdmin(bot)
1110
+
1111
+ await admin.ban_user(chat_id, user_id) # مسدود کردن
1112
+ await admin.unban_user(chat_id, user_id) # رفع مسدودیت
1113
+ await admin.mute_user(chat_id, user_id) # بی‌صدا کردن
1114
+ await admin.unmute_user(chat_id, user_id) # رفع بی‌صدایی
1115
+ await admin.pin_message(chat_id, message) # سنجاق کردن
1116
+ await admin.unpin_message(chat_id, message) # رفع سنجاق
1117
+ await admin.unpin_all(chat_id) # رفع همه سنجاق‌ها
1118
+ await admin.purge_messages(chat_id, limit=100) # پاکسازی پیام‌ها
1119
+
1120
+ # عملیات دسته‌ای
1121
+ await admin.bulk_action(chat_id, "ban", [user_id1, user_id2])
1122
+
1123
+ # لاگ مدیریتی
1124
+ events = await admin.get_admin_log(chat_id, limit=50)
1125
+ ```
1126
+
1127
+ ### آینه‌سازی پیام
1128
+
1129
+ ```python
1130
+ from spluspy.mirror import MessageMirror
1131
+
1132
+ mirror = MessageMirror(bot)
1133
+
1134
+ # افزودن مسیر آینه‌سازی
1135
+ mirror.add_route(
1136
+ source=-1001234567890,
1137
+ targets=[-1009876543210, -1001112223334],
1138
+ strip_forward=True,
1139
+ strip_sender=False,
1140
+ add_prefix="[Mirror]"
1141
+ )
1142
+
1143
+ # یا به صورت تدریجی
1144
+ mirror.add_source(-1001234567890)
1145
+ mirror.add_target(-1009876543210)
1146
+
1147
+ await mirror.start()
1148
+ ```
1149
+
1150
+ ### زمان‌بند
1151
+
1152
+ ```python
1153
+ from spluspy.scheduler.scheduler import MessageScheduler
1154
+
1155
+ scheduler = MessageScheduler(bot)
1156
+
1157
+ # ارسال پیام هر ساعت
1158
+ scheduler.schedule_interval("hourly_greeting", chat_id, "سلام!", interval=3600)
1159
+
1160
+ # ارسال پیام با تاخیر
1161
+ scheduler.schedule_once("reminder", chat_id, "فراموش نکن!", delay=300)
1162
+
1163
+ # لغو وظیفه زمان‌بندی شده
1164
+ scheduler.cancel("hourly_greeting")
927
1165
  ```
928
1166
 
929
1167
  ### مدیریت خطا
@@ -960,14 +1198,14 @@ bot.on_error(error_handler.build())
960
1198
 
961
1199
  ```python
962
1200
  # ارسال چندین پیام
963
- پیام‌ها = ["سلام ۱", "سلام ۲", "سلام ۳"]
964
- نتایج = await bot.batch_send(chat_id, پیام‌ها)
1201
+ messages = ["سلام ۱", "سلام ۲", "سلام ۳"]
1202
+ results = await bot.batch_send(chat_id, messages)
965
1203
 
966
1204
  # حذف چندین پیام
967
- await bot.batch_delete(chat_id, [پیام۱, پیام۲, پیام۳])
1205
+ await bot.batch_delete(chat_id, [msg1, msg2, msg3])
968
1206
 
969
1207
  # فوروارد چندین پیام
970
- await bot.batch_forward(chat_id, [پیام۱, پیام۲])
1208
+ await bot.batch_forward(chat_id, [msg1, msg2])
971
1209
  ```
972
1210
 
973
1211
  ### انتقال فایل با پیشرفت
@@ -989,25 +1227,46 @@ await message.download(progress=tracker)
989
1227
  # اجرای ربات
990
1228
  spluspy run bot.py
991
1229
 
1230
+ # اجرا با نشست سفارشی
1231
+ spluspy run bot.py --session my_bot
1232
+
992
1233
  # اطلاعات نشست
993
- spluspy session-info
1234
+ spluspy session-info my_session.session
994
1235
 
995
1236
  # نمایش نسخه
996
1237
  spluspy version
997
1238
 
998
- # اعتبارسنجی نشست
999
- spluspy validate
1239
+ # اعتبارسنجی اسکریپت ربات
1240
+ spluspy validate bot.py
1000
1241
  ```
1001
1242
 
1002
1243
  ### Docker
1003
1244
 
1004
1245
  ```dockerfile
1005
1246
  FROM python:3.12-slim
1247
+
1006
1248
  WORKDIR /app
1007
- COPY requirements.txt .
1008
- RUN pip install spluspy
1009
- COPY . .
1010
- CMD ["spluspy", "run", "bot.py"]
1249
+
1250
+ # نصب وابستگی‌های سیستمی
1251
+ RUN apt-get update && apt-get install -y --no-install-recommends \
1252
+ gcc \
1253
+ && rm -rf /var/lib/apt/lists/*
1254
+
1255
+ # نصب spluspy
1256
+ RUN pip install --no-cache-dir spluspy[all]
1257
+
1258
+ # کپی اسکریپت ربات
1259
+ COPY bot.py .
1260
+
1261
+ # اجرای ربات
1262
+ CMD ["python", "bot.py"]
1263
+ ```
1264
+
1265
+ ساخت و اجرا:
1266
+
1267
+ ```bash
1268
+ docker build -t my-spluspy-bot .
1269
+ docker run -v ./sessions:/app/sessions my-spluspy-bot
1011
1270
  ```
1012
1271
 
1013
1272
  ### ساختار پروژه
@@ -1019,8 +1278,13 @@ spluspy/
1019
1278
  ├── cli.py # نقطه ورود CLI
1020
1279
  ├── config.py # پیکربندی
1021
1280
  ├── compat.py # لایه سازگاری
1281
+ ├── afk.py # پاسخگوی خودکار AFK
1282
+ ├── admin.py # مدیریت چت
1283
+ ├── mirror.py # موتور آینه‌سازی پیام
1022
1284
  ├── client/ # کلاینت و API مکالمه
1023
- ├── types/ # مدل‌های دامنه (Message, User, Chat, Media, و غیره)
1285
+ │ ├── client.py # کلاس اصلی Client
1286
+ │ └── conversation.py # API مکالمه
1287
+ ├── models/ # مدل‌های دامنه (Message, User, Chat, Media, و غیره)
1024
1288
  ├── events/ # انواع رویداد و بیلدرها
1025
1289
  ├── filters/ # فیلترهای قابل ترکیب پیام
1026
1290
  ├── errors/ # سلسله مراتب استثنای سفارشی
@@ -1032,7 +1296,34 @@ spluspy/
1032
1296
  ├── fsm/ # ماشین حالت محدود
1033
1297
  ├── scheduler/ # زمان‌بند وظایف
1034
1298
  ├── utils/ # لاگر، کش، کمک‌کننده‌ها
1035
- └── sync/ # کلاینت همگام‌سازی شده
1299
+ ├── sync/ # کلاینت همگام‌سازی شده
1300
+ └── _engine/ # موتور MTProto سطح پایین
1301
+ ```
1302
+
1303
+ ### سلسله مراتب خطاها
1304
+
1305
+ ```
1306
+ SplusPyError
1307
+ ├── SoroushPlusAPIError
1308
+ │ ├── RPCError
1309
+ │ │ ├── FloodWait
1310
+ │ │ ├── Unauthorized
1311
+ │ │ ├── BadRequest
1312
+ │ │ │ ├── ChatNotFound
1313
+ │ │ │ ├── UserNotFound
1314
+ │ │ │ └── MessageNotFound
1315
+ │ │ └── ...
1316
+ │ ├── SessionExpiredError
1317
+ │ └── SessionError
1318
+ ├── AuthError
1319
+ ├── ValidationError
1320
+ ├── JoinChatError
1321
+ │ ├── InvalidInviteLinkError
1322
+ │ ├── InviteLinkExpiredError
1323
+ │ ├── ChatFullError
1324
+ │ ├── ChatDeactivatedError
1325
+ │ └── MembershipRequiredError
1326
+ └── FloodWaitError (محدودیت نرخ)
1036
1327
  ```
1037
1328
 
1038
1329
  ---
@@ -1043,17 +1334,47 @@ spluspy/
1043
1334
 
1044
1335
  1. Fork the repository
1045
1336
  2. Create a feature branch (`git checkout -b feature/your-feature`)
1046
- 3. Make your changes
1047
- 4. Run tests: `pytest`
1048
- 5. Submit a pull request
1337
+ 3. Set up the development environment:
1338
+ ```bash
1339
+ python -m venv venv
1340
+ source venv/bin/activate
1341
+ pip install -e ".[dev]"
1342
+ ```
1343
+ 4. Make your changes
1344
+ 5. Run linting and formatting:
1345
+ ```bash
1346
+ ruff check spluspy/
1347
+ black spluspy/
1348
+ ```
1349
+ 6. Run type checking:
1350
+ ```bash
1351
+ mypy spluspy/
1352
+ ```
1353
+ 7. Run tests: `pytest`
1354
+ 8. Submit a pull request
1049
1355
 
1050
1356
  ### فارسی
1051
1357
 
1052
1358
  1. مخزن را Fork کنید
1053
1359
  2. شاخه ویژگی بسازید (`git checkout -b feature/your-feature`)
1054
- 3. تغییرات خود را اعمال کنید
1055
- 4. تست‌ها را اجرا کنید: `pytest`
1056
- 5. درخواست Pull ارسال کنید
1360
+ 3. محیط توسعه را راه‌اندازی کنید:
1361
+ ```bash
1362
+ python -m venv venv
1363
+ source venv/bin/activate
1364
+ pip install -e ".[dev]"
1365
+ ```
1366
+ 4. تغییرات خود را اعمال کنید
1367
+ 5. لینتر و فرمت‌کننده را اجرا کنید:
1368
+ ```bash
1369
+ ruff check spluspy/
1370
+ black spluspy/
1371
+ ```
1372
+ 6. بررسی نوع را اجرا کنید:
1373
+ ```bash
1374
+ mypy spluspy/
1375
+ ```
1376
+ 7. تست‌ها را اجرا کنید: `pytest`
1377
+ 8. درخواست Pull ارسال کنید
1057
1378
 
1058
1379
  ---
1059
1380
 
@@ -1081,4 +1402,4 @@ SPlusPy یک کتابخانه غیررسمی و شخص ثالث است. مسئو
1081
1402
 
1082
1403
  **ساخته شده با ❤️ برای جامعه سروش پلاس**
1083
1404
 
1084
- </div>
1405
+ </div>