示例#1
0
    def __call__(self, *args):
        args = self.lua.lua2python(args)
        args_text = json.dumps(args, ensure_ascii=False, encoding="utf8")[1:-1]
        func_text = json.dumps([self.source], ensure_ascii=False, encoding='utf8')[1:-1]
        wrapper_script = """
        (function(func_text){
            try{
                var func = eval("(" + func_text + ")");
                return {
                    result: func(%(args)s),
                    error: false,
                }
            }
            catch(e){
                return {
                    error: true,
                    error_repr: e.toString(),
                }
            }
        })(%(func_text)s)
        """ % {"func_text": func_text, "args": args_text}

        # print(wrapper_script)
        res = self.tab.evaljs(wrapper_script)

        if not isinstance(res, dict):
            raise ScriptError("[lua] unknown error during JS function call: %r; %r" % (res, wrapper_script))

        if res["error"]:
            raise ScriptError("[lua] error during JS function call: %r" % (res.get("error_repr", "<unknown error>"),))

        return res.get("result")
示例#2
0
    def set_result_header(self, name, value):
        if not all([isinstance(h, basestring) for h in [name, value]]):
            raise ScriptError(
                "splash:set_result_header() arguments must be strings")

        try:
            name = name.decode('utf-8').encode('ascii')
            value = value.decode('utf-8').encode('ascii')
        except UnicodeEncodeError:
            raise ScriptError(
                "splash:set_result_header() arguments must be ascii")

        header = (name, value)
        self._result_headers.append(header)
示例#3
0
    def start(self, lua_source, sandboxed, lua_package_path,
              lua_sandbox_allowed_modules):
        self.log(lua_source)
        self.sandboxed = sandboxed
        self.lua = SplashLuaRuntime(
            sandboxed=sandboxed,
            lua_package_path=lua_package_path,
            lua_sandbox_allowed_modules=lua_sandbox_allowed_modules)
        self.splash = Splash(self.lua, self.tab, self.render_options)

        self.runner = SplashScriptRunner(
            lua=self.lua,
            splash=self.splash,
            log=self.log,
            sandboxed=sandboxed,
        )

        try:
            main_coro = self.get_main(lua_source)
        except (ValueError, lupa.LuaSyntaxError, lupa.LuaError) as e:
            raise ScriptError("lua_source: " + repr(e))

        self.runner.start(
            main_coro=main_coro,
            return_result=self.return_result,
            return_error=self.return_error,
        )
示例#4
0
    def autoload(self, source_or_url=None, source=None, url=None):
        if len([a
                for a in [source_or_url, source, url] if a is not None]) != 1:
            raise ScriptError("splash:autoload requires a single argument")

        if source_or_url is not None:
            source_or_url = source_or_url.strip()
            if source_or_url.startswith(("http://", "https://")):
                source, url = None, source_or_url
            else:
                source, url = source_or_url, None

        if source is not None:
            # load source directly
            self.tab.autoload(source)
            return ImmediateResult(True)
        else:
            # load JS from a remote resource
            cmd_id = next(self._command_ids)

            def callback(reply):
                if reply.error():
                    reason = REQUEST_ERRORS_SHORT.get(reply.error(), '?')
                    self._return(cmd_id, None, reason)
                else:
                    source = bytes(reply.readAll())
                    self.tab.autoload(source)
                    self._return(cmd_id, True)

            return AsyncBrowserCommand(cmd_id, "http_get",
                                       dict(url=url, callback=callback))
示例#5
0
    def go(self, url, baseurl=None, headers=None):
        if url is None:
            raise ScriptError("'url' is required for splash:go")

        if self.tab.web_page.navigation_locked:
            return ImmediateResult((None, "navigation_locked"))

        cmd_id = next(self._command_ids)

        def success():
            try:
                code = self.tab.last_http_status()
                if code and 400 <= code < 600:
                    # return HTTP errors as errors
                    self._return(cmd_id, None, "http%d" % code)
                else:
                    self._return(cmd_id, True)
            except Exception as e:
                self._return(cmd_id, None, "internal_error")

        def error(error_info):
            self._return(cmd_id, None, self._error_info_to_lua(error_info))

        return AsyncBrowserCommand(
            cmd_id, "go",
            dict(
                url=url,
                baseurl=baseurl,
                callback=success,
                errback=error,
                headers=self.lua.lua2python(headers, max_depth=3),
            ))
示例#6
0
 def set_resource_timeout(self, timeout):
     if timeout is None:
         timeout = 0
     timeout = float(timeout)
     if timeout < 0:
         raise ScriptError("splash.resource_timeout can't be negative")
     self.tab.set_resource_timeout(timeout)
示例#7
0
 def wrapper(self, *args, **kwargs):
     try:
         return meth(self, *args, **kwargs)
     except ScriptError as e:
         self._exceptions.append(e)
         raise
     except BaseException as e:
         self._exceptions.append(ScriptError(e))
         raise
示例#8
0
    def http_get(self, url, headers=None, follow_redirects=True):
        if url is None:
            raise ScriptError("'url' is required for splash:http_get")

        cmd_id = next(self._command_ids)

        def callback(reply):
            reply_har = reply2har(reply, include_content=True, binary_content=True)
            self._return(cmd_id, self.lua.python2lua(reply_har))

        return AsyncBrowserCommand(cmd_id, "http_get", dict(
            url=url,
            callback=callback,
            headers=self.lua.lua2python(headers, max_depth=3),
            follow_redirects=follow_redirects,
        ))
示例#9
0
 def set_user_agent(self, value):
     if not isinstance(value, basestring):
         raise ScriptError(
             "splash:set_user_agent() argument must be a string")
     self.tab.set_user_agent(value)
示例#10
0
 def set_result_content_type(self, content_type):
     if not isinstance(content_type, basestring):
         raise ScriptError(
             "splash:set_result_content_type() argument must be a string")
     self._result_content_type = content_type
示例#11
0
 def set_timeout(self, timeout):
     timeout = float(timeout)
     if timeout < 0:
         raise ScriptError("request:set_timeout() argument can't be < 0")
     self.request.timeout = timeout
示例#12
0
 def set_result_status_code(self, code):
     if not isinstance(code, int) or not (200 <= code <= 999):
         raise ScriptError(
             "splash:set_result_status_code() argument must be a number 200 <= code <= 999"
         )
     self._result_status_code = code