spluspy 1.0.0__tar.gz → 1.0.2__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 (169) hide show
  1. spluspy-1.0.2/PKG-INFO +173 -0
  2. spluspy-1.0.2/README.rst +133 -0
  3. {spluspy-1.0.0 → spluspy-1.0.2}/setup.py +2 -8
  4. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/__init__.py +3 -1
  5. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/chats.py +246 -0
  6. spluspy-1.0.2/spluspy/client/ratelimiter.py +188 -0
  7. spluspy-1.0.2/spluspy/client/soroushclient.py +645 -0
  8. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/telegrambaseclient.py +59 -0
  9. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/updates.py +2 -4
  10. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/users.py +9 -0
  11. spluspy-1.0.2/spluspy/crypto/aes.py +225 -0
  12. spluspy-1.0.2/spluspy/crypto/aesctr.py +130 -0
  13. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/__init__.py +10 -0
  14. spluspy-1.0.2/spluspy/events/decorators.py +362 -0
  15. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/extensions/messagepacker.py +28 -28
  16. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/helpers.py +81 -0
  17. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/connection.py +9 -6
  18. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/websocket.py +1 -1
  19. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/mtprotosender.py +16 -59
  20. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/mtprotostate.py +4 -0
  21. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/version.py +1 -1
  22. spluspy-1.0.2/spluspy.egg-info/PKG-INFO +173 -0
  23. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy.egg-info/SOURCES.txt +2 -0
  24. spluspy-1.0.0/PKG-INFO +0 -86
  25. spluspy-1.0.0/README.rst +0 -48
  26. spluspy-1.0.0/spluspy/client/soroushclient.py +0 -19
  27. spluspy-1.0.0/spluspy/crypto/aes.py +0 -111
  28. spluspy-1.0.0/spluspy/crypto/aesctr.py +0 -42
  29. spluspy-1.0.0/spluspy.egg-info/PKG-INFO +0 -86
  30. {spluspy-1.0.0 → spluspy-1.0.2}/setup.cfg +0 -0
  31. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/_updates/__init__.py +0 -0
  32. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/_updates/entitycache.py +0 -0
  33. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/_updates/messagebox.py +0 -0
  34. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/_updates/session.py +0 -0
  35. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/__init__.py +0 -0
  36. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/account.py +0 -0
  37. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/auth.py +0 -0
  38. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/bots.py +0 -0
  39. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/buttons.py +0 -0
  40. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/dialogs.py +0 -0
  41. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/downloads.py +0 -0
  42. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/messageparse.py +0 -0
  43. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/messages.py +0 -0
  44. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/client/uploads.py +0 -0
  45. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/crypto/__init__.py +0 -0
  46. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/crypto/authkey.py +0 -0
  47. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/crypto/cdndecrypter.py +0 -0
  48. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/crypto/factorization.py +0 -0
  49. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/crypto/libssl.py +0 -0
  50. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/crypto/rsa.py +0 -0
  51. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/custom.py +0 -0
  52. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/errors/__init__.py +0 -0
  53. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/errors/common.py +0 -0
  54. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/errors/rpcbaseerrors.py +0 -0
  55. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/errors/rpcerrorlist.py +0 -0
  56. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/album.py +0 -0
  57. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/callbackquery.py +0 -0
  58. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/chataction.py +0 -0
  59. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/common.py +0 -0
  60. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/inlinequery.py +0 -0
  61. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/messagedeleted.py +0 -0
  62. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/messageedited.py +0 -0
  63. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/messageread.py +0 -0
  64. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/newmessage.py +0 -0
  65. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/raw.py +0 -0
  66. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/events/userupdate.py +0 -0
  67. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/extensions/__init__.py +0 -0
  68. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/extensions/binaryreader.py +0 -0
  69. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/extensions/html.py +0 -0
  70. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/extensions/markdown.py +0 -0
  71. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/functions.py +0 -0
  72. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/hints.py +0 -0
  73. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/__init__.py +0 -0
  74. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/authenticator.py +0 -0
  75. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/__init__.py +0 -0
  76. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/http.py +0 -0
  77. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/tcpabridged.py +0 -0
  78. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/tcpfull.py +0 -0
  79. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/tcpintermediate.py +0 -0
  80. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/tcpmtproxy.py +0 -0
  81. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/connection/tcpobfuscated.py +0 -0
  82. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/mtprotoplainsender.py +0 -0
  83. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/network/requeststate.py +0 -0
  84. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/password.py +0 -0
  85. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/requestiter.py +0 -0
  86. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/sessions/__init__.py +0 -0
  87. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/sessions/abstract.py +0 -0
  88. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/sessions/memory.py +0 -0
  89. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/sessions/sqlite.py +0 -0
  90. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/sessions/string.py +0 -0
  91. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/sync.py +0 -0
  92. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/__init__.py +0 -0
  93. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/alltlobjects.py +0 -0
  94. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/core/__init__.py +0 -0
  95. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/core/gzippacked.py +0 -0
  96. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/core/messagecontainer.py +0 -0
  97. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/core/rpcresult.py +0 -0
  98. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/core/tlmessage.py +0 -0
  99. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/__init__.py +0 -0
  100. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/adminlogevent.py +0 -0
  101. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/button.py +0 -0
  102. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/chatgetter.py +0 -0
  103. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/conversation.py +0 -0
  104. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/dialog.py +0 -0
  105. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/draft.py +0 -0
  106. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/file.py +0 -0
  107. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/forward.py +0 -0
  108. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/inlinebuilder.py +0 -0
  109. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/inlineresult.py +0 -0
  110. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/inlineresults.py +0 -0
  111. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/inputsizedfile.py +0 -0
  112. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/message.py +0 -0
  113. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/messagebutton.py +0 -0
  114. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/participantpermissions.py +0 -0
  115. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/qrlogin.py +0 -0
  116. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/sendergetter.py +0 -0
  117. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/custom/types.py +0 -0
  118. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/__init__.py +0 -0
  119. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/account.py +0 -0
  120. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/auth.py +0 -0
  121. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/bots.py +0 -0
  122. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/channels.py +0 -0
  123. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/chatlists.py +0 -0
  124. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/conference.py +0 -0
  125. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/contacts.py +0 -0
  126. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/folders.py +0 -0
  127. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/help.py +0 -0
  128. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/langpack.py +0 -0
  129. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/messages.py +0 -0
  130. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/payments.py +0 -0
  131. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/phone.py +0 -0
  132. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/photos.py +0 -0
  133. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/premium.py +0 -0
  134. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/stats.py +0 -0
  135. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/stories.py +0 -0
  136. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/thirdParty.py +0 -0
  137. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/updates.py +0 -0
  138. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/upload.py +0 -0
  139. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/functions/users.py +0 -0
  140. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/patched/__init__.py +0 -0
  141. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/tlobject.py +0 -0
  142. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/__init__.py +0 -0
  143. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/account.py +0 -0
  144. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/auth.py +0 -0
  145. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/bots.py +0 -0
  146. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/channels.py +0 -0
  147. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/chatlists.py +0 -0
  148. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/conference.py +0 -0
  149. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/contacts.py +0 -0
  150. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/help.py +0 -0
  151. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/messages.py +0 -0
  152. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/payments.py +0 -0
  153. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/phone.py +0 -0
  154. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/photos.py +0 -0
  155. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/premium.py +0 -0
  156. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/stats.py +0 -0
  157. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/stickers.py +0 -0
  158. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/storage.py +0 -0
  159. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/stories.py +0 -0
  160. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/thirdParty.py +0 -0
  161. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/update.py +0 -0
  162. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/updates.py +0 -0
  163. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/upload.py +0 -0
  164. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/tl/types/users.py +0 -0
  165. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/types.py +0 -0
  166. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy/utils.py +0 -0
  167. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy.egg-info/dependency_links.txt +0 -0
  168. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy.egg-info/requires.txt +0 -0
  169. {spluspy-1.0.0 → spluspy-1.0.2}/spluspy.egg-info/top_level.txt +0 -0
