def preparse_worksheet_cell(s, globals): """ Preparse the contents of a worksheet cell in the notebook, respecting the user using ``preparser(False)`` to turn off the preparser. This function calls :func:`~sage.misc.preparser.preparse_file` which also reloads attached files. It also does displayhook formatting by calling the :func:`~sagenb.notebook.interfaces.format.displayhook_hack` function. INPUT: - ``s`` - a string containing code - ``globals`` - a string:object dictionary; passed directly to :func:`~sage.misc.preparser.preparse_file` OUTPUT: - a string """ if do_preparse(): s = preparse_file(s, globals=globals) s = displayhook_hack(s) if _automatic_names: s = automatic_name_filter(s) return s
def execProcess(session, message_queue, output_handler, resource_limits, sysargs, fs_secret): """ Run the code, outputting into a pipe. Meant to be run as a separate process. :arg str session: the ID of the session running the code :arg multiprocessing.Queue message_queue: a queue through which this process will be passed input messages :arg device_process.OutputIPython output_handler: the context wrapper in which to execute the code :arg list resource_limits: list of tuples of the form ``(resource, limit)``, to be passed as arguments to :func:`resource.setrlimit`. """ # we need a new context since we just forked global fs fs.new_context() from Queue import Empty global user_code # Since the user can set a timeout, we safeguard by having a maximum timeout MAX_TIMEOUT=60 timeout=0.1 upload_recv, upload_send=Pipe() file_parent, file_child=Pipe() file_upload_process=Process(target=upload_files, args=(upload_recv, file_child, session, fs_secret['upload'])) file_upload_process.start() fs_hmac=hmac.new(fs_secret[''], digestmod=sha1) del fs_secret if resource_limits is None: resource_limits=[] from resource import setrlimit for r,l in resource_limits: setrlimit(r, l) while True: try: msg=message_queue.get(timeout=timeout) except Empty: break if msg[0]=="exec": msg=msg[1] else: break # Now msg is an IPython message for the user session if msg['msg_type']!="execute_request": raise ValueError("Received invalid message: %s"%(msg,)) # TODO: we probably ought not prepend our own code, in case the user has some # "from __future__ import ..." statements, which *must* occur at the top of the code block # alternatively, we could move any such statements above our statements code = line_prefix.sub("", msg['content']['code'].encode('utf8')) CONFIG.EMBEDDED_MODE["sage_mode"] = sage_mode = msg['content']['sage_mode'] if enable_sage and sage_mode: from sage.misc.preparser import preparse_file code = user_code_sage + "\n" + preparse_file(code) elif sage_mode: code = "print 'NOTE: Sage Mode is unavailable, which may cause errors if using Sage-specific syntax.'\n" + user_code + code else: code = user_code + code code = displayhook_hack(code) # always add a newline to avoid this bug in Python versions < 2.7: http://bugs.python.org/issue1184112 code += '\n' log("Executing: %r"%code) output_handler.set_parent_header(msg['header']) old_files=dict([(f,os.stat(f).st_mtime) for f in os.listdir(os.getcwd())]) if 'files' in msg['content']: for filename in msg['content']['files']: with open(filename,'w') as f: fs.copy_file(f,filename=filename, session=session, hmac=fs_hmac) old_files[filename]=-1 file_parent.send(True) with output_handler: try: import user_convenience locals={'_sagecell': user_convenience.UserConvenience(output_handler, upload_send), '_sage_messages': output_handler, '_sage_upload_file_pipe': upload_send} if enable_sage and sage_mode: locals['sage'] = sage exec code in locals # I've commented out fields we aren't using below to # save bandwidth output_handler.message_queue.raw_message("execute_reply", {"status":"ok", #"payload":[], #"user_expressions":{}, #"user_variables":{} }) # technically should send back an execution_state: idle message too except: (etype, evalue, etb) = sys.exc_info() try: from IPython.core import ultratb as ultraTB except ImportError: # Workaround for IPython 0.10 from IPython import ultraTB err = ultraTB.VerboseTB(include_vars = 0, tb_offset = 1) try: # Check whether the exception has any further details error_value = evalue[0] except: error_value = "" #TODO: docs have this as exc_name and exc_value, #but it seems like IPython returns ename and #evalue! err_msg={"ename": etype.__name__, "evalue": str(error_value), "traceback": err.text(etype, evalue, etb, context=3), "status": "error"} output_handler.message_queue.raw_message("execute_reply", err_msg) upload_send.send_bytes(json.dumps({'msg_type': 'end_exec'})) new_files=file_parent.recv() old_files.update(new_files) # TODO: security implications here calling something that the user had access to. timeout=max(0,min(float(interact_sagecell.__sage_cell_timeout__), MAX_TIMEOUT)) file_list=[] for filename in os.listdir(os.getcwd()): if filename not in old_files or old_files[filename]!=os.stat(filename).st_mtime: file_list.append(filename) try: with open(filename) as f: fs.create_file(f, session=session, filename=filename, hmac=fs_hmac) except Exception as e: sys.stdout.write("An exception occurred: %s\n"%(e,)) if len(file_list)>0: output_handler.message_queue.message('files', {'files': file_list}) log("Done executing code: %r"%code) upload_send.send_bytes(json.dumps({'msg_type': 'end_session'})) file_upload_process.join()
def execProcess(session, message_queue, output_handler, resource_limits, sysargs, fs_secret): """ Run the code, outputting into a pipe. Meant to be run as a separate process. :arg str session: the ID of the session running the code :arg multiprocessing.Queue message_queue: a queue through which this process will be passed input messages :arg device_process.OutputIPython output_handler: the context wrapper in which to execute the code :arg list resource_limits: list of tuples of the form ``(resource, limit)``, to be passed as arguments to :func:`resource.setrlimit`. """ # we need a new context since we just forked global fs fs.new_context() from Queue import Empty global user_code # Since the user can set a timeout, we safeguard by having a maximum timeout MAX_TIMEOUT = 60 timeout = 0.1 upload_recv, upload_send = Pipe() file_parent, file_child = Pipe() file_upload_process = Process(target=upload_files, args=(upload_recv, file_child, session, fs_secret['upload'])) file_upload_process.start() fs_hmac = hmac.new(fs_secret[''], digestmod=sha1) del fs_secret if resource_limits is None: resource_limits = [] from resource import setrlimit for r, l in resource_limits: setrlimit(r, l) while True: try: msg = message_queue.get(timeout=timeout) except Empty: break if msg[0] == "exec": msg = msg[1] else: break # Now msg is an IPython message for the user session if msg['msg_type'] != "execute_request": raise ValueError("Received invalid message: %s" % (msg, )) # TODO: we probably ought not prepend our own code, in case the user has some # "from __future__ import ..." statements, which *must* occur at the top of the code block # alternatively, we could move any such statements above our statements code = line_prefix.sub("", msg['content']['code'].encode('utf8')) CONFIG.EMBEDDED_MODE["sage_mode"] = sage_mode = msg['content'][ 'sage_mode'] if enable_sage and sage_mode: from sage.misc.preparser import preparse_file code = user_code_sage + "\n" + preparse_file(code) elif sage_mode: code = "print 'NOTE: Sage Mode is unavailable, which may cause errors if using Sage-specific syntax.'\n" + user_code + code else: code = user_code + code code = displayhook_hack(code) # always add a newline to avoid this bug in Python versions < 2.7: http://bugs.python.org/issue1184112 code += '\n' log("Executing: %r" % code) output_handler.set_parent_header(msg['header']) old_files = dict([(f, os.stat(f).st_mtime) for f in os.listdir(os.getcwd())]) if 'files' in msg['content']: for filename in msg['content']['files']: with open(filename, 'w') as f: fs.copy_file(f, filename=filename, session=session, hmac=fs_hmac) old_files[filename] = -1 file_parent.send(True) with output_handler: try: import user_convenience locals = { '_sagecell': user_convenience.UserConvenience(output_handler, upload_send), '_sage_messages': output_handler, '_sage_upload_file_pipe': upload_send } if enable_sage and sage_mode: locals['sage'] = sage exec code in locals # I've commented out fields we aren't using below to # save bandwidth output_handler.message_queue.raw_message( "execute_reply", { "status": "ok", #"payload":[], #"user_expressions":{}, #"user_variables":{} }) # technically should send back an execution_state: idle message too except: (etype, evalue, etb) = sys.exc_info() try: from IPython.core import ultratb as ultraTB except ImportError: # Workaround for IPython 0.10 from IPython import ultraTB err = ultraTB.VerboseTB(include_vars=0, tb_offset=1) try: # Check whether the exception has any further details error_value = evalue[0] except: error_value = "" #TODO: docs have this as exc_name and exc_value, #but it seems like IPython returns ename and #evalue! err_msg = { "ename": etype.__name__, "evalue": str(error_value), "traceback": err.text(etype, evalue, etb, context=3), "status": "error" } output_handler.message_queue.raw_message( "execute_reply", err_msg) upload_send.send_bytes(json.dumps({'msg_type': 'end_exec'})) new_files = file_parent.recv() old_files.update(new_files) # TODO: security implications here calling something that the user had access to. timeout = max( 0, min(float(interact_sagecell.__sage_cell_timeout__), MAX_TIMEOUT)) file_list = [] for filename in os.listdir(os.getcwd()): if filename not in old_files or old_files[filename] != os.stat( filename).st_mtime: file_list.append(filename) try: with open(filename) as f: fs.create_file(f, session=session, filename=filename, hmac=fs_hmac) except Exception as e: sys.stdout.write("An exception occurred: %s\n" % (e, )) if len(file_list) > 0: output_handler.message_queue.message('files', {'files': file_list}) log("Done executing code: %r" % code) upload_send.send_bytes(json.dumps({'msg_type': 'end_session'})) file_upload_process.join()