Пример #1
0
class WebcamWindow(Window):
    def __init__(self, tui):
        super().__init__(tui)
        self.body.contents.append((Text("Available Webcams"), ('pack', None)))
        self.body.contents.append((Divider(), ('pack', None)))

        self.walker = SimpleFocusListWalker([])
        listbox = ListBox(self.walker)
        self.body.contents.append((listbox, ('weight', 1)))
        self.body.focus_position = 2
        self.add_hotkey('U', self.update, "update")
        self.update()

    def update(self):
        def camlist_cb(json_msg):
            self.walker.clear()

            def button_cb(locator, url, button):
                webbrowser.open_new(url)
                self.tui.pop_window()

            self.display_errors(json_msg)
            webcams = json_msg.get('webcams', None)
            if not webcams: return
            for locator, webcam in webcams.items():
                name = webcam["name"]
                url = webcam["url"]
                button = Button(name)
                urwid.connect_signal(button,
                                     'click',
                                     button_cb,
                                     user_args=[locator, url])
                self.walker.append(AttrMap(button, None, focus_map='selected'))

        self.tui.controller.get_camlist(camlist_cb)
Пример #2
0
class ChatMessages(ListBox):
    """ Show the last couple of chat messages as a scrolling list """

    def __init__(self, chat):
        self.chat = chat
        self.walker = SimpleFocusListWalker([])
        super(ChatMessages, self).__init__(self.walker)

    def add(self, message):
        self.walker.append(Text(message))
        self.set_focus(len(self.walker)-1)
Пример #3
0
class ChatMessages(ListBox):
    """ Show the last couple of chat messages as a scrolling list """

    def __init__(self, chat):
        self.chat = chat
        self.walker = SimpleFocusListWalker([])
        super(ChatMessages, self).__init__(self.walker)

    def add(self, message):
        self.walker.append(Text(message))
        self.set_focus(len(self.walker) - 1)
Пример #4
0
class ProgressView(BaseView):
    def __init__(self, controller):
        self.controller = controller
        self.listwalker = SimpleFocusListWalker([])
        self.listbox = ListBox(self.listwalker)
        self.linebox = MyLineBox(self.listbox)
        body = [
            ('pack', Text("")),
            ('weight', 1, Padding.center_79(self.linebox)),
            ('pack', Text("")),
        ]
        self.pile = Pile(body)
        super().__init__(self.pile)

    def add_log_tail(self, text):
        at_end = len(
            self.listwalker) == 0 or self.listbox.focus_position == len(
                self.listwalker) - 1
        for line in text.splitlines():
            self.listwalker.append(Text(line))
        if at_end:
            self.listbox.set_focus(len(self.listwalker) - 1)
            self.listbox.set_focus_valign('bottom')

    def clear_log_tail(self):
        self.listwalker[:] = []

    def set_status(self, text):
        self.linebox.set_title(text)

    def show_complete(self, include_exit=False):
        buttons = [
            ok_btn(_("Reboot Now"), on_press=self.reboot),
        ]
        if include_exit:
            buttons.append(cancel_btn(_("Exit To Shell"), on_press=self.quit))
        buttons = button_pile(buttons)

        new_pile = Pile([
            ('pack', Text("")),
            buttons,
            ('pack', Text("")),
        ])
        self.pile.contents[-1] = (new_pile, self.pile.options('pack'))
        self.pile.focus_position = len(self.pile.contents) - 1

    def reboot(self, btn):
        self.controller.reboot()

    def quit(self, btn):
        self.controller.quit()
Пример #5
0
class LogWindow(Window):
    def __init__(self, tui):
        super().__init__(tui)
        description = Text(
            "NOTICE. The log displayed here is a copy of the "
            "daemon log. Keeping the the loglevel at debug impacts "
            "performance. When done, run ':loglevel warning'")
        self.body.contents.append((description, ('pack', None)))
        self.walker = SimpleFocusListWalker([])
        self.listbox = ScrollingListBox(self.walker)
        self.body.contents.append((self.listbox, ('weight', 1)))
        #self.add_hotkey('-', self.update, "increase")
        #self.add_hotkey('+', self.update, "decrease")
        #c e w i d

    def wrap(self, line):
        if line.startswith('CRITICAL'):
            focusmap = 'critical'
        elif line.startswith('ERROR'):
            focusmap = 'error'
        elif line.startswith('WARNING'):
            focusmap = 'warning'
        elif line.startswith('INFO'):
            focusmap = 'info'
        else:
            focusmap = 'default'

        txt = Text(line.strip())
        return AttrMap(txt, focusmap)

    def start(self):
        self.walker.append(Text("---- START LOGGING ----", align='center'))

        def log_cb(json_msg):
            line = json_msg.get('log', None)
            if not line:
                return
            self.walker.append(self.wrap(line))

        self.tui.controller.start_logs(log_cb)

    def stop(self):
        self.tui.controller.stop_logs()
