From 150cff9b0dcda21c232e8e56f97d76641bb90a39 Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 13 Mar 2015 13:22:50 +0100 Subject: [PATCH] Update modgui code (direct webapp vs using mod-ui), much faster now --- source/carla_modgui.py | 181 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 169 insertions(+), 12 deletions(-) diff --git a/source/carla_modgui.py b/source/carla_modgui.py index 6dc807354..507f405c4 100755 --- a/source/carla_modgui.py +++ b/source/carla_modgui.py @@ -24,6 +24,8 @@ from carla_config import * # ------------------------------------------------------------------------------------------------------------ # Imports (Global) +import json + if config_UseQt5: from PyQt5.QtCore import pyqtSlot, QPoint, QThread, QSize, QUrl from PyQt4.QtGui import QImage, QPainter @@ -35,6 +37,15 @@ else: from PyQt4.QtGui import QMainWindow from PyQt4.QtWebKit import QWebElement, QWebSettings, QWebView +# ------------------------------------------------------------------------------------------------------------ +# Imports (tornado) + +from pystache import render as pyrender +from tornado.gen import engine +from tornado.ioloop import IOLoop +from tornado.web import asynchronous, HTTPError +from tornado.web import Application, RequestHandler, StaticFileHandler + # ------------------------------------------------------------------------------------------------------------ # Imports (Custom) @@ -53,18 +64,19 @@ PORTn = 8998 + int(random()*9000) PORT = str(PORTn) ROOT = "/usr/share" -#ROOT = "/home/falktx/Personal/FOSS/Git-mine/mod-app/source/modules" +ROOT = "/home/falktx/FOSS/GIT-mine/MOD/mod-app/source/modules" DATA_DIR = os.path.expanduser("~/.local/share/mod-data/") +HTML_DIR = os.path.join(ROOT, "mod-ui", "html") os.environ['MOD_DEV_HOST'] = "1" os.environ['MOD_DEV_HMI'] = "1" os.environ['MOD_DESKTOP'] = "1" -os.environ['MOD_LOG'] = "0" +os.environ['MOD_LOG'] = "1" # TESTING os.environ['MOD_DATA_DIR'] = DATA_DIR +os.environ['MOD_HTML_DIR'] = HTML_DIR os.environ['MOD_KEY_PATH'] = os.path.join(DATA_DIR, "keys") os.environ['MOD_CLOUD_PUB'] = os.path.join(ROOT, "mod-ui", "keys", "cloud_key.pub") -os.environ['MOD_HTML_DIR'] = os.path.join(ROOT, "mod-ui", "html") os.environ['MOD_PLUGIN_LIBRARY_DIR'] = os.path.join(DATA_DIR, "lib") os.environ['MOD_DEFAULT_JACK_BUFSIZE'] = "0" @@ -75,25 +87,169 @@ os.environ['MOD_DEVICE_WEBSERVER_PORT'] = PORT # ------------------------------------------------------------------------------------------------------------ # Imports (MOD) -from mod import webserver +from mod.indexing import EffectIndex from mod.lv2 import PluginSerializer -from mod.session import SESSION -# Dummy monitor var, we don't need it -SESSION.monitor_server = "skip" +# ------------------------------------------------------------------------------------------------------------ +# MOD related classes + +class EffectSearcher(RequestHandler): + index = EffectIndex() + + @classmethod + def urls(cls, path): + return [ + (r"/%s/(get)/([a-z0-9]+)?" % path, cls), + ] + + def get(self, action, objid=None): + if action != 'get': + raise HTTPError(404) + + try: + self.set_header('Access-Control-Allow-Origin', self.request.headers['Origin']) + except KeyError: + pass + + self.set_header('Content-Type', 'application/json') + + if objid is None: + objid = self.get_by_url() + + try: + response = self.get_object(objid) + except: + raise HTTPError(404) + + self.write(json.dumps(response)) + + def get_by_url(self): + try: + url = self.request.arguments['url'][0] + except (KeyError, IndexError): + raise HTTPError(404) + + search = self.index.find(url=url) + try: + entry = next(search) + except StopIteration: + raise HTTPError(404) + + return entry['id'] + + def get_object(self, objid): + path = os.path.join(self.index.data_source, objid) + md_path = path + '.metadata' + obj = json.loads(open(path).read()) + if os.path.exists(md_path): + obj.update(json.loads(open(md_path).read())) + return obj + +class EffectGet(EffectSearcher): + @asynchronous + @engine + def get(self, instance_id): + objid = self.get_by_url() + + try: + options = self.get_object(objid) + presets = [] + for _, preset in options['presets'].items(): + presets.append({'label': preset['label']}) + options['presets'] = presets + except: + raise HTTPError(404) + + if self.request.connection.stream.closed(): + return + + self.write(json.dumps(options)) + self.finish() + +class EffectStylesheet(EffectSearcher): + def get(self): + objid = self.get_by_url() + + try: + effect = self.get_object(objid) + except: + raise HTTPError(404) + + try: + path = effect['gui']['stylesheet'] + except: + raise HTTPError(404) + + if not os.path.exists(path): + raise HTTPError(404) + + content = open(path).read() + context = { 'ns': '?url=%s&bundle=%s' % (effect['url'], effect['package']) } + + self.set_header('Content-type', 'text/css') + self.write(pyrender(content, context)) + +class EffectResource(StaticFileHandler, EffectSearcher): + def initialize(self): + # Overrides StaticFileHandler initialize + pass + + def get(self, path): + try: + objid = self.get_by_url() + + try: + options = self.get_object(objid) + except: + raise HTTPError(404) + + try: + document_root = options['gui']['resourcesDirectory'] + except: + raise HTTPError(404) + + super(EffectResource, self).initialize(document_root) + super(EffectResource, self).get(path) + + except HTTPError as e: + if e.status_code != 404: + raise e + + super(EffectResource, self).initialize(os.path.join(HTML_DIR, 'resources')) + super(EffectResource, self).get(path) # ------------------------------------------------------------------------------------------------------------ # WebServer Thread class WebServerThread(QThread): + # signals + running = pyqtSignal() + def __init__(self, parent=None): QThread.__init__(self, parent) + self.fApplication = Application( + EffectSearcher.urls('effect') + + [ + (r"/effect/get/?", EffectGet), + (r"/effect/stylesheet.css", EffectStylesheet), + (r"/resources/(.*)", EffectResource), + (r"/(.*)", StaticFileHandler, {"path": HTML_DIR}), + ], + debug=True) + + self.fPrepareWasCalled = False + def run(self): - webserver.run() + if not self.fPrepareWasCalled: + self.fPrepareWasCalled = True + self.fApplication.listen(PORT, address="0.0.0.0") + + self.running.emit() + IOLoop.instance().start() def stopWait(self): - webserver.stop() + IOLoop.instance().stop() return self.wait(5000) # ------------------------------------------------------------------------------------------------------------ @@ -165,7 +321,8 @@ class HostWindow(QMainWindow): self.fWebview.loadFinished.connect(self.slot_webviewLoadFinished) - url = "http://127.0.0.1:%s/icon.html?v=0#%s" % (PORT, URI) + url = "http://127.0.0.1:%s/icon.html#%s" % (PORT, URI) + print("url:", url) self.fWebview.load(QUrl(url)) # ---------------------------------------------------------------------------------------------------- @@ -488,8 +645,8 @@ if __name__ == '__main__': # ------------------------------------------------------------- # Read CLI args - if len(sys.argv) < 3: - print("usage: %s " % sys.argv[0]) + if len(sys.argv) < 2: + print("usage: %s " % sys.argv[0]) sys.exit(1) libPrefix = os.getenv("CARLA_LIB_PREFIX")