Example #1
0
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)
Example #2
0
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
Example #3
0
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
Example #4
0
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())
Example #5
0
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()
Example #6
0
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
Example #7
0
File: top.py Project: mfkiwl/pstack
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()
Example #8
0
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()
Example #9
0
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()
Example #10
0
class TUI:
    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 generate_main_view(self):
        main_view = HydraWidget("Welcome to INF1900 interactive grading tool!")

        subviews = (("c", ClonePanel()), ("g", GradePanel()),
                    ("a", AssemblePanel()), ("p", PushPanel()), ("m",
                                                                 MailPanel()))

        heads = []
        for letter, view, in subviews:
            hint = view.name
            connect_signal(view, QUIT_SIGNAL, self.display_main)
            connect_signal(view, SET_HEADER_TEXT_SIGNAL, self.set_header_text)
            connect_signal(view, DRAW_SIGNAL, self.draw_screen)
            heads.append((letter, "blue_head", hint, self.display_subview, {
                "view": view,
                "hint": hint
            }))

        main_view.add_heads(heads)

        return main_view

    def start(self):
        try:
            self.loop.run()
        finally:
            self.loop.screen.stop()

    def unhandled_input(self, key):
        if key in self.keybind:
            self.keybind[key]()
            return None

    def bind_global(self, key, callback):
        self.keybind[key] = callback

    def set_header_text(self, string):
        self.root.header.set_text(string)

    def quit(self, *kargs):
        raise ExitMainLoop()

    def pause(self, *kargs):
        print("PAUSE")
        self.loop.stop()
        os.kill(os.getpid(), signal.SIGSTOP)
        self.loop.start()
        self.loop.draw_screen()

    def interrupt(self, *kargs):
        pass

    def handle_os_signals(self):
        signal.signal(signal.SIGQUIT, self.quit)
        signal.signal(signal.SIGTSTP, self.pause)
        signal.signal(signal.SIGINT, self.interrupt)

    @staticmethod
    def generate_helper_text(hints):
        markup = []
        for key, text, text_palette in hints:
            markup.extend(
                (("helper_key", key), " ", (text_palette, text), " "))

        return Text(markup, align="center")

    def draw_screen(self):
        self.loop.draw_screen()

    def __change_view(self, view, hint):
        self.root.body = view if not hasattr(view, "root") else view.root
        self.set_header_text(hint)

    def display_subview(self, view, hint):
        self.root.footer = self.subview_helper_text
        self.__change_view(view, hint)

    def display_main(self, *kargs):
        self.root.footer = self.main_helper_text
        self.root.body = self.generate_main_view(
        )  # to reload data from app state
        self.__change_view(self.root.body, "")
Example #11
0
        self.open_pop_up()
    def create_pop_up (self):
        p = PopUpDialog(self.item)
        connect_signal(p, 'close',
            lambda button: self.close_pop_up())
        return p
    def get_pop_up_parameters (self):
        return {'left':0, 'top':1, 'overlay_width':25, 'overlay_height':20}
"""
    Testing
"""
if __name__ == '__main__':
    b = Button('click me')
    p1 = Process.Process(1, lambda x: x, lambda: x)
    popup = ProcessItemDialog(b, p1)
    connect_signal(b, 'click', lambda x: popup.open())
    proc = AttrMap(popup, None)
    lb = ListBox(SimpleFocusListWalker([proc]))

    def exit (p):
        if p is 'q':
            raise ExitMainLoop

    m = MainLoop(
        lb,
        palette=palette,
        pop_ups=True,
        unhandled_input=exit
    )
    m.run()
Example #12
0
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:
            f.write(string)