Пример #6
0
class DeviceListWindow(Window):
    def __init__(self, tui):
        super().__init__(tui)
        self.body.contents.append(
            (Text("Available CNC Devices"), ('pack', None)))
        self.body.contents.append((Divider(), ('pack', None)))

        self.walker = SimpleFocusListWalker([])
        listbox = ListBox(self.walker)
        self.body.contents.append((listbox, ('weight', 1)))
        self.body.focus_position = 2
        self.add_hotkey('U', self.update, "update")
        self.add_hotkey('w', self.webcams, "webcams")
        self.add_hotkey('a', self.actions, "actions")
        self.update()

    def update(self):
        def devlist_cb(json_msg):
            self.walker.clear()

            def button_cb(locator, device, button):
                window = DeviceWindow(self.tui, locator, device)
                self.tui.push_window(window)

            self.display_errors(json_msg)
            devices = json_msg.get('devices')
            if not devices: return
            for locator, device in devices.items():
                button = Button(device)
                urwid.connect_signal(button,
                                     'click',
                                     button_cb,
                                     user_args=[locator, device])
                self.walker.append(AttrMap(button, None, focus_map='selected'))

        self.tui.controller.get_devlist(devlist_cb)
Пример #7
0
class ActionWindow(Window):
    def __init__(self, tui):
        super().__init__(tui)
        self.body.contents.append((Text("Available Actions"), ('pack', None)))
        self.body.contents.append((Divider(), ('pack', None)))

        self.walker = SimpleFocusListWalker([])
        listbox = ListBox(self.walker)
        self.body.contents.append((listbox, ('weight', 1)))
        self.body.focus_position = 2
        self.add_hotkey('U', self.update, "update")
        self.update()

    def update(self):
        def action_cb(json_msg):
            self.walker.clear()

            def button_cb(cmd, button):
                self.tui.controller.action(cmd, None)
                self.tui.pop_window()

            self.display_errors(json_msg)
            actions = json_msg.get('actions', None)
            if not actions: return
            for action in actions:
                cmd = action['command']
                label = action['short']
                description = action['long']
                button = Button("[{}] - {}".format(label, description))
                urwid.connect_signal(button,
                                     'click',
                                     button_cb,
                                     user_args=[cmd])
                self.walker.append(AttrMap(button, None, focus_map='selected'))

        self.tui.controller.get_actions(action_cb)
