From a9a8e54dac44021a60844dd457a725b1f126126f Mon Sep 17 00:00:00 2001 From: Walter Purcaro Date: Fri, 12 Dec 2014 00:50:38 +0100 Subject: Fix JsEngine --- pyload/Core.py | 10 +- pyload/config/default.conf | 1 + pyload/network/JsEngine.py | 255 +++++++++++++++++++++++++++++++++++++++++++++ pyload/utils/JsEngine.py | 242 ------------------------------------------ pyload/webui/__init__.py | 2 +- 5 files changed, 262 insertions(+), 248 deletions(-) create mode 100644 pyload/network/JsEngine.py delete mode 100644 pyload/utils/JsEngine.py diff --git a/pyload/Core.py b/pyload/Core.py index e6f4a0b5a..4d07bfe0f 100644 --- a/pyload/Core.py +++ b/pyload/Core.py @@ -30,7 +30,7 @@ from pyload.manager.event.PullEvents import PullManager from pyload.network.RequestFactory import RequestFactory from pyload.manager.thread.ServerThread import WebServer from pyload.manager.event.Scheduler import Scheduler -from pyload.utils.JsEngine import JsEngine +from pyload.network.JsEngine import JsEngine from pyload import remote from pyload.manager.RemoteManager import RemoteManager from pyload.database import DatabaseBackend, FileHandler @@ -84,21 +84,21 @@ class Core(object): from pyload.config.Setup import SetupAssistant as Setup self.config = ConfigParser() - s = Setup(pypath, self.config) + s = Setup(self.config) s.set_user() exit() elif option in ("-s", "--setup"): from pyload.config.Setup import SetupAssistant as Setup self.config = ConfigParser() - s = Setup(pypath, self.config) + s = Setup(self.config) s.start() exit() elif option == "--changedir": from pyload.config.Setup import SetupAssistant as Setup self.config = ConfigParser() - s = Setup(pypath, self.config) + s = Setup(self.config) s.conf_path(True) exit() elif option in ("-q", "--quit"): @@ -249,7 +249,7 @@ class Core(object): print "This is your first start, running configuration assistent now." self.config = ConfigParser() - s = Setup(pypath, self.config) + s = Setup(self.config) res = False try: res = s.start() diff --git a/pyload/config/default.conf b/pyload/config/default.conf index d1f39f481..773e800af 100644 --- a/pyload/config/default.conf +++ b/pyload/config/default.conf @@ -30,6 +30,7 @@ general - "General": int min_free_space : "Min Free Space (MB)" = 200 bool folder_per_package : "Create folder for each package" = True int renice : "CPU Priority" = 0 + auto;common;pyv8;node;rhino;jsc jsengine : "JS Engine" = auto download - "Download": int chunks : "Max connections for one download" = 3 int max_downloads : "Max Parallel Downloads" = 3 diff --git a/pyload/network/JsEngine.py b/pyload/network/JsEngine.py new file mode 100644 index 000000000..dfee29530 --- /dev/null +++ b/pyload/network/JsEngine.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- + +import subprocess +import sys + +from os import path +from urllib import quote + +from pyload.utils import encode, decode, uniqify + + +class JsEngine(object): + """ JS Engine superclass """ + + def __init__(self, core, engine=None): + self.core = core + self.engine = None #: Engine Instance + + if not engine: + engine = self.core.config.get("general", "jsengine") + + if engine != "auto" and self.set(engine) is False: + engine = "auto" + self.core.log.warning("JS Engine set to \"auto\" for safely") + + if engine == "auto": + for E in self.find(): + if self.set(E) is True: + break + else: + self.core.log.error("No JS Engine available") + + + @classmethod + def find(cls): + """ Check if there is any engine available """ + return [E for E in ENGINES if E.find()] + + + def get(self, engine=None): + """ Convert engine name (string) to relative JSE class (AbstractEngine extended) """ + if not engine: + JSE = self.engine + + elif isinstance(engine, basestring): + engine_name = engine.lower() + for E in ENGINES: + if E.__name == engine_name: #: doesn't check if E(NGINE) is available, just convert string to class + JSE = E + break + else: + raise ValueError("JSE") + + elif issubclass(engine, AbstractEngine): + JSE = engine + + else: + raise TypeError("engine") + + return JSE + + + def set(self, engine): + """ Set engine name (string) or JSE class (AbstractEngine extended) as default engine """ + if isinstance(engine, basestring): + return self.set(self.get(engine)) + + elif issubclass(engine, AbstractEngine) and engine.find(): + self.engine = engine + return True + + else: + return False + + + def eval(self, script, engine=None): #: engine can be a jse name """string""" or an AbstractEngine """class""" + JSE = self.get(engine) + + if not JSE: + raise TypeError("engine") + + script = encode(script) + + out, err = JSE.eval(script) + + results = [out] + + if self.core.config.get("general", "debug"): + if err: + self.core.log.debug(JSE.__name + ":", err) + + engines = self.find() + engines.remove(JSE) + for E in engines: + out, err = E.eval(script) + res = err or out + self.core.log.debug(E.__name + ":", res) + results.append(res) + + if len(results) > 1 and len(uniqify(results)) > 1: + self.core.log.warning("JS output of two or more engines mismatch") + + return results[0] + + +class AbstractEngine(object): + """ JSE base class """ + + __name = "" + + + def __init__(self): + self.setup() + self.available = self.find() + + + def setup(self): + pass + + + @classmethod + def find(cls): + """ Check if the engine is available """ + try: + __import__(cls.__name) + except Exception: + try: + out, err = cls().eval("print(23+19)") + except Exception: + res = False + else: + res = out == "42" + else: + res = True + + return res + + + def _eval(args): + if not self.available: + return None, "JS Engine \"%s\" not found" % self.__name + + try: + p = subprocess.Popen(args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + bufsize=-1) + return map(lambda x: x.strip(), p.communicate()) + except Exception, e: + return None, e + + + def eval(script): + raise NotImplementedError + + +class Pyv8Engine(AbstractEngine): + + __name = "pyv8" + + + def eval(self, script): + if not self.available: + return None, "JS Engine \"%s\" not found" % self.__name + + try: + rt = PyV8.JSContext() + rt.enter() + res = rt.eval(script), None #@TODO: parse stderr + except Exception, e: + res = None, e + + return res + + +class CommonEngine(AbstractEngine): + + __name = "js" + + + def setup(self): + subprocess.Popen(["js", "-v"], bufsize=-1).communicate() + + + def eval(self, script): + script = "print(eval(unescape('%s')))" % quote(script) + args = ["js", "-e", script] + return self._eval(args) + + +class NodeEngine(AbstractEngine): + + __name = "nodejs" + + + def setup(self): + subprocess.Popen(["node", "-v"], bufsize=-1).communicate() + + + def eval(self, script): + script = "console.log(eval(unescape('%s')))" % quote(script) + args = ["node", "-e", script] + return self._eval(args) + + +class RhinoEngine(AbstractEngine): + + __name = "rhino" + + + def setup(self): + jspath = [ + "/usr/share/java*/js.jar", + "js.jar", + path.join(pypath, "js.jar") + ] + for p in jspath: + if path.exists(p): + self.path = p + break + else: + self.path = "" + + + def eval(self, script): + script = "print(eval(unescape('%s')))" % quote(script) + args = ["java", "-cp", self.path, "org.mozilla.javascript.tools.shell.Main", "-e", script] + res = decode(self._eval(args)) + try: + return res.encode("ISO-8859-1") + finally: + return res + + +class JscEngine(AbstractEngine): + + __name = "javascriptcore" + + + def setup(self): + jspath = "/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc" + self.path = jspath if path.exists(jspath) else "" + + + def eval(self, script): + script = "print(eval(unescape('%s')))" % quote(script) + args = [self.path, "-e", script] + return self._eval(args) + + +#@NOTE: Priority ordered +ENGINES = [CommonEngine, Pyv8Engine, NodeEngine, RhinoEngine] + +if sys.platform == "darwin": + ENGINES.insert(JscEngine) diff --git a/pyload/utils/JsEngine.py b/pyload/utils/JsEngine.py deleted file mode 100644 index 459c53971..000000000 --- a/pyload/utils/JsEngine.py +++ /dev/null @@ -1,242 +0,0 @@ -# -*- coding: utf-8 -*- - -import subprocess -import sys - -from os import path -from urllib import quote - -from pyload.utils import encode, decode, uniqify - - -class JsEngine(object): - """ JS Engine superclass """ - - def __init__(self, core, engine=None): #: engine can be a jse name """string""" or an AbstractEngine """class""" - - self.core = core - self.engine = None #: Default engine Instance - - if not ENGINES: - self.core.log.critical("No JS Engine found!") - return - - if not engine: - engine = self.core.config.get("general", "jsengine") - - if engine != "auto" and self.set(engine) is False: - engine = "auto" - self.core.log.warning("JS Engine set to \"auto\" for safely") - - if engine == "auto": - for E in self.find(): - if self.set(E) is True: - break - else: - self.core.log.error("No JS Engine available") - - - @classmethod - def find(cls): - """ Check if there is any engine available """ - return [E for E in ENGINES if E.find()] - - - def get(self, engine): - """ Convert engine name (string) to relative JSE class (AbstractEngine extended) """ - if isinstance(engine, basestring): - engine_name = engine.lower() - for E in ENGINES: - if E.__name == engine_name: #: doesn't check if E(NGINE) is available, just convert string to class - JSE = E - break - else: - JSE = None - elif issubclass(engine, AbstractEngine): - JSE = engine - else: - JSE = None - return JSE - - - def set(self, engine): - """ Set engine name (string) or JSE class (AbstractEngine extended) as default engine """ - if isinstance(engine, basestring): - self.set(self.get(engine)) - elif issubclass(engine, AbstractEngine) and engine.find(): - self.engine = engine - return True - else: - return False - - - def eval(self, script, engine=None): #: engine can be a jse name """string""" or an AbstractEngine """class""" - if not engine: - JSE = self.engine - else: - JSE = self.get(engine) - - if not JSE: - return None - - script = encode(script) - - out, err = JSE.eval(script) - - results = [out] - - if self.core.config.get("general", "debug"): - if err: - self.core.log.debug(JSE.__name + ":", err) - - engines = self.find() - engines.remove(JSE) - for E in engines: - out, err = E.eval(script) - res = err or out - self.core.log.debug(E.__name + ":", res) - results.append(res) - - if len(results) > 1 and len(uniqify(results)) > 1: - self.core.log.warning("JS output of two or more engines mismatch") - - return results[0] - - -class AbstractEngine(object): - """ JSE base class """ - - __name = "" - - def __init__(self): - self.setup() - self.available = self.find() - - def setup(self): - pass - - @classmethod - def find(cls): - """ Check if the engine is available """ - try: - __import__(cls.__name) - except ImportError: - try: - out, err = cls().eval("print(23+19)") - except Exception: - res = False - else: - res = out == "42" - else: - res = True - finally: - return res - - def _eval(args): - if not self.available: - return None, "JS Engine \"%s\" not found" % self.__name - - try: - p = subprocess.Popen(args, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - bufsize=-1) - return map(lambda x: x.strip(), p.communicate()) - except Exception, e: - return None, e - - - def eval(script): - raise NotImplementedError - - -class Pyv8Engine(AbstractEngine): - - __name = "pyv8" - - def eval(self, script): - if not self.available: - return None, "JS Engine \"%s\" not found" % self.__name - - try: - rt = PyV8.JSContext() - rt.enter() - res = rt.eval(script), None #@TODO: parse stderr - except Exception, e: - res = None, e - finally: - return res - - -class CommonEngine(AbstractEngine): - - __name = "js" - - def setup(self): - subprocess.Popen(["js", "-v"], bufsize=-1).communicate() - - def eval(self, script): - script = "print(eval(unescape('%s')))" % quote(script) - args = ["js", "-e", script] - return self._eval(args) - - -class NodeEngine(AbstractEngine): - - __name = "nodejs" - - def setup(self): - subprocess.Popen(["node", "-v"], bufsize=-1).communicate() - - def eval(self, script): - script = "console.log(eval(unescape('%s')))" % quote(script) - args = ["node", "-e", script] - return self._eval(args) - - -class RhinoEngine(AbstractEngine): - - __name = "rhino" - - def setup(self): - jspath = [ - "/usr/share/java*/js.jar", - "js.jar", - path.join(pypath, "js.jar") - ] - for p in jspath: - if path.exists(p): - self.path = p - break - else: - self.path = "" - - def eval(self, script): - script = "print(eval(unescape('%s')))" % quote(script) - args = ["java", "-cp", self.path, "org.mozilla.javascript.tools.shell.Main", "-e", script] - res = decode(self._eval(args)) - try: - return res.encode("ISO-8859-1") - finally: - return res - - -class JscEngine(AbstractEngine): - - __name = "javascriptcore" - - def setup(self): - jspath = "/System/Library/Frameworks/JavaScriptCore.framework/Resources/jsc" - self.path = jspath if path.exists(jspath) else "" - - def eval(self, script): - script = "print(eval(unescape('%s')))" % quote(script) - args = [self.path, "-e", script] - return self._eval(args) - - -#@NOTE: Priority ordered -ENGINES = [CommonEngine, Pyv8Engine, NodeEngine, RhinoEngine] - -if sys.platform == "darwin": - ENGINES.insert(JscEngine) diff --git a/pyload/webui/__init__.py b/pyload/webui/__init__.py index 045c78e70..4f06d160e 100644 --- a/pyload/webui/__init__.py +++ b/pyload/webui/__init__.py @@ -26,7 +26,7 @@ SETUP = None PYLOAD = None from pyload.manager.thread import ServerThread -from pyload.utils.JsEngine import JsEngine +from pyload.network.JsEngine import JsEngine if not ServerThread.core: if ServerThread.setup: -- cgit v1.2.3