spluspy-1.0.2/PKG-INFO ADDED
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 2.4
2
+ Name: spluspy
3
+ Version: 1.0.2
4
+ Summary: Soroush Plus library for Python
5
+ Home-page: https://github.com/Itskillmaster/spluspy
6
+ Download-URL: https://github.com/Itskillmaster/spluspy/releases
7
+ Author: AliMirshekari And Soroush Fathi
8
+ Author-email: dramff1@gmail.com
9
+ License: GPL-3.0
10
+ Keywords: soroush plus telegram api chat client library messaging mtproto
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Communications :: Chat
14
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.5
17
+ Classifier: Programming Language :: Python :: 3.6
18
+ Classifier: Programming Language :: Python :: 3.7
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Requires-Python: >=3.5
21
+ Description-Content-Type: text/x-rst
22
+ Requires-Dist: pyaes
23
+ Requires-Dist: rsa
24
+ Requires-Dist: websockets
25
+ Provides-Extra: cryptg
26
+ Requires-Dist: cryptg; extra == "cryptg"
27
+ Dynamic: author
28
+ Dynamic: author-email
29
+ Dynamic: classifier
30
+ Dynamic: description
31
+ Dynamic: description-content-type
32
+ Dynamic: download-url
33
+ Dynamic: home-page
34
+ Dynamic: keywords
35
+ Dynamic: license
36
+ Dynamic: provides-extra
37
+ Dynamic: requires-dist
38
+ Dynamic: requires-python
39
+ Dynamic: summary
40
+
41
+ SPlusPy
42
+ =======
43
+
44
+ **SPlusPy** is an asynchronous Python 3 MTProto library for interacting
45
+ with the `Soroush Plus <https://web.splus.ir>`_ platform as either a
46
+ user account or a bot account (an alternative to the official Bot API).
47
+
48
+ Built as a fork of Telethon, SPlusPy has been adapted specifically for
49
+ the Soroush Plus ecosystem. It supports the native Soroush Plus TL
50
+ schema (Layer 182), DC routing, RSA encryption, and WebSocket transport,
51
+ providing a modern and reliable developer experience.
52
+
53
+ .. note::
54
+
55
+ SPlusPy is an unofficial third-party library. Please use it
56
+ responsibly and ensure your applications comply with Soroush Plus's
57
+ Terms of Service. Improper use may result in account restrictions.
58
+
59
+ Features
60
+ --------
61
+
62
+ - Fully asynchronous (``asyncio``)
63
+ - User and bot account support
64
+ - Native MTProto implementation
65
+ - WebSocket transport
66
+ - RSA encryption
67
+ - Soroush Plus TL schema (Layer 182)
68
+ - Based on the Telethon architecture
69
+ - Modern Python 3 support
70
+ - Convenience methods for sending files, photos, audio, video
71
+ - Chat management: ban, unban, kick, pin/unpin messages
72
+ - Admin and permissions management
73
+ - High-performance encryption with optional ``cryptg`` support
74
+
75
+ What is SPlusPy?
76
+ ----------------
77
+
78
+ `Soroush Plus <https://web.splus.ir>`_ is a popular messaging platform.
79
+
80
+ SPlusPy provides a clean, Pythonic interface for communicating with the
81
+ Soroush Plus MTProto API. Instead of implementing the protocol yourself,
82
+ you can focus entirely on building your application while SPlusPy
83
+ handles authentication, networking, serialization, and protocol details.
84
+
85
+ Installing
86
+ ----------
87
+
88
+ Install the latest version from PyPI:
89
+
90
+ .. code-block:: sh
91
+
92
+ pip install -U splusthon
93
+
94
+ For faster encryption (recommended):
95
+
96
+ .. code-block:: sh
97
+
98
+ pip install cryptg
99
+
100
+ Creating a client
101
+ -----------------
102
+
103
+ SPlusPy includes the default Soroush Plus API credentials, so there is
104
+ no need to obtain your own ``api_id`` or ``api_hash``.
105
+
106
+ .. code-block:: python
107
+
108
+ import asyncio
109
+ from spluspy import SoroushClient
110
+
111
+ bot = SoroushClient('my_bot')
112
+
113
+ @bot.on_message(incoming=True)
114
+ async def handler(event):
115
+ if event.is_private and event.raw_text == 'Hello':
116
+ await event.reply('Hi!')
117
+
118
+ async def main():
119
+ await bot.start()
120
+ print('Bot is running!')
121
+ await bot.run_until_disconnected()
122
+
123
+ asyncio.run(main())
124
+
125
+ Quick Examples
126
+ --------------
127
+
128
+ Sending messages and files:
129
+
130
+ .. code-block:: python
131
+
132
+ # Send a text message
133
+ await client.send_message('username', 'Hello!')
134
+
135
+ # Send a photo
136
+ await client.send_photo(chat, 'photo.jpg', caption='Check this out!')
137
+
138
+ # Send audio/music
139
+ await client.send_audio(chat, 'song.mp3')
140
+
141
+ # Send a video
142
+ await client.send_video(chat, 'video.mp4')
143
+
144
+ # Send a document
145
+ await client.send_document(chat, 'file.pdf')
146
+
147
+ Chat management:
148
+
149
+ .. code-block:: python
150
+
151
+ # Ban a user
152
+ await client.ban_chat_member(chat, user)
153
+
154
+ # Unban a user
155
+ await client.unban_chat_member(chat, user)
156
+
157
+ # Pin a message
158
+ await client.pin_message(chat, message)
159
+
160
+ # Unpin all messages
161
+ await client.unpin_all_messages(chat)
162
+
163
+ Documentation
164
+ -------------
165
+
166
+ More examples and complete documentation will be available in future
167
+ releases.
168
+
169
+ License
170
+ -------
171
+
172
+ SPlusPy is open-source software distributed under its respective
173
+ license.
@@ -0,0 +1,133 @@
1
+ SPlusPy
2
+ =======
3
+
4
+ **SPlusPy** is an asynchronous Python 3 MTProto library for interacting
5
+ with the `Soroush Plus <https://web.splus.ir>`_ platform as either a
6
+ user account or a bot account (an alternative to the official Bot API).
7
+
8
+ Built as a fork of Telethon, SPlusPy has been adapted specifically for
9
+ the Soroush Plus ecosystem. It supports the native Soroush Plus TL
10
+ schema (Layer 182), DC routing, RSA encryption, and WebSocket transport,
11
+ providing a modern and reliable developer experience.
12
+
13
+ .. note::
14
+
15
+ SPlusPy is an unofficial third-party library. Please use it
16
+ responsibly and ensure your applications comply with Soroush Plus's
17
+ Terms of Service. Improper use may result in account restrictions.
18
+
19
+ Features
20
+ --------
21
+
22
+ - Fully asynchronous (``asyncio``)
23
+ - User and bot account support
24
+ - Native MTProto implementation
25
+ - WebSocket transport
26
+ - RSA encryption
27
+ - Soroush Plus TL schema (Layer 182)
28
+ - Based on the Telethon architecture
29
+ - Modern Python 3 support
30
+ - Convenience methods for sending files, photos, audio, video
31
+ - Chat management: ban, unban, kick, pin/unpin messages
32
+ - Admin and permissions management
33
+ - High-performance encryption with optional ``cryptg`` support
34
+
35
+ What is SPlusPy?
36
+ ----------------
37
+
38
+ `Soroush Plus <https://web.splus.ir>`_ is a popular messaging platform.
39
+
40
+ SPlusPy provides a clean, Pythonic interface for communicating with the
41
+ Soroush Plus MTProto API. Instead of implementing the protocol yourself,
42
+ you can focus entirely on building your application while SPlusPy
43
+ handles authentication, networking, serialization, and protocol details.
44
+
45
+ Installing
46
+ ----------
47
+
48
+ Install the latest version from PyPI:
49
+
50
+ .. code-block:: sh
51
+
52
+ pip install -U splusthon
53
+
54
+ For faster encryption (recommended):
55
+
56
+ .. code-block:: sh
57
+
58
+ pip install cryptg
59
+
60
+ Creating a client
61
+ -----------------
62
+
63
+ SPlusPy includes the default Soroush Plus API credentials, so there is
64
+ no need to obtain your own ``api_id`` or ``api_hash``.
65
+
66
+ .. code-block:: python
67
+
68
+ import asyncio
69
+ from spluspy import SoroushClient
70
+
71
+ bot = SoroushClient('my_bot')
72
+
73
+ @bot.on_message(incoming=True)
74
+ async def handler(event):
75
+ if event.is_private and event.raw_text == 'Hello':
76
+ await event.reply('Hi!')
77
+
78
+ async def main():
79
+ await bot.start()
80
+ print('Bot is running!')
81
+ await bot.run_until_disconnected()
82
+
83
+ asyncio.run(main())
84
+
85
+ Quick Examples
86
+ --------------
87
+
88
+ Sending messages and files:
89
+
90
+ .. code-block:: python
91
+
92
+ # Send a text message
93
+ await client.send_message('username', 'Hello!')
94
+
95
+ # Send a photo
96
+ await client.send_photo(chat, 'photo.jpg', caption='Check this out!')
97
+
98
+ # Send audio/music
99
+ await client.send_audio(chat, 'song.mp3')
100
+
101
+ # Send a video
102
+ await client.send_video(chat, 'video.mp4')
103
+
104
+ # Send a document
105
+ await client.send_document(chat, 'file.pdf')
106
+
107
+ Chat management:
108
+
109
+ .. code-block:: python
110
+
111
+ # Ban a user
112
+ await client.ban_chat_member(chat, user)
113
+
114
+ # Unban a user
115
+ await client.unban_chat_member(chat, user)
116
+
117
+ # Pin a message
118
+ await client.pin_message(chat, message)
119
+
120
+ # Unpin all messages
121
+ await client.unpin_all_messages(chat)
122
+
123
+ Documentation
124
+ -------------
125
+
126
+ More examples and complete documentation will be available in future
127
+ releases.
128
+
129
+ License
130
+ -------
131
+
132
+ SPlusPy is open-source software distributed under its respective
133
+ license.
@@ -216,6 +216,7 @@ def main(argv):
216
216
  version=version,