Example #13
0
    def __init__(self, verbose: bool, server_conn: ServerConnection):
        def _handle_global_input(key: str):
            if key == 'f5':
                self._input_view.set_edit_text('cont')
                self._input_view.keypress(0, 'enter')
            elif key == 'f8':
                self._input_view.set_edit_text('step')
                self._input_view.keypress(0, 'enter')
            elif key == 'f10':
                self._input_view.set_edit_text('quit')
                self._input_view.keypress(0, 'enter')
            else:
                logger.error(f"Function key '{key}' not implemented")

        self._source_view = Text("Source code will be shown here...")
        source_widget = LineBox(
            Padding(Filler(Pile([
                Text(('banner', "Source code"), align='center'),
                self._source_view
            ]),
                           valign='top',
                           top=1,
                           bottom=1),
                    left=1,
                    right=1))

        self._disasm_view = Text("Dissambled code will be shown here...")
        disasm_widget = LineBox(
            Padding(Filler(Pile([
                Text(('banner', "Disassembled code"), align='center'),
                self._disasm_view
            ]),
                           valign='top',
                           top=1,
                           bottom=1),
                    left=1,
                    right=1))

        self._register_view = Text("Registers will be shown here...")
        register_widget = LineBox(
            Padding(Filler(Pile([
                Text(('banner', "Registers"), align='center'),
                self._register_view
            ]),
                           valign='top',
                           top=1,
                           bottom=1),
                    left=1,
                    right=1))

        self._stack_view = Text("Stack will be shown here...")
        stack_widget = LineBox(
            Padding(Filler(Pile(
                [Text(('banner', "Stack"), align='center'), self._stack_view]),
                           valign='top',
                           top=1,
                           bottom=1),
                    left=1,
                    right=1))

        self._input_view = CommandInput(self, server_conn)
        input_widget = LineBox(
            Padding(Filler(
                self._input_view,
                valign='top',
            ), left=1, right=1))

        self._log_view = Text("Log messages will be shown here...")
        log_widget = LineBox(
            Padding(Filler(
                self._log_view,
                valign='top',
            ), left=1, right=1))

        title = AttrMap(
            Text("CWDebug - a source-level debugger for the AmigaOS",
                 align='center'), 'banner')
        menu = AttrMap(
            Text("F5 = Continue, F8 = Single-step over, F10 = Quit"), 'banner')
        screen = Frame(
            header=title,
            body=Pile([
                Columns([
                    Pile([source_widget, disasm_widget]),
                    Pile([register_widget, stack_widget])
                ]),
                # 2 needs to be added for the line box
                (INPUT_WIDGET_HEIGHT + 2, input_widget),
                (MAX_NUM_OF_LOG_MESSAGES + 2, log_widget)
            ]),
            footer=menu)

        logger.remove()
        logger.add(UrwidHandler(self._log_view))
        logger.info("Created main screen, starting event loop")

        self._disassembler = capstone.Cs(capstone.CS_ARCH_M68K,
                                         capstone.CS_MODE_32)

        loop = MainLoop(screen, PALETTE, unhandled_input=_handle_global_input)
        loop.run()
Example #14
0
 def run(self):
     loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input)
     loop.run()
Example #15
0
 def run(self):
     self.tick()
     with utils.console_blank():
         MainLoop.run(self)