Пример #8
0
class ProgressView(BaseView):
    def __init__(self, controller):
        self.controller = controller
        self.spinner = Spinner(controller.loop)

        self.event_listwalker = SimpleFocusListWalker([])
        self.event_listbox = ListBox(self.event_listwalker)
        self.event_linebox = MyLineBox(self.event_listbox)
        self.event_buttons = button_pile([other_btn("View full log", on_press=self.view_log)])
        event_body = [
            ('pack', Text("")),
            ('weight', 1, Padding.center_79(self.event_linebox)),
            ('pack', Text("")),
            ('pack', self.event_buttons),
            ('pack', Text("")),
        ]
        self.event_pile = Pile(event_body)

        self.log_listwalker = SimpleFocusListWalker([])
        self.log_listbox = ListBox(self.log_listwalker)
        log_linebox = MyLineBox(self.log_listbox, _("Full installer output"))
        log_body = [
            ('weight', 1, log_linebox),
            ('pack', button_pile([other_btn(_("Close"), on_press=self.close_log)])),
            ]
        self.log_pile = Pile(log_body)

        super().__init__(self.event_pile)

    def add_event(self, text):
        at_end = len(self.event_listwalker) == 0 or self.event_listbox.focus_position == len(self.event_listwalker) - 1
        if len(self.event_listwalker) > 0:
            self.event_listwalker[-1] = self.event_listwalker[-1][0]
        self.event_listwalker.append(Columns([('pack', Text(text)), ('pack', self.spinner)], dividechars=1))
        if at_end:
            self.event_listbox.set_focus(len(self.event_listwalker) - 1)
            self.event_listbox.set_focus_valign('bottom')

    def add_log_line(self, text):
        at_end = len(self.log_listwalker) == 0 or self.log_listbox.focus_position == len(self.log_listwalker) - 1
        self.log_listwalker.append(Text(text))
        if at_end:
            self.log_listbox.set_focus(len(self.log_listwalker) - 1)
            self.log_listbox.set_focus_valign('bottom')

    def set_status(self, text):
        self.event_linebox.set_title(text)

    def show_complete(self, include_exit=False):
        p = self.event_buttons.original_widget
        p.contents.append(
            (ok_btn(_("Reboot Now"), on_press=self.reboot), p.options('pack')))
        if include_exit:
            p.contents.append(
                (cancel_btn(_("Exit To Shell"), on_press=self.quit), p.options('pack')))

        w = 0
        for b, o in p.contents:
            w = max(len(b.base_widget.label), w)
        self.event_buttons.width = self.event_buttons.min_width = w + 4
        self.event_pile.focus_position = 3
        p.focus_position = 1

    def reboot(self, btn):
        self.controller.reboot()

    def quit(self, btn):
        self.controller.quit()

    def view_log(self, btn):
        self._w = self.log_pile

    def close_log(self, btn):
        self._w = self.event_pile
Пример #9
0
class GUI(object):
    def __init__(self):
        self.screen = Screen()
        self.screen.set_input_timeouts(max_wait=0)
        self.steps = GridFlow([], 20, 2, 1, 'left')
        self.progress = SimpleFocusListWalker([])
        self.log = SimpleFocusListWalker([])

        self.widget = AttrMap(
            LineBox(Pile([
                ('fixed', 6, AttrMap(Filler(self.steps), 'default')),
                ('fixed', 1, Filler(Divider('\u2500'))),
                ('fixed', 3, ListBox(self.progress)),
                AttrMap(LineBox(ListBox(self.log), title='Message log'),
                        'default')
            ]),
                    title='Indico 1.2 -> 2.0 migration'), 'global_frame')

        self.screen.register_palette(
            [('green', 'light green', ''), ('white', 'white', ''),
             ('red', 'dark red', ''), ('yellow', 'yellow', ''),
             ('progress_empty', 'black',
              'light gray'), ('progress_progress', 'light cyan', 'light gray'),
             ('progress_done', 'black', 'light cyan'),
             ('box', 'white', 'dark gray'), ('step_done', 'light green', ''),
             ('step_working', 'dark gray',
              ''), ('global_frame', 'light cyan',
                    ''), ('fill', 'light cyan', 'dark cyan'),
             ('done', 'white', 'dark green'), ('eta', 'yellow', 'dark gray')] +
            generate_urwid_palette(PALETTE))

    def print_log(self, icon, message, prefix='', event_id=''):
        self.log.append(
            Text([
                color_segments(icon), ' ',
                color_segments(prefix), ' ' if prefix else '',
                color_segments(
                    '%[cyan][%[cyan!]{}%[cyan]]%[reset]'.format(event_id))
                if event_id else '', ' ' if event_id else '',
                color_segments(message)
            ]))
        self.log.set_focus(len(self.log) - 1)
        self.redraw()

    def start(self):
        # don't let Python warnings ruin the GUI
        warnings.filterwarnings('ignore')
        self.screen.start()
        self.redraw()

    def stop(self):
        self.screen.stop()
        warnings.filterwarnings('default')

    def create_progress_bar(self, description):
        if self.progress:
            del self.progress[:]
        return StepProgressBar(self, description)

    def set_success(self):
        if self.progress:
            del self.progress[:]
        self.progress.append(
            AttrMap(Text('Migration finished!', align='center'), 'done'))
        self.progress.append(
            AttrMap(Text('Please press any key...', align='center'), 'done'))
        self.redraw()
        self.wait_for_input()

    def wait_for_input(self):
        self.screen._getch(None)

    def set_step_banner(self, msg):
        if self.progress:
            del self.progress[:]
        self.progress.append(BoxAdapter(AttrMap(SolidFill('#'), 'fill'), 3))

    def redraw(self):
        screen_size = self.screen.get_cols_rows()
        canvas = self.widget.render(screen_size, focus=True)
        self.screen.get_input()
        self.screen.draw_screen(screen_size, canvas)
Пример #10
0
class ScrollingListBox(ListBox):
    def __init__(self, rolling_packet_buffer=None):
        """
        
        Args:
            rolling_packet_buffer (int, optional): Max packets to
                keep in the rolling buffer at a time. Defaults to unlimited.
        """
        self.walker = SimpleFocusListWalker([])
        self.packets = scapy.plist.PacketList()
        self.rolling_packet_buffer = rolling_packet_buffer
        super(ScrollingListBox, self).__init__(self.walker)

    def add(self, message, packet):
        """

        Args:
            message (str): Text message that will appear
            packet (Scapy packet): Packet that corresponds to this entry.
        """
        txt = AttrMap(Text(message), 'frame', 'selected')
        self.walker.append(txt)
        self.packets.append(packet)

        if self.rolling_packet_buffer is not None and len(
                self.walker) > self.rolling_packet_buffer:
            self.packets.pop(0)
            self.walker.pop(0)

        currently_selected = self.get_focus()
        if isinstance(currently_selected, (list, tuple)):
            currently_selected = currently_selected[0]

        # This ensures auto scrolling only engages if our selected item is the bottom one
        if len(self.walker) <= 1 or currently_selected is self.walker[-2]:
            self.set_focus(len(self.walker) - 1)

    def get_packet(self, message):
        """ Given message, return the corresponding packet. """
        return self.packets[self.walker.index(message)]

    def _keypress_up(self, size):
        # TODO: Not sure why key up is failing like this... Really need to figure out root cause
        #out = super(ScrollingListBox, self)._keypress_up(size)

        try:
            self.set_focus(self.walker.prev_position(self.walker.focus))
            return None  # No more handling needed
        except IndexError:
            # IndexError is expected when we're at the top of the list
            return True

    def _keypress_down(self, size):
        # TODO: Not sure why key up is failing like this... Really need to figure out root cause (jumping down a page before incrementing down)

        try:
            self.set_focus(self.walker.next_position(self.walker.focus))
            return None  # No more handling needed
        except IndexError:
            # IndexError is expected when we're at the top of the list
            return True
Пример #11
0
class TableBox(WidgetWrap):

	headers = False

	dividechars = 0
	min_width = 1

	zebra = False
	odd = (None, 'darker gray')
	even = (None, None)

	row_factory = TableRow

	listbox = None

	def __init__(self, rows, columns, title=None, headers=False, zebra=False, dividechars=1, padding=None, row_factory=None):
		self.columns = columns
		self.headers = headers
		self.zebra = zebra
		self.dividechars = dividechars
		if row_factory is not None:
			self.row_factory = row_factory


		_rows = []

		if self.headers:
			header = Columns([],dividechars=self.dividechars, min_width=self.min_width)
			for k in columns:
				head = columns[k].get('header', k)
				size = TableRow.size_options(*columns[k]['size']) if 'size' in columns[k] else TableRow.size_options()
				header.contents.append( (Text(head), size) )
			header = AttrMap(header, 'table_header')

				
		for i, row in enumerate(rows):
			r = self.build_row(row, i)
			_rows.append(r)

		self.listwalker = SimpleFocusListWalker(_rows)
		self.listbox = ListBox(self.listwalker)
		self.frame = Frame(self.listbox)
		widget = self.frame
		if padding is not None:
			widget = Padding(self.frame, left=padding[0], right=padding[1])

		if self.headers:
			self.set_title(header)
		elif title:
			self.set_title(title)

		self.__super.__init__(widget)

	def set_title(self, txt):
		if not isinstance(txt, Widget):
			txt = Text(txt)
		self.frame.header = txt
		self.title = txt

	def build_row(self, data, i):
		tablerow = data
		if not isinstance(tablerow, Widget):
			color = None
			if self.zebra:
				color = self.even if (i+1) % 2 == 0 else self.odd
			tablerow = self.row_factory(tablerow, parent=self, color=color, dividechars=self.dividechars, min_width=self.min_width)

			if self.zebra:
				tablerow = AttrMap(tablerow, B16(*color))
		return tablerow

	def __getitem__(self, idx):
		if hasattr(self.listwalker[idx], 'original_widget'):
			return self.listwalker[idx].original_widget
		else:
			return self.listwalker[idx]

	def __setitem__(self, idx, value):
		self.listwalker[idx] = self.build_row(value, idx)

	def __delitem__(self, idx):
		del self.listwalker[idx]

	def __len__(self):
		return len(self.listwalker)

	def __iter__(self):
		return iter(self.listwalker)

	def insert(self, idx, value):
		self.listwalker.insert(idx, self.build_row(value, idx))

	def append(self, value):
		idx = len(self.listwalker)
		self.listwalker.append(self.build_row(value, idx))
