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/') 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/', 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')