217
217
  description="Soroush Plus library for Python",
218
218
  long_description=long_description,
219
+ long_description_content_type='text/x-rst',
219
220
 
220
221
  url='https://github.com/Itskillmaster/spluspy',
221
222
  download_url='https://github.com/Itskillmaster/spluspy/releases',
@@ -225,16 +226,9 @@ def main(argv):
225
226
 
226
227
  license='GPL-3.0',
227
228
 
228
- # See https://stackoverflow.com/a/40300957/4759433
229
- # -> https://www.python.org/dev/peps/pep-0345/#requires-python
230
- # -> http://setuptools.readthedocs.io/en/latest/setuptools.html
231
229
  python_requires='>=3.5',
232
230
 
233
- # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
234
231
  classifiers=[
235
- # 3 - Alpha
236
- # 4 - Beta
237
- # 5 - Production/Stable
238
232
  'Development Status :: 5 - Production/Stable',
239
233
 
240
234
  'Intended Audience :: Developers',
@@ -248,7 +242,7 @@ def main(argv):
248
242
  'Programming Language :: Python :: 3.7',
249
243
  'Programming Language :: Python :: 3.8',
250
244
  ],
251
- keywords='telegram api chat client library messaging mtproto',
245
+ keywords='soroush plus telegram api chat client library messaging mtproto',
252
246
  packages=find_packages(exclude=[
253
247
  'spluspy_*', 'tests*'
254
248
  ]),
