class ClipLauncher(object): event_loop = None tracks = [] transport = None def __init__(self, tracks=None, tempo=None): self.main_loop = MainLoop(widget=None) self.osc = OscUI(self) self.transport = JACKOSCKlickTransport(tempo, osc=self.osc.server) self.tracks = tracks or self.tracks self.urwid = UrwidUI(self) self.main_loop.widget = self.urwid def start(self): try: self.main_loop.run() except: self.main_loop.stop() exc_type, value, tb = exc_info() print( "\nLooks like ClipLauncher has encountered an error :/" + "\nHere's a chance to clean up and/or see what's going on.\n") print_exc() post_mortem(tb)
def start(self): self.loop = MainLoop(self.ui, PALETTE, handle_mouse=True, unhandled_input=self.handle_keypress) self.loop.set_alarm_at(0, discard_args(self.issue_list)) self.loop.run()
def run_twisted(self): from twisted.internet import reactor evloop = urwid.TwistedEventLoop(reactor, manage_reactor=False) self.screen = urwid.raw_display.Screen() self.screen.register_palette(self.palette) self.loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input, screen=self.screen, event_loop=evloop) self.loop.set_alarm_in(0.1, lambda loop, _: loop.draw_screen()) self.loop.start() # The loggers get a Handler that writes to the screen. We want this to only # happen if the screen exists, so de-register them after the reactor stops. reactor.addSystemEventTrigger('after', 'startup', self.register_loggers) reactor.addSystemEventTrigger('before', 'shutdown', self.unregister_loggers) reactor.run() # We might have stopped the screen already, and the stop() method # doesn't check for stopping twice. if self.called_loop_stop: self.logger.warn('Internal error!') else: self.loop.stop() self.called_loop_stop = True
def menu(): hello = Text( "Приветствую! Для продолжения настройте параметры лабиринта.\n" + "Если карта лабиринта будет некорректно отображаться, " + "попробуйте уменьшить значение ширины или развернуть окно.") height_enter = IntEdit("Высота лабиринта: ", 30) width_enter = IntEdit("Ширина лабиринта: ", 45) done = Button("Готово") done_pad = Padding(done, align="center", width=10) back = AttrMap(SolidFill("\u25E6"), "blueprint") pile = Pile( [hello, Divider("\u2500"), height_enter, width_enter, done_pad]) menu = Filler(LineBox(pile)) main_widget = Overlay(menu, back, align="center", width=35, height=12, valign="middle") loop = MainLoop(main_widget, palette) connect_signal(done, 'click', start_game) loop.run() return MazeGame(height_enter.value(), width_enter.value())
class Window: def __init__(self, body=SolidFill(), header=None, footer=None, focus_part=None, unhandled_input=None, palette=None): self.document = Frame(body, header, footer, focus_part) self.loop = MainLoop( self.document, palette, event_loop=AsyncioEventLoop(loop=asyncio.get_event_loop()), unhandled_input=unhandled_input ) self.loop.screen.set_terminal_properties(colors=256) self.body = body self.footer = footer self.header = header def run(self): self.loop.run() def exit(self): raise ExitMainLoop() def set_state(self, key, value): self.state[key] = value def get_state(self, key): try: return self.state[key] except KeyError: return None
def main(): kern = QueueKernelManager() kern.start_kernel() kern.start_channels() queue = kern.rcvd_queue widget = InterpreterWidget() screen = PagerScreen() interp = IpyInterpreter(widget, screen, kern) eventloop = IpyEventLoop(queue, interp) mainloop = MainLoop(widget, unhandled_input = interp.handle_input, event_loop = eventloop) try: mainloop.run() except: try: kern.stop_channels() kern.kill_kernel() except RuntimeError: pass raise
def __init__(self, tracks=None, tempo=None): self.main_loop = MainLoop(widget=None) self.osc = OscUI(self) self.transport = JACKOSCKlickTransport(tempo, osc=self.osc.server) self.tracks = tracks or self.tracks self.urwid = UrwidUI(self) self.main_loop.widget = self.urwid
def main(): background = AttrMap(SolidFill(' '), 'basic') pwdialog = PasswordDialog().compose() box = AttrMap(LineBox(pwdialog), 'blackongrey') window = Overlay(box, background, 'center', 30, 'middle', 10) mainloop = MainLoop(window, unhandled_input=callback, palette=simple_colours) mainloop.run()
def __init__(self): self.cr = CommandRunner() self.console = ConsoleMode() self.node_view = NodeViewMode(self) self.lock_ticks = 0 # start in a locked state self.locked = False self.juju_state, _ = pegasus.poll_state() self.init_machine() MainLoop.__init__(self, self.node_view.target, STYLES, unhandled_input=self._header_hotkeys)
def __init__(self, body=SolidFill(), header=None, footer=None, focus_part=None, unhandled_input=None, palette=None): self.document = Frame(body, header, footer, focus_part) self.loop = MainLoop( self.document, palette, event_loop=AsyncioEventLoop(loop=asyncio.get_event_loop()), unhandled_input=unhandled_input ) self.loop.screen.set_terminal_properties(colors=256) self.body = body self.footer = footer self.header = header
class Application(object): def __init__(self): pass def run(self): """Run commander""" self.parse_args() self.init_logger() self.create_ui() self.create_remote_api() self._run() self.finalize() def parse_args(self): print("Parsing args...") def init_logger(self): print("Initiating logger...") def create_ui(self): print("Creating user interface...") self.main_window = MainWindow(self) self.login_window = LoginWindow(self, get_user=self.get_user) def create_remote_api(self): print("Creating remote api ...") def _run(self): self.loop = MainLoop(self.main_window, input_filter=self.input_filter) self.login_window.show() self.loop.run() def exit(self): raise ExitMainLoop() def finalize(self): print("Finalizing") def get_user(self, username, password): if username == "18" and password == "123": return True return False def input_filter(self, keys, raw): if 'f10' in keys: self.exit() return keys
def top(period=1, get_state=get_demo_state): """Display process information. Arguments: - period (float) : update period - get_state (callable) : function to generate state information """ engine_table = Columns([]) process_table = Columns([]) def make_text(title, attr="", align="left"): """Create a Text object with given content, style and alignment.""" return Text((attr, " %s" % title), align=align) def make_separator(): """Create a separator.""" return make_text("") def update(): engines, processes = get_state() engine_table.contents = get_engine_table_content(engines) process_table.contents = get_process_table_content([header] + processes) items = [ make_separator(), make_text("Process Viewer", attr="section", align="center"), make_text("Engine Usage:"), LineBox(engine_table, **{arg: " " for arg in linebox_args}), make_text("Process Table:"), make_separator(), LineBox(process_table), make_separator(), make_text("Press (q) to quit.") ] def on_timer(loop, user_data): update() loop.set_alarm_in(period, on_timer) def on_key(key): if key in ('q', 'Q'): raise ExitMainLoop() loop = MainLoop(get_padded(items), palette, unhandled_input=on_key) on_timer(loop, None) # Start timer loop.run()
def __init__(self, port, logs=None): # Build Web App self.port = port self.logs = logs self.webapp = web.Application(middlewares=[ # Just in case someone wants to use it behind a reverse proxy # Not sure why someone will want to do that though XForwardedRelaxed().middleware, # Handle unexpected and HTTP exceptions self._middleware_exceptions, # Handle media type validation self._middleware_media_type, # Handle schema validation self._middleware_schema, ]) self.webapp.router.add_get('/api/logs', self.api_logs) self.webapp.router.add_post('/api/config', self.api_config) self.webapp.router.add_post('/api/push', self.api_push) self.webapp.router.add_post('/api/message', self.api_message) # Enable CORS in case someone wants to build a web agent self.cors = CorsConfig( self.webapp, defaults={ '*': ResourceOptions( allow_credentials=True, expose_headers='*', allow_headers='*', ) } ) for route in self.webapp.router.routes(): self.cors.add(route) # Create task for the push hearbeat event_loop = get_event_loop() self.timestamp = None self.heartbeat = event_loop.create_task(self._check_last_timestamp()) # Build Terminal UI App self.ui = UIManager() self.tuiapp = MainLoop( self.ui.topmost, pop_ups=True, palette=self.ui.palette, event_loop=AsyncioEventLoop(loop=event_loop), )
def __init__(self, config, interface): self.config = config self.data_path = path.expanduser(self.config.get_data_path()) self.notes = self.load_notes(self.data_path) self.tags = self.load_tags(self.notes) self.interface = interface self.editor_mode = False self.key_handler = KeyHandler(self, config) self.loop = MainLoop(interface, config.get_palette(), input_filter=self.key_handler.handle) self.refresh_interface() self.interface.focus_first_note() self.loop.run()
def setUp(self): super(ControllerTest, self).setUp() stream = BytesIO() self.encoder = StreamResultToBytes(stream) self.loop = MainLoop(Console(self.repository)) watcher = MemoryWatcher(stream) self.controller = Controller(watcher, self.repository)
def __init__(self, screen_controller, wallpaper_controller): self._scrctrl = screen_controller self._wpctrl = wallpaper_controller self._layout() self._reading_command = False self._loop = MainLoop(widget=self._root, palette=palette, unhandled_input=self._handle_global_input) self._loop.screen.set_terminal_properties( colors=256, bright_is_bold=False, has_underline=True) # make special key combinations available, see # https://github.com/urwid/urwid/issues/140 self._loop.screen.tty_signal_keys(stop='undefined')
def run_twisted(self): from twisted.internet import reactor evloop = urwid.TwistedEventLoop(reactor, manage_reactor=False) self.screen = urwid.raw_display.Screen() self.screen.register_palette(self.palette) self.loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input, screen = self.screen, event_loop = evloop) self.loop.set_alarm_in(0.1, lambda loop, _: loop.draw_screen()) self.loop.start() # The loggers get a Handler that writes to the screen. We want this to only # happen if the screen exists, so de-register them after the reactor stops. reactor.addSystemEventTrigger('after','startup', self.register_loggers) reactor.addSystemEventTrigger('before','shutdown', self.unregister_loggers) reactor.run() # We might have stopped the screen already, and the stop() method # doesn't check for stopping twice. if self.called_loop_stop: self.logger.warn('Internal error!') else: self.loop.stop() self.called_loop_stop = True
class Application(object): allowed_colors = (1, 16, 88, 256) def __init__(self, appname='nobix'): self.appname = appname self.conf = ConfigParser() def run(self, args=None): """Main entry point for application""" if args is None: args = sys.argv[1:] self.configure() self.init_ui() self.main_loop() def configure(self): self.conf.read('nobix.cfg') def init_ui(self): colors = self.conf.getint("ui", "colors") skins_dir = self.conf.get("paths", "skins") if colors not in self.allowed_colors: self.stop() self.window = MainWindow(self) def main_loop(self): tmp_palette = [ ('mainbody', 'white', 'dark blue'), ('menubar', 'black', 'light gray'), ('statusbar', 'white', 'dark cyan'), ] self.loop = MainLoop(self.window, palette=tmp_palette, unhandled_input=self.unhandled_input) self.loop.run() def quit(self): raise ExitMainLoop() def unhandled_input(self, key): if key in ('q', 'Q'): self.quit()
def diary(args, db): ''' ## diary > ch2 diary [DATE] The date can be an absolute day or the number of days previous. So `ch2 diary 1` selects yesterday. Display the daily diary. Enter information here. To exit, alt-q (or, without saving, alt-x). > ch2 diary (--month | --year | --schedule SCHEDULE) [DATE} Display a summary for the month / year / schedule. ''' date, schedule = args[DATE], args[SCHEDULE] if not date: date = dt.date.today() else: days = None try: # try int first because we need to separate the case of days from years days = int(date) if days > 1000: days = None except ValueError: pass if days is None: date = to_date(date) else: date = dt.date.today() - dt.timedelta(days=days) with db.session_context() as s: TopicJournal.check_tz(log, s) if schedule: schedule = Schedule(schedule) if schedule.start or schedule.finish: raise Exception('Schedule must be open (no start or finish)') MainLoop(ScheduleDiary(log, db, date, schedule), palette=PALETTE_RAINBOW).run() else: MainLoop(DailyDiary(log, db, date), palette=PALETTE_RAINBOW).run() if not args[FAST]: print('\n Please wait while statistics are updated...') run_pipeline(db, PipelineType.STATISTIC) print(' ...done (thanks!)\n')
def setUp(self): super(FileWatcherTest, self).setUp() self.filename = self.useFixture(TempDir()).join("foo") with open(self.filename, "wb") as fd: fd.write(b("hello")) self.loop = MainLoop(None) self.protocol = DummyProtocol(self.loop) self.watcher = FileWatcher(self.filename)
def start(self): self.issue_list() self.loop = MainLoop(self.ui, PALETTE, handle_mouse=True, unhandled_input=self.handle_keypress) self.loop.run()
def __init__(self, body): TUI.root = Frame(body.root, Text(("header", ""), "center"), Text(TUI.main_helper_text, "center")) TUI.loop = MainLoop(TUI.root, TUI.palette, unhandled_input=TUI.unhandled_input) TUI.install_signals_handler()
def main_loop(self): tmp_palette = [ ('mainbody', 'white', 'dark blue'), ('menubar', 'black', 'light gray'), ('statusbar', 'white', 'dark cyan'), ] self.loop = MainLoop(self.window, palette=tmp_palette, unhandled_input=self.unhandled_input) self.loop.run()
def __init__(self, controller, style): # Shared objects to help event handling. self.events = Queue() self.lock = Lock() self.view = MainWindow(controller) self.screen = raw_display.Screen() self.screen.set_terminal_properties(256) self.loop = MainLoop(widget=self.view, palette=style, screen=self.screen, unhandled_input=Tui.exit_handler, pop_ups=True) self.pipe = self.loop.watch_pipe(self.update_ui) self.loop.set_alarm_in(0.1, self.update_timer, self.view.logo.timer) connect_signal(self.view.issues_table, 'refresh', lambda source: self.loop.draw_screen()) connect_signal(self.view.stat_table, 'refresh', lambda source: self.loop.draw_screen())
def __init__(self, startCoords=(0, 0)): """ Controller constructor New game: self._startinPosition = (0, 0) Load game: self._startingPosition = startCoords """ self._saveDir = 'saves' self._player = Player("Patrick", 15, gold=100) self._playerLocation = startCoords self._room = None self.map = None self._currentRoom = None self.loadFile('src/data/world.csv') self._roomKey = self.getRoomKey() # Preseed _visited dict with special rooms self._visited = { '00': Room(0, 0, self.map['00'][1]), # Office '01': SearchRoom(0, 1, self.map['01'][1]), # Search '02': TutorialRoom(0, 2, self.map['02'][1]), # Interrogate '03': Room(0, 3, self.map['03'][1]), # Combat '-55': Bookstore(-5, 5, self.map['-55'][1]), # Bookstore '-312': GroceryStore(-3, 12, self.map['-312'][1]), # Grocery '110': Bar(1, 10, self.map['110'][1]), # Bar '615': Room(6, 15, self.map['615'][1]) # Apartment } self._gameView = GameView(self.getDescriptionText(), self.getStatText(), directions=self.getDirectionOptions(), actions=self.getActionOptions(), gameOpts=self.getGameOptions(), controller=self) self._initialView = InitialView(['New game', 'Load game', 'Exit'], self._gameView, game_loop=None, controller=self) self._loop = MainLoop(self._initialView.screen, palette=[('reversed', 'standout', '')]) self._initialView.set_game_loop(self._loop)
def main(): task_list_box = TaskListBox() refresh = partial(on_tasks_refresh, task_list_box) with just_start(write_status, refresh, client_notify) as action_runner: task_list_box.action_handler = ActionHandler(action_runner, FocusedTask(task_list_box)) task_list_box = LineBox(task_list_box, title='Tasks') status_box = LineBox(Filler(status, valign=TOP), title='App Status') columns = Columns([('weight', 1.3, task_list_box), ('weight', 1, status_box)]) MainLoop( TopWidget(columns, footer=pomodoro_status_box), palette=( ('error', *get_error_colors()), ) ).run()
def __init__(self): self.keybind = {} self.main_helper_text = self.generate_helper_text([ ("F10", "Quit", "helper_text_red"), ]) self.subview_helper_text = self.generate_helper_text([ ("F1", "Confirm", "helper_text_green"), ("F5", "Abort", "helper_text_brown"), ("F10", "Quit", "helper_text_red"), ("TAB", "Next", "helper_text_light"), ("S-TAB", "Previous", "helper_text_light") ]) self.root = Frame(self.generate_main_view(), Text(("header", ""), "center"), self.main_helper_text) self.loop = MainLoop(self.root, palette, unhandled_input=self.unhandled_input) self.bind_global("f10", self.quit) self.handle_os_signals()
def run(self): board = Filler(Text(u''), valign='top') footer = Pile([ Divider(div_char=u'\u2500'), CommandLineWrapper(board=board, client=self.client) ], focus_item=1) screen = Frame(board, footer=footer, focus_part='footer') try: MainLoop(screen, [ ('complete', 'default', 'default'), ('complete_selected', 'default,bold', 'default') ], pop_ups=True).run() except KeyboardInterrupt: pass
def main(): # optional param # rows p = ProcessTable() r = ResourceManager() # height is num_cpus rows + mem row + swap row + empty row r_height = len(r.cpu_meters) + 3 frame = Frame(p, header=BoxAdapter(r, r_height), footer=Footer()) def exit(key): if key in ('q', 'Q'): raise ExitMainLoop() def refresh(loop, data): p.update() r.update() loop.set_alarm_in(2, refresh) mainloop = MainLoop(frame, palette, pop_ups=True, unhandled_input=exit) mainloop.set_alarm_in(1, refresh) mainloop.run()
from urwid import MainLoop, ExitMainLoop, Text, Filler, AttrMap PALETTE = [ ('banner', 'black', 'light gray'), ('streak', 'black', 'dark red'), ('bg', 'black', 'dark blue'), ] def exit_on_q(key): if key == 'Q': raise ExitMainLoop() txt = Text(('banner', u"Hello World"), align='center') map1 = AttrMap(txt, 'streak') fill = Filler(map1) map2 = AttrMap(fill, 'bg') loop = MainLoop(map2, PALETTE, unhandled_input=exit_on_q) if __name__ == '__main__': loop.run()
i.split() for i in [line.strip() for line in open('/proc/stat')] ] # Testing if __name__ == '__main__': from sys import argv from timeit import Timer cm = CPUMeter(1) frame = Frame(ListBox([cm]), header=None, footer=Footer()) def exit(key): if key in ('q', 'Q'): raise ExitMainLoop() def refresh(loop, data): cm.update() loop.set_alarm_in(1, refresh) if argv[1] == 'perf': t = Timer(lambda: cm.update()) print 'CPUMeter: ', t.timeit(number=10000) else: main_loop = MainLoop(frame, palette, unhandled_input=exit, pop_ups=True) main_loop.set_alarm_in(1, refresh) main_loop.run()
(4, Text('run│', wrap='clip')), (Text('key', wrap='clip')), ]), 'title_header') body_frame = Frame(body, header=title_header, footer=footer.get_widget()) wrapper = GazuaFrame(body_frame, arrow_callback=on_arrow_pressed) palette = [ ('header', 'white', 'dark red', 'bold'), ('footer', 'white', 'light gray', 'bold'), ('title_header', 'black', 'dark cyan', 'bold'), ('footer', 'black', 'light gray'), ('group', 'black', 'yellow', 'bold'), ('host', 'black', 'dark green'), ('aws_focus', 'black', 'dark green'), ('group_focus', 'black', 'dark green'), ('instance_focus', 'black', 'yellow'), ] def key_pressed(key): if key == 'esc': raise urwid.ExitMainLoop() loop = MainLoop(wrapper, palette, handle_mouse=False, unhandled_input=key_pressed) loop.run()
class Tui(object): signals = ['close'] def __init__(self, controller, style): # Shared objects to help event handling. self.events = Queue() self.lock = Lock() self.view = MainWindow(controller) self.screen = raw_display.Screen() self.screen.set_terminal_properties(256) self.loop = MainLoop(widget=self.view, palette=style, screen=self.screen, unhandled_input=Tui.exit_handler, pop_ups=True) self.pipe = self.loop.watch_pipe(self.update_ui) self.loop.set_alarm_in(0.1, self.update_timer, self.view.logo.timer) connect_signal(self.view.issues_table, 'refresh', lambda source: self.loop.draw_screen()) connect_signal(self.view.stat_table, 'refresh', lambda source: self.loop.draw_screen()) def update_ui(self, _): while True: try: event = self.events.get_nowait() if hasattr(self, event['fn']): getattr(self, event['fn'])(**event['kwargs']) except Exception: break def update_timer(self, loop, timer): if timer.update(): loop.set_alarm_in(0.1, self.update_timer, timer) def new_fuzz_job(self, ident, cost, sut, fuzzer, batch): self.view.job_table.add_fuzz_job(ident, fuzzer, sut, cost, batch) def new_reduce_job(self, ident, cost, sut, issue_id, size): self.view.job_table.add_reduce_job(ident, sut, cost, issue_id, size) def new_update_job(self, ident, cost, sut): self.view.job_table.add_update_job(ident, sut) def new_validate_job(self, ident, cost, sut, issue_id): self.view.job_table.add_validate_job(ident, sut, issue_id) def remove_job(self, ident): self.view.job_table.remove_job(ident) def activate_job(self, ident): self.view.job_table.activate_job(ident) def job_progress(self, ident, progress): self.view.job_table.job_progress(ident, progress) def update_load(self, load): self.view.logo.load.set_completion(load) def update_fuzz_stat(self): self.view.stat_table.update() def new_issue(self, ident, issue): # Do shiny animation if a new issue has received. self.view.logo.do_animate = True self.loop.set_alarm_at(time.time() + 5, callback=self.view.logo.stop_animation) self.loop.set_alarm_in(0.1, self.view.logo.animate, self.view.logo) self.view.issues_table.add_row(issue) def invalid_issue(self, ident, issue): self.view.issues_table.invalidate_row(ident=issue['_id']) def update_issue(self, ident, issue): self.view.issues_table.update_row(ident=issue['_id']) def reduced_issue(self, ident, issue): self.view.issues_table.update_row(ident=issue['_id']) def warning(self, ident, msg): self.view._emit('warning', msg) @staticmethod def exit_handler(key): if key in ('q', 'Q', 'f10'): raise ExitMainLoop()
class Chat(object): """ The main chat class. Connects the GUI pieces together. """ def __init__(self, nickname): self.nickname = nickname self.output = ChatMessages(self) self.message = ChatInput(self) self.window = Frame( body=self.output, footer=self.message, focus_part='footer' ) self.main_loop = None self.connection = Connection(self) def connected(self): self.write_status('Connected') def send_message(self, message): self.connection.send('MSG', self.nickname, message) def write(self, message): self.output.add(message) def write_message(self, nickname, message): self.write("%s <%s> %s" % (self.time(), nickname, message)) def write_status(self, message): self.write("*** %s ***" % message) def time(self, date=False): format_string = '%X' if date: format_string = '%c' return datetime.now().strftime(format_string).strip() def user_command(self, command): arguments = command.split(' ') command = arguments.pop(0) def _require_args(args, n): if len(args) < n: self.write("%s needs %d argument(s), %d given" % (command, n, len(args))) return False return True def _quit(): raise ExitMainLoop() def _unknown(): self.write('Unknown command %r' % command) def _nickname(new_nickname): self.nickname = new_nickname self.write_status('Nickname changed to %r' % new_nickname) command_map = { 'quit': (_quit, 0), 'nickname': (_nickname, 1) } command, args_needed = command_map.get(command, (_unknown, 0)) if _require_args(arguments, args_needed): command(*arguments) def connect(self): self.write_status('Connecting') self.connection.open() def run(self): """ Start the chat client """ self.write_status("Chat started at %s" % self.time(date=True)) self.main_loop = MainLoop(self.window, event_loop=GeventLoop()) gevent.spawn(self.connect) self.main_loop.run()
def run(self): """ Start the chat client """ self.write_status("Chat started at %s" % self.time(date=True)) self.main_loop = MainLoop(self.window, event_loop=GeventLoop()) gevent.spawn(self.connect) self.main_loop.run()
class Chat(object): """ The main chat class. Connects the GUI pieces together. """ def __init__(self, nickname): self.nickname = nickname self.output = ChatMessages(self) self.message = ChatInput(self) self.window = Frame(body=self.output, footer=self.message, focus_part="footer") self.main_loop = None self.connection = Connection(self) def connected(self): self.write_status("Connected") def send_message(self, message): self.connection.send("MSG", self.nickname, message) def write(self, message): self.output.add(message) def write_message(self, nickname, message): self.write("%s <%s> %s" % (self.time(), nickname, message)) def write_status(self, message): self.write("*** %s ***" % message) def time(self, date=False): format_string = "%X" if date: format_string = "%c" return datetime.now().strftime(format_string).strip() def user_command(self, command): arguments = command.split(" ") command = arguments.pop(0) def _require_args(args, n): if len(args) < n: self.write("%s needs %d argument(s), %d given" % (command, n, len(args))) return False return True def _quit(): raise ExitMainLoop() def _unknown(): self.write("Unknown command %r" % command) def _nickname(new_nickname): self.nickname = new_nickname self.write_status("Nickname changed to %r" % new_nickname) command_map = {"quit": (_quit, 0), "nickname": (_nickname, 1)} command, args_needed = command_map.get(command, (_unknown, 0)) if _require_args(arguments, args_needed): command(*arguments) def connect(self): self.write_status("Connecting") self.connection.open() def run(self): """ Start the chat client """ self.write_status("Chat started at %s" % self.time(date=True)) self.main_loop = MainLoop(self.window, event_loop=GeventLoop()) gevent.spawn(self.connect) self.main_loop.run()
class Shipit(): ISSUE_LIST = 0 ISSUE_DETAIL = 1 PR_DETAIL = 2 PR_DIFF = 3 def __init__(self, ui, repo): self.ui = ui self.repo = repo self.issues_and_prs = IssuesAndPullRequests(self.repo) self.issues_and_prs.set_modified_callback(self.on_modify_issues_and_prs) self.issues_and_prs.show_open_issues() # Event handlers on("show_open_issues", self.issues_and_prs.show_open_issues) on("show_closed_issues", self.issues_and_prs.show_closed_issues) on("show_pull_requests", self.issues_and_prs.show_pull_requests) def start(self): self.issue_list() self.loop = MainLoop(self.ui, PALETTE, handle_mouse=True, unhandled_input=self.handle_keypress) self.loop.run() def on_modify_issues_and_prs(self): self.ui.issues_and_pulls(self.issues_and_prs) def issue_list(self): self.mode = self.ISSUE_LIST self.ui.issues_and_pulls(self.issues_and_prs) def issue_detail(self, issue): self.mode = self.ISSUE_DETAIL self.ui.issue(issue) def pull_request_detail(self, pr): self.mode = self.PR_DETAIL self.ui.pull_request(pr) def diff(self, pr): self.mode = self.PR_DIFF self.ui.diff(pr) def handle_keypress(self, key): # R: reopen # D: delete if key == KEY_OPEN_ISSUE: if self.mode is self.ISSUE_LIST: issue_text = spawn_editor(NEW_ISSUE) if issue_text is None: # TODO: cancelled by the user return contents = unlines(issue_text) title, *body = contents if not title: # TODO: incorrect input, at least a title is needed return body = lines(body) issue = self.repo.create_issue(title=title, body=body) if issue: self.issue_detail(issue) elif key == KEY_CLOSE_ISSUE: issue = self.ui.get_issue() if not issue: return issue.close() if self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) elif key == KEY_REOPEN_ISSUE: issue = self.ui.get_issue() if issue and is_closed(issue): issue.reopen() if self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) elif key == KEY_BACK: if self.mode is self.PR_DIFF: pr = self.ui.get_focused_item() self.pull_request_detail(pr) elif self.mode in [self.ISSUE_DETAIL, self.PR_DETAIL]: self.issue_list() elif key == KEY_DETAIL: if self.mode is self.ISSUE_LIST: issue_or_pr = self.ui.get_focused_item() if is_issue(issue_or_pr): self.issue_detail(issue_or_pr) elif is_pull_request(issue_or_pr): self.pull_request_detail(issue_or_pr) elif key == KEY_EDIT: # TODO: not the issue but what it's focused, could be a comment! issue = self.ui.get_issue() if issue is None: return title_and_body = '\n'.join([issue.title, issue.body_text]) issue_text = spawn_editor(title_and_body) if issue_text is None: # TODO: cancelled return contents = unlines(issue_text) title, *body = contents if not title: # TODO: incorrect input, at least a title is needed return body = lines(body) issue.edit(title=title, body=body) if self.mode is self.ISSUE_LIST: self.issue_list() elif self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) elif key == KEY_COMMENT: issue = self.ui.get_issue() if issue is None: return # Inline all the thread comments issue_thread = [format_comment(comment) for comment in issue.iter_comments()] issue_thread.insert(0,'\n\n'.join([issue.title, issue.body_text, ''])) # Make the whole thread a comment issue_thread.insert(0, '<!---\n') issue_thread.append('-->') comment_text = spawn_editor('\n'.join(issue_thread)) if comment_text is None: # TODO: cancelled return # TODO: strip comments first! if not comment_text.strip(): # TODO: invalid input return issue.create_comment(comment_text) self.issue_detail(issue) elif key == KEY_QUIT: raise ExitMainLoop elif key == KEY_DIFF: if self.mode is self.PR_DETAIL: pr = self.ui.get_focused_item() self.diff(pr)
The text will automatically align correctly. To exit, press Return.""") string = [] cursor = 0 if len(sys.argv) > 1: string = hilbert_to_str(sys.argv[1]) cursor = len(string) if len(string) > 1: text.set_text(str_to_hilbert(string)) elif len(string) == 1: text.set_text(''.join(string)) filler = SolidFill(" ") overlay = Overlay(Filler(text), filler, "center", 40, "middle", 40) main = MainLoop(overlay, unhandled_input=keystroke) main.run() print("Do you want to save the file? (Ctrl+C to abort)") try: default = sys.argv[1] if len(sys.argv) > 1 else "test.act" fn = input("Save as [{}]: ".format(default)) if not fn: fn = default with open(fn, "w") as f: if len(string) > 1: lines = str_to_hilbert(string).split("\n") for line in lines: f.write(line.rstrip()) f.write("\n") else:
def _run(self): self.loop = MainLoop(self.main_window, input_filter=self.input_filter) self.login_window.show() self.loop.run()
class Shipit(): ISSUE_LIST = 0 ISSUE_DETAIL = 1 PR_DETAIL = 2 PR_DIFF = 3 def __init__(self, ui, repo, user): self.ui = ui self.repo = repo self.user = user self.issues_and_prs = IssuesAndPullRequests(self.repo) self.issues_and_prs.set_modified_callback( self.on_modify_issues_and_prs) self.issues_and_prs.show_open_issues() # Event handlers on("show_all", self.issues_and_prs.show_all) created_by_you = partial(self.issues_and_prs.show_created_by, self.user) on("show_created_by_you", created_by_you) assigned_to_you = partial(self.issues_and_prs.show_assigned_to, self.user) on("show_assigned_to_you", assigned_to_you) mentioning_you = partial(self.issues_and_prs.show_mentioning, self.user) on("show_mentioning_you", mentioning_you) on("show_open_issues", self.issues_and_prs.show_open_issues) on("show_closed_issues", self.issues_and_prs.show_closed_issues) on("show_pull_requests", self.issues_and_prs.show_pull_requests) on("filter_by_labels", self.issues_and_prs.filter_by_labels) on("clear_label_filters", self.issues_and_prs.clear_label_filters) def start(self): self.loop = MainLoop(self.ui, PALETTE, handle_mouse=True, unhandled_input=self.handle_keypress) self.loop.set_alarm_at(0, discard_args(self.issue_list)) self.loop.run() def on_modify_issues_and_prs(self): self.ui.issues_and_pulls(self.issues_and_prs) def issue_list(self): self.mode = self.ISSUE_LIST self.ui.issues_and_pulls(self.issues_and_prs) self.loop.draw_screen() def issue_detail(self, issue): self.mode = self.ISSUE_DETAIL self.ui.issue(issue) self.loop.draw_screen() def pull_request_detail(self, pr): self.mode = self.PR_DETAIL self.ui.pull_request(pr) self.loop.draw_screen() def diff(self, pr): self.mode = self.PR_DIFF self.ui.diff(pr) self.loop.draw_screen() def handle_keypress(self, key): if key == KEY_OPEN_ISSUE: if self.mode is self.ISSUE_LIST: issue_text = self.spawn_editor(NEW_ISSUE) if issue_text is None: # TODO: cancelled by the user return contents = unlines(issue_text) title, *body = contents if not title: # TODO: incorrect input, at least a title is needed return body = lines(body) issue = self.repo.create_issue(title=title, body=body) if issue: self.issue_detail(issue) else: self.issue_list() elif key == KEY_CLOSE_ISSUE: issue = self.ui.get_issue() if not issue: return self.issues_and_prs.close(issue) if self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) elif key == KEY_REOPEN_ISSUE: issue = self.ui.get_issue() if issue and is_closed(issue): self.issues_and_prs.reopen(issue) if self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) elif key == KEY_BACK: if self.mode is self.PR_DIFF: pr = self.ui.get_focused_item() self.pull_request_detail(pr) elif self.mode in [self.ISSUE_DETAIL, self.PR_DETAIL]: self.issue_list() elif key == KEY_DETAIL: if self.mode is self.ISSUE_LIST: issue_or_pr = self.ui.get_focused_item() if is_issue(issue_or_pr): self.issue_detail(issue_or_pr) elif is_pull_request(issue_or_pr): self.pull_request_detail(issue_or_pr) elif key == KEY_EDIT: item = self.ui.get_focused_item() if item is None: return if is_pull_request(item): item = item.issue # In case you aren't the owner of the repo, you are only allowed to # edit things that you created. if self.repo.owner != self.user and item.user != self.user: # TODO: beep return if is_issue(item): self.edit_issue(item) else: self.edit_body(item) elif key == KEY_COMMENT: item = self.ui.get_issue_or_pr() if item is None: return if is_pull_request(item): issue = item.issue self.comment_issue(item.issue, pull_request=item) else: self.comment_issue(item) elif key == KEY_DIFF: if self.mode is self.PR_DETAIL: pr = self.ui.get_focused_item() self.diff(pr) elif key == KEY_BROWSER: item = self.ui.get_focused_item() if hasattr(item, '_api'): webbrowser.open(item.html_url) elif key == KEY_QUIT: raise ExitMainLoop def edit_issue(self, issue): title_and_body = '\n'.join([issue.title, issue.body]) issue_text = self.spawn_editor(title_and_body) if issue_text is None: # TODO: cancelled return contents = unlines(issue_text) title, *body = contents if not title: # TODO: incorrect input, at least a title is needed return body = lines(body) issue.edit(title=title, body=body) if self.mode is self.ISSUE_LIST: # TODO: focus self.issue_list() elif self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) # TODO def edit_pull_request(self, pr): pass def edit_body(self, item): text = self.spawn_editor(item.body) if text is None: # TODO: cancelled return # TODO: ui must be updated! item.edit(text) def comment_issue(self, issue, *, pull_request=False): issue_thread = format_issue_thread(issue) comment_text = self.spawn_editor('\n'.join(issue_thread)) if comment_text is None: # TODO: cancelled return if not comment_text: # TODO: A empty comment is invalid input return issue.create_comment(comment_text) if pull_request: self.pull_request_detail(pull_request) else: self.issue_detail(issue) def spawn_editor(self, help_text=None): """ Open a editor with a temporary file containing ``help_text``. If the exit code is 0 the text from the file will be returned. Otherwise, ``None`` is returned. """ text = '' if help_text is None else help_text tmp_file = tempfile.NamedTemporaryFile(mode='w+', suffix='.markdown', delete=False) tmp_file.write(text) tmp_file.close() fname = tmp_file.name self.loop.screen.stop() return_code = subprocess.call([os.getenv('EDITOR', 'vim'), fname]) self.loop.screen.start() if return_code == 0: with open(fname, 'r') as f: contents = f.read() if return_code != 0: return None else: return strip_comments(contents)
class Shipit(): ISSUE_LIST = 0 ISSUE_DETAIL = 1 PR_DETAIL = 2 PR_DIFF = 3 def __init__(self, ui, repo, user): self.ui = ui self.repo = repo self.user = user self.issues_and_prs = IssuesAndPullRequests(self.repo) self.issues_and_prs.set_modified_callback(self.on_modify_issues_and_prs) self.issues_and_prs.show_open_issues() # Event handlers on("show_all", self.issues_and_prs.show_all) created_by_you = partial(self.issues_and_prs.show_created_by, self.user) on("show_created_by_you", created_by_you) assigned_to_you = partial(self.issues_and_prs.show_assigned_to, self.user) on("show_assigned_to_you", assigned_to_you) mentioning_you = partial(self.issues_and_prs.show_mentioning, self.user) on("show_mentioning_you", mentioning_you) on("show_open_issues", self.issues_and_prs.show_open_issues) on("show_closed_issues", self.issues_and_prs.show_closed_issues) on("show_pull_requests", self.issues_and_prs.show_pull_requests) on("filter_by_labels", self.issues_and_prs.filter_by_labels) on("clear_label_filters", self.issues_and_prs.clear_label_filters) def start(self): self.loop = MainLoop(self.ui, PALETTE, handle_mouse=True, unhandled_input=self.handle_keypress) self.loop.set_alarm_at(0, discard_args(self.issue_list)) self.loop.run() def on_modify_issues_and_prs(self): self.ui.issues_and_pulls(self.issues_and_prs) def issue_list(self): self.mode = self.ISSUE_LIST self.ui.issues_and_pulls(self.issues_and_prs) self.loop.draw_screen() def issue_detail(self, issue): self.mode = self.ISSUE_DETAIL self.ui.issue(issue) self.loop.draw_screen() def pull_request_detail(self, pr): self.mode = self.PR_DETAIL self.ui.pull_request(pr) self.loop.draw_screen() def diff(self, pr): self.mode = self.PR_DIFF self.ui.diff(pr) self.loop.draw_screen() def handle_keypress(self, key): if key == KEY_OPEN_ISSUE: if self.mode is self.ISSUE_LIST: issue_text = self.spawn_editor(NEW_ISSUE) if issue_text is None: # TODO: cancelled by the user return contents = unlines(issue_text) title, *body = contents if not title: # TODO: incorrect input, at least a title is needed return body = lines(body) issue = self.repo.create_issue(title=title, body=body) if issue: self.issue_detail(issue) else: self.issue_list() elif key == KEY_CLOSE_ISSUE: issue = self.ui.get_issue() if not issue: return self.issues_and_prs.close(issue) if self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) elif key == KEY_REOPEN_ISSUE: issue = self.ui.get_issue() if issue and is_closed(issue): self.issues_and_prs.reopen(issue) if self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) elif key == KEY_BACK: if self.mode is self.PR_DIFF: pr = self.ui.get_focused_item() self.pull_request_detail(pr) elif self.mode in [self.ISSUE_DETAIL, self.PR_DETAIL]: self.issue_list() elif key == KEY_DETAIL: if self.mode is self.ISSUE_LIST: issue_or_pr = self.ui.get_focused_item() if is_issue(issue_or_pr): self.issue_detail(issue_or_pr) elif is_pull_request(issue_or_pr): self.pull_request_detail(issue_or_pr) elif key == KEY_EDIT: item = self.ui.get_focused_item() if item is None: return if is_pull_request(item): item = item.issue # In case you aren't the owner of the repo, you are only allowed to # edit things that you created. if self.repo.owner != self.user and item.user != self.user: # TODO: beep return if is_issue(item): self.edit_issue(item) else: self.edit_body(item) elif key == KEY_COMMENT: item = self.ui.get_issue_or_pr() if item is None: return if is_pull_request(item): issue = item.issue self.comment_issue(item.issue, pull_request=item) else: self.comment_issue(item) elif key == KEY_DIFF: if self.mode is self.PR_DETAIL: pr = self.ui.get_focused_item() self.diff(pr) elif key == KEY_BROWSER: item = self.ui.get_focused_item() if hasattr(item, '_api'): webbrowser.open(item.html_url) elif key == KEY_QUIT: raise ExitMainLoop def edit_issue(self, issue): title_and_body = '\n'.join([issue.title, issue.body]) issue_text = self.spawn_editor(title_and_body) if issue_text is None: # TODO: cancelled return contents = unlines(issue_text) title, *body = contents if not title: # TODO: incorrect input, at least a title is needed return body = lines(body) issue.edit(title=title, body=body) if self.mode is self.ISSUE_LIST: # TODO: focus self.issue_list() elif self.mode is self.ISSUE_DETAIL: self.issue_detail(issue) # TODO def edit_pull_request(self, pr): pass def edit_body(self, item): text = self.spawn_editor(item.body) if text is None: # TODO: cancelled return # TODO: ui must be updated! item.edit(text) def comment_issue(self, issue, *, pull_request=False): issue_thread = format_issue_thread(issue) comment_text = self.spawn_editor('\n'.join(issue_thread)) if comment_text is None: # TODO: cancelled return if not comment_text: # TODO: A empty comment is invalid input return issue.create_comment(comment_text) if pull_request: self.pull_request_detail(pull_request) else: self.issue_detail(issue) def spawn_editor(self, help_text=None): """ Open a editor with a temporary file containing ``help_text``. If the exit code is 0 the text from the file will be returned. Otherwise, ``None`` is returned. """ text = '' if help_text is None else help_text tmp_file = tempfile.NamedTemporaryFile(mode='w+', suffix='.markdown', delete=False) tmp_file.write(text) tmp_file.close() fname = tmp_file.name self.loop.screen.stop() return_code = subprocess.call([os.getenv('EDITOR', 'vim'), fname]) self.loop.screen.start() if return_code == 0: with open(fname, 'r') as f: contents = f.read() if return_code != 0: return None else: return strip_comments(contents)
def run(self): self.tick() with utils.console_blank(): MainLoop.run(self)
class CursesGUI(object): def __init__(self, choice_callback=None, command_callback=None, help_callback=None): self.palette = [ ('brick', 'light red', 'black'), ('rubble', 'yellow', 'black'), ('wood', 'light green', 'black'), ('concrete', 'white', 'black'), ('stone', 'light cyan', 'black'), ('marble', 'light magenta', 'black'), ('jack', 'dark gray', 'white'), ('msg_info', 'white', 'black'), ('msg_err', 'light red', 'black'), ('msg_debug', 'light green', 'black'), ] self.choice_callback = choice_callback self.command_callback = command_callback self.help_callback = help_callback self.screen = None self.loop = None self.called_loop_stop = False self.reactor_stop_fired = False self.quit_flag = False self.edit_msg = "Make selection ('q' to quit): " self.roll_list = SimpleListWalker([]) self.game_log_list = SimpleListWalker([]) self.choices_list = SimpleListWalker([]) self.state_text = SimpleListWalker([Text('Connecting...')]) self.edit_widget = Edit(self.edit_msg) self.roll = ListBox(self.roll_list) self.game_log = ListBox(self.game_log_list) self.choices = ListBox(self.choices_list) self.state = ListBox(self.state_text) self.left_frame = Pile([ LineBox(self.state), (13, LineBox(self.choices)), ]) self.right_frame = Pile([ LineBox(self.game_log), LineBox(self.roll) ]) self.state.set_focus(len(self.state_text)-1) self.columns = Columns([('weight', 0.75, self.left_frame), ('weight', 0.25, self.right_frame) ]) self.frame_widget = Frame(footer=self.edit_widget, body=self.columns, focus_part='footer') self.exc_info = None def register_loggers(self): """Gets the global loggers and sets up log handlers. """ self.game_logger_handler = RollLogHandler(self._roll_write) self.logger_handler = RollLogHandler(self._roll_write) self.game_logger = logging.getLogger('gtr.game') self.logger = logging.getLogger('gtr') self.logger.addHandler(self.logger_handler) self.game_logger.addHandler(self.game_logger_handler) #self.set_log_level(logging.INFO) def unregister_loggers(self): self.game_logger.removeHandler(self.game_logger_handler) self.logger.removeHandler(self.logger_handler) def fail_safely(f): """Wraps functions in this class to catch arbitrary exceptions, shut down the event loop and reset the terminal to a normal state. It then re-raises the exception. """ @wraps(f) def wrapper(self, *args, **kwargs): retval = None try: retval = f(self, *args, **kwargs) except urwid.ExitMainLoop: from twisted.internet import reactor if not self.reactor_stop_fired and reactor.running: # Make sure to call reactor.stop once reactor.stop() self.reactor_stop_fired = True except: #pdb.set_trace() from twisted.internet import reactor if not self.reactor_stop_fired and reactor.running: # Make sure to call reactor.stop once reactor.stop() self.reactor_stop_fired = True if not self.called_loop_stop: self.called_loop_stop = True self.loop.stop() # Save exception info for printing later outside the GUI. self.exc_info = sys.exc_info() raise return retval return wrapper def set_log_level(self, level): """Set the log level as per the standard library logging module. Default is logging.INFO. """ logging.getLogger('gtr.game').setLevel(level) logging.getLogger('gtr').setLevel(level) def run(self): loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input) loop.run() def run_twisted(self): from twisted.internet import reactor evloop = urwid.TwistedEventLoop(reactor, manage_reactor=False) self.screen = urwid.raw_display.Screen() self.screen.register_palette(self.palette) self.loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input, screen = self.screen, event_loop = evloop) self.loop.set_alarm_in(0.1, lambda loop, _: loop.draw_screen()) self.loop.start() # The loggers get a Handler that writes to the screen. We want this to only # happen if the screen exists, so de-register them after the reactor stops. reactor.addSystemEventTrigger('after','startup', self.register_loggers) reactor.addSystemEventTrigger('before','shutdown', self.unregister_loggers) reactor.run() # We might have stopped the screen already, and the stop() method # doesn't check for stopping twice. if self.called_loop_stop: self.logger.warn('Internal error!') else: self.loop.stop() self.called_loop_stop = True @fail_safely def handle_input(self, key): if key == 'enter': text = self.edit_widget.edit_text if text in ['q', 'Q']: self.handle_quit_request() else: self.quit_flag = False try: i = int(text) except ValueError: i = None self.handle_invalid_choice(text) if i is not None: self.handle_choice(i) self.edit_widget.set_edit_text('') def _roll_write(self, line, attr=None): """Add a line to the roll with palette attributes 'attr'. If no attr is specified, None is used. Default attr is plain text """ text = Text((attr, '* ' + line)) self.roll_list.append(text) self.roll_list.set_focus(len(self.roll_list)-1) self._modified() @fail_safely def update_state(self, state): """Sets the game state window via one large string. """ self.logger.debug('Drawing game state.') self.state_text[:] = [self.colorize(s) for s in state.split('\n')] self._modified() @fail_safely def update_game_log(self, log): """Sets the game log window via one large string. """ self.logger.debug('Drawing game log.') self.game_log_list[:] = [self.colorize(s) for s in log.split('\n')] self.game_log_list.set_focus(len(self.game_log_list)-1) self._modified() @fail_safely def update_choices(self, choices): """Update choices list. """ self.choices_list[:] = [self.colorize(str(c)) for c in choices] self._modified() length = len([c for c in choices if c[2] == '[']) i = randint(1,length) if length else 0 self.choices_list.append(self.colorize('\nPicking random choice: {0} in 1s'.format(i))) self._modified() #from twisted.internet import reactor #reactor.callLater(1, self.handle_choice, i) @fail_safely def update_prompt(self, prompt): """Set the prompt for the input field. """ self.edit_widget.set_caption(prompt) self._modified() def _modified(self): if self.loop: self.loop.draw_screen() @fail_safely def quit(self): """Quit the program. """ #import pdb; pdb.set_trace() #raise TypeError('Artificial TypeError') raise urwid.ExitMainLoop() def handle_invalid_choice(self, s): if len(s): text = 'Invalid choice: "' + s + '". Please enter an integer.' self.logger.warn(text) def handle_quit_request(self): if True or self.quit_flag: self.quit() else: self.quit_flag = True text = 'Are you sure you want to quit? Press Q again to confirm.' self.logger.warn(text) def handle_choice(self, i): if self.choice_callback: self.choice_callback(i) def colorize(self, s): """Applies color to roles found in a string. A string with attributes applied looks like Text([('attr1', 'some text'), 'some more text']) so we need to split into a list of tuples of text. """ regex_color_dict = { r'\b([Ll]egionaries|[Ll]egionary|[Ll]eg|LEGIONARIES|LEGIONARY|LEG)\b' : 'brick', r'\b([Ll]aborers?|[Ll]ab|LABORERS?|LAB)\b' : 'rubble', r'\b([Cc]raftsmen|[Cc]raftsman|[Cc]ra|CRAFTSMEN|CRAFTSMAN|CRA)\b' : 'wood', r'\b([Aa]rchitects?|[Aa]rc|ARCHITECTS?|ARC)\b' : 'concrete', r'\b([Mm]erchants?|[Mm]er|MERCHANTS?|MER)\b' : 'stone', r'\b([Pp]atrons?|[Pp]at|PATRONS?|PAT)\b' : 'marble', r'\b([Jj]acks?|JACKS?)\b' : 'jack', r'\b([Bb]ricks?|[Bb]ri|BRICKS?|BRI)\b' : 'brick', r'\b([Rr]ubble|[Rr]ub|RUBBLE|RUB)\b' : 'rubble', r'\b([Ww]ood|[Ww]oo|WOOD|WOO)\b' : 'wood', r'\b([Cc]oncrete|[Cc]on|CONCRETE|CON)\b' : 'concrete', r'\b([Ss]tone|[Ss]to|STONE|STO)\b' : 'stone', r'\b([Mm]arble|[Mm]ar|MARBLE|MAR)\b' : 'marble', } def _colorize(s, regex, attr): """s is a tuple of ('attr', 'text'). This splits based on the regex and adds attr to any matches. Returns a list of tuples [('attr1', 'text1'), ('attr2', 'text2'), ('attr3','text3')] with some attributes being None if they aren't colored. """ output = [] a, t = s # Make a list of all tokens, split by matches tokens = re.split(regex, t) for tok in tokens: m = re.match(regex, tok) if m: # matches get the new attributes output.append( (attr,tok) ) else: # non-matches keep the old ones output.append( (a, tok) ) return output output = [ (None, s) ] for k,v in regex_color_dict.items(): new_output = [] for token in output: new_output.extend(_colorize(token, k, v)) output[:] = new_output return Text(output)
def doorkomsten_alarm_handler(_loop: urwid.MainLoop, output: Output): if output.program.state == States.DOORKOMSTEN_MENU: output.input_user.keypress((), 'enter') _loop.set_alarm_in(DOORKOMSTEN_REFRESH, doorkomsten_alarm_handler, user_data=output)
def run(self): loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input) loop.run()