Пример #12
0
class DeviceWindow(Window):
    def __init__(self, tui, locator, device):
        super().__init__(tui)
        self.body.contents.append(
            (Text("Selected device \"{}\"".format(device)), ('pack', None)))
        fn = self.tui.controller.get_filename(locator)
        self.filename_txt = Text("Selected file \"{}\"".format(fn))
        self.body.contents.append((self.filename_txt, ('pack', None)))
        self.body.contents.append((Divider(), ('pack', None)))

        self.statuswidget = Pile([])
        self.body.contents.append((self.statuswidget, ('pack', None)))
        self.body.contents.append((Divider(), ('pack', None)))

        self.locator = locator
        self.device = device

        self.walker = SimpleFocusListWalker([])
        listbox = ListBox(self.walker)
        self.body.contents.append((listbox, ('weight', 1)))
        self.body.focus_position = 5
        self.add_hotkey('U', self.update, "update")
        self.add_hotkey('w', self.webcams, "webcams")
        self.add_hotkey('a', self.actions, "actions")
        self.status = defaultdict(str)
        self.update()

    def start(self):
        self.update()
        self.tui.controller.subscribe(
            partial(self.update_status_cb, self.statuswidget), self.locator)

    def stop(self):
        self.tui.controller.unsubscribe(None, self.locator)

    def update_status_cb(self, container, json_msg):
        self.display_errors(json_msg)
        ## TODO filter error from loop below. The results should be in a known
        ## section like 'i3'
        data = json_msg.get(self.locator, {})
        for key, value in data.items():
            self.status[key] = value

        def parse_time(status, container, ignore):
            try:
                tstart = float(status['starttime'])
                tstop = float(status['stoptime'])
                offset = self.tui.controller.time_offset
                if tstop == -1:
                    d = time.time() - tstart - offset
                else:
                    d = tstop - tstart
                t = time.asctime(time.localtime(tstart + offset))
                txt = "Started at {} ({}h{}m)".format(t, int(d / 3600),
                                                      int(d % 3600) // 60)
                attr = 'Flabel'
                w = AttrMap(Text(txt), attr, attr)
                container.contents.append((w, container.options('pack')))
            except ValueError:
                pass
            finally:
                ignore.append('starttime')
                #ignore.append('stoptime') ## leave for debugging for now

        def parse_progress(status, container, ignore):
            try:
                fsize = int(status['filesize'])
                fprog = int(status['progress'])
                tstart = float(status['starttime'])
                tstop = float(status['stoptime'])
                cz = float(status['current_z'])
                fz = float(status['final_z'])
                ce = float(status['current_e'])
                fe = float(status['final_e'])
                offset = self.tui.controller.time_offset
                if tstop == -1:
                    d = time.time() - tstart - offset
                else:
                    d = tstop - tstart
                rate = fprog / fsize
                attr = 'Flabel'

                def div(a, b):
                    if b == 0:
                        return 0
                    return a / b

                label = "File: {:0.0f}/{:0.0f} Kb ({:0.2f}%)".format(
                    fprog / 1024, fsize / 1024, rate * 100)
                bar = NamedProgressBar(label, 'progress_normal',
                                       'progress_complete', fprog, fsize,
                                       'status')
                container.contents.append((bar, container.options('pack')))

                label = "Z Travel: {:0.2f}/{:0.2f} mm ({:0.2f}%)".format(
                    cz, fz,
                    div(cz, fz) * 100)
                bar = NamedProgressBar(label, 'progress_normal',
                                       'progress_complete', cz, fz, 'status')
                container.contents.append((bar, container.options('pack')))

                label = "Extruded: {:0.0f}/{:0.0f} mm ({:0.2f}%)".format(
                    ce, fe,
                    div(ce, fe) * 100)
                bar = NamedProgressBar(label, 'progress_normal',
                                       'progress_complete', ce, fe, 'status')
                container.contents.append((bar, container.options('pack')))
            except:
                pass
            finally:
                ignore.append('filesize')
                ignore.append('progress')
                ignore.append('current_z')
                ignore.append('final_z')
                ignore.append('current_e')
                ignore.append('final_e')

        def parse_status(status, container, ignore):
            stat_cols = Columns([], 0)
            w = make_w(stat_cols, 'connected', 'connected', 'disconnected')
            w = make_w(stat_cols, 'idle', 'active', 'idle', reverse=True)
            w = make_w(stat_cols, 'paused', 'paused', 'operating')
            container.contents.append((stat_cols, container.options('pack')))
            ignore.append('connected')
            ignore.append('idle')
            ignore.append('paused')

        def make_w(container, key, Tlabel, Flabel, reverse=False):
            if (self.status[key] == True) ^ reverse:
                label = "[{}]".format(Tlabel)
                attr = 'Tlabel'
            else:
                label = "[{}]".format(Flabel)
                attr = 'Flabel'
            w = AttrMap(Text(label), attr, attr)
            container.contents.append((w, container.options('pack')))

        ignore = ['last_temp_request']
        # We really got to properly parse this to some struct first
        container.contents.clear()
        ## progress
        parse_status(self.status, container, ignore)
        parse_progress(self.status, container, ignore)
        parse_time(self.status, container, ignore)

        for key, value in sorted(self.status.items()):
            if key in ignore: continue
            attr = 'Flabel'
            w = AttrMap(Text("{}: {}".format(key, value)), attr, attr)
            container.contents.append((w, container.options('pack')))

    def update_status(self):
        self.tui.controller.get_data(
            partial(self.update_status_cb, self.statuswidget), self.locator)

    def update(self):
        self.update_status()
        self.walker.clear()
        locator = self.locator

        def cmd_cb(json_msg):
            self.display_errors(json_msg)
            self.update_status()

        fn = self.tui.controller.get_filename(locator)
        self.filename_txt.set_text("Selected file \"{}\"".format(fn))

        button = Button("[c] Connect")

        def button_cb(button, locator):
            self.tui.controller.connect(cmd_cb, locator)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('c',
                        partial(button_cb, button, locator),
                        "connect",
                        omit_header=True)

        button = Button("[D] Disconnect")

        def button_cb(button, locator):
            self.tui.controller.disconnect(cmd_cb, locator)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('D',
                        partial(button_cb, button, locator),
                        "disconnect",
                        omit_header=True)

        button = Button("[s] Start")

        def button_cb(button, locator):
            fn = self.tui.controller.get_filename(locator)
            if not fn:
                self.footer.set_text("Please Select a file first")
                return
            self.tui.controller.start(
                cmd_cb, locator, self.tui.controller.get_filename(locator))

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('s',
                        partial(button_cb, button, locator),
                        "start",
                        omit_header=True)

        button = Button("[S] Stop (ask nicely to stop)")

        def button_cb(button, locator):
            self.tui.controller.stop(cmd_cb, locator)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('S',
                        partial(button_cb, button, locator),
                        "stop",
                        omit_header=True)

        button = Button("[!] Abort (Interrupt then disconnect)")

        def button_cb(button, locator):
            self.tui.controller.abort(cmd_cb, locator)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('!',
                        partial(button_cb, button, locator),
                        "abort",
                        omit_header=True)

        button = Button("[p] Pause")

        def button_cb(button, locator):
            self.tui.controller.pause(cmd_cb, locator)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('p',
                        partial(button_cb, button, locator),
                        "pause",
                        omit_header=True)

        button = Button("[r] Resume")

        def button_cb(button, locator):
            self.tui.controller.resume(cmd_cb, locator)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('r',
                        partial(button_cb, button, locator),
                        "resume",
                        omit_header=True)

        button = Button("[l] Load File")

        def button_cb(button, locator):
            window = FileListWindow(self.tui, locator, self.device)
            self.tui.push_window(window)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('l',
                        partial(button_cb, button, locator),
                        "load",
                        omit_header=True)

        button = Button("[m] Manual Control")

        def button_cb(button, locator):
            window = ManualControlWindow(self.tui, locator, self.device)
            self.tui.push_window(window)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('m',
                        partial(button_cb, button, locator),
                        "manual",
                        omit_header=True)
Пример #13
0
class ManualControlWindow(Window):
    def __init__(self, tui, locator, device):
        super().__init__(tui)
        self.locator = locator
        self.device = device

        self.add_hotkey('U', self.update, "update")
        self.add_hotkey('w', self.webcams, "webcams")
        self.add_hotkey('a', self.actions, "actions")

        self.body.contents.append(
            (Text("Selected device \"{}\"".format(device)), ('pack', None)))
        self.body.contents.append((Divider(), ('pack', None)))

        self.walker = SimpleFocusListWalker([])
        listbox = ListBox(self.walker)
        self.body.contents.append((listbox, ('weight', 1)))
        self.body.focus_position = 2
        self.update()

    def update(self):
        self.walker.clear()
        locator = self.locator

        def cmd_cb(json_msg):
            self.display_errors(json_msg)

        button = Button("[h] Home (G28 W)")

        def button_cb(button, locator):
            self.tui.controller.action("gcode {} 'G28 W'".format(locator),
                                       cmd_cb)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('h',
                        partial(button_cb, button, locator),
                        "home",
                        omit_header=True)

        def edit_cb(txt):
            self.tui.controller.action("gcode {} 'G90'".format(locator),
                                       cmd_cb)
            self.tui.controller.action(
                "gcode {} 'G1 X{}'".format(locator, txt), cmd_cb)

        edit = CB_Edit("Move to ABS X (mm): ", "0", None, edit_cb, NUMERICALS)
        self.walker.append(AttrMap(edit, None, focus_map='selected'))

        def edit_cb(txt):
            self.tui.controller.action("gcode {} 'G90'".format(locator),
                                       cmd_cb)
            self.tui.controller.action(
                "gcode {} 'G1 Y{}'".format(locator, txt), cmd_cb)

        edit = CB_Edit("Move to ABS Y (mm): ", "0", None, edit_cb, NUMERICALS)
        self.walker.append(AttrMap(edit, None, focus_map='selected'))

        def edit_cb(txt):
            self.tui.controller.action("gcode {} 'G90'".format(locator),
                                       cmd_cb)
            self.tui.controller.action(
                "gcode {} 'G1 Z{}'".format(locator, txt), cmd_cb)

        edit = CB_Edit("Move to ABS Z (mm): ", "0", None, edit_cb, NUMERICALS)
        self.walker.append(AttrMap(edit, None, focus_map='selected'))

        def edit_cb(txt):
            self.tui.controller.action(
                "gcode {} 'G1 F{}'".format(locator, txt), cmd_cb)

        edit = CB_Edit("Set Feedrate mm/min: ", "", None, edit_cb, NUMERICALS)
        self.walker.append(AttrMap(edit, None, focus_map='selected'))

        def edit_cb(txt):
            self.tui.controller.action(
                "gcode {} 'M104 S{}'".format(locator, txt), cmd_cb)

        edit = CB_Edit("Set Extruder Temperature °C: ", "0", None, edit_cb,
                       NUMERICALS)
        self.walker.append(AttrMap(edit, None, focus_map='selected'))

        def edit_cb(txt):
            self.tui.controller.action(
                "gcode {} 'M140 S{}'".format(locator, txt), cmd_cb)

        edit = CB_Edit("Set Bed Temperature °C: ", "0", None, edit_cb,
                       NUMERICALS)
        self.walker.append(AttrMap(edit, None, focus_map='selected'))

        button = Button("[L] Load filament (G1 E100 F300)")

        def button_cb(button, locator):
            self.tui.controller.action("gcode {} 'M83'".format(locator),
                                       cmd_cb)
            self.tui.controller.action(
                "gcode {} 'G1 E100 F300'".format(locator), cmd_cb)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('L',
                        partial(button_cb, button, locator),
                        "load",
                        omit_header=True)

        button = Button("[U] Unload filament (G1 E-100 F2000)")

        def button_cb(button, locator):
            self.tui.controller.action("gcode {} 'M83'".format(locator),
                                       cmd_cb)
            self.tui.controller.action(
                "gcode {} 'G1 E-100 F2000'".format(locator), cmd_cb)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('U',
                        partial(button_cb, button, locator),
                        "unload",
                        omit_header=True)

        button = Button("[r] Release steppers (M18)")

        def button_cb(button, locator):
            self.tui.controller.action("gcode {} 'M18'".format(locator),
                                       cmd_cb)

        urwid.connect_signal(button, 'click', button_cb, locator)
        self.walker.append(AttrMap(button, None, focus_map='selected'))
        self.add_hotkey('r',
                        partial(button_cb, button, locator),
                        "release",
                        omit_header=True)

        self.walker.append(Divider())

        def enter_cb(edit, txt):
            if edit.hjkl_active:
                edit.hjkl_active = False
                edit.set_edit_text("[enter] to activate / deactivate")
            else:
                edit.hjkl_active = True
                edit.set_edit_text("")
                self.footer.set_text("Use keys 'hjklaz' to move printer.")

        def edit_cb(edit, txt):
            if not edit.hjkl_active: return
            key = txt[-1]
            m = {'h': "X-", 'l': "X", 'j': "Y-", 'k': "Y", 'a': "Z", 'z': "Z-"}
            if key not in m:
                self.footer.set_text(
                    "key '{}' not handled. Please use keys 'hjklaz' to move printer."
                    .format(key))
                return
            edit.set_edit_text("{}".format(m[key]))
            increment = 10
            c = "gcode {} 'G1 ".format(locator) + m[key] + "{}'".format(
                increment)
            self.tui.controller.action("gcode {} 'G91'".format(locator),
                                       cmd_cb)
            self.tui.controller.action(c, cmd_cb)

            #self.tui.controller.action("gcode {} 'G1 F{}'".format(locator, txt), cmd_cb)

        edit = CB_Edit("VI Move: ", "[enter] to activate", edit_cb, enter_cb,
                       [i for i in "hjklaz"])
        edit.type_cb = partial(edit_cb,
                               edit)  ##hack to solve cyclic dependency
        edit.enter_cb = partial(enter_cb,
                                edit)  ##hack to solve cyclic dependency
        edit.hjkl_active = False
        self.walker.append(AttrMap(edit, None, focus_map='selected'))
Пример #14
0
class FileListWindow(Window):
    def __init__(self, tui, locator, device):
        super().__init__(tui)
        self.body.contents.append(
            (Text("Select file to load on \"{}\"".format(device)), ('pack',
                                                                    None)))
        self.body.contents.append((Divider(), ('pack', None)))
        self.device = device

        self.locator = locator
        self.device = device
        self.all_files = []

        def limit(regexp):
            self.regexp = regexp
            self.populate_list()

        def enter(edit_text):
            if len(self.walker) < 1:
                self.tui.pop_window()
                return
            button = self.walker[0]
            button.keypress(1, 'enter')

        editbox = CB_Edit("Limit (regexp): ", "", limit, enter)
        self.body.contents.append((editbox, ('pack', 1)))
        self.body.contents.append((Divider(), ('pack', 1)))

        self.walker = SimpleFocusListWalker([])
        listbox = ListBox(self.walker)
        self.body.contents.append((listbox, ('weight', 1)))
        self.body.focus_position = 2
        self.update()
        self.regexp = ".*"

    def populate_list(self):
        try:
            p = re.compile(self.regexp, re.IGNORECASE)
        except re.error:
            filtered_files = self.all_files
        else:
            filtered_files = filter(p.search, self.all_files)

        def button_cb(locator, filename, button):
            self.filename = filename
            self.tui.controller.set_filename(locator, filename)
            self.tui.pop_window()

        self.walker.clear()
        for line in filtered_files:
            filename = line.strip()
            button = Button(filename)
            urwid.connect_signal(button,
                                 'click',
                                 button_cb,
                                 user_args=[self.locator, filename])
            self.walker.append(AttrMap(button, None, focus_map='selected'))

    def update(self):
        def filelist_cb(json_msg):
            self.display_errors(json_msg)
            self.all_files = json_msg.get('files', [])
            self.populate_list()

        self.tui.controller.get_filelist(filelist_cb, self.locator)