@@ -5,6 +5,7 @@ from .tl import patched as _ # import for its side-effects
5
5
  from . import version, events, utils, errors, types, functions, custom
6
6
  from .sessions import Session, MemorySession, SQLiteSession, StringSession
7
7
  from .tl.custom import Conversation, Message, Dialog, Forward, Draft
8
+ from .client.ratelimiter import RateLimiter, RetryConfig
8
9
 
9
10
  __version__ = version.__version__
10
11
 
@@ -16,5 +17,6 @@ __all__ = [
16
17
  'Session', 'MemorySession', 'SQLiteSession', 'StringSession',
17
18
  'Conversation', 'Message', 'Dialog', 'Forward', 'Draft',
18
19
  'types', 'functions', 'custom', 'errors',
19
- 'events', 'utils', 'connection'
20
+ 'events', 'utils', 'connection',
21
+ 'RateLimiter', 'RetryConfig'
20
22
  ]
@@ -1334,3 +1334,249 @@ class ChatMethods:
1334
1334
  await self._return_exported_sender(sender)
1335
1335
 
1336
1336
  # endregion
1337
+
1338
+ # region Convenience methods
1339
+
1340
+ async def ban_chat_member(
1341
+ self: 'SoroushClient',
1342
+ chat: 'hints.EntityLike',
1343
+ user: 'hints.EntityLike',
1344
+ *,
1345
+ until_date: 'hints.DateLike' = None,
1346
+ view_messages: bool = True,
1347
+ send_messages: bool = True,
1348
+ send_media: bool = True,
1349
+ send_stickers: bool = True,
1350
+ send_gifs: bool = True,
1351
+ send_inline: bool = True,
1352
+ send_polls: bool = True,
1353
+ embed_links: bool = True
1354
+ ):
1355
+ """
1356
+ Bans a user from a chat (group, supergroup or channel).
1357
+
1358
+ This is a convenience wrapper around `edit_permissions`.
1359
+
1360
+ Arguments
1361
+ chat (`entity`):
1362
+ The chat where the user should be banned.
1363
+
1364
+ user (`entity`):
1365
+ The user to ban.
1366
+
1367
+ until_date (`DateLike`, optional):
1368
+ When the ban will be lifted. If not specified, the ban is permanent.
1369
+
1370
+ view_messages (`bool`, optional):
1371
+ Whether to also prevent the user from viewing messages. Defaults to True.
1372
+
1373
+ send_messages (`bool`, optional):
1374
+ Whether to prevent the user from sending messages. Defaults to True.
1375
+
1376
+ send_media (`bool`, optional):
1377
+ Whether to prevent the user from sending media. Defaults to True.
1378
+
1379
+ send_stickers (`bool`, optional):
1380
+ Whether to prevent the user from sending stickers. Defaults to True.
1381
+
1382
+ send_gifs (`bool`, optional):
1383
+ Whether to prevent the user from sending GIFs. Defaults to True.
1384
+
1385
+ send_inline (`bool`, optional):
1386
+ Whether to prevent the user from using inline bots. Defaults to True.
1387
+
1388
+ send_polls (`bool`, optional):
1389
+ Whether to prevent the user from sending polls. Defaults to True.
1390
+
1391
+ embed_links (`bool`, optional):
1392
+ Whether to prevent the user from embedding links. Defaults to True.
1393
+
1394
+ Example
1395
+ .. code-block:: python
1396
+
1397
+ # Ban a user permanently
1398
+ await client.ban_chat_member(chat, user)
1399
+
1400
+ # Ban for 1 hour
1401
+ from datetime import timedelta
1402
+ await client.ban_chat_member(chat, user, until_date=timedelta(hours=1))
1403
+
1404
+ # Ban but allow viewing messages
1405
+ await client.ban_chat_member(chat, user, view_messages=False)
1406
+ """
1407
+ return await self.edit_permissions(
1408
+ chat, user, until_date=until_date,
1409
+ view_messages=view_messages,
1410
+ send_messages=send_messages,
1411
+ send_media=send_media,
1412
+ send_stickers=send_stickers,
1413
+ send_gifs=send_gifs,
1414
+ send_inline=send_inline,
1415
+ send_polls=send_polls,
1416
+ embed_link_previews=embed_links
1417
+ )
1418
+
1419
+ async def unban_chat_member(
1420
+ self: 'SoroushClient',
1421
+ chat: 'hints.EntityLike',
1422
+ user: 'hints.EntityLike',
1423
+ *,
1424
+ view_messages: bool = True
1425
+ ):
1426
+ """
1427
+ Unbans a previously banned user from a chat.
1428
+
1429
+ Arguments
1430
+ chat (`entity`):
1431
+ The chat where the user should be unbanned.
1432
+
1433
+ user (`entity`):
1434
+ The user to unban.
1435
+
1436
+ view_messages (`bool`, optional):
1437
+ Whether the user can view messages after unbanning. Defaults to True.
1438
+
1439
+ Example
1440
+ .. code-block:: python
1441
+
1442
+ await client.unban_chat_member(chat, user)
1443
+ """
1444
+ return await self.edit_permissions(
1445
+ chat, user,
1446
+ view_messages=view_messages,
1447
+ send_messages=True,
1448
+ send_media=True,
1449
+ send_stickers=True,
1450
+ send_gifs=True,
1451
+ send_inline=True,
1452
+ send_polls=True,
1453
+ embed_link_previews=True
1454
+ )
1455
+
1456
+ async def kick_chat_member(
1457
+ self: 'SoroushClient',
1458
+ chat: 'hints.EntityLike',
1459
+ user: 'hints.EntityLike'
1460
+ ):
1461
+ """
1462
+ Kicks a user from a chat (ban + unban).
1463
+
1464
+ This is a convenience wrapper around `kick_participant`.
1465
+
1466
+ Arguments
1467
+ chat (`entity`):
1468
+ The chat where the user should be kicked from.
1469
+
1470
+ user (`entity`):
1471
+ The user to kick.
1472
+
1473
+ Example
1474
+ .. code-block:: python
1475
+
1476
+ await client.kick_chat_member(chat, user)
1477
+ """
1478
+ return await self.kick_participant(chat, user)
1479
+
1480
+ async def pin_message(
1481
+ self: 'SoroushClient',
1482
+ chat: 'hints.EntityLike',
1483
+ message: 'typing.Union[int, types.Message]',
1484
+ *,
1485
+ notify: bool = False
1486
+ ):
1487
+ """
1488
+ Pins a message in a chat.
1489
+
1490
+ Arguments
1491
+ chat (`entity`):
1492
+ The chat where the message should be pinned.
1493
+
1494
+ message (`int` | `Message`):
1495
+ The message to pin (either the message ID or the message object).
1496
+
1497
+ notify (`bool`, optional):
1498
+ Whether to notify all members about the pinned message. Defaults to False.
1499
+
1500
+ Example
1501
+ .. code-block:: python
1502
+
1503
+ # Pin a message
1504
+ await client.pin_message(chat, message)
1505
+
1506
+ # Pin and notify everyone
1507
+ await client.pin_message(chat, message, notify=True)
1508
+ """
1509
+ entity = await self.get_input_entity(chat)
1510
+ msg_id = utils.get_message_id(message)
1511
+ return await self(functions.messages.UpdatePinnedMessageRequest(
1512
+ peer=entity,
1513
+ id=msg_id,
1514
+ silent=not notify
1515
+ ))
1516
+
1517
+ async def unpin_message(
1518
+ self: 'SoroushClient',
1519
+ chat: 'hints.EntityLike',
1520
+ message: 'typing.Union[int, types.Message]'
1521
+ ):
1522
+ """
1523
+ Unpins a specific message from a chat.
1524
+
1525
+ Arguments
1526
+ chat (`entity`):
1527
+ The chat from which to unpin the message.
1528
+
1529
+ message (`int` | `Message`):
1530
+ The message to unpin.
1531
+
1532
+ Example
1533
+ .. code-block:: python
1534
+
1535
+ await client.unpin_message(chat, message)
1536
+ """
1537
+ entity = await self.get_input_entity(chat)
1538
+ msg_id = utils.get_message_id(message)
1539
+ return await self(functions.messages.UpdatePinnedMessageRequest(
1540
+ peer=entity,
1541
+ id=msg_id,
1542
+ unpin=True
1543
+ ))
1544
+
1545
+ async def unpin_all_messages(
1546
+ self: 'SoroushClient',
1547
+ chat: 'hints.EntityLike'
1548
+ ):
1549
+ """
1550
+ Unpins all pinned messages in a chat.
1551
+
1552
+ Arguments
1553
+ chat (`entity`):
1554
+ The chat from which to unpin all messages.
1555
+
1556
+ Example
1557
+ .. code-block:: python
1558
+
1559
+ await client.unpin_all_messages(chat)
1560
+ """
1561
+ entity = await self.get_input_entity(chat)
1562
+ ty = helpers._entity_type(entity)
1563
+ if ty == helpers._EntityType.CHANNEL:
1564
+ return await self(functions.channels.UpdatePinnedRequest(
1565
+ channel=entity,
1566
+ id=0 # 0 means unpin all
1567
+ ))
1568
+ else:
1569
+ # For basic groups, unpin all by getting pinned messages and unpinning each
1570
+ pinned = await self(functions.messages.GetPinnedMessagesRequest(
1571
+ peer=entity
1572
+ ))
1573
+ if pinned.messages:
1574
+ for msg in pinned.messages:
1575
+ await self(functions.messages.UpdatePinnedMessageRequest(
1576
+ peer=entity,
1577
+ id=msg.id,
1578
+ unpin=True
1579
+ ))
1580
+ return None
1581
+
1582
+ # endregion