From f83cf4308e2644c8bc3ec37e2bc9e0ffbc062c35 Mon Sep 17 00:00:00 2001 From: n9k Date: Mon, 1 Aug 2022 00:42:04 +0000 Subject: [PATCH] Control socket: reload emotes --- anonstream/control/parse.py | 2 + anonstream/control/spec/methods/emote.py | 51 ++++++++++++++++++++++++ anonstream/control/spec/methods/help.py | 1 + anonstream/emote.py | 8 ++++ 4 files changed, 62 insertions(+) create mode 100644 anonstream/control/spec/methods/emote.py diff --git a/anonstream/control/parse.py b/anonstream/control/parse.py index de30db3..7acf77f 100644 --- a/anonstream/control/parse.py +++ b/anonstream/control/parse.py @@ -5,6 +5,7 @@ from anonstream.control.spec import ParseException, Parsed from anonstream.control.spec.common import Str from anonstream.control.spec.methods.allowedness import SPEC as SPEC_ALLOWEDNESS from anonstream.control.spec.methods.chat import SPEC as SPEC_CHAT +from anonstream.control.spec.methods.emote import SPEC as SPEC_EMOTE from anonstream.control.spec.methods.help import SPEC as SPEC_HELP from anonstream.control.spec.methods.quit import SPEC as SPEC_QUIT from anonstream.control.spec.methods.title import SPEC as SPEC_TITLE @@ -17,6 +18,7 @@ SPEC = Str({ 'chat': SPEC_CHAT, 'user': SPEC_USER, 'allowednesss': SPEC_ALLOWEDNESS, + 'emote': SPEC_EMOTE, }) async def parse(request): diff --git a/anonstream/control/spec/methods/emote.py b/anonstream/control/spec/methods/emote.py new file mode 100644 index 0000000..8318ad4 --- /dev/null +++ b/anonstream/control/spec/methods/emote.py @@ -0,0 +1,51 @@ +# SPDX-FileCopyrightText: 2022 n9k +# SPDX-License-Identifier: AGPL-3.0-or-later + +import json + +from quart import current_app + +from anonstream.emote import load_emote_schema_async, BadEmote +from anonstream.helpers.emote import get_emote_markup +from anonstream.control.spec.common import Str, End +from anonstream.control.exceptions import CommandFailed + +CONFIG = current_app.config +EMOTES = current_app.emotes + +async def cmd_emote_help(): + normal = ['emote', 'help'] + response = ( + 'Usage: emote reload\n' + 'Commands:\n' + ' emote reload......try to reload the emote schema (existing messages are not modified)\n' + ) + return normal, response + +async def cmd_emote_reload(): + try: + emotes = await load_emote_schema_async(CONFIG['EMOTE_SCHEMA']) + except OSError as e: + raise CommandFailed(f'could not read emote schema: {e}') from e + except json.JSONDecodeError as e: + raise CommandFailed('could not decode emote schema as json') from e + except BadEmote as e: + error, *_ = e.args + raise CommandFailed(error) from e + else: + # Mutate current_app.emotes in place + EMOTES.clear() + for emote in emotes: + EMOTES.append(emote) + # Clear emote markup cache -- emotes by the same name may have changed + get_emote_markup.cache_clear() + normal = ['emote', 'reload'] + response = '' + return normal, response + +SPEC = Str({ + None: End(cmd_emote_help), + 'help': End(cmd_emote_help), + 'reload': End(cmd_emote_reload), +}) + diff --git a/anonstream/control/spec/methods/help.py b/anonstream/control/spec/methods/help.py index ab0e5c7..2cd7d2f 100644 --- a/anonstream/control/spec/methods/help.py +++ b/anonstream/control/spec/methods/help.py @@ -24,6 +24,7 @@ async def cmd_help(): ' allowedness setdefault BOOLEAN.set the default allowedness\n' ' allowedness add SET STRING.....add to the blacklist/whitelist\n' ' allowedness remove SET STRING..remove from the blacklist/whitelist\n' + ' emote reload...................try reloading the emote schema\n' ) return normal, response diff --git a/anonstream/emote.py b/anonstream/emote.py index 26bc5dc..cd5c5cd 100644 --- a/anonstream/emote.py +++ b/anonstream/emote.py @@ -1,6 +1,7 @@ import json import re +import aiofiles from quart import escape class BadEmote(Exception): @@ -19,6 +20,13 @@ def load_emote_schema(filepath): precompute_emote_regex(emotes) return emotes +async def load_emote_schema_async(filepath): + async with aiofiles.open(filepath) as fp: + data = await fp.read(8192) + emotes = json.loads(data) + precompute_emote_regex(emotes) + return emotes + def precompute_emote_regex(schema): for emote in schema: if not emote['name']: