diff --git a/mautrix_telegram/commands/portal.py b/mautrix_telegram/commands/portal.py index 43cdca76..ede472e3 100644 --- a/mautrix_telegram/commands/portal.py +++ b/mautrix_telegram/commands/portal.py @@ -14,7 +14,7 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from typing import Dict, Callable, Optional, Tuple, Coroutine +from typing import Dict, Callable, Optional, Tuple, Coroutine, Awaitable from io import StringIO import asyncio @@ -396,13 +396,38 @@ async def upgrade(evt: CommandEvent) -> Dict: @command_handler(help_section=SECTION_PORTAL_MANAGEMENT, help_text="View or change per-portal settings.", help_args="<`help`|_subcommand_> [...]") -async def config(evt: CommandEvent) -> Dict: +async def config(evt: CommandEvent) -> None: cmd = evt.args[0].lower() if len(evt.args) > 0 else "help" - portal = po.Portal.get_by_mxid(evt.room_id) - if not portal and cmd != "help": - return await evt.reply("This is not a portal room.") if cmd not in ("view", "defaults", "set", "unset", "add", "del"): - return await evt.reply("""**Usage:** `$cmdprefix config [...]`. Subcommands: + await config_help(evt) + return + elif cmd == "defaults": + await config_defaults(evt) + return + + portal = po.Portal.get_by_mxid(evt.room_id) + if not portal: + await evt.reply("This is not a portal room.") + return + elif cmd == "view": + await config_view(evt, portal) + return + + key = evt.args[1] if len(evt.args) > 1 else None + value = yaml.load(" ".join(evt.args[2:])) if len(evt.args) > 2 else None + if cmd == "set": + await config_set(evt, portal, key, value) + elif cmd == "unset": + await config_unset(evt, portal, key) + elif cmd == "add" or cmd == "del": + await config_add_del(evt, portal, key, value, cmd) + else: + return + portal.save() + + +def config_help(evt: CommandEvent) -> Awaitable[Dict]: + return evt.reply("""**Usage:** `$cmdprefix config [...]`. Subcommands: * **help** - View this help text. * **view** - View the current config data. @@ -412,66 +437,73 @@ async def config(evt: CommandEvent) -> Dict: * **add** <_key_> <_value_> - Add a value to an array. * **del** <_key_> <_value_> - Remove a value from an array. """) - elif cmd == "view": - stream = StringIO() - yaml.dump(portal.local_config, stream) - return await evt.reply(f"Room-specific config:\n\n```yaml\n{stream.getvalue()}\n```", - allow_html=True) - elif cmd == "defaults": - stream = StringIO() - yaml.dump({ - "edits_as_replies": evt.config["bridge.edits_as_replies"], - "bridge_notices": { - "default": evt.config["bridge.bridge_notices.default"], - "exceptions": evt.config["bridge.bridge_notices.exceptions"], - }, - "bot_messages_as_notices": evt.config["bridge.bot_messages_as_notices"], - "inline_images": evt.config["bridge.inline_images"], - "native_stickers": evt.config["bridge.native_stickers"], - "message_formats": evt.config["bridge.message_formats"], - "state_event_formats": evt.config["bridge.state_event_formats"], - }, stream) - return await evt.reply(f"Bridge instance wide config:\n\n```yaml\n{stream.getvalue()}```", - allow_html=True) - key = evt.args[1] if len(evt.args) > 1 else None - value = yaml.load(" ".join(evt.args[2:])) if len(evt.args) > 2 else None - if cmd == "set": - if not key or value is None: - return await evt.reply(f"**Usage:** `$cmdprefix+sp config {cmd} `") - elif util.recursive_set(portal.local_config, key, value): - return await evt.reply(f"Successfully set the value of `{key}` to `{value}`.") - else: - return await evt.reply(f"Failed to set value of `{key}`. " - "Does the path contain non-map types?") - elif cmd == "unset": - if not key: - return await evt.reply(f"**Usage:** `$cmdprefix+sp config {cmd} `") - elif util.recursive_del(portal.local_config, key): - return await evt.reply(f"Successfully deleted `{key}` from config.") - else: - return await evt.reply(f"`{key}` not found in config.") - elif cmd == "add" or cmd == "del": - if not key or value is None: - return await evt.reply(f"**Usage:** `$cmdprefix+sp config {cmd} `") - arr = util.recursive_get(portal.local_config, key) - if not arr: - return await evt.reply(f"`{key}` not found in config. " - f"Maybe do `$cmdprefix+sp config set {key} []` first?") - elif not isinstance(arr, list): - return await evt.reply("`{key}` does not seem to be an array.") - elif cmd == "add": - if value in arr: - return await evt.reply(f"The array at `{key}` already contains `{value}`.") - arr.append(value) - return await evt.reply(f"Successfully added `{value}` to the array at `{key}`") - else: - if value not in arr: - return await evt.reply(f"The array at `{key}` does not contain `{value}`.") - arr.remove(value) - return await evt.reply(f"Successfully removed `{value}` from the array at `{key}`") - portal.save() +def config_view(evt: CommandEvent, portal: po.Portal) -> Awaitable[Dict]: + stream = StringIO() + yaml.dump(portal.local_config, stream) + return evt.reply(f"Room-specific config:\n\n```yaml\n{stream.getvalue()}```", + allow_html=True) + + +def config_defaults(evt: CommandEvent) -> Awaitable[Dict]: + stream = StringIO() + yaml.dump({ + "edits_as_replies": evt.config["bridge.edits_as_replies"], + "bridge_notices": { + "default": evt.config["bridge.bridge_notices.default"], + "exceptions": evt.config["bridge.bridge_notices.exceptions"], + }, + "bot_messages_as_notices": evt.config["bridge.bot_messages_as_notices"], + "inline_images": evt.config["bridge.inline_images"], + "native_stickers": evt.config["bridge.native_stickers"], + "message_formats": evt.config["bridge.message_formats"], + "state_event_formats": evt.config["bridge.state_event_formats"], + }, stream) + return evt.reply(f"Bridge instance wide config:\n\n```yaml\n{stream.getvalue()}```", + allow_html=True) + + +def config_set(evt: CommandEvent, portal: po.Portal, key: str, value: str) -> Awaitable[Dict]: + if not key or value is None: + return evt.reply(f"**Usage:** `$cmdprefix+sp config set `") + elif util.recursive_set(portal.local_config, key, value): + return evt.reply(f"Successfully set the value of `{key}` to `{value}`.") + else: + return evt.reply(f"Failed to set value of `{key}`. " + "Does the path contain non-map types?") + + +def config_unset(evt: CommandEvent, portal: po.Portal, key: str) -> Awaitable[Dict]: + if not key: + return evt.reply(f"**Usage:** `$cmdprefix+sp config unset `") + elif util.recursive_del(portal.local_config, key): + return evt.reply(f"Successfully deleted `{key}` from config.") + else: + return evt.reply(f"`{key}` not found in config.") + + +def config_add_del(evt: CommandEvent, portal: po.Portal, key: str, value: str, cmd: str + ) -> Awaitable[Dict]: + if not key or value is None: + return evt.reply(f"**Usage:** `$cmdprefix+sp config {cmd} `") + + arr = util.recursive_get(portal.local_config, key) + if not arr: + return evt.reply(f"`{key}` not found in config. " + f"Maybe do `$cmdprefix+sp config set {key} []` first?") + elif not isinstance(arr, list): + return evt.reply("`{key}` does not seem to be an array.") + elif cmd == "add": + if value in arr: + return evt.reply(f"The array at `{key}` already contains `{value}`.") + arr.append(value) + return evt.reply(f"Successfully added `{value}` to the array at `{key}`") + else: + if value not in arr: + return evt.reply(f"The array at `{key}` does not contain `{value}`.") + arr.remove(value) + return evt.reply(f"Successfully removed `{value}` from the array at `{key}`") @command_handler(help_section=SECTION_PORTAL_MANAGEMENT, diff --git a/mautrix_telegram/portal.py b/mautrix_telegram/portal.py index b7303316..789104f2 100644 --- a/mautrix_telegram/portal.py +++ b/mautrix_telegram/portal.py @@ -983,9 +983,9 @@ class Portal: if msgtype == "m.notice": bridge_notices = self.get_config("bridge_notices") - if not bridge_notices.get("default", False): - if sender_id not in bridge_notices.get("exceptions"): - return + if not bridge_notices.get("default", False) and sender_id not in bridge_notices.get( + "exceptions"): + return if msgtype == "m.text": await self._handle_matrix_text(sender_id, event_id, space, client, message, reply_to)