python.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. # █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
  2. # █▀█ █ █ █ █▀█ █▀▄ █
  3. # © Copyright 2022
  4. # https://t.me/hikariatama
  5. #
  6. # 🔒 Licensed under the GNU AGPLv3
  7. # 🌐 https://www.gnu.org/licenses/agpl-3.0.html
  8. import contextlib
  9. import itertools
  10. import sys
  11. from types import ModuleType
  12. import os
  13. import typing
  14. import telethon
  15. from meval import meval
  16. from telethon.errors.rpcerrorlist import MessageIdInvalidError
  17. from telethon.tl.types import Message
  18. from .. import loader, main, utils
  19. from ..log import HikkaException
  20. @loader.tds
  21. class PythonMod(loader.Module):
  22. """Evaluates python code"""
  23. strings = {
  24. "name": "Python",
  25. "eval": (
  26. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  27. " Code:</b>\n<code>{}</code>\n<emoji"
  28. " document_id=5472164874886846699>✨</emoji><b>"
  29. " Result:</b>\n<code>{}</code>"
  30. ),
  31. "err": (
  32. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  33. " Code:</b>\n<code>{}</code>\n\n<emoji"
  34. " document_id=6323575131239089635>🚫</emoji><b> Error:</b>\n{}"
  35. ),
  36. }
  37. strings_ru = {
  38. "eval": (
  39. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  40. " Код:</b>\n<code>{}</code>\n<emoji"
  41. " document_id=5472164874886846699>✨</emoji><b>"
  42. " Результат:</b>\n<code>{}</code>"
  43. ),
  44. "err": (
  45. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  46. " Код:</b>\n<code>{}</code>\n\n<emoji"
  47. " document_id=6323575131239089635>🚫</emoji><b> Ошибка:</b>\n{}"
  48. ),
  49. "_cls_doc": "Выполняет Python код",
  50. }
  51. strings_de = {
  52. "eval": (
  53. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  54. " Code:</b>\n<code>{}</code>\n<emoji"
  55. " document_id=5472164874886846699>✨</emoji><b>"
  56. " Resultat:</b>\n<code>{}</code>"
  57. ),
  58. "err": (
  59. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  60. " Code:</b>\n<code>{}</code>\n\n<emoji"
  61. " document_id=6323575131239089635>🚫</emoji><b> Fehler:</b>\n{}"
  62. ),
  63. "_cls_doc": "Führt Python Code aus",
  64. }
  65. strings_tr = {
  66. "eval": (
  67. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  68. " Kod:</b>\n<code>{}</code>\n<emoji"
  69. " document_id=5472164874886846699>✨</emoji><b>"
  70. " Sonuç:</b>\n<code>{}</code>"
  71. ),
  72. "err": (
  73. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  74. " Kod:</b>\n<code>{}</code>\n\n<emoji"
  75. " document_id=6323575131239089635>🚫</emoji><b> Hata:</b>\n{}"
  76. ),
  77. "_cls_doc": "Python kodunu çalıştırır",
  78. }
  79. strings_hi = {
  80. "eval": (
  81. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  82. " कोड:</b>\n<code>{}</code>\n<emoji"
  83. " document_id=5472164874886846699>✨</emoji><b>"
  84. " परिणाम:</b>\n<code>{}</code>"
  85. ),
  86. "err": (
  87. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  88. " कोड:</b>\n<code>{}</code>\n\n<emoji"
  89. " document_id=6323575131239089635>🚫</emoji><b> त्रुटि:</b>\n{}"
  90. ),
  91. "_cls_doc": "Python कोड चलाता है",
  92. }
  93. strings_uz = {
  94. "eval": (
  95. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  96. " Kod:</b>\n<code>{}</code>\n<emoji"
  97. " document_id=5472164874886846699>✨</emoji><b>"
  98. " Natija:</b>\n<code>{}</code>"
  99. ),
  100. "err": (
  101. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  102. " Kod:</b>\n<code>{}</code>\n\n<emoji"
  103. " document_id=6323575131239089635>🚫</emoji><b> Xato:</b>\n{}"
  104. ),
  105. "_cls_doc": "Python kodini ishga tushiradi",
  106. }
  107. strings_ja = {
  108. "eval": (
  109. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  110. " コード:</b>\n<code>{}</code>\n<emoji"
  111. " document_id=5472164874886846699>✨</emoji><b>"
  112. " 結果:</b>\n<code>{}</code>"
  113. ),
  114. "err": (
  115. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  116. " コード:</b>\n<code>{}</code>\n\n<emoji"
  117. " document_id=6323575131239089635>🚫</emoji><b> エラー:</b>\n{}"
  118. ),
  119. "_cls_doc": "Pythonコードを実行します",
  120. }
  121. strings_kr = {
  122. "eval": (
  123. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  124. " 코드:</b>\n<code>{}</code>\n<emoji"
  125. " document_id=5472164874886846699>✨</emoji><b>"
  126. " 결과:</b>\n<code>{}</code>"
  127. ),
  128. "err": (
  129. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  130. " 코드:</b>\n<code>{}</code>\n\n<emoji"
  131. " document_id=6323575131239089635>🚫</emoji><b> 오류:</b>\n{}"
  132. ),
  133. "_cls_doc": "Python 코드를 실행합니다",
  134. }
  135. strings_ar = {
  136. "eval": (
  137. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  138. " الكود:</b>\n<code>{}</code>\n<emoji"
  139. " document_id=5472164874886846699>✨</emoji><b>"
  140. " النتيجة:</b>\n<code>{}</code>"
  141. ),
  142. "err": (
  143. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  144. " الكود:</b>\n<code>{}</code>\n\n<emoji"
  145. " document_id=6323575131239089635>🚫</emoji><b> خطأ:</b>\n{}"
  146. ),
  147. "_cls_doc": "ينفذ الكود بيثون",
  148. }
  149. strings_es = {
  150. "eval": (
  151. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  152. " Código:</b>\n<code>{}</code>\n<emoji"
  153. " document_id=5472164874886846699>✨</emoji><b>"
  154. " Resultado:</b>\n<code>{}</code>"
  155. ),
  156. "err": (
  157. "<emoji document_id=5431376038628171216>🎬</emoji><b>"
  158. " Código:</b>\n<code>{}</code>\n\n<emoji"
  159. " document_id=6323575131239089635>🚫</emoji><b> Error:</b>\n{}"
  160. ),
  161. "_cls_doc": "Ejecuta código Python",
  162. }
  163. @loader.owner
  164. @loader.command(
  165. ru_doc="Алиас для команды .e",
  166. de_doc="Alias für den Befehl .e",
  167. tr_doc="Komut .e için takma ad",
  168. hi_doc="कमांड .e के लिए उपनाम",
  169. uz_doc="Buyruq .e uchun alohida nom",
  170. ja_doc="コマンド.eのエイリアス",
  171. kr_doc="명령 .e의 별칭",
  172. ar_doc="الأمر .e للأمر",
  173. es_doc="Alias para el comando .e",
  174. )
  175. async def eval(self, message: Message):
  176. """Alias for .e command"""
  177. await self.e(message)
  178. @loader.owner
  179. @loader.command(
  180. ru_doc="Выполняет Python код",
  181. de_doc="Führt Python Code aus",
  182. tr_doc="Python kodu çalıştırır",
  183. hi_doc="Python कोड चलाता है",
  184. uz_doc="Python kodini ishga tushiradi",
  185. ja_doc="Pythonコードを実行します",
  186. kr_doc="Python 코드를 실행합니다",
  187. ar_doc="ينفذ الكود بيثون",
  188. es_doc="Ejecuta código Python",
  189. )
  190. async def e(self, message: Message):
  191. """Evaluates python code"""
  192. ret = self.strings("eval")
  193. try:
  194. result = await meval(
  195. utils.get_args_raw(message),
  196. globals(),
  197. **await self.getattrs(message),
  198. )
  199. except Exception:
  200. item = HikkaException.from_exc_info(*sys.exc_info())
  201. exc = (
  202. "\n<b>🪐 Full stack:</b>\n\n"
  203. + "\n".join(item.full_stack.splitlines()[:-1])
  204. + "\n\n"
  205. + "🚫 "
  206. + item.full_stack.splitlines()[-1]
  207. )
  208. exc = exc.replace(str(self._client.hikka_me.phone), "📵")
  209. if os.environ.get("hikka_session"):
  210. exc = exc.replace(
  211. os.environ.get("hikka_session"),
  212. "StringSession(**************************)",
  213. )
  214. await utils.answer(
  215. message,
  216. self.strings("err").format(
  217. utils.escape_html(utils.get_args_raw(message)),
  218. exc,
  219. ),
  220. )
  221. return
  222. if callable(getattr(result, "stringify", None)):
  223. with contextlib.suppress(Exception):
  224. result = str(result.stringify())
  225. result = str(result)
  226. ret = ret.format(
  227. utils.escape_html(utils.get_args_raw(message)),
  228. utils.escape_html(result),
  229. )
  230. ret = ret.replace(str(self._client.hikka_me.phone), "📵")
  231. if redis := os.environ.get("REDIS_URL") or main.get_config_key("redis_uri"):
  232. ret = ret.replace(redis, "redis://**************************")
  233. if os.environ.get("hikka_session"):
  234. ret = ret.replace(
  235. os.environ.get("hikka_session"),
  236. "StringSession(**************************)",
  237. )
  238. with contextlib.suppress(MessageIdInvalidError):
  239. await utils.answer(message, ret)
  240. async def getattrs(self, message: Message) -> dict:
  241. reply = await message.get_reply_message()
  242. return {
  243. **{
  244. "message": message,
  245. "client": self._client,
  246. "reply": reply,
  247. "r": reply,
  248. **self.get_sub(telethon.tl.types),
  249. **self.get_sub(telethon.tl.functions),
  250. "event": message,
  251. "chat": message.to_id,
  252. "telethon": telethon,
  253. "utils": utils,
  254. "main": main,
  255. "loader": loader,
  256. "f": telethon.tl.functions,
  257. "c": self._client,
  258. "m": message,
  259. "lookup": self.lookup,
  260. "self": self,
  261. "db": self.db,
  262. },
  263. }
  264. def get_sub(self, obj: typing.Any, _depth: int = 1) -> dict:
  265. """Get all callable capitalised objects in an object recursively, ignoring _*"""
  266. return {
  267. **dict(
  268. filter(
  269. lambda x: x[0][0] != "_"
  270. and x[0][0].upper() == x[0][0]
  271. and callable(x[1]),
  272. obj.__dict__.items(),
  273. )
  274. ),
  275. **dict(
  276. itertools.chain.from_iterable(
  277. [
  278. self.get_sub(y[1], _depth + 1).items()
  279. for y in filter(
  280. lambda x: x[0][0] != "_"
  281. and isinstance(x[1], ModuleType)
  282. and x[1] != obj
  283. and x[1].__package__.rsplit(".", _depth)[0]
  284. == "telethon.tl",
  285. obj.__dict__.items(),
  286. )
  287. ]
  288. )
  289. ),
  290. }