def run(c, all): ''' Run all @produce nodes in a separate thread. Report progress via a timer in *this* thread. ''' aList = getList(c, all) g.app.at_produce_command = None def thread_target(): # runList must not change Leo's outline or log! # runList uses c only to update c.at_produce_command. runList(c, aList) t = threading.Thread(target=thread_target) t.setDaemon(True) t.start() timer = g.IdleTime(handler=None, delay=500, tag='at-produce') c._at_produce_max = 20 c._at_produce_count = c._at_produce_max - 1 def timer_callback(tag): timer_callback_helper(c, t, timer) timer.handler = timer_callback timer.start()
def __init__(self, path=None): self.qc = queue.Queue() # The command queue. self.qr = queue.Queue() # The request queue. stdin_q = self.QueueStdin(qc=self.qc) stdout_q = self.QueueStdout(qr=self.qr) # Start the singleton listener, in the main Leo thread. timer = getattr(g.app, 'xdb_timer', None) if timer: self.timer = timer else: self.timer = g.IdleTime(listener, delay=0) self.timer.start() # Init the base classes. threading.Thread.__init__(self) super().__init__( stdin=stdin_q, stdout=stdout_q, readrc=False, # Don't read a .rc file. ) sys.stdout = stdout_q self.daemon = True self.path = path self.prompt = '(xdb) ' self.saved_frame = None self.saved_traceback = None
def main(): """ Command Line Utility Entry Point Arguments: sys.argv: Command line arguments Returns: None """ args = cmdLineHandler() leoG.IdleTime = idle_time.IdleTime bridge = leoBridge.controller(gui='nullGui', silent=True, verbose=False, loadPlugins=True, readSettings=True) cmdrT = bridge.openLeoFile(args.fpnTests) if os.path.exists(args.fpnResults): os.remove(args.fpnResults) fdR = codecs.open(args.fpnResults, 'w', encoding='utf-8') testCmdr = lib_test.TestCmdr(cmdrT, fdR) genFindTests = lib_test.findTests(cmdrT) itPoll = leoG.IdleTime((lambda itRunTests: lib_test.runTests( itRunTests, cmdrT, fdR, testCmdr, genFindTests)), delay=10) itPoll.start() idle_time.IdleTime.idle()
def _babelExec(babelG, babelCmdr, babelRoot): """ Execute a Script Arguments: babelG: Babel globals babelCmdr: Leo-Editor commander for the file containing the script to execute babelRoot: The "Babel Root" for the script to execute Returns: None Side Effects: For each line <line> in the target node body, A child node is created with empty body and headline "<elapsed time> - <line>" If <line> writes any non-blanks to stdout, then a child node is created with headline "stdout - <line>" and body containing the standard output. If <line> writes any non-blanks to stderr, then a child node is created with headline "stderr - <line>" and body containing the standard error output. Most importantly the output nodes are created in real time when they occur, not later when the <line> terminates. If there is a selected range, then this selected range is executed. If there is no selected range, then the whole body of the currently selected node is executed. If the language at the current cursor position is "python," then the Python interpreter executes the target text. If the language at the current cursor position is "shell," then the Bash interpreter executes the target text. The scheme for real-time streaming of stdout and stderr while the script is still executing is taken from: http://stackoverflow.com/questions/18421757/live-output-from-subprocess-command """ script = getScript(cmdr, babelRoot, useSelectedText=False, language='python') code = compile(script, 'Babel Parameter Script', 'exec') gld = { 'babel': babelG.babel_api, 'b': babelG.babel_api, '__file__': 'Babel Parameter Script', 'c': cmdr, 'g': leoG, 'p': babelRoot } exec(code, gld) # Create Nodes? createNodes = gld.get('babel_node_creation') if createNodes is None: createNodes = babelCmdr.nodeCreationDefault cmdrScr, scriptRoot = scrOrResRoot(cmdr, gld, babelG, babelRoot, 'script') if createNodes: cmdrRes, resultsRoot = scrOrResRoot(cmdr, gld, babelG, babelRoot, 'results') else: cmdrRes = None resultsRoot = None # Determine the language and then the interpreter langx = leoG.scanForAtLanguage(cmdrScr, scriptRoot) if langx == 'python': interpreter = gld.get('babel_python') if not interpreter: interpreter = babelCmdr.interpreterPython cmdList = [interpreter, '-u'] elif langx == 'shell': interpreter = gld.get('babel_shell') if not interpreter: interpreter = babelCmdr.interpreterShell cmdList = [interpreter] else: babelCmdr.babelExecCnt += 1 raise babelG.babel_api.BABEL_LANGUAGE( 'Unknown language "{0}"'.format(langx)) script = getScript(cmdrScr, scriptRoot, useSelectedText=False, language=langx) cmdrScr.setCurrentDirectoryFromContext(scriptRoot) cwd = leoG.os_path_abspath(os.getcwd()) pathScript = cmdr.writeScriptFile(script) cmdList.append(pathScript) babel_script_args = gld.get('babel_script_args') if babel_script_args: cmdList.extend(babel_script_args) # pylint: disable=unexpected-keyword-arg wro = tempfile.NamedTemporaryFile(buffering=0) wre = tempfile.NamedTemporaryFile(buffering=0) reo = io.open(wro.name, 'rb', buffering=0) ree = io.open(wre.name, 'rb', buffering=0) if gld.get('babel_redirect_stdout'): # Redirect stdout to stderr wro = wre babelCmdr.cmdDoneFlag = False babelCmdr.cmdDoneStdPolled = False babelCmdr.cmdDoneErrPolled = False start = time.time() subPscript = subprocess.Popen(cmdList, cwd=cwd, stdout=wro, stderr=wre) subPbabKill = subprocess.Popen( [babelG.pathBabelKill, str(subPscript.pid)]) babelCmdr.reo = reo # Kludge to allow itf() to determine which output it polls itOut = leoG.IdleTime( (lambda ito: itf(babelCmdr.colorStdout, reo, babelCmdr)), delay=1000) itErr = leoG.IdleTime( (lambda ito: itf(babelCmdr.colorStderr, ree, babelCmdr)), delay=1000) if (not itOut) or (not itErr): raise babelG.babel_api.BABEL_ERROR('leoG.IdleTime() failed') itOut.start() itErr.start() itPoll = leoG.IdleTime((lambda itobj: itp( itobj, cmdr, cmdrRes, resultsRoot, subPscript, subPbabKill, wro, reo, wre, ree, itOut, itErr, start, createNodes)), delay=1000) if not itPoll: raise babelG.babel_api.BABEL_ERROR('leoG.IdleTime() failed') itPoll.start()
def load_clouds(self, from_background=None): """ load_clouds - Handle loading from cloud on startup and after background checking for changes. Args: from_background (set): set of (remote, ID) str tuples if we're called after a background check process finds changes. """ if from_background is None: from_background = set() skipped = [] background = [] # things to check in background for lc_v in self.find_clouds(): kwargs = self.kw_from_node(lc_v) if from_background and \ (kwargs['remote'], kwargs['ID']) not in from_background: # only process nodes from the background checking continue read = False read_on_load = kwargs.get('read_on_load', '').lower() if from_background: # was 'background', changes found, so now treat as 'ask' read_on_load = 'ask' if read_on_load == 'yes': read = True elif read_on_load == 'ask': try: last_read = datetime.strptime( lc_v.u['_leo_cloud']['last_read'], "%Y-%m-%dT%H:%M:%S.%f") except KeyError: last_read = None message = "Read cloud data '%s', overwriting local nodes?" % kwargs['ID'] if last_read: delta = datetime.now() - last_read message = "%s\n%s, %sh:%sm:%ss ago" % ( message, last_read.strftime("%a %b %d %H:%M"), 24*delta.days+int(delta.seconds / 3600), int(delta.seconds / 60) % 60, delta.seconds % 60) read = g.app.gui.runAskYesNoCancelDialog(self.c, "Read cloud data?", message=message) read = str(read).lower() == 'yes' if read: self.read_current(p=self.c.vnode2position(lc_v)) elif read_on_load == 'background': # second time round, with from_background data, this will # have been changed to 'ask' (above), so no infinite loop background.append((lc_v, kwargs, self.recursive_hash(lc_v, [], include_current=False))) elif read_on_load == 'no': g.es("NOTE: not reading '%s' from cloud" % kwargs['ID']) elif read_on_load != 'ask': skipped.append(kwargs['ID']) if skipped: g.app.gui.runAskOkDialog(self.c, "Unloaded cloud data", message="There is unloaded (possibly stale) cloud data, use\nread_on_load: yes|no|ask\n" "in @leo_cloud nodes to avoid this message.\nUnloaded data:\n%s" % ', '.join(skipped)) if background: # send to background thread for checking names = ', '.join([i[1]['ID'] for i in background]) g.es("Checking cloud trees in background:\n%s" % names) thread = threading.Thread(target=self.bg_check, args=(background,)) thread.start() # start watching for results g.IdleTime(self.bg_post_process).start()