Example #16
0
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()
Example #17
0
class Controller(object):
    """ The controller class - holds the map, instantiates the rooms, tracks the
        player and enemies """
    DIRECTIONS = {
        'EAST': (1, 0),
        'WEST': (-1, 0),
        'SOUTH': (0, -1),
        'NORTH': (0, 1)
    }

    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 start(self):
        """ Start the main game loop """
        logging.info('Game started')
        self._loop.run()

    def stop(self):
        """ Stop the main game loop """
        self._loop.stop()

    def loadFile(self, mapFile):
        """ReturnType void"""
        self.map = {}

        with open(mapFile) as csvDataFile:
            csvReader = csv.reader(csvDataFile, delimiter='|')
            for row in csvReader:
                key = "{0}{1}".format(row.pop(0), row.pop(0))
                roomTitle = row.pop(0)
                self.map.update({key: [roomTitle, row]})
        logging.debug(str(self.map))

    def getPlayerLocation(self):
        """ Returns the player's current location as a tuple
            ReturnType tuple (x, y) """
        logging.debug('Accessing Controller._playerLocation: %s',
                      self._playerLocation)
        return self._playerLocation

    def getRoomKey(self):
        """ Generates a key for the map based on the player's current location
            @ReturnType String """
        return '{}{}'.format(self._playerLocation[0], self._playerLocation[1])

    def getRooms(self):
        """ Returns the loaded map. It is slated for removal very soon and should
            not be used
            @ReturnType dict """
        return self.map

    def getDescriptionText(self):
        """ Gets the description text from the room at the player's current location

            @ReturnType String """
        text = self._visited[self._roomKey].getText()
        return text

    def getStatText(self):
        """ Returns a formatted string representation of the player's basic stats,
            including current health / max health, equipped weapon, and damage range """
        stats = "HP: {}/{}         Equipped weapon: {}        Damage: {}".format(
            self._player.getHP(), self._player.getMaxHP(),
            self._player._weapon._name, self._player._weapon.getDamage())
        return stats

    def _canMove(self, direction):
        """ Checks if there is a room in <direction> from current room """
        dirX, dirY = Controller.DIRECTIONS[direction]
        roomKey = '{}{}'.format(self._playerLocation[0] + dirX,
                                self._playerLocation[1] + dirY)
        return roomKey in self.map

    def getDirectionOptions(self):
        """ Builds the list of directions the player can move
            ReturnType list of Strings """
        return [
            "Move {}".format(x).title()
            for x in ["NORTH", "WEST", "EAST", "SOUTH"] if self._canMove(x)
        ]

    def getActionOptions(self):
        """ Builds and returns the list of actions the player can take in the room
            ReturnType list of Strings """
        options = []
        # Try to add item to menu
        try:
            if not self._room.item.isHidden():
                logging.debug("Visible item in room")
                options.append("Pick up " + self._room.item.identify())
            else:
                logging.debug("Hidden item in room")
                options.append("Search room")
        except AttributeError:
            logging.debug("No item in room")
            pass
        # Try to add enemy to menu
        try:
            if not self._room.enemy.isDead():
                options.append("Fight " + self._room.enemy.getName())
        except AttributeError:
            pass
        # Try to add NPC to menu
        try:
            options.append("Interrogate " + self._room.character.getName())
        except AttributeError:
            pass

        return options

    def getGameOptions(self):
        """ Returns the metagame options (e.g. Save, Load, Quit)
            ReturnType list of strings """
        options = ["Save", "Load", "Exit game"]
        return options

    def movePlayer(self, direction):
        """ Updates the player's current location and instantiates a room if necessary
            ReturnType None """
        if not self._canMove(direction):
            return
        self._player.move(Controller.DIRECTIONS[direction])
        self._playerLocation = self._player.getLocation()
        self._roomKey = self.getRoomKey()
        try:
            logging.debug('Returning to previously visited room')
            self._room = self._visited[self._roomKey]
        except KeyError:
            logging.debug('Visiting a new room, generating room')
            self._visited[self._roomKey] = Factory.roomFactory(
                self._playerLocation[0], self._playerLocation[1],
                self.map[self._roomKey][1])
            self._room = self._visited[self._roomKey]
            logging.debug('Created new room')
        finally:
            logging.debug('Room %s', self._roomKey)
            logging.debug('Room description: %s', self._room.getText())

    def updateGameView(self):
        """ Updates the GameView screen after player action """

        self._gameView.updateDescription(self.getDescriptionText())
        self._gameView.updateStats(self.getStatText())
        self._gameView.updateDirectionMenu(self.getDirectionOptions())
        self._gameView.updateActionMenu(self.getActionOptions())
        self._gameView.setMenuFocus(0)

    def moveCallback(self, button):
        """ Updates the gameView object every time the player moves """
        functions = {
            'move_north': (self.movePlayer, "NORTH"),
            'move_south': (self.movePlayer, "SOUTH"),
            'move_east': (self.movePlayer, "EAST"),
            'move_west': (self.movePlayer, "WEST")
        }
        label = button._w.original_widget.text.lower().replace(' ', '_')
        try:
            functions[label][0](functions[label][1])
        except KeyError:
            return
        self.updateGameView()

    def optionCallback(self, button):
        """ Updates the gameView object whenever the player uses the
            game options menu (save/load/quit/etc) """
        functions = {
            'save': self.saveGame,
            'load': self.loadGame,
            'exit_game': exitGame
        }
        label = button._w.original_widget.text.lower().replace(' ', '_')
        try:
            functions[label]()
        except KeyError:
            pass

    def actionCallback(self, button):
        """ Updates the gameView object whenever the player performs an action from
            the action menu
            Precondition: Action menu item is selected by player. Action menu items should be in
                          the format 'pick up <item>', 'fight <enemy>', 'interrogate <npc>'
            Postcondition: The appropriate action method is run
            @ReturnType None"""
        label = button._w.original_widget.text.lower().replace(' ', '_')
        try:
            if self._room.item.isHidden():
                logging.debug("Trying to search the room")
                if self._room.search():
                    logging.debug("Found item %s", self._room.item.identify())
                    self._room.item.find()
                    self._room.updateText(
                        "You're in the hallway outside your office. \
This is where you found the {}.".format(self._room.item.identify()))
                else:
                    logging.debug("Item still hidden")
            else:
                logging.debug("Trying to add item to inventory")
                logging.debug(self._room.item)
                self._player.addItem(self._room.item)
                self._room.removeItem()
        except AttributeError:
            logging.debug("No item in room")
            try:
                logging.debug("Trying to fight enemy")
                self._player.fight(self._room.enemy)
                logging.debug(
                    "Fought enemy - results: Player HP: %s\nEnemy HP: %s",
                    self._player.getHP(), self._room.enemy.getHP())
                if self._room.enemy.isDead():
                    self._room.killEnemy()
                else:
                    self.playerDead()
            except AttributeError:
                logging.debug("No enemy to fight")
                self._player.interrogate(self._room.character)
        finally:
            self.updateGameView()
            logging.debug("Action menu item %s pressed", label)

    def playerDead(self):
        """ Handle the player dying """
        pass

    def saveGame(self):
        """ Pickles the controller state and player to save the current game state
            Precondition: None
            Postcondition: Saves game state in saves/<player name>_<save index>
            @ReturnType None """
        try:
            makedirs(self._saveDir)
        except OSError as e:
            if e.errno != errno.EEXIST:
                raise
        with open(self._saveDir + '/patrick_001', 'w+') as f:
            dill.dump(self._player, f)
            dill.dump(self._playerLocation, f)
            dill.dump(self._currentRoom, f)
            dill.dump(self.map, f)
            dill.dump(self._visited, f)
            dill.dump(self._roomKey, f)

    def loadGame(self):
        """ Unpickles the controller (self) and player (self._player) to load the
            saved game state
            Precondition: Save game file in saves/<player name>_<save index>
            Postcondition: Loads game state
            @ReturnType None """
        try:
            with open(self._saveDir + '/patrick_001') as f:
                self._player = dill.load(f)
                self._playerLocation = dill.load(f)
                self._currentRoom = dill.load(f)
                self.map = dill.load(f)
                self._visited = dill.load(f)
                self._roomKey = dill.load(f)
                self.updateGameView()
        except IOError:
            return
