help.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. # ©️ Dan Gazizullin, 2021-2023
  2. # This file is a part of Hikka Userbot
  3. # 🌐 https://github.com/hikariatama/Hikka
  4. # You can redistribute it and/or modify it under the terms of the GNU AGPLv3
  5. # 🔑 https://www.gnu.org/licenses/agpl-3.0.html
  6. import difflib
  7. import inspect
  8. import logging
  9. from telethon.extensions.html import CUSTOM_EMOJIS
  10. from telethon.tl.types import Message
  11. from .. import loader, utils
  12. from ..compat.dragon import DRAGON_EMOJI
  13. from ..types import DragonModule
  14. logger = logging.getLogger(__name__)
  15. @loader.tds
  16. class HelpMod(loader.Module):
  17. """Shows help for modules and commands"""
  18. strings = {
  19. "name": "Help",
  20. "undoc": "🦥 No docs",
  21. "all_header": (
  22. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} mods available,"
  23. " {} hidden:</b>"
  24. ),
  25. "no_mod": "🚫 <b>Specify module to hide</b>",
  26. "hidden_shown": (
  27. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} modules hidden,"
  28. " {} modules shown:</b>\n{}\n{}"
  29. ),
  30. "support": (
  31. "{} <b>Link to</b> <a href='https://t.me/hikka_talks'>support chat</a></b>"
  32. ),
  33. "partial_load": (
  34. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Userbot is not"
  35. " fully loaded, so not all modules are shown</b>"
  36. ),
  37. "not_exact": (
  38. "<emoji document_id=5312383351217201533>☝️</emoji> <b>No exact match"
  39. " occured, so the closest result is shown instead</b>"
  40. ),
  41. "request_join": "You requested link for Hikka support chat",
  42. "core_notice": (
  43. "<emoji document_id=5312383351217201533>☝️</emoji> <b>This is a core"
  44. " module. You can't unload it nor replace</b>"
  45. ),
  46. }
  47. strings_ru = {
  48. "undoc": "🦥 Нет описания",
  49. "all_header": (
  50. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} модулей доступно,"
  51. " {} скрыто:</b>"
  52. ),
  53. "no_mod": "🚫 <b>Укажи модуль(-и), которые нужно скрыть</b>",
  54. "hidden_shown": (
  55. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} модулей скрыто,"
  56. " {} модулей показано:</b>\n{}\n{}"
  57. ),
  58. "support": (
  59. "{} <b>Ссылка на</b> <a href='https://t.me/hikka_talks'>чат помощи</a></b>"
  60. ),
  61. "_cls_doc": "Показывает помощь по модулям",
  62. "partial_load": (
  63. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Юзербот еще не"
  64. " загрузился полностью, поэтому показаны не все модули</b>"
  65. ),
  66. "not_exact": (
  67. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Точного совпадения"
  68. " не нашлось, поэтому было выбрано наиболее подходящее</b>"
  69. ),
  70. "request_join": "Вы запросили ссылку на чат помощи Hikka",
  71. "core_notice": (
  72. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Это встроенный"
  73. " модуль. Вы не можете его выгрузить или заменить</b>"
  74. ),
  75. }
  76. strings_fr = {
  77. "undoc": "🦥 Pas de description",
  78. "all_header": (
  79. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} module disponible,"
  80. " {} caché:</b>"
  81. ),
  82. "no_mod": "🚫 <b>Indiquer le module(-s) à cacher</b>",
  83. "hidden_shown": (
  84. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} module caché,"
  85. " {} module montré:</b>\n{}\n{}"
  86. ),
  87. "support": (
  88. "{} <b>Liens</b> <a href='https://t.me/hikka_talks'>chat d'aide</a></b>"
  89. ),
  90. "_cls_doc": "Affiche l'aide par module",
  91. "partial_load": (
  92. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Le robot utilisateur"
  93. " n'a pas encore complètement chargé, donc pas tous les modules ont été"
  94. " montrés</b>"
  95. ),
  96. "not_exact": (
  97. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Pas de correspondance"
  98. " exacte trouvé, donc le plus approprié a été choisi</b>"
  99. ),
  100. "request_join": "Vous avez demandé un lien vers le chat d'aide Hikka",
  101. "core_notice": (
  102. "<emoji document_id=5312383351217201533>☝️</emoji> <b>C'est un module"
  103. " intégré. Vous ne pouvez pas le décharger ou le remplacer</b>"
  104. ),
  105. }
  106. strings_it = {
  107. "undoc": "🦥 Nessuna documentazione",
  108. "all_header": (
  109. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} moduli disponibili,"
  110. " {} nascosti:</b>"
  111. ),
  112. "no_mod": "🚫 <b>Specifica il modulo da nascondere</b>",
  113. "hidden_shown": (
  114. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} moduli nascosti,"
  115. " {} moduli mostrati:</b>\n{}\n{}"
  116. ),
  117. "support": (
  118. "{} <b>Link al</b> <a href='https://t.me/hikka_talks'>chat di"
  119. " supporto</a></b>"
  120. ),
  121. "_cls_doc": "Mostra l'aiuto per i moduli",
  122. "partial_load": (
  123. "<emoji document_id=5312383351217201533>☝️</emoji> <b>L'userbot non è"
  124. " stato completamente caricato, quindi non tutti i moduli sono mostrati</b>"
  125. ),
  126. "not_exact": (
  127. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Nessuna"
  128. " corrispondenza esatta è stata trovata, quindi è stato mostrato il"
  129. " risultato più simile</b>"
  130. ),
  131. "request_join": "Hai richiesto il link per il gruppo di supporto Hikka",
  132. "core_notice": (
  133. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Questo è un modulo"
  134. " principale. Non puoi scaricarlo né sostituirlo</b>"
  135. ),
  136. }
  137. strings_de = {
  138. "undoc": "🦥 Keine Dokumentation",
  139. "all_header": (
  140. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} Module verfügbar,"
  141. " {} versteckt:</b>"
  142. ),
  143. "no_mod": "🚫 <b>Gib das Modul an, das du verstecken willst</b>",
  144. "hidden_shown": (
  145. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} Module versteckt,"
  146. " {} Module angezeigt:</b>\n{}\n{}"
  147. ),
  148. "support": (
  149. "{} <b>Link zum</b> <a href='https://t.me/hikka_talks'>Supportchat</a></b>"
  150. ),
  151. "_cls_doc": "Zeigt Hilfe zu Modulen an",
  152. "partial_load": (
  153. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Der Userbot ist noch"
  154. " nicht vollständig geladen, daher werden nicht alle Module angezeigt</b>"
  155. ),
  156. "not_exact": (
  157. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Es wurde kein exakter"
  158. " Treffer gefunden, daher wird das nächstbeste Ergebnis angezeigt</b>"
  159. ),
  160. "request_join": "Du hast den Link zum Supportchat angefordert",
  161. "core_notice": (
  162. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Dies ist ein"
  163. " eingebauter Modul. Du kannst ihn nicht entladen oder ersetzen</b>"
  164. ),
  165. }
  166. strings_tr = {
  167. "undoc": "🦥 Dokümantasyon yok",
  168. "all_header": (
  169. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} adet modül mevcut,"
  170. " {} gizli:</b>"
  171. ),
  172. "no_mod": "🚫 <b>Gizlemek istediğin modülü belirt</b>",
  173. "hidden_shown": (
  174. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} adet modül"
  175. " gizlendi, {} adet modül gösterildi:</b>\n{}\n{}"
  176. ),
  177. "support": "{} <b><a href='https://t.me/hikka_talks'>Destek sohbeti</a></b>",
  178. "_cls_doc": "Modül yardımını gösterir",
  179. "partial_load": (
  180. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Kullanıcı botu"
  181. " henüz tam olarak yüklenmediğinden, tüm modüller görüntülenmez</b>"
  182. ),
  183. "not_exact": (
  184. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Herhangi bir"
  185. " eşleşme bulunamadığından, en uygun sonuç gösterildi</b>"
  186. ),
  187. "request_join": "Hikka Destek sohbetinin davet bağlantısını istediniz",
  188. "core_notice": (
  189. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Bu dahili"
  190. " b,r modül. Bu modülü kaldıramaz veya değiştiremezsin</b>"
  191. ),
  192. }
  193. strings_uz = {
  194. "undoc": "🦥 Hujjatlanmagan",
  195. "all_header": (
  196. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} Umumiy modullar,"
  197. " yashirin {}:</b>"
  198. ),
  199. "no_mod": "🚫 <b>Yashirish uchun modul kiriting</b>",
  200. "hidden_shown": (
  201. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} yashirin,"
  202. " {} modullar ko'rsatilgan:</b>\n{}\n{}"
  203. ),
  204. "support": "{} <b><a href='https://t.me/hikka_talks'>Yordam chat</a></b>",
  205. "_cls_doc": "Modul yordamini ko'rsatadi",
  206. "partial_load": (
  207. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Foydalanuvchi boti"
  208. " hali to'liq yuklanmaganligi sababli, barcha modullar ko'rsatilmaydi</b>"
  209. ),
  210. "not_exact": (
  211. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Hech qanday moslik"
  212. " topilmadi, shuning uchun eng mos natija ko'rsatildi</b>"
  213. ),
  214. "request_join": "Siz yordam chat havolasini so'radingiz",
  215. "core_notice": (
  216. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Bu bir qo'shimcha"
  217. " modul, uni o'chirib yoki o'zgartirib bo'lmaysiz</b>"
  218. ),
  219. }
  220. strings_es = {
  221. "undoc": "🦥 Sin documentar",
  222. "all_header": (
  223. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} módulos,"
  224. " {} ocultos:</b>"
  225. ),
  226. "no_mod": "🚫 <b>Por favor, introduce el módulo que deseas ocultar</b>",
  227. "hidden_shown": (
  228. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} ocultos,"
  229. " {} módulos mostrados:</b>\n{}\n{}"
  230. ),
  231. "support": "{} <b><a href='https://t.me/hikka_talks'>Chat de soporte</a></b>",
  232. "_cls_doc": "Muestra la ayuda del módulo",
  233. "partial_load": (
  234. "<emoji document_id=5312383351217201533>☝️</emoji> <b>El bot no se ha"
  235. " cargado por completoaún, por lo que no se muestran todos los módulos</b>"
  236. ),
  237. "not_exact": (
  238. "<emoji document_id=5312383351217201533>☝️</emoji> <b>No se encontraron"
  239. " resultados exactos, por lo que se muestran los resultados más"
  240. " relevantes</b>"
  241. ),
  242. "request_join": "Se ha solicitado el enlace al chat de soporte",
  243. "core_notice": (
  244. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Este es un módulo"
  245. " corazón, por loque no se puede eliminar o modificar</b>"
  246. ),
  247. }
  248. strings_kk = {
  249. "undoc": "🦥 Құжатталмаған",
  250. "all_header": (
  251. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} қосымша модуль,"
  252. " {} жасырын:</b>"
  253. ),
  254. "no_mod": "🚫 <b>Жасыру үшін модуль енгізіңіз</b>",
  255. "hidden_shown": (
  256. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} жасырын,"
  257. " {} модуль көрсетілді:</b>\n{}\n{}"
  258. ),
  259. "support": "{} <b><a href='https://t.me/hikka_talks'>Көмек сөйлесу</a></b>",
  260. "_cls_doc": "Модуль көмектерін көрсетеді",
  261. "partial_load": (
  262. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Пайдаланушы боты"
  263. " әлде бірінші бетіне жүктелгеннен кейін, барлық модулдер көрсетілмейді</b>"
  264. ),
  265. "not_exact": (
  266. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Ешқандай"
  267. " таптырылмаған нәтиже жоқ, сондықтан ең қанағаттары көрсетілді</b>"
  268. ),
  269. "request_join": "Сіз көмек сөйлесудің сілтемесін сұрағансыз",
  270. "core_notice": (
  271. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Бұл қосымша модуль,"
  272. " оны жою немесе өзгерту мүмкін емес</b>"
  273. ),
  274. }
  275. strings_tt = {
  276. "undoc": "🦥 Тасвирлау юк",
  277. "all_header": (
  278. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} модульләр бар,"
  279. " {} яшерелгән:</b>"
  280. ),
  281. "no_mod": "🚫 <b>Яшерергә кирәк булган модульне күрсәтегез (- һәм)</b>",
  282. "hidden_shown": (
  283. "<emoji document_id=5188377234380954537>🌘</emoji> <b>{} модуль яшерелгән,"
  284. " {} модуль яшерелгән:</b>\n{}\n{}"
  285. ),
  286. "support": (
  287. "{} <b>Сылтама</b> <href='https://t.me/hikka_talks'>ярдәм чаты</a></b>"
  288. ),
  289. "_cls_doc": "Модульләр буенча ярдәм күрсәтә",
  290. "partial_load": (
  291. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Юзербот әле тулысынча"
  292. " йөкләнмәгән, шуңа күрә барлык модульләр дә күрсәтелмәгән</b>"
  293. ),
  294. "not_exact": (
  295. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Төгәл матч табылмады,"
  296. " шуңа күрә иң яхшысы сайланды</b>"
  297. ),
  298. "request_join": "Сез Hikka ярдәм чатына сылтама сорадыгыз",
  299. "core_notice": (
  300. "<emoji document_id=5312383351217201533>☝️</emoji> <b>Бу урнаштырылган"
  301. " модуль. Сез аны бушатырга яки алыштыра алмыйсыз</b>"
  302. ),
  303. }
  304. def __init__(self):
  305. self.config = loader.ModuleConfig(
  306. loader.ConfigValue(
  307. "core_emoji",
  308. "▪️",
  309. lambda: "Core module bullet",
  310. validator=loader.validators.Emoji(length=1),
  311. ),
  312. loader.ConfigValue(
  313. "hikka_emoji",
  314. "🌘",
  315. lambda: "Hikka-only module bullet",
  316. validator=loader.validators.Emoji(length=1),
  317. ),
  318. loader.ConfigValue(
  319. "plain_emoji",
  320. "▫️",
  321. lambda: "Plain module bullet",
  322. validator=loader.validators.Emoji(length=1),
  323. ),
  324. loader.ConfigValue(
  325. "empty_emoji",
  326. "🙈",
  327. lambda: "Empty modules bullet",
  328. validator=loader.validators.Emoji(length=1),
  329. ),
  330. )
  331. @loader.command(
  332. ru_doc=(
  333. "<модуль или модули> - Спрятать модуль(-и) из помощи\n*Разделяй модули"
  334. " пробелами"
  335. ),
  336. fr_doc=(
  337. "<module ou modules> - Cache le module (-s) de l'aide\n*Séparez les"
  338. " modules avec des espaces"
  339. ),
  340. it_doc=(
  341. "<module o moduli> - Nascondi il modulo (- i) dalla guida\n*Separa i moduli"
  342. " spazi"
  343. ),
  344. de_doc=(
  345. "<Modul oder Module> - Verstecke Modul(-e) aus der Hilfe\n*Modulnamen"
  346. " mit Leerzeichen trennen"
  347. ),
  348. tr_doc=(
  349. "<modül veya modüller> - Yardımdan modül(-ler) gizle\n*Modülleri boşluk"
  350. " ile ayır"
  351. ),
  352. uz_doc=(
  353. "<modul yoki modullar> - Modul(-lar) yordamidan yashirish\n*Modullarni"
  354. " bo'sh joy bilan ajratish"
  355. ),
  356. es_doc=(
  357. "<módulo o módulos> - Oculta el módulo (-s) de la ayuda\n*Separa los"
  358. " módulos con espacios"
  359. ),
  360. kk_doc=(
  361. "<модуль немесе модульдер> - Анықтамадан модульді (-дерді)"
  362. " жасыру\n*Модульдерді бос қойып айыр"
  363. ),
  364. )
  365. async def helphide(self, message: Message):
  366. """<module or modules> - Hide module(-s) from help
  367. *Split modules by spaces"""
  368. modules = utils.get_args(message)
  369. if not modules:
  370. await utils.answer(message, self.strings("no_mod"))
  371. return
  372. modules = list(
  373. filter(lambda module: self.lookup(module, include_dragon=True), modules)
  374. )
  375. currently_hidden = self.get("hide", [])
  376. hidden, shown = [], []
  377. for module in modules:
  378. module = self.lookup(module, include_dragon=True)
  379. module = (
  380. module.name
  381. if isinstance(module, DragonModule)
  382. else module.__class__.__name__
  383. )
  384. if module in currently_hidden:
  385. currently_hidden.remove(module)
  386. shown += [module]
  387. else:
  388. currently_hidden += [module]
  389. hidden += [module]
  390. self.set("hide", currently_hidden)
  391. await utils.answer(
  392. message,
  393. self.strings("hidden_shown").format(
  394. len(hidden),
  395. len(shown),
  396. "\n".join([f"👁‍🗨 <i>{m}</i>" for m in hidden]),
  397. "\n".join([f"👁 <i>{m}</i>" for m in shown]),
  398. ),
  399. )
  400. def find_aliases(self, command: str) -> list:
  401. """Find aliases for command"""
  402. aliases = []
  403. _command = self.allmodules.commands[command]
  404. if getattr(_command, "alias", None) and not (
  405. aliases := getattr(_command, "aliases", None)
  406. ):
  407. aliases = [_command.alias]
  408. return aliases or []
  409. async def modhelp(self, message: Message, args: str):
  410. exact = True
  411. module = self.lookup(args, include_dragon=True)
  412. if not module:
  413. cmd = args.lower().strip(self.get_prefix())
  414. if method := self.allmodules.dispatch(cmd)[1]:
  415. module = method.__self__
  416. if not module:
  417. module = self.lookup(
  418. next(
  419. (
  420. reversed(
  421. sorted(
  422. [
  423. module.strings["name"]
  424. for module in self.allmodules.modules
  425. ],
  426. key=lambda x: difflib.SequenceMatcher(
  427. None,
  428. args.lower(),
  429. x,
  430. ).ratio(),
  431. )
  432. )
  433. ),
  434. None,
  435. )
  436. )
  437. exact = False
  438. is_dragon = isinstance(module, DragonModule)
  439. try:
  440. name = module.strings("name")
  441. except (KeyError, AttributeError):
  442. name = getattr(module, "name", "ERROR")
  443. _name = (
  444. "{} (v{}.{}.{})".format(
  445. utils.escape_html(name),
  446. module.__version__[0],
  447. module.__version__[1],
  448. module.__version__[2],
  449. )
  450. if hasattr(module, "__version__")
  451. else utils.escape_html(name)
  452. )
  453. reply = "{} <b>{}</b>:".format(
  454. (
  455. DRAGON_EMOJI
  456. if is_dragon
  457. else "<emoji document_id=5188377234380954537>🌘</emoji>"
  458. ),
  459. _name,
  460. )
  461. if module.__doc__:
  462. reply += (
  463. "<i>\n<emoji document_id=5787544344906959608>ℹ️</emoji> "
  464. + utils.escape_html(inspect.getdoc(module))
  465. + "\n</i>"
  466. )
  467. commands = (
  468. module.commands
  469. if is_dragon
  470. else {
  471. name: func
  472. for name, func in module.commands.items()
  473. if await self.allmodules.check_security(message, func)
  474. }
  475. )
  476. if hasattr(module, "inline_handlers") and not is_dragon:
  477. for name, fun in module.inline_handlers.items():
  478. reply += (
  479. "\n<emoji document_id=5372981976804366741>🤖</emoji>"
  480. " <code>{}</code> {}".format(
  481. f"@{self.inline.bot_username} {name}",
  482. (
  483. utils.escape_html(inspect.getdoc(fun))
  484. if fun.__doc__
  485. else self.strings("undoc")
  486. ),
  487. )
  488. )
  489. for name, fun in commands.items():
  490. reply += (
  491. "\n<emoji document_id=4971987363145188045>▫️</emoji>"
  492. " <code>{}{}</code>{} {}".format(
  493. self.get_prefix("dragon" if is_dragon else None),
  494. name,
  495. " ({})".format(
  496. ", ".join(
  497. "<code>{}{}</code>".format(
  498. self.get_prefix("dragon" if is_dragon else None), alias
  499. )
  500. for alias in self.find_aliases(name)
  501. )
  502. )
  503. if self.find_aliases(name)
  504. else "",
  505. utils.escape_html(fun)
  506. if is_dragon
  507. else (
  508. utils.escape_html(inspect.getdoc(fun))
  509. if fun.__doc__
  510. else self.strings("undoc")
  511. ),
  512. )
  513. )
  514. await utils.answer(
  515. message,
  516. reply
  517. + (f"\n\n{self.strings('not_exact')}" if not exact else "")
  518. + (
  519. f"\n\n{self.strings('core_notice')}"
  520. if module.__origin__.startswith("<core")
  521. else ""
  522. ),
  523. )
  524. @loader.unrestricted
  525. @loader.command(
  526. ru_doc="[модуль] [-f] - Показать помощь",
  527. fr_doc="[module] [-f] - Afficher l'aide",
  528. it_doc="[modulo] [-f] - Mostra l'aiuto",
  529. de_doc="[Modul] [-f] - Hilfe anzeigen",
  530. tr_doc="[modül] [-f] - Yardımı göster",
  531. uz_doc="[modul] [-f] - Yordamni ko'rsatish",
  532. es_doc="[módulo] [-f] - Mostrar ayuda",
  533. kk_doc="[модуль] [-f] - Анықтама көрсету",
  534. )
  535. async def help(self, message: Message):
  536. """[module] [-f] - Show help"""
  537. args = utils.get_args_raw(message)
  538. force = False
  539. if "-f" in args:
  540. args = args.replace(" -f", "").replace("-f", "")
  541. force = True
  542. if args:
  543. await self.modhelp(message, args)
  544. return
  545. hidden = self.get("hide", [])
  546. reply = self.strings("all_header").format(
  547. len(self.allmodules.modules) + len(self.allmodules.dragon_modules),
  548. 0
  549. if force
  550. else sum(
  551. module.__class__.__name__ in hidden
  552. for module in self.allmodules.modules
  553. )
  554. + sum(module.name in hidden for module in self.allmodules.dragon_modules),
  555. )
  556. shown_warn = False
  557. plain_ = []
  558. core_ = []
  559. inline_ = []
  560. no_commands_ = []
  561. dragon_ = []
  562. for mod in self.allmodules.dragon_modules:
  563. if mod.name in self.get("hide", []) and not force:
  564. continue
  565. tmp = "\n{} <code>{}</code>".format(DRAGON_EMOJI, mod.name)
  566. first = True
  567. for cmd in mod.commands:
  568. cmd = cmd.split()[0]
  569. if first:
  570. tmp += f": ( {cmd}"
  571. first = False
  572. else:
  573. tmp += f" | {cmd}"
  574. dragon_ += [tmp + " )"]
  575. for mod in self.allmodules.modules:
  576. if not hasattr(mod, "commands"):
  577. logger.debug("Module %s is not inited yet", mod.__class__.__name__)
  578. continue
  579. if mod.__class__.__name__ in self.get("hide", []) and not force:
  580. continue
  581. tmp = ""
  582. try:
  583. name = mod.strings["name"]
  584. except KeyError:
  585. name = getattr(mod, "name", "ERROR")
  586. inline = (
  587. hasattr(mod, "callback_handlers")
  588. and mod.callback_handlers
  589. or hasattr(mod, "inline_handlers")
  590. and mod.inline_handlers
  591. )
  592. if not inline:
  593. for cmd_ in mod.commands.values():
  594. try:
  595. inline = "await self.inline.form(" in inspect.getsource(
  596. cmd_.__code__
  597. )
  598. except Exception:
  599. pass
  600. core = mod.__origin__.startswith("<core")
  601. if core:
  602. emoji = self.config["core_emoji"]
  603. elif inline:
  604. emoji = self.config["hikka_emoji"]
  605. else:
  606. emoji = self.config["plain_emoji"]
  607. if (
  608. not getattr(mod, "commands", None)
  609. and not getattr(mod, "inline_handlers", None)
  610. and not getattr(mod, "callback_handlers", None)
  611. ):
  612. no_commands_ += [
  613. "\n{} <code>{}</code>".format(self.config["empty_emoji"], name)
  614. ]
  615. continue
  616. tmp += "\n{} <code>{}</code>".format(emoji, name)
  617. first = True
  618. commands = [
  619. name
  620. for name, func in mod.commands.items()
  621. if await self.allmodules.check_security(message, func) or force
  622. ]
  623. for cmd in commands:
  624. if first:
  625. tmp += f": ( {cmd}"
  626. first = False
  627. else:
  628. tmp += f" | {cmd}"
  629. icommands = [
  630. name
  631. for name, func in mod.inline_handlers.items()
  632. if await self.inline.check_inline_security(
  633. func=func,
  634. user=message.sender_id,
  635. )
  636. or force
  637. ]
  638. for cmd in icommands:
  639. if first:
  640. tmp += f": ( 🤖 {cmd}"
  641. first = False
  642. else:
  643. tmp += f" | 🤖 {cmd}"
  644. if commands or icommands:
  645. tmp += " )"
  646. if core:
  647. core_ += [tmp]
  648. elif inline:
  649. inline_ += [tmp]
  650. else:
  651. plain_ += [tmp]
  652. elif not shown_warn and (mod.commands or mod.inline_handlers):
  653. reply = (
  654. "<i>You have permissions to execute only these"
  655. f" commands</i>\n{reply}"
  656. )
  657. shown_warn = True
  658. plain_.sort(key=lambda x: x.split()[1])
  659. core_.sort(key=lambda x: x.split()[1])
  660. inline_.sort(key=lambda x: x.split()[1])
  661. no_commands_.sort(key=lambda x: x.split()[1])
  662. no_commands_ = "".join(no_commands_) if force else ""
  663. dragon_.sort()
  664. partial_load = (
  665. ""
  666. if self.lookup("Loader").fully_loaded
  667. else f"\n\n{self.strings('partial_load')}"
  668. )
  669. await utils.answer(
  670. message,
  671. "{}\n{}{}{}{}{}{}".format(
  672. reply,
  673. "".join(core_),
  674. "".join(plain_),
  675. "".join(inline_),
  676. "".join(dragon_),
  677. no_commands_,
  678. partial_load,
  679. ),
  680. )
  681. @loader.command(
  682. ru_doc="Показать ссылку на чат помощи Hikka",
  683. fr_doc="Afficher le lien du chat d'aide de Hikka",
  684. it_doc="Mostra il link al gruppo di supporto Hikka",
  685. de_doc="Zeige den Link zum Hikka-Hilfe-Chat",
  686. tr_doc="Hikka yardım sohbetinin bağlantısını göster",
  687. uz_doc="Hikka yordam sohbatining havolasini ko'rsatish",
  688. es_doc="Mostrar enlace al chat de ayuda de Hikka",
  689. kk_doc="Hikka анықтама сөйлесушісінің сілтемесін көрсету",
  690. )
  691. async def support(self, message):
  692. """Get link of Hikka support chat"""
  693. if message.out:
  694. await self.request_join("@hikka_talks", self.strings("request_join"))
  695. await utils.answer(
  696. message,
  697. self.strings("support").format(
  698. (
  699. utils.get_platform_emoji()
  700. if self._client.hikka_me.premium and CUSTOM_EMOJIS
  701. else "🌘"
  702. )
  703. ),
  704. )