def run(*path, **query): if len(path) == 0: tangelo.http_status(400, "Missing Path") return {"error": "missing path to config file"} required = query.get("required") is not None url = "/" + "/".join(path) content = analyze_url(url).content if content is None or content.type not in [Content.File, Content.NotFound]: tangelo.http_status(400, "Illegal Path") return {"error": "illegal web path (path does not point to a config file)"} elif content.type == Content.NotFound: if required: return {"error": "File not found", "file": url} else: return {"result": {}} try: config = tangelo.util.yaml_safe_load(content.path, dict) except IOError: tangelo.http_status(404) return {"error": "could not open file at %s" % (url)} except TypeError: tangelo.http_status(400, "Not An Associative Array") return {"error": "file at %s did not contain a top-level associative array" % (url)} except ValueError as e: tangelo.http_status(400, "YAML Error") return {"error": "could not parse YAML from file at %s: %s" % (url, e.message)} return {"result": config}
def post(*pargs, **query): args = query.get("args", "") timeout = float(query.get("timeout", 0)) if len(pargs) == 0: tangelo.http_status(400, "Required Argument Missing") return {"error": "No program path was specified"} program_url = "/" + "/".join(pargs) content = analyze_url(program_url).content if content is None or content.type != Content.File: tangelo.http_status(404, "Not Found") return {"error": "Could not find a script at %s" % (program_url)} program = content.path # Check the user arguments. userargs = args.split() if "--port" in userargs: tangelo.http_status(400, "Illegal Argument") return {"error": "You may not specify '--port' among the arguments passed in 'args'"} # Obtain an available port. port = tangelo.util.get_free_port() # Generate a unique key. key = tangelo.util.generate_key(processes.keys()) # Detect http vs. https scheme = "ws" ssl_key = cherrypy.config.get("server.ssl_private_key") ssl_cert = cherrypy.config.get("server.ssl_certificate") # Generate command line. cmdline = [vtkpython, weblauncher, program, "--port", str(port)] + userargs if ssl_key and ssl_cert: scheme = "wss" cmdline.extend(["--sslKey", ssl_key, "--sslCert", ssl_cert]) # Launch the requested process. tangelo.log_info("VTKWEB", "Starting process: %s" % (" ".join(cmdline))) try: process = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except (OSError, IOError) as e: tangelo.log_warning("VTKWEB", "Error: could not launch VTKWeb process") return {"error": e.strerror} # Capture the new process's stdout and stderr streams in # non-blocking readers. stdout = tangelo.util.NonBlockingReader(process.stdout) stderr = tangelo.util.NonBlockingReader(process.stderr) # Read from stdout to look for the signal that the process has # started properly. class FactoryStarted: pass class Failed: pass class Timeout: pass signal = "Starting factory" if timeout <= 0: timeout = 10 sleeptime = 0.5 wait = 0 saved_lines = [] try: while True: lines = stdout.readlines() saved_lines += lines for line in lines: if line == "": # This indicates that stdout has closed without # starting the process. raise Failed() elif signal in line: # This means that the server has started. raise FactoryStarted() # If neither failure nor success occurred in the last block # of lines from stdout, either time out, or try again after # a short delay. if wait >= timeout: raise Timeout() wait += sleeptime time.sleep(sleeptime) except Timeout: tangelo.http_status(524, "Timeout") return {"error": "Process startup timed out"} except Failed: tangelo.http_status(500) return {"error": "Process did not start up properly", "stdout": saved_lines, "stderr": stderr.readlines()} except FactoryStarted: stdout.pushlines(saved_lines) # Create a websocket handler path dedicated to this process. host = "localhost" if cherrypy.server.socket_host == "0.0.0.0" else cherrypy.server.socket_host tangelo.websocket.mount(key, WebSocketRelay(host, port, key), "wamp") # Log the new process in the process table, including non-blocking # stdout and stderr readers. processes[key] = {"port": port, "process": process, "stdout": stdout, "stderr": stderr} # Form the websocket URL from the hostname/port used in the # request, and the newly generated key. url = "%s://%s/ws/%s/ws" % (scheme, cherrypy.request.base.split("//")[1], key) return {"key": key, "url": url}
def analysis_dict(base, url=None): if url is None: url = base base = "/analyze-url/" return eval(str(analyze_url("%s%s" % (base, url))))
def post(*pargs, **query): args = query.get("args", "") timeout = float(query.get("timeout", 0)) processes = tangelo.plugin_store()["processes"] if len(pargs) == 0: tangelo.http_status(400, "Required Argument Missing") return {"error": "No program path was specified"} program_url = "/" + "/".join(pargs) content = analyze_url(program_url).content if content is None or content.type != Content.File: tangelo.http_status(404, "Not Found") return {"error": "Could not find a script at %s" % (program_url)} elif content.path is None: tangelo.http_status(403, "Restricted") return {"error": "The script at %s is access-restricted"} program = content.path # Check the user arguments. userargs = args.split() if "--port" in userargs: tangelo.http_status(400, "Illegal Argument") return {"error": "You may not specify '--port' among the arguments passed in 'args'"} # Obtain an available port. port = tangelo.util.get_free_port() # Generate a unique key. key = tangelo.util.generate_key(processes.keys()) # Detect http vs. https scheme = "ws" ssl_key = cherrypy.config.get("server.ssl_private_key") ssl_cert = cherrypy.config.get("server.ssl_certificate") # Generate command line. cmdline = [vtkpython, weblauncher, program, "--port", str(port)] + userargs if ssl_key and ssl_cert: scheme = "wss" cmdline.extend(["--sslKey", ssl_key, "--sslCert", ssl_cert]) # Launch the requested process. tangelo.log_info("VTKWEB", "Starting process: %s" % (" ".join(cmdline))) try: process = subprocess.Popen(cmdline, stdout=subprocess.PIPE, stderr=subprocess.PIPE) except (OSError, IOError) as e: tangelo.log_warning("VTKWEB", "Error: could not launch VTKWeb process") return {"error": e.strerror} # Capture the new process's stdout and stderr streams in # non-blocking readers. stdout = tangelo.util.NonBlockingReader(process.stdout) stderr = tangelo.util.NonBlockingReader(process.stderr) # Read from stdout to look for the signal that the process has # started properly. class FactoryStarted: pass class Failed: pass class Timeout: pass signal = "Starting factory" if timeout <= 0: timeout = 10 sleeptime = 0.5 wait = 0 saved_lines = [] try: while True: lines = stdout.readlines() saved_lines += lines for line in lines: if line == "": # This indicates that stdout has closed without # starting the process. raise Failed() elif signal in line: # This means that the server has started. raise FactoryStarted() # If neither failure nor success occurred in the last block # of lines from stdout, either time out, or try again after # a short delay. if wait >= timeout: raise Timeout() wait += sleeptime time.sleep(sleeptime) except Timeout: tangelo.http_status(524, "Timeout") return {"error": "Process startup timed out"} except Failed: tangelo.http_status(500) return {"error": "Process did not start up properly", "stdout": saved_lines, "stderr": stderr.readlines()} except FactoryStarted: stdout.pushlines(saved_lines) # Create a websocket handler path dedicated to this process. host = "localhost" if cherrypy.server.socket_host == "0.0.0.0" else cherrypy.server.socket_host tangelo.websocket.mount(key, WebSocketRelay(host, port, key), "wamp") # Log the new process in the process table, including non-blocking # stdout and stderr readers. processes[key] = {"port": port, "process": process, "stdout": stdout, "stderr": stderr} # Form the websocket URL from the hostname/port used in the # request, and the newly generated key. url = "%s://%s/ws/%s/ws" % (scheme, cherrypy.request.base.split("//")[1], key) return {"key": key, "url": url}