Control socket: reload emotes
このコミットが含まれているのは:
コミット
51ff285067
|
@ -5,6 +5,7 @@ from anonstream.control.spec import ParseException, Parsed
|
||||||
from anonstream.control.spec.common import Str
|
from anonstream.control.spec.common import Str
|
||||||
from anonstream.control.spec.methods.allowedness import SPEC as SPEC_ALLOWEDNESS
|
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.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.help import SPEC as SPEC_HELP
|
||||||
from anonstream.control.spec.methods.quit import SPEC as SPEC_QUIT
|
from anonstream.control.spec.methods.quit import SPEC as SPEC_QUIT
|
||||||
from anonstream.control.spec.methods.title import SPEC as SPEC_TITLE
|
from anonstream.control.spec.methods.title import SPEC as SPEC_TITLE
|
||||||
|
@ -17,6 +18,7 @@ SPEC = Str({
|
||||||
'chat': SPEC_CHAT,
|
'chat': SPEC_CHAT,
|
||||||
'user': SPEC_USER,
|
'user': SPEC_USER,
|
||||||
'allowednesss': SPEC_ALLOWEDNESS,
|
'allowednesss': SPEC_ALLOWEDNESS,
|
||||||
|
'emote': SPEC_EMOTE,
|
||||||
})
|
})
|
||||||
|
|
||||||
async def parse(request):
|
async def parse(request):
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
# SPDX-FileCopyrightText: 2022 n9k <https://git.076.ne.jp/ninya9k>
|
||||||
|
# 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),
|
||||||
|
})
|
||||||
|
|
|
@ -24,6 +24,7 @@ async def cmd_help():
|
||||||
' allowedness setdefault BOOLEAN.set the default allowedness\n'
|
' allowedness setdefault BOOLEAN.set the default allowedness\n'
|
||||||
' allowedness add SET STRING.....add to the blacklist/whitelist\n'
|
' allowedness add SET STRING.....add to the blacklist/whitelist\n'
|
||||||
' allowedness remove SET STRING..remove from 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
|
return normal, response
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import json
|
import json
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
import aiofiles
|
||||||
from quart import escape
|
from quart import escape
|
||||||
|
|
||||||
class BadEmote(Exception):
|
class BadEmote(Exception):
|
||||||
|
@ -9,15 +10,23 @@ class BadEmote(Exception):
|
||||||
class BadEmoteName(BadEmote):
|
class BadEmoteName(BadEmote):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def _load_emote_schema(emotes):
|
||||||
|
for key in ('name', 'file', 'width', 'height'):
|
||||||
|
for emote in emotes:
|
||||||
|
if key not in emote:
|
||||||
|
raise BadEmote(f'emotes must have a `{key}`: {emote}')
|
||||||
|
precompute_emote_regex(emotes)
|
||||||
|
return emotes
|
||||||
|
|
||||||
def load_emote_schema(filepath):
|
def load_emote_schema(filepath):
|
||||||
with open(filepath) as fp:
|
with open(filepath) as fp:
|
||||||
emotes = json.load(fp)
|
emotes = json.load(fp)
|
||||||
for key in ('name', 'file', 'width', 'height'):
|
return _load_emote_schema(emotes)
|
||||||
for emote in emotes:
|
|
||||||
if key not in emote:
|
async def load_emote_schema_async(filepath):
|
||||||
raise BadEmote(f'emotes must have a `{key}`: {emote}')
|
async with aiofiles.open(filepath) as fp:
|
||||||
precompute_emote_regex(emotes)
|
data = await fp.read(8192)
|
||||||
return emotes
|
return _load_emote_schema(json.loads(data))
|
||||||
|
|
||||||
def precompute_emote_regex(schema):
|
def precompute_emote_regex(schema):
|
||||||
for emote in schema:
|
for emote in schema:
|
||||||
|
|
読み込み中…
新しいイシューから参照