|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +import npyscreen |
| 4 | +import datetime |
| 5 | +import curses |
| 6 | +import time |
| 7 | +import rest_client |
| 8 | +import curses |
| 9 | + |
| 10 | +class CommandList(npyscreen.MultiLineAction): |
| 11 | + def __init__(self, *args, **keywords): |
| 12 | + super(CommandList, self).__init__(*args, **keywords) |
| 13 | + self.command_handlers = {} |
| 14 | + |
| 15 | + # Any non highlited command handlers |
| 16 | + self.add_handlers({ |
| 17 | + "q": self.exit_app, |
| 18 | + curses.ascii.ESC : self.exit_app |
| 19 | + }) |
| 20 | + |
| 21 | + # All handlers for when a command is highlighted |
| 22 | + self.add_command_handlers({ |
| 23 | + curses.ascii.NL: self.select_command, |
| 24 | + curses.ascii.CR: self.select_command, |
| 25 | + curses.ascii.SP: self.go_to_command_details, |
| 26 | + ord("i"): self.go_to_command_details |
| 27 | + }) |
| 28 | + |
| 29 | + # Disable handling of ALL mouse events right now. Without this we're |
| 30 | + # unable to select text when inside of interactive search. This is |
| 31 | + # convenient for access to the clipboard since on bash it'll |
| 32 | + # automatically execute the command. Eventually find a way to allow this. |
| 33 | + # It'd be nice to allow clicking to select a line. |
| 34 | + curses.mousemask(0) |
| 35 | + |
| 36 | + def exit_app(self, vl): |
| 37 | + self.parent.parentApp.switchForm(None) |
| 38 | + |
| 39 | + def display_value(self, vl): |
| 40 | + return "{0}".format(vl) |
| 41 | + |
| 42 | + def add_command_handlers(self, command_handlers): |
| 43 | + self.command_handlers = command_handlers |
| 44 | + # wire up to use npyscreens h_act_on_hightlited |
| 45 | + event_handlers = dict((key, self.h_act_on_highlighted) for (key, value) in |
| 46 | + command_handlers.items()) |
| 47 | + self.add_handlers(event_handlers) |
| 48 | + |
| 49 | + def actionHighlighted(self, command, keypress): |
| 50 | + if keypress in self.command_handlers: |
| 51 | + return self.command_handlers[keypress](command) |
| 52 | + |
| 53 | + def go_to_command_details(self, command): |
| 54 | + command_details = rest_client.get_command(command.uuid) |
| 55 | + self.parent.parentApp.getForm('EDITRECORDFM').value = command_details |
| 56 | + self.parent.parentApp.switchForm('EDITRECORDFM') |
| 57 | + |
| 58 | + def select_command(self, command): |
| 59 | + self.parent.parentApp.return_value = command |
| 60 | + self.parent.parentApp.switchForm(None) |
| 61 | + |
| 62 | +class CommandListDisplay(npyscreen.FormMutt): |
| 63 | + MAIN_WIDGET_CLASS = CommandList |
| 64 | + #COMMAND_WIDGET_CLASS = None |
| 65 | + |
| 66 | + def beforeEditing(self): |
| 67 | + self.wStatus1.value = "Bashhub Commands " |
| 68 | + self.update_list() |
| 69 | + |
| 70 | + def update_list(self): |
| 71 | + self.wMain.values = self.parentApp.commands |
| 72 | + self.wMain.display() |
| 73 | + |
| 74 | +class EditRecord(npyscreen.ActionForm): |
| 75 | + |
| 76 | + def __init__(self, *args, **keywords): |
| 77 | + super(EditRecord, self).__init__() |
| 78 | + self.add_handlers({ |
| 79 | + "q": self.previous_form, |
| 80 | + curses.ascii.ESC : self.exit_app |
| 81 | + }) |
| 82 | + |
| 83 | + def create(self): |
| 84 | + self.value = None |
| 85 | + self.command = self.add(npyscreen.TitleFixedText, name = "Command:") |
| 86 | + self.path = self.add(npyscreen.TitleFixedText, name = "Path:") |
| 87 | + self.created = self.add(npyscreen.TitleFixedText, name = "Created At:") |
| 88 | + self.exit_status = self.add(npyscreen.TitleFixedText, name = "Exit Status:") |
| 89 | + self.system_name = self.add(npyscreen.TitleFixedText, name = "System Name:") |
| 90 | + self.session_id = self.add(npyscreen.TitleFixedText, name = "Session Id:") |
| 91 | + self.uuid = self.add(npyscreen.TitleFixedText, name = "UUID:") |
| 92 | + |
| 93 | + def exit_app(self, vl): |
| 94 | + self.parentApp.switchForm(None) |
| 95 | + |
| 96 | + def previous_form(self, vl): |
| 97 | + self.parentApp.switchFormPrevious() |
| 98 | + |
| 99 | + def beforeEditing(self): |
| 100 | + if self.value: |
| 101 | + record = self.value |
| 102 | + self.name = "Command Details" |
| 103 | + date_string = datetime.datetime.fromtimestamp(record.created/1000).strftime('%Y-%m-%d %H:%M:%S') |
| 104 | + self.created.value = date_string |
| 105 | + self.command.value = record.command |
| 106 | + self.path.value = record.path |
| 107 | + |
| 108 | + # Handle old commands that don't have exit status |
| 109 | + exit_status = "None" if record.exit_status is None else str(record.exit_status) |
| 110 | + self.exit_status.value = exit_status |
| 111 | + |
| 112 | + self.system_name.value = record.system_name |
| 113 | + self.session_id.value = record.session_id |
| 114 | + self.uuid.value = record.uuid |
| 115 | + |
| 116 | + else: |
| 117 | + self.command = "not found" |
| 118 | + |
| 119 | + def on_ok(self): |
| 120 | + self.parentApp.switchFormPrevious() |
| 121 | + |
| 122 | + def on_cancel(self): |
| 123 | + self.parentApp.switchFormPrevious() |
| 124 | + |
| 125 | + |
| 126 | +class InteractiveSearch(npyscreen.NPSAppManaged): |
| 127 | + |
| 128 | + def __init__(self, commands, rest_client=None): |
| 129 | + super(InteractiveSearch, self).__init__() |
| 130 | + self.commands = commands |
| 131 | + self.rest_client = rest_client |
| 132 | + self.return_value = None |
| 133 | + |
| 134 | + def onStart(self): |
| 135 | + self.addForm("MAIN", CommandListDisplay) |
| 136 | + self.addForm("EDITRECORDFM", EditRecord) |
| 137 | + |
0 commit comments