| 
							- #!/usr/bin/env python3
 - # -*- coding: utf-8 -*-
 - 
 - # Carla bridge for LV2 modguis
 - # Copyright (C) 2015-2019 Filipe Coelho <falktx@falktx.com>
 - #
 - # This program is free software; you can redistribute it and/or
 - # modify it under the terms of the GNU General Public License as
 - # published by the Free Software Foundation; either version 2 of
 - # the License, or any later version.
 - #
 - # This program is distributed in the hope that it will be useful,
 - # but WITHOUT ANY WARRANTY; without even the implied warranty of
 - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 - # GNU General Public License for more details.
 - #
 - # For a full copy of the GNU General Public License see the doc/GPL.txt file.
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - # Imports (Global)
 - 
 - import os
 - 
 - from PyQt5.QtCore import pyqtSignal, QThread
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - # Generate a random port number between 9000 and 18000
 - 
 - from random import random
 - 
 - PORTn = 8998 + int(random()*9000)
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - # Imports (tornado)
 - 
 - from tornado.log import enable_pretty_logging
 - from tornado.ioloop import IOLoop
 - from tornado.util import unicode_type
 - from tornado.web import HTTPError
 - from tornado.web import Application, RequestHandler, StaticFileHandler
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - # Set up environment for the webserver
 - 
 - PORT     = str(PORTn)
 - ROOT     = "/usr/share/mod"
 - DATA_DIR = os.path.expanduser("~/.local/share/mod-data/")
 - HTML_DIR = os.path.join(ROOT, "html")
 - 
 - os.environ['MOD_DEV_HOST'] = "1"
 - os.environ['MOD_DEV_HMI']  = "1"
 - os.environ['MOD_DESKTOP']  = "1"
 - 
 - 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, "keys", "cloud_key.pub")
 - os.environ['MOD_PLUGIN_LIBRARY_DIR'] = os.path.join(DATA_DIR, "lib")
 - 
 - os.environ['MOD_PHANTOM_BINARY']        = "/usr/bin/phantomjs"
 - os.environ['MOD_SCREENSHOT_JS']         = os.path.join(ROOT, "screenshot.js")
 - os.environ['MOD_DEVICE_WEBSERVER_PORT'] = PORT
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - # Imports (MOD)
 - 
 - from mod.utils import get_plugin_info, get_plugin_gui, get_plugin_gui_mini, init as lv2_init
 - 
 - # ------------------------------------------------------------------------------------------------------------
 - # MOD related classes
 - 
 - class JsonRequestHandler(RequestHandler):
 -     def write(self, data):
 -         if isinstance(data, (bytes, unicode_type, dict)):
 -             RequestHandler.write(self, data)
 -             self.finish()
 -             return
 - 
 -         elif data is True:
 -             data = "true"
 -             self.set_header("Content-Type", "application/json; charset=UTF-8")
 - 
 -         elif data is False:
 -             data = "false"
 -             self.set_header("Content-Type", "application/json; charset=UTF-8")
 - 
 -         else:
 -             data = json.dumps(data)
 -             self.set_header("Content-Type", "application/json; charset=UTF-8")
 - 
 -         RequestHandler.write(self, data)
 -         self.finish()
 - 
 - class EffectGet(JsonRequestHandler):
 -     def get(self):
 -         uri = self.get_argument('uri')
 - 
 -         try:
 -             data = get_plugin_info(uri)
 -         except:
 -             print("ERROR: get_plugin_info for '%s' failed" % uri)
 -             raise HTTPError(404)
 - 
 -         self.write(data)
 - 
 - class EffectFile(StaticFileHandler):
 -     def initialize(self):
 -         # return custom type directly. The browser will do the parsing
 -         self.custom_type = None
 - 
 -         uri = self.get_argument('uri')
 - 
 -         try:
 -             self.modgui = get_plugin_gui(uri)
 -         except:
 -             raise HTTPError(404)
 - 
 -         try:
 -             root = self.modgui['resourcesDirectory']
 -         except:
 -             raise HTTPError(404)
 - 
 -         return StaticFileHandler.initialize(self, root)
 - 
 -     def parse_url_path(self, prop):
 -         try:
 -             path = self.modgui[prop]
 -         except:
 -             raise HTTPError(404)
 - 
 -         if prop in ("iconTemplate", "settingsTemplate", "stylesheet", "javascript"):
 -             self.custom_type = "text/plain"
 - 
 -         return path
 - 
 -     def get_content_type(self):
 -         if self.custom_type is not None:
 -             return self.custom_type
 -         return StaticFileHandler.get_content_type(self)
 - 
 - class EffectResource(StaticFileHandler):
 - 
 -     def initialize(self):
 -         # Overrides StaticFileHandler initialize
 -         pass
 - 
 -     def get(self, path):
 -         try:
 -             uri = self.get_argument('uri')
 -         except:
 -             return self.shared_resource(path)
 - 
 -         try:
 -             modgui = get_plugin_gui_mini(uri)
 -         except:
 -             raise HTTPError(404)
 - 
 -         try:
 -             root = modgui['resourcesDirectory']
 -         except:
 -             raise HTTPError(404)
 - 
 -         try:
 -             super(EffectResource, self).initialize(root)
 -             return super(EffectResource, self).get(path)
 -         except HTTPError as e:
 -             if e.status_code != 404:
 -                 raise e
 -             return self.shared_resource(path)
 -         except IOError:
 -             raise HTTPError(404)
 - 
 -     def shared_resource(self, path):
 -         super(EffectResource, self).initialize(os.path.join(HTML_DIR, 'resources'))
 -         return 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(
 -             [
 -                 (r"/effect/get/?", EffectGet),
 -                 (r"/effect/file/(.*)", EffectFile),
 -                 (r"/resources/(.*)", EffectResource),
 -                 (r"/(.*)", StaticFileHandler, {"path": HTML_DIR}),
 -             ],
 -             debug=True)
 - 
 -         self.fPrepareWasCalled = False
 - 
 -     def run(self):
 -         if not self.fPrepareWasCalled:
 -             self.fPrepareWasCalled = True
 -             self.fApplication.listen(PORT, address="0.0.0.0")
 -             if int(os.getenv("MOD_LOG", "0")):
 -                 enable_pretty_logging()
 - 
 -         self.running.emit()
 -         IOLoop.instance().start()
 - 
 -     def stopWait(self):
 -         IOLoop.instance().stop()
 -         return self.wait(5000)
 
 
  |