class Runner: STOP = 0 CONTINUE = 1 def __init__(self, fn, In = None, Out = None): if In is None: In = sys.stdin if Out is None: Out = sys.stdout self.fn = fn self.chan = Chan() self.chan.set_channels(In, Out) self.filewatch = FileWatcher(fn) self.code_locals = {} try: self.load_code(self.code_locals) self.filewatch.note_new_files() self.chan.send_cmd('ready') except: self.filewatch.note_new_files() self.chan.send_cmd('exception', string = traceback.format_exc()) def run_cmd(self, cmd): if cmd['action'] == 'shutdown': return Runner.STOP elif cmd['action'] == 'get_locals': value = self.code_locals.get(cmd['var'], '') self.chan.send_cmd('locals', val = value) elif cmd['action'] == 'set_reload_interval': self.filewatch.interval = cmd['value'] elif cmd['action'] == 'run_func': self.run_func(cmd) elif cmd['action'] == 'crash': sys.exit() elif cmd['action'] == 'abort': # client disconnected, but script was finished by that time pass elif cmd['action'] == 'source_changed': value = 1 if self.filewatch.has_changed() else 0 self.chan.send_cmd('', value = value) else: log('runner.py has idea was this incoming is:\n', repr(cmd)) raise NotImplementedError return Runner.CONTINUE def loop(self): import time while 1: cmd = self.chan.recv_cmd() #log("Test %d %s\n" % (time.time(), repr(cmd))) if self.run_cmd(cmd) == Runner.STOP: return def load_code(self, my_locals): with open(self.fn) as f: code_src = f.read() try: self.code = compile(code_src, os.path.abspath(self.fn), 'exec') except Exception, e: hosts_line = re.findall('^(hosts\s*=[^\n]+)', code_src) if hosts_line: c = compile(hosts_line[0], '', 'exec') exec c in my_locals raise e exec self.code in my_locals