settings.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. # Friendly Telegram (telegram userbot)
  2. # Copyright (C) 2018-2021 The Authors
  3. # This program is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU Affero General Public License as published by
  5. # the Free Software Foundation, either version 3 of the License, or
  6. # (at your option) any later version.
  7. # This program is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. # GNU Affero General Public License for more details.
  11. # You should have received a copy of the GNU Affero General Public License
  12. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. # █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
  14. # █▀█ █ █ █ █▀█ █▀▄ █
  15. # © Copyright 2022
  16. # https://t.me/hikariatama
  17. #
  18. # 🔒 Licensed under the GNU AGPLv3
  19. # 🌐 https://www.gnu.org/licenses/agpl-3.0.html
  20. from telethon.tl.types import Message
  21. from .. import loader, main, translations, utils
  22. from ..inline.types import InlineCall
  23. @loader.tds
  24. class CoreMod(loader.Module):
  25. """Control core userbot settings"""
  26. strings = {
  27. "name": "Settings",
  28. "too_many_args": "🚫 <b>Too many args</b>",
  29. "blacklisted": "✅ <b>Chat {} blacklisted from userbot</b>",
  30. "unblacklisted": "✅ <b>Chat {} unblacklisted from userbot</b>",
  31. "user_blacklisted": "✅ <b>User {} blacklisted from userbot</b>",
  32. "user_unblacklisted": "✅ <b>User {} unblacklisted from userbot</b>",
  33. "what_prefix": "❓ <b>What should the prefix be set to?</b>",
  34. "prefix_incorrect": "🚫 <b>Prefix must be one symbol in length</b>",
  35. "prefix_set": (
  36. "✅ <b>Command prefix updated. Type</b> <code>{newprefix}setprefix"
  37. " {oldprefix}</code> <b>to change it back</b>"
  38. ),
  39. "alias_created": "✅ <b>Alias created. Access it with</b> <code>{}</code>",
  40. "aliases": "<b>🔗 Aliases:</b>\n",
  41. "no_command": "🚫 <b>Command</b> <code>{}</code> <b>does not exist</b>",
  42. "alias_args": "🚫 <b>You must provide a command and the alias for it</b>",
  43. "delalias_args": "🚫 <b>You must provide the alias name</b>",
  44. "alias_removed": "✅ <b>Alias</b> <code>{}</code> <b>removed.",
  45. "no_alias": "<b>🚫 Alias</b> <code>{}</code> <b>does not exist</b>",
  46. "db_cleared": "<b>✅ Database cleared</b>",
  47. "hikka": "🌘 <b>Hikka userbot</b>\n<b>Version: {}.{}.{}</b>",
  48. "check_url": "🚫 <b>You need to specify valid url containing a langpack</b>",
  49. "lang_saved": "{} <b>Language saved!</b>",
  50. "pack_saved": "✅ <b>Translate pack saved!</b>",
  51. "incorrect_language": "🚫 <b>Incorrect language specified</b>",
  52. "lang_removed": "✅ <b>Translations reset to default ones</b>",
  53. "check_pack": "🚫 <b>Invalid pack format in url</b>",
  54. "confirm_cleardb": "⚠️ <b>Are you sure, that you want to clear database?</b>",
  55. "cleardb_confirm": "🗑 Clear database",
  56. "cancel": "🚫 Cancel",
  57. }
  58. strings_ru = {
  59. "too_many_args": "🚫 <b>Слишком много аргументов</b>",
  60. "blacklisted": "✅ <b>Чат {} добавлен в черный список юзербота</b>",
  61. "unblacklisted": "✅ <b>Чат {} удален из черного списка юзербота</b>",
  62. "user_blacklisted": (
  63. "✅ <b>Пользователь {} добавлен в черный список юзербота</b>"
  64. ),
  65. "user_unblacklisted": (
  66. "✅ <b>Пользователь {} удален из черного списка юзербота</b>"
  67. ),
  68. "what_prefix": "❓ <b>А какой префикс ставить то?</b>",
  69. "prefix_incorrect": "🚫 <b>Префикс должен состоять только из одного символа</b>",
  70. "prefix_set": (
  71. "✅ <b>Префикс обновлен. Чтобы вернуть его, используй</b>"
  72. " <code>{newprefix}setprefix {oldprefix}</code>"
  73. ),
  74. "alias_created": "✅ <b>Алиас создан. Используй его через</b> <code>{}</code>",
  75. "aliases": "<b>🔗 Алиасы:</b>\n",
  76. "no_command": "🚫 <b>Команда</b> <code>{}</code> <b>не существует</b>",
  77. "alias_args": "🚫 <b>Требуется ввести команду и алиас для нее</b>",
  78. "delalias_args": "🚫 <b>Требуется имя алиаса</b>",
  79. "alias_removed": "✅ <b>Алиас</b> <code>{}</code> <b>удален.",
  80. "no_alias": "<b>🚫 Алиас</b> <code>{}</code> <b>не существует</b>",
  81. "db_cleared": "<b>✅ База очищена</b>",
  82. "hikka": "🌘 <b>Hikka userbot</b>\n<b>Версия: {}.{}.{}</b>",
  83. "check_url": "🚫 <b>Укажи правильную ссылку, ведущую на пак с переводом</b>",
  84. "lang_saved": "{} <b>Язык сохранен!</b>",
  85. "pack_saved": "✅ <b>Пак перевода сохранен!</b>",
  86. "incorrect_language": "🚫 <b>Указан неверный язык</b>",
  87. "lang_removed": "✅ <b>Переводы сброшены</b>",
  88. "check_pack": "🚫 <b>По ссылке находится неправильный пак</b>",
  89. "_cmd_doc_hikka": "Показать версию Hikka",
  90. "_cmd_doc_blacklist": "[чат] [модуль] - Отключить бота где-либо",
  91. "_cmd_doc_unblacklist": "<чат> - Включить бота где-либо",
  92. "_cmd_doc_blacklistuser": (
  93. "[пользователь] - Запретить пользователю выполнять все команды"
  94. ),
  95. "_cmd_doc_unblacklistuser": (
  96. "[пользователь] - Разрешить пользователю выполнять команды, на которые ему"
  97. " хватает разрешений"
  98. ),
  99. "_cmd_doc_setprefix": "<префикс> - Установить префикс",
  100. "_cmd_doc_aliases": "Показать алиасы",
  101. "_cmd_doc_addalias": "Установить алиас для команды",
  102. "_cmd_doc_delalias": "Удалить алиас для команды",
  103. "_cmd_doc_addtrnsl": (
  104. "Установить пак перевода\n.addtrnsl <пак>\nТребуется перезагрузка после"
  105. " выполнения"
  106. ),
  107. "_cmd_doc_cleartrnsl": "Удалить все паки перевода",
  108. "_cmd_doc_setlang": (
  109. "Выбрать предпочитаемый язык перевода\nТребуется перезагрузка после"
  110. " выполнения"
  111. ),
  112. "_cmd_doc_cleardb": "Сброс до заводских настроек - сброс базы данных",
  113. "_cls_doc": "Управление базовыми настройками юзербота",
  114. "confirm_cleardb": "⚠️ <b>Вы уверены, что хотите сбросить базу данных?</b>",
  115. "cleardb_confirm": "🗑 Очистить базу",
  116. "cancel": "🚫 Отмена",
  117. }
  118. async def blacklistcommon(self, message: Message):
  119. args = utils.get_args(message)
  120. if len(args) > 2:
  121. await utils.answer(message, self.strings("too_many_args"))
  122. return
  123. chatid = None
  124. module = None
  125. if args:
  126. try:
  127. chatid = int(args[0])
  128. except ValueError:
  129. module = args[0]
  130. if len(args) == 2:
  131. module = args[1]
  132. if chatid is None:
  133. chatid = utils.get_chat_id(message)
  134. module = self.allmodules.get_classname(module)
  135. return f"{str(chatid)}.{module}" if module else chatid
  136. async def hikkacmd(self, message: Message):
  137. """Get Hikka version"""
  138. await utils.answer(message, self.strings("hikka").format(*main.__version__))
  139. async def blacklistcmd(self, message: Message):
  140. """[chat_id] [module] - Blacklist the bot from operating somewhere"""
  141. chatid = await self.blacklistcommon(message)
  142. self._db.set(
  143. main.__name__,
  144. "blacklist_chats",
  145. self._db.get(main.__name__, "blacklist_chats", []) + [chatid],
  146. )
  147. await utils.answer(message, self.strings("blacklisted").format(chatid))
  148. async def unblacklistcmd(self, message: Message):
  149. """<chat_id> - Unblacklist the bot from operating somewhere"""
  150. chatid = await self.blacklistcommon(message)
  151. self._db.set(
  152. main.__name__,
  153. "blacklist_chats",
  154. list(set(self._db.get(main.__name__, "blacklist_chats", [])) - {chatid}),
  155. )
  156. await utils.answer(message, self.strings("unblacklisted").format(chatid))
  157. async def getuser(self, message: Message):
  158. try:
  159. return int(utils.get_args(message)[0])
  160. except (ValueError, IndexError):
  161. reply = await message.get_reply_message()
  162. if reply:
  163. return reply.sender_id
  164. return message.to_id.user_id if message.is_private else False
  165. async def blacklistusercmd(self, message: Message):
  166. """[user_id] - Prevent this user from running any commands"""
  167. user = await self.getuser(message)
  168. if not user:
  169. await utils.answer(message, self.strings("who_to_unblacklist"))
  170. return
  171. self._db.set(
  172. main.__name__,
  173. "blacklist_users",
  174. self._db.get(main.__name__, "blacklist_users", []) + [user],
  175. )
  176. await utils.answer(message, self.strings("user_blacklisted").format(user))
  177. async def unblacklistusercmd(self, message: Message):
  178. """[user_id] - Allow this user to run permitted commands"""
  179. user = await self.getuser(message)
  180. if not user:
  181. await utils.answer(message, self.strings("who_to_unblacklist"))
  182. return
  183. self._db.set(
  184. main.__name__,
  185. "blacklist_users",
  186. list(set(self._db.get(main.__name__, "blacklist_users", [])) - {user}),
  187. )
  188. await utils.answer(
  189. message,
  190. self.strings("user_unblacklisted").format(user),
  191. )
  192. @loader.owner
  193. async def setprefixcmd(self, message: Message):
  194. """<prefix> - Sets command prefix"""
  195. args = utils.get_args_raw(message)
  196. if not args:
  197. await utils.answer(message, self.strings("what_prefix"))
  198. return
  199. if len(args) != 1:
  200. await utils.answer(message, self.strings("prefix_incorrect"))
  201. return
  202. oldprefix = self.get_prefix()
  203. self._db.set(main.__name__, "command_prefix", args)
  204. await utils.answer(
  205. message,
  206. self.strings("prefix_set").format(
  207. newprefix=utils.escape_html(args[0]),
  208. oldprefix=utils.escape_html(oldprefix),
  209. ),
  210. )
  211. @loader.owner
  212. async def aliasescmd(self, message: Message):
  213. """Print all your aliases"""
  214. aliases = self.allmodules.aliases
  215. string = self.strings("aliases")
  216. string += "\n".join(
  217. [f"▫️ <code>{i}</code> &lt;- {y}" for i, y in aliases.items()]
  218. )
  219. await utils.answer(message, string)
  220. @loader.owner
  221. async def addaliascmd(self, message: Message):
  222. """Set an alias for a command"""
  223. args = utils.get_args(message)
  224. if len(args) != 2:
  225. await utils.answer(message, self.strings("alias_args"))
  226. return
  227. alias, cmd = args
  228. if self.allmodules.add_alias(alias, cmd):
  229. self.set(
  230. "aliases",
  231. {
  232. **self.get("aliases", {}),
  233. alias: cmd,
  234. },
  235. )
  236. await utils.answer(
  237. message,
  238. self.strings("alias_created").format(utils.escape_html(alias)),
  239. )
  240. else:
  241. await utils.answer(
  242. message,
  243. self.strings("no_command").format(utils.escape_html(cmd)),
  244. )
  245. @loader.owner
  246. async def delaliascmd(self, message: Message):
  247. """Remove an alias for a command"""
  248. args = utils.get_args(message)
  249. if len(args) != 1:
  250. await utils.answer(message, self.strings("delalias_args"))
  251. return
  252. alias = args[0]
  253. removed = self.allmodules.remove_alias(alias)
  254. if not removed:
  255. await utils.answer(
  256. message,
  257. self.strings("no_alias").format(utils.escape_html(alias)),
  258. )
  259. return
  260. current = self.get("aliases", {})
  261. del current[alias]
  262. self.set("aliases", current)
  263. await utils.answer(
  264. message,
  265. self.strings("alias_removed").format(utils.escape_html(alias)),
  266. )
  267. async def dllangpackcmd(self, message: Message):
  268. """[link to a langpack | empty to remove] - Change Hikka translate pack (external)"""
  269. args = utils.get_args_raw(message)
  270. if not args:
  271. self._db.set(translations.__name__, "pack", False)
  272. await self.translator.init()
  273. await utils.answer(message, self.strings("lang_removed"))
  274. return
  275. if not utils.check_url(args):
  276. await utils.answer(message, self.strings("check_url"))
  277. return
  278. self._db.set(translations.__name__, "pack", args)
  279. success = await self.translator.init()
  280. await utils.answer(
  281. message, self.strings("pack_saved" if success else "check_pack")
  282. )
  283. async def setlangcmd(self, message: Message):
  284. """[languages in the order of priority] - Change default language"""
  285. args = utils.get_args_raw(message)
  286. if not args or any(len(i) != 2 for i in args.split(" ")):
  287. await utils.answer(message, self.strings("incorrect_language"))
  288. return
  289. self._db.set(translations.__name__, "lang", args.lower())
  290. await self.translator.init()
  291. await utils.answer(
  292. message,
  293. self.strings("lang_saved").format(
  294. "".join(
  295. [
  296. utils.get_lang_flag(
  297. lang.lower() if lang.lower() != "en" else "gb"
  298. )
  299. for lang in args.lower().split(" ")
  300. ]
  301. )
  302. ),
  303. )
  304. @loader.owner
  305. async def cleardbcmd(self, message: Message):
  306. """Clears the entire database, effectively performing a factory reset"""
  307. await self.inline.form(
  308. self.strings("confirm_cleardb"),
  309. message,
  310. reply_markup=[
  311. {
  312. "text": self.strings("cleardb_confirm"),
  313. "callback": self._inline__cleardb,
  314. },
  315. {
  316. "text": self.strings("cancel"),
  317. "action": "close",
  318. },
  319. ],
  320. )
  321. async def _inline__cleardb(self, call: InlineCall):
  322. self._db.clear()
  323. self._db.save()
  324. await utils.answer(call, self.strings("db_cleared"))