streaming-docker/api/apiserver.py

119 lines
3.2 KiB
Python

import time
import logging
import eventlet
import flask
from flask import g, jsonify, request
from flask_cors import CORS
from flask_socketio import SocketIO
import snowmix
logging.basicConfig(level=logging.INFO)
eventlet.monkey_patch()
app = flask.Flask('snowmix-apiserver')
cors = CORS(app)
socketio = SocketIO(app)
app.snowmix = snowmix.SnowmixClient('snowmix')
app.snowmix.sem = eventlet.Semaphore()
state = {}
def start_updater(name, func, interval=1.0):
def updater():
global state
while True:
try:
data = func()
if state.get(name) != data:
state[name] = data
socketio.emit(name, data, broadcast=True)
except:
logging.exception('Oops?')
time.sleep(interval)
socketio.start_background_task(updater)
start_updater('scenes', (lambda: [app.snowmix.scene_info(s) for s in app.snowmix.scene_list()]), 0.3)
start_updater('feeds', (lambda: app.snowmix.feed_list()), 3.0)
start_updater('images', (lambda: app.snowmix.image_list()), 5.0)
@app.route('/api/1/scenes/')
def scenes():
return jsonify([
app.snowmix.scene_info(s)
for s in app.snowmix.scene_list()
])
@app.route('/api/1/scenes/<int:scene_id>')
def scene_info(scene_id):
return jsonify(app.snowmix.scene_info(scene_id))
def patch_scene(scene_id, req):
if 'alpha' in req:
app.snowmix.scene_alpha(scene_id, req['alpha'], -1)
if 'text_alpha' in req:
app.snowmix.scene_alpha(scene_id, req['text_alpha'], -2)
if 'background_alpha' in req:
app.snowmix.scene_alpha(scene_id, req['background_alpha'], -3)
def patch_frame(scene_id, frame_id, req):
if 'active' in req:
app.snowmix.frame_set_active(scene_id, frame_id, bool(req['active']))
if 'alpha' in req.get('front', {}):
app.snowmix.scene_alpha(scene_id, req['front']['alpha'], frame_id)
if 'alpha' in req.get('back', {}):
app.snowmix.scene_alpha(scene_id, req['back']['alpha'], frame_id, back=True)
if 'source' in req.get('front', {}):
app.snowmix.frame_set_source(scene_id, frame_id, req['front']['source'])
if 'source' in req.get('back', {}):
app.snowmix.frame_set_source(scene_id, frame_id, req['back']['source'], True)
@app.route('/api/1/scenes/<int:scene_id>', methods=['PATCH'])
def scene_patch(scene_id):
req = request.json
patch_scene(scene_id, req)
return 'OK'
@app.route('/api/1/feeds/')
def feeds():
return jsonify(app.snowmix.feed_list())
@app.route('/api/1/images/')
def images():
return jsonify(app.snowmix.image_list())
@socketio.on('connect')
def on_connect():
for k, v in state.items():
socketio.emit(k, v)
@socketio.on('command')
def command(cmd):
pass
@socketio.on('scene_mod')
def on_scene_mod(data):
patch_scene(int(data.pop('id')), data)
@socketio.on('frame_mod')
def on_frame_mod(data):
patch_frame(int(data.pop('scene_id')), int(data.pop('frame_id')), data)
@socketio.on('scene_cut')
def on_scene_cut(data):
app.snowmix.scene_cut(int(data.pop('id')))
@socketio.on('scene_fade')
def on_scene_fade(data):
app.snowmix.scene_fade(int(data.pop('id')))
if __name__ == "__main__":
socketio.run(app, host='0.0.0.0')