Example #18
0
def run():
    loop = MainLoop(wrapper,
                    palette,
                    handle_mouse=False,
                    unhandled_input=key_pressed)
    loop.run()
Example #19
0
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)
Example #20
0
        (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()
Example #21
0
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)
Example #22
0
class Ui:

    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 _layout(self):
        self._wallpaper_count = Text(str(len(self._wpctrl.wallpapers)))
        self._info = Text("", wrap='clip')
        self._head = Columns([('pack', self._wallpaper_count),
                              (10, Text("Wallpapers")),
                              self._info],
                             dividechars=1)
        header = Pile([self._head, AttrMap(Divider("─"), 'divider')])

        self._screens = [ScreenWidget(screen, self._scrctrl)
                         for screen in self._scrctrl.screens]
        body = ListBoxWithTabSupport(self._screens)

        self._root = Frame(header=header, body=body)


    def run_loop(self):
        self._log_handler = CallbackLogHandler(self.info)
        logging.getLogger(__package__).addHandler(self._log_handler)
        self._loop.run()
        logging.getLogger(__package__).removeHandler(self._log_handler)


    def info(self, message):
        self._info.set_text("⋮ " + str(message))

    def _start_reading_command(self):
        self._reading_command = True
        self._info = Edit(caption="_⟩ ", wrap='clip')
        self._head.contents[2] = (self._info, self._head.options('pack'))
        self._root.set_focus_path(("header", 0, 2))

    def _finish_reading_command(self):
        command = self._info.get_edit_text()
        self._info = Text("", wrap='clip')
        self._head.contents[2] = (self._info, self._head.options('pack'))
        self._root.focus_position = "body"
        self._reading_command = False
        return command

    def _handle_global_input(self, key):
        if self._reading_command:
            if key == 'esc':
                self._finish_reading_command()
            elif key == 'enter':
                command = self._finish_reading_command()
                log.info(f"Commands ({command}) are not implemented yet.")
            return

        if key == 'esc':
            raise ExitMainLoop()
        elif key == ':' or key == '-':
            self._start_reading_command()
        elif key == 'ctrl s':
            self._wpctrl.save_updates()
        elif key == 'x':
            self._scrctrl.cycle_collections()
        elif key in _shift_number_keys:
            current_screen_idx = self._root.focus.focus._screen.idx
            key_number = _shift_number_keys[key]
            self._scrctrl.move_wallpaper(current_screen_idx, key_number)
        else:
            log.info("unhandled key: '%s'", key)
            return
        for screen_widget in self._screens:
            screen_widget.update()
        return True
Example #23
0
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)
Example #24
0
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()
Example #25
0
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()
Example #26
0
            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()
Example #27
0
 def run(self):
     loop = MainLoop(self.frame_widget, unhandled_input=self.handle_input)
     loop.run()
