1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012 |
- # █ █ ▀ █▄▀ ▄▀█ █▀█ ▀
- # █▀█ █ █ █ █▀█ █▀▄ █
- # © Copyright 2022
- # https://t.me/hikariatama
- #
- # 🔒 Licensed under the GNU AGPLv3
- # 🌐 https://www.gnu.org/licenses/agpl-3.0.html
- # scope: inline
- import logging
- import atexit
- import random
- import sys
- import os
- import telethon
- from telethon.tl.types import Message
- from telethon.tl.functions.messages import (
- GetDialogFiltersRequest,
- UpdateDialogFilterRequest,
- )
- from telethon.tl.functions.channels import JoinChannelRequest
- from telethon.utils import get_display_name
- from .. import loader, main, utils
- from ..inline.types import InlineCall
- logger = logging.getLogger(__name__)
- def restart(*argv):
- os.execl(
- sys.executable,
- sys.executable,
- "-m",
- os.path.relpath(utils.get_base_dir()),
- *argv,
- )
- @loader.tds
- class HikkaSettingsMod(loader.Module):
- """Advanced settings for Hikka Userbot"""
- strings = {
- "name": "HikkaSettings",
- "watchers": "👀 <b>Watchers:</b>\n\n<b>{}</b>",
- "mod404": "🚫 <b>Watcher {} not found</b>",
- "disabled": "👀 <b>Watcher {} is now <u>disabled</u></b>",
- "enabled": "👀 <b>Watcher {} is now <u>enabled</u></b>",
- "args": "🚫 <b>You need to specify watcher name</b>",
- "user_nn": "🔰 <b>NoNick for this user is now {}</b>",
- "no_cmd": "🔰 <b>Please, specify command to toggle NoNick for</b>",
- "cmd_nn": "🔰 <b>NoNick for </b><code>{}</code><b> is now {}</b>",
- "cmd404": "🔰 <b>Command not found</b>",
- "inline_settings": "⚙️ <b>Here you can configure your Hikka settings</b>",
- "confirm_update": (
- "🧭 <b>Please, confirm that you want to update. Your userbot will be"
- " restarted</b>"
- ),
- "confirm_restart": "🔄 <b>Please, confirm that you want to restart</b>",
- "suggest_fs": "✅ Suggest FS for modules",
- "do_not_suggest_fs": "🚫 Suggest FS for modules",
- "use_fs": "✅ Always use FS for modules",
- "do_not_use_fs": "🚫 Always use FS for modules",
- "btn_restart": "🔄 Restart",
- "btn_update": "🧭 Update",
- "close_menu": "😌 Close menu",
- "custom_emojis": "✅ Custom emojis",
- "no_custom_emojis": "🚫 Custom emojis",
- "suggest_subscribe": "✅ Suggest subscribe to channel",
- "do_not_suggest_subscribe": "🚫 Suggest subscribe to channel",
- "private_not_allowed": "🚫 <b>This command must be executed in chat</b>",
- "nonick_warning": (
- "Warning! You enabled NoNick with default prefix! "
- "You may get muted in Hikka chats. Change prefix or "
- "disable NoNick!"
- ),
- "reply_required": (
- "🚫 <b>Reply to a message of user, which needs to be added to NoNick</b>"
- ),
- "deauth_confirm": (
- "⚠️ <b>This action will fully remove Hikka from this account and can't be"
- " reverted!</b>\n\n<i>- Hikka chats will be removed\n- Session will be"
- " terminated and removed\n- Hikka inline bot will be removed</i>"
- ),
- "deauth_confirm_step2": (
- "⚠️ <b>Are you really sure you want to delete Hikka?</b>"
- ),
- "deauth_yes": "I'm sure",
- "deauth_no_1": "I'm not sure",
- "deauth_no_2": "I'm uncertain",
- "deauth_no_3": "I'm struggling to answer",
- "deauth_cancel": "🚫 Cancel",
- "deauth_confirm_btn": "😢 Delete",
- "uninstall": "😢 <b>Uninstalling Hikka...</b>",
- "uninstalled": (
- "😢 <b>Hikka uninstalled. Web interface is still active, you can add another"
- " account</b>"
- ),
- "logs_cleared": "🗑 <b>Logs cleared</b>",
- "cmd_nn_list": "🔰 <b>NoNick is enabled for these commands:</b>\n\n{}",
- "user_nn_list": "🔰 <b>NoNick is enabled for these users:</b>\n\n{}",
- "chat_nn_list": "🔰 <b>NoNick is enabled for these chats:</b>\n\n{}",
- "nothing": "🔰 <b>Nothing to show...</b>",
- "privacy_leak": (
- "⚠️ <b>This command gives access to your Hikka web interface. It's not"
- " recommended to run it in public group chats. Consider using it in <a"
- " href='tg://openmessage?user_id={}'>Saved messages</a>. Type"
- " </b><code>{}proxypass force_insecure</code><b> to ignore this warning</b>"
- ),
- "privacy_leak_nowarn": (
- "⚠️ <b>This command gives access to your Hikka web interface. It's not"
- " recommended to run it in public group chats. Consider using it in <a"
- " href='tg://openmessage?user_id={}'>Saved messages</a>.</b>"
- ),
- "opening_tunnel": "🔁 <b>Opening tunnel to Hikka web interface...</b>",
- "tunnel_opened": "🎉 <b>Tunnel opened. This link is valid for about 1 hour</b>",
- "web_btn": "🌍 Web interface",
- "btn_yes": "🚸 Open anyway",
- "btn_no": "🔻 Cancel",
- "lavhost_web": (
- "✌️ <b>This link leads to your Hikka web interface on lavHost</b>\n\n<i>💡"
- " You'll need to authorize using lavHost credentials, specified on"
- " registration</i>"
- ),
- "disable_stats": "✅ Anonymous stats allowed",
- "enable_stats": "🚫 Anonymous stats disabled",
- }
- strings_ru = {
- "watchers": "👀 <b>Смотрители:</b>\n\n<b>{}</b>",
- "mod404": "🚫 <b>Смотритель {} не найден</b>",
- "disabled": "👀 <b>Смотритель {} теперь <u>выключен</u></b>",
- "enabled": "👀 <b>Смотритель {} теперь <u>включен</u></b>",
- "args": "🚫 <b>Укажи имя смотрителя</b>",
- "user_nn": "🔰 <b>Состояние NoNick для этого пользователя: {}</b>",
- "no_cmd": "🔰 <b>Укажи команду, для которой надо включить\\выключить NoNick</b>",
- "cmd_nn": "🔰 <b>Состояние NoNick для </b><code>{}</code><b>: {}</b>",
- "cmd404": "🔰 <b>Команда не найдена</b>",
- "inline_settings": "⚙️ <b>Здесь можно управлять настройками Hikka</b>",
- "confirm_update": "🧭 <b>Подтвердите обновление. Юзербот будет перезагружен</b>",
- "confirm_restart": "🔄 <b>Подтвердите перезагрузку</b>",
- "suggest_fs": "✅ Предлагать сохранение модулей",
- "do_not_suggest_fs": "🚫 Предлагать сохранение модулей",
- "use_fs": "✅ Всегда сохранять модули",
- "do_not_use_fs": "🚫 Всегда сохранять модули",
- "btn_restart": "🔄 Перезагрузка",
- "btn_update": "🧭 Обновление",
- "close_menu": "😌 Закрыть меню",
- "custom_emojis": "✅ Кастомные эмодзи",
- "no_custom_emojis": "🚫 Кастомные эмодзи",
- "suggest_subscribe": "✅ Предлагать подписку на канал",
- "do_not_suggest_subscribe": "🚫 Предлагать подписку на канал",
- "private_not_allowed": "🚫 <b>Эту команду нужно выполнять в чате</b>",
- "_cls_doc": "Дополнительные настройки Hikka",
- "nonick_warning": (
- "Внимание! Ты включил NoNick со стандартным префиксом! "
- "Тебя могут замьютить в чатах Hikka. Измени префикс или "
- "отключи глобальный NoNick!"
- ),
- "reply_required": (
- "🚫 <b>Ответь на сообщение пользователя, для которого нужно включить"
- " NoNick</b>"
- ),
- "deauth_confirm": (
- "⚠️ <b>Это действие полностью удалит Hikka с этого аккаунта! Его нельзя"
- " отменить</b>\n\n<i>- Все чаты, связанные с Hikka будут удалены\n- Сессия"
- " Hikka будет сброшена\n- Инлайн бот Hikka будет удален</i>"
- ),
- "deauth_confirm_step2": "⚠️ <b>Ты точно уверен, что хочешь удалить Hikka?</b>",
- "deauth_yes": "Я уверен",
- "deauth_no_1": "Я не уверен",
- "deauth_no_2": "Не точно",
- "deauth_no_3": "Нет",
- "deauth_cancel": "🚫 Отмена",
- "deauth_confirm_btn": "😢 Удалить",
- "uninstall": "😢 <b>Удаляю Hikka...</b>",
- "uninstalled": (
- "😢 <b>Hikka удалена. Веб-интерфейс все еще активен, можно добавить другие"
- " аккаунты!</b>"
- ),
- "logs_cleared": "🗑 <b>Логи очищены</b>",
- "cmd_nn_list": "🔰 <b>NoNick включен для этих команд:</b>\n\n{}",
- "user_nn_list": "🔰 <b>NoNick включен для этих пользователей:</b>\n\n{}",
- "chat_nn_list": "🔰 <b>NoNick включен для этих чатов:</b>\n\n{}",
- "nothing": "🔰 <b>Нечего показывать...</b>",
- "privacy_leak": (
- "⚠️ <b>Эта команда дает доступ к веб-интерфейсу Hikka. Ее выполнение в"
- " публичных чатах является угрозой безопасности. Предпочтительно выполнять"
- " ее в <a href='tg://openmessage?user_id={}'>Избранных сообщениях</a>."
- " Выполни </b><code>{}proxypass force_insecure</code><b> чтобы отключить"
- " это предупреждение</b>"
- ),
- "privacy_leak_nowarn": (
- "⚠️ <b>Эта команда дает доступ к веб-интерфейсу Hikka. Ее выполнение в"
- " публичных чатах является угрозой безопасности. Предпочтительно выполнять"
- " ее в <a href='tg://openmessage?user_id={}'>Избранных сообщениях</a>.</b>"
- ),
- "opening_tunnel": "🔁 <b>Открываю тоннель к веб-интерфейсу Hikka...</b>",
- "tunnel_opened": (
- "🎉 <b>Тоннель открыт. Эта ссылка будет активна не более часа</b>"
- ),
- "web_btn": "🌍 Веб-интерфейс",
- "btn_yes": "🚸 Все равно открыть",
- "btn_no": "🔻 Закрыть",
- "lavhost_web": (
- "✌️ <b>По этой ссылке ты попадешь в веб-интерфейс Hikka на"
- " lavHost</b>\n\n<i>💡 Тебе нужно будет авторизоваться, используя данные,"
- " указанные при настройке lavHost</i>"
- ),
- "disable_stats": "✅ Анонимная стата разрешена",
- "enable_stats": "🚫 Анонимная стата запрещена",
- }
- def get_watchers(self) -> tuple:
- return [
- str(watcher.__self__.__class__.strings["name"])
- for watcher in self.allmodules.watchers
- if watcher.__self__.__class__.strings is not None
- ], self._db.get(main.__name__, "disabled_watchers", {})
- async def _uninstall(self, call: InlineCall):
- await call.edit(self.strings("uninstall"))
- async with self._client.conversation("@BotFather") as conv:
- for msg in [
- "/deletebot",
- f"@{self.inline.bot_username}",
- "Yes, I am totally sure.",
- ]:
- m = await conv.send_message(msg)
- r = await conv.get_response()
- logger.debug(f">> {m.raw_text}")
- logger.debug(f"<< {r.raw_text}")
- await m.delete()
- await r.delete()
- async for dialog in self._client.iter_dialogs(
- None,
- ignore_migrated=True,
- ):
- if (
- dialog.name
- in {
- "hikka-logs",
- "hikka-onload",
- "hikka-assets",
- "hikka-backups",
- "hikka-acc-switcher",
- "silent-tags",
- }
- and dialog.is_channel
- and (
- dialog.entity.participants_count == 1
- or dialog.entity.participants_count == 2
- and dialog.name in {"hikka-logs", "silent-tags"}
- )
- or (
- self._client.loader.inline.init_complete
- and dialog.entity.id == self._client.loader.inline.bot_id
- )
- ):
- await self._client.delete_dialog(dialog.entity)
- folders = await self._client(GetDialogFiltersRequest())
- if any(folder.title == "hikka" for folder in folders):
- folder_id = max(
- folders,
- key=lambda x: x.id,
- ).id
- await self._client(UpdateDialogFilterRequest(id=folder_id))
- for handler in logging.getLogger().handlers:
- handler.setLevel(logging.CRITICAL)
- await self._client.log_out()
- await call.edit(self.strings("uninstalled"))
- if "LAVHOST" in os.environ:
- os.system("lavhost restart")
- return
- atexit.register(restart, *sys.argv[1:])
- sys.exit(0)
- async def _uninstall_confirm_step_2(self, call: InlineCall):
- await call.edit(
- self.strings("deauth_confirm_step2"),
- utils.chunks(
- list(
- sorted(
- [
- {
- "text": self.strings("deauth_yes"),
- "callback": self._uninstall,
- },
- *[
- {
- "text": self.strings(f"deauth_no_{i}"),
- "action": "close",
- }
- for i in range(1, 4)
- ],
- ],
- key=lambda _: random.random(),
- )
- ),
- 2,
- )
- + [
- [
- {
- "text": self.strings("deauth_cancel"),
- "action": "close",
- }
- ]
- ],
- )
- @loader.command(ru_doc="Удалить Hikka")
- async def uninstall_hikka(self, message: Message):
- """Uninstall Hikka"""
- await self.inline.form(
- self.strings("deauth_confirm"),
- message,
- [
- {
- "text": self.strings("deauth_confirm_btn"),
- "callback": self._uninstall_confirm_step_2,
- },
- {"text": self.strings("deauth_cancel"), "action": "close"},
- ],
- )
- @loader.command(ru_doc="Очистить логи")
- async def clearlogs(self, message: Message):
- """Clear logs"""
- for handler in logging.getLogger().handlers:
- handler.buffer = []
- handler.handledbuffer = []
- handler.tg_buff = ""
- await utils.answer(message, self.strings("logs_cleared"))
- @loader.command(ru_doc="Показать активные смотрители")
- async def watchers(self, message: Message):
- """List current watchers"""
- watchers, disabled_watchers = self.get_watchers()
- watchers = [
- f"♻️ {watcher}"
- for watcher in watchers
- if watcher not in list(disabled_watchers.keys())
- ]
- watchers += [f"💢 {k} {v}" for k, v in disabled_watchers.items()]
- await utils.answer(
- message, self.strings("watchers").format("\n".join(watchers))
- )
- @loader.command(ru_doc="<module> - Включить/выключить смотрителя в текущем чате")
- async def watcherbl(self, message: Message):
- """<module> - Toggle watcher in current chat"""
- args = utils.get_args_raw(message)
- if not args:
- await utils.answer(message, self.strings("args"))
- return
- watchers, disabled_watchers = self.get_watchers()
- if args.lower() not in map(lambda x: x.lower(), watchers):
- await utils.answer(message, self.strings("mod404").format(args))
- return
- args = next((x.lower() == args.lower() for x in watchers), False)
- current_bl = [
- v for k, v in disabled_watchers.items() if k.lower() == args.lower()
- ]
- current_bl = current_bl[0] if current_bl else []
- chat = utils.get_chat_id(message)
- if chat not in current_bl:
- if args in disabled_watchers:
- for k in disabled_watchers:
- if k.lower() == args.lower():
- disabled_watchers[k].append(chat)
- break
- else:
- disabled_watchers[args] = [chat]
- await utils.answer(
- message,
- self.strings("disabled").format(args) + " <b>in current chat</b>",
- )
- else:
- for k in disabled_watchers.copy():
- if k.lower() == args.lower():
- disabled_watchers[k].remove(chat)
- if not disabled_watchers[k]:
- del disabled_watchers[k]
- break
- await utils.answer(
- message,
- self.strings("enabled").format(args) + " <b>in current chat</b>",
- )
- self._db.set(main.__name__, "disabled_watchers", disabled_watchers)
- @loader.command(
- ru_doc=(
- "<модуль> - Управление глобальными правилами смотрителя\n"
- "Аргументы:\n"
- "[-c - только в чатах]\n"
- "[-p - только в лс]\n"
- "[-o - только исходящие]\n"
- "[-i - только входящие]"
- )
- )
- async def watchercmd(self, message: Message):
- """<module> - Toggle global watcher rules
- Args:
- [-c - only in chats]
- [-p - only in pm]
- [-o - only out]
- [-i - only incoming]"""
- args = utils.get_args_raw(message)
- if not args:
- return await utils.answer(message, self.strings("args"))
- chats, pm, out, incoming = False, False, False, False
- if "-c" in args:
- args = args.replace("-c", "").replace(" ", " ").strip()
- chats = True
- if "-p" in args:
- args = args.replace("-p", "").replace(" ", " ").strip()
- pm = True
- if "-o" in args:
- args = args.replace("-o", "").replace(" ", " ").strip()
- out = True
- if "-i" in args:
- args = args.replace("-i", "").replace(" ", " ").strip()
- incoming = True
- if chats and pm:
- pm = False
- if out and incoming:
- incoming = False
- watchers, disabled_watchers = self.get_watchers()
- if args.lower() not in [watcher.lower() for watcher in watchers]:
- return await utils.answer(message, self.strings("mod404").format(args))
- args = [watcher for watcher in watchers if watcher.lower() == args.lower()][0]
- if chats or pm or out or incoming:
- disabled_watchers[args] = [
- *(["only_chats"] if chats else []),
- *(["only_pm"] if pm else []),
- *(["out"] if out else []),
- *(["in"] if incoming else []),
- ]
- self._db.set(main.__name__, "disabled_watchers", disabled_watchers)
- await utils.answer(
- message,
- self.strings("enabled").format(args)
- + f" (<code>{disabled_watchers[args]}</code>)",
- )
- return
- if args in disabled_watchers and "*" in disabled_watchers[args]:
- await utils.answer(message, self.strings("enabled").format(args))
- del disabled_watchers[args]
- self._db.set(main.__name__, "disabled_watchers", disabled_watchers)
- return
- disabled_watchers[args] = ["*"]
- self._db.set(main.__name__, "disabled_watchers", disabled_watchers)
- await utils.answer(message, self.strings("disabled").format(args))
- @loader.command(ru_doc="Включить NoNick для определенного пользователя")
- async def nonickuser(self, message: Message):
- """Allow no nickname for certain user"""
- reply = await message.get_reply_message()
- if not reply:
- await utils.answer(message, self.strings("reply_required"))
- return
- u = reply.sender_id
- if not isinstance(u, int):
- u = u.user_id
- nn = self._db.get(main.__name__, "nonickusers", [])
- if u not in nn:
- nn += [u]
- nn = list(set(nn)) # skipcq: PTC-W0018
- await utils.answer(message, self.strings("user_nn").format("on"))
- else:
- nn = list(set(nn) - {u})
- await utils.answer(message, self.strings("user_nn").format("off"))
- self._db.set(main.__name__, "nonickusers", nn)
- @loader.command(ru_doc="Включить NoNick для определенного чата")
- async def nonickchat(self, message: Message):
- """Allow no nickname in certain chat"""
- if message.is_private:
- await utils.answer(message, self.strings("private_not_allowed"))
- return
- chat = utils.get_chat_id(message)
- nn = self._db.get(main.__name__, "nonickchats", [])
- if chat not in nn:
- nn += [chat]
- nn = list(set(nn)) # skipcq: PTC-W0018
- await utils.answer(
- message,
- self.strings("cmd_nn").format(
- utils.escape_html((await message.get_chat()).title),
- "on",
- ),
- )
- else:
- nn = list(set(nn) - {chat})
- await utils.answer(
- message,
- self.strings("cmd_nn").format(
- utils.escape_html((await message.get_chat()).title),
- "off",
- ),
- )
- self._db.set(main.__name__, "nonickchats", nn)
- @loader.command(ru_doc="Включить NoNick для определенной команды")
- async def nonickcmdcmd(self, message: Message):
- """Allow certain command to be executed without nickname"""
- args = utils.get_args_raw(message)
- if not args:
- await utils.answer(message, self.strings("no_cmd"))
- return
- if args not in self.allmodules.commands:
- await utils.answer(message, self.strings("cmd404"))
- return
- nn = self._db.get(main.__name__, "nonickcmds", [])
- if args not in nn:
- nn += [args]
- nn = list(set(nn))
- await utils.answer(
- message,
- self.strings("cmd_nn").format(
- self.get_prefix() + args,
- "on",
- ),
- )
- else:
- nn = list(set(nn) - {args})
- await utils.answer(
- message,
- self.strings("cmd_nn").format(
- self.get_prefix() + args,
- "off",
- ),
- )
- self._db.set(main.__name__, "nonickcmds", nn)
- @loader.command(ru_doc="Показать список активных NoNick команд")
- async def nonickcmds(self, message: Message):
- """Returns the list of NoNick commands"""
- if not self._db.get(main.__name__, "nonickcmds", []):
- await utils.answer(message, self.strings("nothing"))
- return
- await utils.answer(
- message,
- self.strings("cmd_nn_list").format(
- "\n".join(
- [
- f"▫️ <code>{self.get_prefix()}{cmd}</code>"
- for cmd in self._db.get(main.__name__, "nonickcmds", [])
- ]
- )
- ),
- )
- @loader.command(ru_doc="Показать список активных NoNick пользователей")
- async def nonickusers(self, message: Message):
- """Returns the list of NoNick users"""
- users = []
- for user_id in self._db.get(main.__name__, "nonickusers", []).copy():
- try:
- user = await self._client.get_entity(user_id)
- except Exception:
- self._db.set(
- main.__name__,
- "nonickusers",
- list(
- (
- set(self._db.get(main.__name__, "nonickusers", []))
- - {user_id}
- )
- ),
- )
- logger.warning(
- f"User {user_id} removed from nonickusers list", exc_info=True
- )
- continue
- users += [
- "▫️ <b><a"
- f' href="tg://user?id={user_id}">{utils.escape_html(get_display_name(user))}</a></b>'
- ]
- if not users:
- await utils.answer(message, self.strings("nothing"))
- return
- await utils.answer(
- message,
- self.strings("user_nn_list").format("\n".join(users)),
- )
- @loader.command(ru_doc="Показать список активных NoNick чатов")
- async def nonickchats(self, message: Message):
- """Returns the list of NoNick chats"""
- chats = []
- for chat in self._db.get(main.__name__, "nonickchats", []):
- try:
- chat_entity = await self._client.get_entity(int(chat))
- except Exception:
- self._db.set(
- main.__name__,
- "nonickchats",
- list(
- (set(self._db.get(main.__name__, "nonickchats", [])) - {chat})
- ),
- )
- logger.warning(f"Chat {chat} removed from nonickchats list")
- continue
- chats += [
- "▫️ <b><a"
- f' href="{utils.get_entity_url(chat_entity)}">{utils.escape_html(get_display_name(chat_entity))}</a></b>'
- ]
- if not chats:
- await utils.answer(message, self.strings("nothing"))
- return
- await utils.answer(
- message,
- self.strings("user_nn_list").format("\n".join(chats)),
- )
- async def inline__setting(self, call: InlineCall, key: str, state: bool = False):
- if callable(key):
- key()
- telethon.extensions.html.CUSTOM_EMOJIS = not main.get_config_key(
- "disable_custom_emojis"
- )
- else:
- self._db.set(main.__name__, key, state)
- if key == "no_nickname" and state and self.get_prefix() == ".":
- await call.answer(
- self.strings("nonick_warning"),
- show_alert=True,
- )
- else:
- await call.answer("Configuration value saved!")
- await call.edit(
- self.strings("inline_settings"),
- reply_markup=self._get_settings_markup(),
- )
- async def inline__update(
- self,
- call: InlineCall,
- confirm_required: bool = False,
- ):
- if confirm_required:
- await call.edit(
- self.strings("confirm_update"),
- reply_markup=[
- {"text": "🪂 Update", "callback": self.inline__update},
- {"text": "🚫 Cancel", "action": "close"},
- ],
- )
- return
- await call.answer("You userbot is being updated...", show_alert=True)
- await call.delete()
- m = await self._client.send_message("me", f"{self.get_prefix()}update --force")
- await self.allmodules.commands["update"](m)
- async def inline__restart(
- self,
- call: InlineCall,
- confirm_required: bool = False,
- ):
- if confirm_required:
- await call.edit(
- self.strings("confirm_restart"),
- reply_markup=[
- {"text": "🔄 Restart", "callback": self.inline__restart},
- {"text": "🚫 Cancel", "action": "close"},
- ],
- )
- return
- await call.answer("You userbot is being restarted...", show_alert=True)
- await call.delete()
- await self.allmodules.commands["restart"](
- await self._client.send_message("me", f"{self.get_prefix()}restart --force")
- )
- def _get_settings_markup(self) -> list:
- return [
- [
- (
- {
- "text": "✅ NoNick",
- "callback": self.inline__setting,
- "args": (
- "no_nickname",
- False,
- ),
- }
- if self._db.get(main.__name__, "no_nickname", False)
- else {
- "text": "🚫 NoNick",
- "callback": self.inline__setting,
- "args": (
- "no_nickname",
- True,
- ),
- }
- ),
- (
- {
- "text": "✅ Grep",
- "callback": self.inline__setting,
- "args": (
- "grep",
- False,
- ),
- }
- if self._db.get(main.__name__, "grep", False)
- else {
- "text": "🚫 Grep",
- "callback": self.inline__setting,
- "args": (
- "grep",
- True,
- ),
- }
- ),
- (
- {
- "text": "✅ InlineLogs",
- "callback": self.inline__setting,
- "args": (
- "inlinelogs",
- False,
- ),
- }
- if self._db.get(main.__name__, "inlinelogs", True)
- else {
- "text": "🚫 InlineLogs",
- "callback": self.inline__setting,
- "args": (
- "inlinelogs",
- True,
- ),
- }
- ),
- ],
- [
- {
- "text": self.strings("do_not_suggest_fs"),
- "callback": self.inline__setting,
- "args": (
- "disable_modules_fs",
- False,
- ),
- }
- if self._db.get(main.__name__, "disable_modules_fs", False)
- else {
- "text": self.strings("suggest_fs"),
- "callback": self.inline__setting,
- "args": (
- "disable_modules_fs",
- True,
- ),
- }
- ],
- [
- (
- {
- "text": self.strings("use_fs"),
- "callback": self.inline__setting,
- "args": (
- "permanent_modules_fs",
- False,
- ),
- }
- if self._db.get(main.__name__, "permanent_modules_fs", False)
- else {
- "text": self.strings("do_not_use_fs"),
- "callback": self.inline__setting,
- "args": (
- "permanent_modules_fs",
- True,
- ),
- }
- ),
- ],
- [
- (
- {
- "text": self.strings("suggest_subscribe"),
- "callback": self.inline__setting,
- "args": (
- "suggest_subscribe",
- False,
- ),
- }
- if self._db.get(main.__name__, "suggest_subscribe", True)
- else {
- "text": self.strings("do_not_suggest_subscribe"),
- "callback": self.inline__setting,
- "args": (
- "suggest_subscribe",
- True,
- ),
- }
- ),
- ],
- [
- (
- {
- "text": self.strings("no_custom_emojis"),
- "callback": self.inline__setting,
- "args": (
- lambda: main.save_config_key(
- "disable_custom_emojis", False
- ),
- ),
- }
- if main.get_config_key("disable_custom_emojis")
- else {
- "text": self.strings("custom_emojis"),
- "callback": self.inline__setting,
- "args": (
- lambda: main.save_config_key("disable_custom_emojis", True),
- ),
- }
- ),
- ],
- [
- (
- {
- "text": self.strings("disable_stats"),
- "callback": self.inline__setting,
- "args": ("stats", False),
- }
- if self._db.get(main.__name__, "stats", True)
- else {
- "text": self.strings("enable_stats"),
- "callback": self.inline__setting,
- "args": (
- "stats",
- True,
- ),
- }
- ),
- ],
- [
- {
- "text": self.strings("btn_restart"),
- "callback": self.inline__restart,
- "args": (True,),
- },
- {
- "text": self.strings("btn_update"),
- "callback": self.inline__update,
- "args": (True,),
- },
- ],
- [{"text": self.strings("close_menu"), "action": "close"}],
- ]
- @loader.owner
- @loader.command(ru_doc="Показать настройки")
- async def settings(self, message: Message):
- """Show settings menu"""
- await self.inline.form(
- self.strings("inline_settings"),
- message=message,
- reply_markup=self._get_settings_markup(),
- )
- @loader.owner
- @loader.command(ru_doc="Открыть тоннель к веб-интерфейсу Hikka")
- async def weburl(self, message: Message, force: bool = False):
- """Opens web tunnel to your Hikka web interface"""
- if "LAVHOST" in os.environ:
- form = await self.inline.form(
- self.strings("lavhost_web"),
- message=message,
- reply_markup={
- "text": self.strings("web_btn"),
- "url": await main.hikka.web.get_url(proxy_pass=False),
- },
- gif="https://t.me/hikari_assets/28",
- )
- return
- if (
- not force
- and not message.is_private
- and "force_insecure" not in message.raw_text.lower()
- ):
- try:
- if not await self.inline.form(
- self.strings("privacy_leak_nowarn").format(self._client.tg_id),
- message=message,
- reply_markup=[
- {
- "text": self.strings("btn_yes"),
- "callback": self.weburl,
- "args": (True,),
- },
- {"text": self.strings("btn_no"), "action": "close"},
- ],
- gif="https://i.gifer.com/embedded/download/Z5tS.gif",
- ):
- raise Exception
- except Exception:
- await utils.answer(
- message,
- self.strings("privacy_leak").format(
- self._client.tg_id,
- self.get_prefix(),
- ),
- )
- return
- if force:
- form = message
- await form.edit(
- self.strings("opening_tunnel"),
- reply_markup={"text": "🕔 Wait...", "data": "empty"},
- gif=(
- "https://i.gifer.com/origin/e4/e43e1b221fd960003dc27d2f2f1b8ce1.gif"
- ),
- )
- else:
- form = await self.inline.form(
- self.strings("opening_tunnel"),
- message=message,
- reply_markup={"text": "🕔 Wait...", "data": "empty"},
- gif=(
- "https://i.gifer.com/origin/e4/e43e1b221fd960003dc27d2f2f1b8ce1.gif"
- ),
- )
- url = await main.hikka.web.get_url(proxy_pass=True)
- await form.edit(
- self.strings("tunnel_opened"),
- reply_markup={"text": self.strings("web_btn"), "url": url},
- gif="https://t.me/hikari_assets/28",
- )
- @loader.loop(interval=1, autostart=True)
- async def loop(self):
- obj = self.allmodules.get_approved_channel
- if not obj:
- return
- channel, event = obj
- try:
- await self._client(JoinChannelRequest(channel))
- except Exception:
- logger.exception("Failed to join channel")
- event.status = False
- event.set()
- else:
- event.status = True
- event.set()
|