Control socket (WIP)

このコミットが含まれているのは:
n9k 2022-06-12 22:23:17 +00:00
コミット e491f54b24
6個のファイルの変更136行の追加0行の削除

ファイルの表示

@ -59,6 +59,13 @@ def create_app(config_file):
@app.before_serving
async def startup():
# Start control server
from anonstream.control.server import start_control_server_at
async def start_control_server():
return await start_control_server_at(app.config['CONTROL_ADDRESS'])
app.add_background_task(start_control_server)
# Create routes and background tasks
import anonstream.routes
import anonstream.tasks

ファイルの表示

@ -13,6 +13,7 @@ def update_flask_from_toml(toml_config, flask_config):
flask_config.update({
'SECRET_KEY_STRING': toml_config['secret_key'],
'SECRET_KEY': toml_config['secret_key'].encode(),
'CONTROL_ADDRESS': toml_config['control']['address'],
'AUTH_USERNAME': toml_config['auth']['username'],
'AUTH_PWHASH': auth_pwhash,
'AUTH_TOKEN': generate_token(),

0
anonstream/control/__init__.py ノーマルファイル
ファイルの表示

0
anonstream/control/commands.py ノーマルファイル
ファイルの表示

125
anonstream/control/server.py ノーマルファイル
ファイルの表示

@ -0,0 +1,125 @@
import asyncio
import json
from anonstream.stream import get_stream_title
def start_control_server_at(address):
return asyncio.start_unix_server(
handle_control_client,
address,
)
async def handle_control_client(reader, writer):
while line := await reader.readline():
try:
request = line.decode('utf-8')
except UnicodeDecodeError as e:
response = f'error: {e}'
else:
method, args, normal, response = await parse(request)
if method is None:
pass
elif normal is not None:
writer.write(f'{normal}\n'.encode())
elif response is not None:
writer.write(f'error: '.encode())
if response is not None:
writer.write(response.encode())
await writer.drain()
else:
writer.close()
break
async def parse(request):
try:
method, *args = request.split()
except ValueError:
method, args, normal, response = None, [], None, ''
else:
match method:
case 'help':
normal_args, response = await parse_help(args)
case 'exit':
normal_args, response = await parse_exit(args)
case 'title':
normal_args, response = await parse_title(args)
case _:
normal_args = None
response = f"method {method!r} is unknown, try 'help'\n"
if normal_args is None:
normal = None
if response is None:
response = f"command {args[0]!r} is unknown, try {f'{method} help'!r}\n"
elif len(normal_args) == 0:
normal = method
else:
normal = f'{method} {" ".join(normal_args)}' or method
return method, args, normal, response
async def parse_help(args):
match args:
case []:
normal_args = []
response = (
'Usage: METHOD {COMMAND | help}\n'
'Examples:\n'
' help.......................show this help message\n'
' exit.......................close the connection\n'
' title [show [CODEC]].......show the stream title\n'
' title set TITLE............set the stream title\n'
' user [show]................show a list of users\n'
' user set USER ATTR VALUE...set an attribute of a user\n'
)
case ['help']:
normal_args = ['help']
response = (
'Usage: help\n'
'show usage syntax and examples\n'
)
case _:
normal_args = None
response = None
return normal_args, response
async def parse_exit(args):
match args:
case []:
normal_args = []
response = None
case ['help']:
normal_args = ['help']
response = (
'Usage: {exit | quit}\n'
'close the connection\n'
)
case _:
normal_args = None
response = None
return normal_args, response
async def parse_title(args):
match args:
case [] | ['show'] | ['show', 'json']:
normal_args = ['show', 'json']
response = json.dumps(await get_stream_title()) + '\n'
case ['show', 'utf-8']:
normal_args = ['show']
response = await get_stream_title() + '\n'
case ['show', arg, *_]:
normal_args = None
response = f"option {arg!r} is unknown, try 'title help'\n"
case ['help']:
normal_args = ['help']
response = (
'Usage: title {show [CODEC] | set TITLE}\n'
'Commands:\n'
' title show [CODEC].....show the stream title\n'
' title set TITLE........set the stream title to TITLE collapsing whitespace\n'
'Arguments:\n'
' CODEC..................=[utf-8 | json]\n'
' TITLE..................a UTF-8-encoded string\n'
)
case _:
normal_args = None
response = None
return normal_args, response

ファイルの表示

@ -1,5 +1,8 @@
secret_key = "place secret key here"
[control]
address = "control.sock"
[auth]
username = "broadcaster"