Example #28
0
def run(host, port):
    """
    Start a websocket client and a terminal UI to interact with it.
    """
    # connection state
    channels = []
    bound_channel = None
    ws = None

    # UI state
    lines = ['example text\n']
    output = Text(lines)
    input_field = Edit('>> ')
    input_state = COMMAND_READ
    widget = Frame(Filler(output, 'top'), footer=input_field)
    widget.focus_position = 'footer'

    # event wiring
    event_loop = AsyncioEventLoop(loop=loop)
    input_cb = None

    def write(msg):
        """
        Show an additional line of text.
        """
        lines.append(msg + '\n')
        output.set_text(lines)

    def prompt_for_password(msg):
        """
        Change prompt to password prompt. Return a future for the typed password.
        """
        nonlocal input_cb, input_state
        input_cb = loop.create_future()
        input_state = PASSWORD_READ
        input_cb.add_done_callback(_password_done)
        input_field.set_mask('*')
        input_field.set_caption(msg)
        return input_cb

    def _password_done(_):
        nonlocal input_state
        input_field.set_mask(None)
        input_state = COMMAND_READ

    def accept_input(key):
        """
        Process typed lines of text. Dispatches to password prompt or command prompt
        as needed.
        """
        if key == 'enter':
            if input_state == PASSWORD_READ:
                input_cb.set_result(input_field.edit_text)
            elif input_state == COMMAND_READ:
                cmd_dispatch(input_field.edit_text)
            input_field.set_edit_text('')

    def update_channels(new_channels):
        """
        Receive channel data.
        """
        nonlocal channels, bound_channel
        channels = new_channels
        if len(channels) == 1:
            bound_channel = channels[0]
            write(f'bound console to channel "{bound_channel}"')
        else:
            write(f'bot is in these channels: {", ".join(channels)}')

    async def ws_dispatch():
        """
        Handle websocket messages.
        """
        nonlocal ws
        ws = await websockets.connect(f'ws://{host}:{port}')
        while True:
            try:
                msg = json.loads(await ws.recv())
                if msg['type'] == SEND_PASSWORD:
                    loop.create_task(
                        ws.send(await prompt_for_password("Server password:"******"dispatching {repr(command)}")
        nonlocal bound_channel
        if not ws:
            write('Not connected')
            return
        parts = command.split()

        if not parts:
            print_help()

        command_part = parts[0].lower()
        if command_part[0] == '/':
            command_part = command_part[1:]
        args = parts[1:]
        if command_part == 'help':
            print_help()
        elif command_part == 'sendcmd':
            if not bound_channel:
                write(
                    'there is not a bound channel! use `/channel <channel>` to bind one!'
                )
            elif not args:
                write(
                    'you must provide a command to run to /sendcmd, ex: /sendcmd help'
                )
            else:
                loop.create_task(
                    ws.send(
                        json.dumps({
                            'type': RUN_COMMAND,
                            'channel': bound_channel,
                            'command': args[0],
                            'args': args[1:],
                            'silent': True,
                        })))
        elif command_part == 'chat':
            if not bound_channel:
                write(
                    'there is not a bound channel! use `/channel <channel>` to bind one!'
                )
            else:
                loop.create_task(
                    ws.send(
                        json.dumps({
                            'type': SEND_PRIVMSG,
                            'channel': bound_channel,
                            'message': ' '.join(args),
                        })))

        elif command_part == 'channel':
            if not channels:
                write(
                    'the bot is not currently in any channels, please have the bot join at least one than relaunch this console'
                )
            elif not args:
                write(
                    f'the bot is currently in these channels: {", ".join(channels)}\ndo `/channel <channel>` to bind this channel to one'
                )
            elif args[0] not in channels:
                write(f'the bot is not currently in "{args[0]}"')
            else:
                bound_channel = args[0]
        elif command_part == 'quit':
            raise ExitMainLoop()

        else:
            write(f"Unrecognized command {repr(command_part)}")

    event_loop.alarm(0, lambda: loop.create_task(ws_dispatch()))
    mainloop = MainLoop(widget,
                        event_loop=event_loop,
                        unhandled_input=accept_input)
    mainloop.run()
Example #29
0
class Controller(object):
    """ The controller for aerende.
    Reacts to keypresses via the key handler. Is responsible for reading and
    writing notes to the filesystem, and manipulating the underlying urwid
    interface.

    Also responsible for exiting aerende.
    """
    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()

    # [ Filesystem Reading / Writing ]

    def load_notes(self, path):
        """ Loads notes from a given file path.
        If no notes file exists at this location, creates an empty one.
        """

        if Path(path).is_file():
            with open(path, 'r') as data_file:
                note_yaml = yaml.load(data_file)
                notes = []

                if note_yaml is None:
                    return notes

                for unique_id, note in note_yaml.items():
                    notes.append(
                        Note(note['title'], note['tags'], note['text'],
                             note['priority'], unique_id))
                return notes
        else:
            open(path, 'x')
            return []

    def write_notes(self, path):
        """ Writes the current note list to the given file path.
        """

        with open(path, 'w') as data_file:
            for note in self.notes:
                yaml.dump(note.to_dictionary(),
                          data_file,
                          default_flow_style=False)

    # [ Note Creation, Updating and Deletion ]

    def create_note(self, title, tags, text):
        """ Creates a new note object, given the title/tags/text, and appends
        it to the current note list.
        """

        note = Note(title, tags, text)
        self.notes.append(note)

    def delete_note(self, unique_id):
        """ Deletes a note from the current note list, given a note UUID.
        """

        for index, note in enumerate(self.notes):
            if note.id == unique_id:
                del self.notes[index]
                break

    def update_note(self, new_note):
        """ Update a note in the current note list to a given new note.
        """

        for index, note in enumerate(self.notes):
            if note.id == new_note.id:
                note = new_note
                break

    def delete_focused_note(self):
        """ Deletes the focused note. Gets the currently focused note object,
        deletes it from the current note list and writes the note list to file.
        """

        note = self.interface.get_focused_note()
        self.delete_note(note.id)
        self.write_notes(self.data_path)

        self.refresh_interface()

    def change_focused_note_priority(self, amount):
        """ Changes the focused note priority by a given amount. First, gets
        the focused note and changes the priority of the note. Then writes the
        note list to file.
        """

        note = self.interface.get_focused_note()
        note.change_priority(amount)
        self.write_notes(self.data_path)
        self.refresh_interface()

    # [ Tag Loading ]

    def load_tags(self, notes):
        """ Returns a list of tag widgets from a list of notes. Does this by
        first getting all the tags from all the notes in the list. It then
        counts the frequency of these notes, then creates the requisite tag
        widgets from this tag: frequency list.
        """

        note_tags = list(map((lambda note: note.tags), notes))
        note_tags = [tag for subtags in note_tags for tag in subtags]
        tag_frequency = Counter(note_tags)

        tag_widgets = list(
            map((lambda tag: Tag(tag, tag_frequency[tag])), tag_frequency))
        tag_widgets.insert(0, Tag('ALL', len(note_tags)))
        return tag_widgets

    # [ Interface Manipulation ]

    def refresh_interface(self):
        """ Refreshes the interface with the current note and tag lists.
        """

        self.interface.draw_notes(self.notes)
        self.tags = self.load_tags(self.notes)
        self.interface.draw_tags(self.tags)

    def show_note_editor(self, note_handler, edit_focused_note=False):
        """ Shows the note editor at the bottom of the interface.
        If the editor is to edit the focused note, rather than a new one,
        then the focused note is retrieved and passed to the interface.
        """

        note_to_edit = None
        if edit_focused_note:
            note_to_edit = self.interface.get_focused_note()
        self.editor_mode = True
        self.interface.show_note_editor(note_handler, note_to_edit)
        self.key_handler.editor = self.interface.get_note_editor()

    def edit_note_handler(self, note, original_note=None):
        """ Handles the return signal from the note editor. If the note is
        not None (which happens if the user presses escape, cancelling the
        editor), then either a new note is created or an existing note is
        updated, depending on whether the original note returned exists.
        """

        if note is not None:
            title = note[0]
            tags = self._convert_tag_input(note[1])
            text = note[2]
            if original_note is not None:
                original_note.edit_note(title, tags, text)
                self.update_note(original_note)
            else:
                self.create_note(title, tags, text)
            self.write_notes(self.data_path)

            # Restart the loop.. Seems to work?
            self.loop.stop()
            self.loop.start()

        self.refresh_interface()
        self.editor_mode = False

    def _convert_tag_input(self, tag_text):
        split_tags = tag_text.split('//')
        return list(map(lambda tag: tag.strip(), split_tags))

    def focus_next_note(self):
        self.interface.focus_next_note()

    def focus_previous_note(self):
        self.interface.focus_previous_note()

    # [ System Functions ]

    def exit(self):
        raise ExitMainLoop()