hikka_info.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  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 git
  9. from telethon.tl.types import Message
  10. from telethon.utils import get_display_name
  11. from .. import loader, utils, version
  12. from ..inline.types import InlineQuery
  13. @loader.tds
  14. class HikkaInfoMod(loader.Module):
  15. """Show userbot info"""
  16. strings = {
  17. "name": "HikkaInfo",
  18. "owner": "Owner",
  19. "version": "Version",
  20. "build": "Build",
  21. "prefix": "Prefix",
  22. "uptime": "Uptime",
  23. "branch": "Branch",
  24. "send_info": "Send userbot info",
  25. "description": "ℹ This will not compromise any sensitive info",
  26. "up-to-date": (
  27. "<emoji document_id=5370699111492229743>😌</emoji><b> Up-to-date</b>"
  28. ),
  29. "update_required": (
  30. "<emoji document_id=5424728541650494040>😕</emoji><b> Update required"
  31. " </b><code>.update</code>"
  32. ),
  33. "setinfo_no_args": (
  34. "<emoji document_id=5370881342659631698>😢</emoji> <b>You need to specify"
  35. " text to change info to</b>"
  36. ),
  37. "setinfo_success": (
  38. "<emoji document_id=5436040291507247633>🎉</emoji> <b>Info changed"
  39. " successfully</b>"
  40. ),
  41. "_cfg_cst_msg": (
  42. "Custom message for info. May contain {me}, {version}, {build}, {prefix},"
  43. " {platform}, {upd}, {uptime}, {branch} keywords"
  44. ),
  45. "_cfg_cst_btn": "Custom button for info. Leave empty to remove button",
  46. "_cfg_banner": "URL to image banner",
  47. }
  48. strings_ru = {
  49. "owner": "Владелец",
  50. "version": "Версия",
  51. "build": "Сборка",
  52. "prefix": "Префикс",
  53. "uptime": "Аптайм",
  54. "branch": "Ветка",
  55. "send_info": "Отправить информацию о юзерботе",
  56. "description": "ℹ Это не раскроет никакой личной информации",
  57. "_ihandle_doc_info": "Отправить информацию о юзерботе",
  58. "up-to-date": (
  59. "<emoji document_id=5370699111492229743>😌</emoji><b> Актуальная версия</b>"
  60. ),
  61. "update_required": (
  62. "<emoji document_id=5424728541650494040>😕</emoji><b> Требуется обновление"
  63. " </b><code>.update</code>"
  64. ),
  65. "_cfg_cst_msg": (
  66. "Кастомный текст сообщения в info. Может содержать ключевые слова {me},"
  67. " {version}, {build}, {prefix}, {platform}, {upd}, {uptime}, {branch}"
  68. ),
  69. "_cfg_cst_btn": (
  70. "Кастомная кнопка в сообщении в info. Оставь пустым, чтобы убрать кнопку"
  71. ),
  72. "_cfg_banner": "Ссылка на баннер-картинку",
  73. "setinfo_no_args": (
  74. "<emoji document_id=5370881342659631698>😢</emoji> <b>Тебе нужно указать"
  75. " текст для кастомного инфо</b>"
  76. ),
  77. "setinfo_success": (
  78. "<emoji document_id=5436040291507247633>🎉</emoji> <b>Текст инфо успешно"
  79. " изменен</b>"
  80. ),
  81. }
  82. def __init__(self):
  83. self.config = loader.ModuleConfig(
  84. loader.ConfigValue(
  85. "custom_message",
  86. doc=lambda: self.strings("_cfg_cst_msg"),
  87. ),
  88. loader.ConfigValue(
  89. "custom_button",
  90. ["🌘 Support chat", "https://t.me/hikka_talks"],
  91. lambda: self.strings("_cfg_cst_btn"),
  92. validator=loader.validators.Union(
  93. loader.validators.Series(fixed_len=2),
  94. loader.validators.NoneType(),
  95. ),
  96. ),
  97. loader.ConfigValue(
  98. "banner_url",
  99. "https://github.com/hikariatama/assets/raw/master/hikka_banner.mp4",
  100. lambda: self.strings("_cfg_banner"),
  101. validator=loader.validators.Link(),
  102. ),
  103. )
  104. async def client_ready(self):
  105. self._me = await self._client.get_me()
  106. # Legacy migration
  107. if (
  108. self.config["banner_url"]
  109. == "https://github.com/hikariatama/assets/raw/master/hikka_banner.png"
  110. ):
  111. self.config[
  112. "banner_url"
  113. ] = "https://github.com/hikariatama/assets/raw/master/hikka_banner.mp4"
  114. def _render_info(self, inline: bool) -> str:
  115. try:
  116. repo = git.Repo(search_parent_directories=True)
  117. diff = repo.git.log([f"HEAD..origin/{version.branch}", "--oneline"])
  118. upd = (
  119. self.strings("update_required") if diff else self.strings("up-to-date")
  120. )
  121. except Exception:
  122. upd = ""
  123. me = '<b><a href="tg://user?id={}">{}</a></b>'.format(
  124. self._me.id,
  125. utils.escape_html(get_display_name(self._me)),
  126. )
  127. build = utils.get_commit_url()
  128. _version = f'<i>{".".join(list(map(str, list(version.__version__))))}</i>'
  129. prefix = f"«<code>{utils.escape_html(self.get_prefix())}</code>»"
  130. platform = utils.get_named_platform()
  131. return (
  132. (
  133. "<b>🌘 Hikka</b>\n"
  134. if "hikka" not in self.config["custom_message"].lower()
  135. else ""
  136. )
  137. + self.config["custom_message"].format(
  138. me=me,
  139. version=_version,
  140. build=build,
  141. prefix=prefix,
  142. platform=platform,
  143. upd=upd,
  144. uptime=utils.formatted_uptime(),
  145. branch=version.branch,
  146. )
  147. if self.config["custom_message"]
  148. else (
  149. "<b>{}</b>\n\n"
  150. f'<b>{{}} {self.strings("owner")}: </b>{me}\n\n'
  151. f"<b>{{}} {self.strings('version')}: </b>{_version} {build}\n"
  152. f"<b>{{}} {self.strings('branch')}: </b><code>{version.branch}</code>\n"
  153. f"{upd}\n\n"
  154. f"<b>{{}} {self.strings('prefix')}: </b>{prefix}\n"
  155. f"<b>{{}} {self.strings('uptime')}: </b>{utils.formatted_uptime()}\n"
  156. f"<b>{platform}</b>\n"
  157. ).format(
  158. *map(
  159. lambda x: utils.remove_html(x) if inline else x,
  160. (
  161. utils.get_platform_emoji()
  162. if self._client.hikka_me.premium and not inline
  163. else "🌘 Hikka",
  164. "<emoji document_id=5373141891321699086>😎</emoji>",
  165. "<emoji document_id=5469741319330996757>💫</emoji>",
  166. "<emoji document_id=5449918202718985124>🌳</emoji>",
  167. "<emoji document_id=5472111548572900003>⌨️</emoji>",
  168. "<emoji document_id=5451646226975955576>⌛️</emoji>",
  169. ),
  170. )
  171. )
  172. )
  173. def _get_mark(self):
  174. return (
  175. {
  176. "text": self.config["custom_button"][0],
  177. "url": self.config["custom_button"][1],
  178. }
  179. if self.config["custom_button"]
  180. else None
  181. )
  182. @loader.inline_handler(
  183. thumb_url="https://img.icons8.com/external-others-inmotus-design/344/external-Moon-round-icons-others-inmotus-design-2.png"
  184. )
  185. @loader.inline_everyone
  186. async def info(self, _: InlineQuery) -> dict:
  187. """Send userbot info"""
  188. return {
  189. "title": self.strings("send_info"),
  190. "description": self.strings("description"),
  191. **(
  192. {"photo": self.config["banner_url"], "caption": self._render_info(True)}
  193. if self.config["banner_url"]
  194. else {"message": self._render_info(True)}
  195. ),
  196. "thumb": (
  197. "https://github.com/hikariatama/Hikka/raw/master/assets/hikka_pfp.png"
  198. ),
  199. "reply_markup": self._get_mark(),
  200. }
  201. @loader.unrestricted
  202. async def infocmd(self, message: Message):
  203. """Send userbot info"""
  204. if self.config["custom_button"]:
  205. await self.inline.form(
  206. message=message,
  207. text=self._render_info(True),
  208. reply_markup=self._get_mark(),
  209. **(
  210. {"photo": self.config["banner_url"]}
  211. if self.config["banner_url"]
  212. else {}
  213. ),
  214. )
  215. else:
  216. try:
  217. await self._client.send_file(
  218. message.peer_id,
  219. self.config["banner_url"],
  220. caption=self._render_info(False),
  221. )
  222. except Exception:
  223. await utils.answer(message, self._render_info(False))
  224. else:
  225. if message.out:
  226. await message.delete()
  227. @loader.unrestricted
  228. async def hikkainfocmd(self, message: Message):
  229. """[en/ru - default en] - Send info aka 'What is Hikka?'"""
  230. args = utils.get_args_raw(message)
  231. args = args if args in {"en", "ru"} else "en"
  232. await utils.answer(
  233. message,
  234. "<emoji document_id=6318565919471699564>🌌</emoji>"
  235. " <b>Hikka</b>\n\nTelegram userbot with a lot of features, like inline"
  236. " galleries, forms, lists and animated emojis support. Userbot - software,"
  237. " running on your Telegram account. If you write a command to any chat, it"
  238. " will get executed right there. Check out live examples at <a"
  239. ' href="https://github.com/hikariatama/Hikka">GitHub</a>'
  240. if args == "en"
  241. else (
  242. "<emoji document_id=6318565919471699564>🌌</emoji>"
  243. " <b>Hikka</b>\n\nTelegram юзербот с огромным количеством функций, из"
  244. " которых: инлайн галереи, формы, списки, а также поддержка"
  245. " анимированных эмодзи. Юзербот - программа, которая запускается на"
  246. " твоем Telegram-аккаунте. Когда ты пишешь команду в любом чате, она"
  247. " сразу же выполняется. Обрати внимание на живые примеры на <a"
  248. ' href="https://github.com/hikariatama/Hikka">GitHub</a>'
  249. ),
  250. )
  251. @loader.command(ru_doc="<текст> - Изменить текст в .info")
  252. async def setinfo(self, message: Message):
  253. """<text> - Change text in .info"""
  254. args = utils.get_args_html(message)
  255. if not args:
  256. return await utils.answer(message, self.strings("setinfo_no_args"))
  257. self.config["custom_message"] = args
  258. await utils.answer(message, self.strings("setinfo_success"))