"""Callbacks for matrix messages""" import html import time import traceback from mab import * # type: ignore import util from database import Database from datatypes import * # # PRIVATE # _db: Database = None # type: ignore _COMMANDS = { "help": "Получить справку", "info": "Получить сведения о комнате", "tokens": "Получить список токенов", "auth": "Создать новый токен", "deauth": "Удалить существующий токен", "name": "Задать (или удалить) имя для токена", "ban": "Забанить IP адрес", "unban": "Разбанить IP адрес", "bans": "Получить список забаненных IP адресов", "short": "(Небезопасно) Создать токен-имя", } def _generate_help_message() -> str: """Generates help message in HTML markup""" result = "Как использовать
    " result += "
  1. Используя !auth, создайте токен
  2. " result += "
  3. Добавьте бота в комнату для уведомлений
  4. " result += "
  5. Выполните !info в комнате, чтобы узнать код канала уведомений
  6. " result += "
  7. Используя полученные токен и код канала, отправьте уведомление через веб-запрос
  8. " result += "
" result += "

Команды" for key in _COMMANDS: result += f"
!{key} - {html.escape(_COMMANDS[key])}" return result # # COMMAND HANDLERS # async def _on_cmd_help(ctx: EventContext) -> None: """!help""" await ctx.bot.send_text(ctx.room, _generate_help_message()) async def _on_cmd_info(ctx: EventContext) -> None: """!info""" # get room info (or add it) room_info = await _db.room_get(ctx.room.room_id) if room_info is None: room_info = await _db.room_create(ctx.room.room_id) # failure if room_info is None: await ctx.bot.send_text( ctx.room, "Нет информации о комнате" ) return # respond response = "Сведения о комнате
" response += f"Канал: {html.escape(room_info.code)}" await ctx.bot.send_text(ctx.room, response) async def _on_cmd_tokens(ctx: EventContext) -> None: """!info""" # get all tokens and check if there are none tokens = await _db.token_get_all() if not tokens: await ctx.bot.send_text( ctx.room, "Нет токенов, используйте !auth" ) return # create the list of tokens response = "Список токенов" for token in tokens: response += f"
{html.escape(token.code)}
" # respond await ctx.bot.send_text(ctx.room, response) async def _on_cmd_auth(ctx: EventContext) -> None: """!auth""" # create new token token = await _db.token_create() # set the name if it is provided if ctx[CTX_CMD_ARGS]: token.name = " ".join(ctx[CTX_CMD_ARGS]) await _db.token_set_name(token.code, token.name) # create the response response = "Создан новый токен" response += f"
Код: {token.code}" response += f"
Имя сервиса: " if token.name: response += f"{html.escape(token.name)}" else: response += "указывается в запросе" # respond await ctx.bot.send_text(ctx.room, response) async def _on_cmd_deauth(ctx: EventContext) -> None: """!deauth""" # no token provided if len(ctx[CTX_CMD_ARGS]) != 1: await ctx.bot.send_text(ctx.room, "Укажите токен, который надо удалить (должен быть ровно один аргумент)") return token = ctx[CTX_CMD_ARGS][0] # check if token does not exist if await _db.token_get(token) is None: await ctx.bot.send_text(ctx.room, "Токен не найден") return # remove the token await _db.token_delete(token) # respond response = f"Удалён токен {token}" await ctx.bot.send_text(ctx.room, response) async def _on_cmd_name(ctx: EventContext) -> None: """!name""" # check arguments if len(ctx[CTX_CMD_ARGS]) < 1: error = "Требуется указать как минимум токен. Если хотите убрать имя, то имя указывать не надо. Если имя нужно назначить или изменить, то после токена укажите новое имя." await ctx.bot.send_text(ctx.room, error) return token = ctx[CTX_CMD_ARGS][0] new_name = " ".join(ctx[CTX_CMD_ARGS][1:]) if not new_name.strip(): new_name = None # check if token exists if await _db.token_get(token) is None: await ctx.bot.send_text(ctx.room, "Токен не существует") return # set new name await _db.token_set_name(token, new_name) # prepare the response if new_name: response = f"Новое имя для токена {token}: {new_name}" else: response = f"Удалено имя для токена {token}" # respond await ctx.bot.send_text(ctx.room, response) async def _on_cmd_ban(ctx: EventContext) -> None: """!ban""" # check arguments if len(ctx[CTX_CMD_ARGS]) < 2: error = "Формат: !ban <IP> <SECONDS> [REASON]" await ctx.bot.send_text(ctx.room, error) return # get event.command_args try: ip = ctx[CTX_CMD_ARGS][0] duration = float(ctx[CTX_CMD_ARGS][1]) reason = " ".join(ctx[CTX_CMD_ARGS][2:]) if ctx[CTX_CMD_ARGS][2:] else "Manual ban" except: error = "Возникла ошибка. Наверняка неправильно указаны секунды." await ctx.bot.send_text(ctx.room, error) return # ban try: await _db.ban_create(ip, time.time() + duration, reason) await ctx.bot.send_text(ctx.room, "IP адрес заблокирован") except: await ctx.bot.send_text(ctx.room, "Возникла ошибка") async def _on_cmd_unban(ctx: EventContext) -> None: """!unban""" # check arguments if len(ctx[CTX_CMD_ARGS]) != 1: error = "Формат: !ban <IP>" await ctx.bot.send_text(ctx.room, error) return # unban try: await _db.ban_delete(ctx[CTX_CMD_ARGS][0]) await ctx.bot.send_text(ctx.room, "IP адрес разблокирован (если он был заблокирован)") except: await ctx.bot.send_text(ctx.room, "Возникла ошибка") async def _on_cmd_bans(ctx: EventContext) -> None: """!bans""" # list bans = _db.ban_get_all() if not bans: await ctx.bot.send_text(ctx.room, "Нет заблокированных IP адресов") return # create the response result = "Список заблокированных IP
" await ctx.bot.send_text(ctx.room, result) async def _on_cmd_short(ctx: EventContext) -> None: """!auth""" # get token to use if len(ctx[CTX_CMD_ARGS]) != 1: error = "Формат: !short <token>" await ctx.bot.send_text(ctx.room, error) return # create new token try: token = await _db.token_create(ctx[CTX_CMD_ARGS][0]) except Exception as e: await ctx.bot.send_text(ctx.room, f"Не удалось создать токен: {" ".join(e.args)}") return # create the response response = "Создан новый токен" response += f"
Код: {token.code}" response += f"
Имя сервиса: указывается в запросе" # respond await ctx.bot.send_text(ctx.room, response) # # PUBLIC # def setup(bot: MatrixBot, db: Database) -> None: """Setup the callbacks""" global _db _db = db bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["info", "room", "i", "r"]), _on_cmd_info ) bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["tokens", "t"]), _on_cmd_tokens ) bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["auth", "create", "a", "c"]), _on_cmd_auth ) bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["deauth", "delete", "d"]), _on_cmd_deauth ) bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["name", "n"]), _on_cmd_name ) bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["ban", "b"]), _on_cmd_ban ) bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["unban", "u"]), _on_cmd_unban ) bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["bans", "l"]), _on_cmd_bans ) bot.add_callback( ~SenderIsBotFilter() & BodyCommandFilter(["short", "s"]), _on_cmd_short ) bot.add_callback( ~SenderIsBotFilter() & NewMessageFilter(), _on_cmd_help )