bashhub 3.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
bashhub/i_search.py ADDED
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env python
2
+
3
+ import npyscreen
4
+ import datetime
5
+ import time
6
+ from . import rest_client
7
+ import curses
8
+
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
+ ord("n"): self.h_cursor_line_down,
19
+ ord("p"): self.h_cursor_line_up,
20
+ curses.ascii.ESC: self.exit_app
21
+ })
22
+
23
+ # All handlers for when a command is highlighted
24
+ self.add_command_handlers({
25
+ ord("i"): self.go_to_command_details,
26
+ curses.ascii.SP: self.go_to_command_details,
27
+ curses.ascii.NL: self.select_command,
28
+ curses.ascii.CR: self.select_command,
29
+ curses.ascii.BS: self.delete_command,
30
+ curses.ascii.DEL: self.delete_command,
31
+ curses.KEY_BACKSPACE: self.delete_command,
32
+ curses.KEY_DC: self.delete_command
33
+ })
34
+
35
+ # Disable handling of ALL mouse events right now. Without this we're
36
+ # unable to select text when inside of interactive search. This is
37
+ # convenient for access to the clipboard since on bash it'll
38
+ # automatically execute the command. Eventually find a way to allow this.
39
+ # It'd be nice to allow clicking to select a line.
40
+ curses.mousemask(0)
41
+
42
+ def delete_command(self, command):
43
+ confirmed = npyscreen.notify_ok_cancel(
44
+ str(command), "Delete Command")
45
+ if confirmed:
46
+ result = rest_client.delete_command(command.uuid)
47
+ if result:
48
+ self.parent.parentApp.commands.remove(command)
49
+ self.parent.update_list()
50
+
51
+ def exit_app(self, vl):
52
+ self.parent.parentApp.switchForm(None)
53
+
54
+ def display_value(self, vl):
55
+ return "{0}".format(vl)
56
+
57
+ def add_command_handlers(self, command_handlers):
58
+ self.command_handlers = command_handlers
59
+ # wire up to use npyscreens h_act_on_hightlited
60
+ event_handlers = dict((key, self.h_act_on_highlighted)
61
+ for (key, value) in command_handlers.items())
62
+ self.add_handlers(event_handlers)
63
+
64
+ def actionHighlighted(self, command, keypress):
65
+ if keypress in self.command_handlers:
66
+ return self.command_handlers[keypress](command)
67
+
68
+ def go_to_command_details(self, command):
69
+ command_details = rest_client.get_command(command.uuid)
70
+ self.parent.parentApp.getForm('EDITRECORDFM').value = command_details
71
+ self.parent.parentApp.switchForm('EDITRECORDFM')
72
+
73
+ def select_command(self, command):
74
+ self.parent.parentApp.return_value = command
75
+ self.parent.parentApp.switchForm(None)
76
+
77
+
78
+ class CommandListDisplay(npyscreen.FormMutt):
79
+ MAIN_WIDGET_CLASS = CommandList
80
+
81
+ #COMMAND_WIDGET_CLASS = None
82
+
83
+ def beforeEditing(self):
84
+ self.wStatus1.value = "Bashhub Commands "
85
+ self.update_list()
86
+
87
+ def update_list(self):
88
+ self.wMain.values = self.parentApp.commands
89
+ self.wMain.display()
90
+
91
+
92
+ class EditRecord(npyscreen.ActionForm):
93
+ def __init__(self, *args, **keywords):
94
+ super(EditRecord, self).__init__()
95
+ self.add_handlers({
96
+ "q": self.previous_form,
97
+ curses.ascii.ESC: self.exit_app
98
+ })
99
+
100
+ def create(self):
101
+ self.value = None
102
+ self.command = self.add(npyscreen.TitleFixedText, name="Command:")
103
+ self.path = self.add(npyscreen.TitleFixedText, name="Path:")
104
+ self.created = self.add(npyscreen.TitleFixedText, name="Created At:")
105
+ self.exit_status = self.add(npyscreen.TitleFixedText,
106
+ name="Exit Status:")
107
+ self.system_name = self.add(npyscreen.TitleFixedText,
108
+ name="System Name:")
109
+ self.session_id = self.add(npyscreen.TitleFixedText,
110
+ name="Session Id:")
111
+ self.uuid = self.add(npyscreen.TitleFixedText, name="UUID:")
112
+
113
+ def exit_app(self, vl):
114
+ self.parentApp.switchForm(None)
115
+
116
+ def previous_form(self, vl):
117
+ self.parentApp.switchFormPrevious()
118
+
119
+ def beforeEditing(self):
120
+ if self.value:
121
+ record = self.value
122
+ self.name = "Command Details"
123
+ date_string = datetime.datetime.fromtimestamp(
124
+ record.created / 1000).strftime('%Y-%m-%d %H:%M:%S')
125
+ self.created.value = date_string
126
+ self.command.value = record.command
127
+ self.path.value = record.path
128
+
129
+ # Handle old commands that don't have exit status
130
+ exit_status = "None" if record.exit_status is None else str(
131
+ record.exit_status)
132
+ self.exit_status.value = exit_status
133
+
134
+ self.system_name.value = record.system_name
135
+ self.session_id.value = record.session_id
136
+ self.uuid.value = record.uuid
137
+
138
+ else:
139
+ self.command = "not found"
140
+
141
+ def on_ok(self):
142
+ self.parentApp.switchFormPrevious()
143
+
144
+ def on_cancel(self):
145
+ self.parentApp.switchFormPrevious()
146
+
147
+
148
+ class InteractiveSearch(npyscreen.NPSAppManaged):
149
+ def __init__(self, commands, rest_client=None):
150
+ super(InteractiveSearch, self).__init__()
151
+ self.commands = commands
152
+ self.rest_client = rest_client
153
+ self.return_value = None
154
+
155
+ def onStart(self):
156
+ self.addForm("MAIN", CommandListDisplay)
157
+ self.addForm("EDITRECORDFM", EditRecord)
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/python
2
+ """
3
+ Sampled from Lyle Scott scrolling curses
4
+ """
5
+ import curses
6
+ import sys
7
+ import random
8
+ import time
9
+ import locale
10
+
11
+
12
+ class InteractiveSearch:
13
+ DOWN = 1
14
+ UP = -1
15
+ SPACE_KEY = 32
16
+ ESC_KEY = 27
17
+ ENTER_KEY = 10
18
+
19
+ PREFIX_SELECTED = '_X_'
20
+ PREFIX_DESELECTED = '___'
21
+
22
+ outputLines = []
23
+ commands = []
24
+ screen = None
25
+
26
+ def __init__(self, commands):
27
+
28
+ self.commands = commands
29
+ # Parse out our input
30
+ self.outputLines = [x.__str__() for x in commands]
31
+ self.nOutputLines = len(self.outputLines)
32
+
33
+ self.topLineNum = 0
34
+ self.highlightLineNum = 0
35
+ self.markedLineNums = []
36
+
37
+ def run(self):
38
+ # Locale set to support utf-8 characters.
39
+ locale.setlocale(locale.LC_ALL, "")
40
+ return curses.wrapper(self._run)
41
+
42
+ def _run(self, screen):
43
+ self.screen = screen
44
+ curses.cbreak()
45
+ curses.start_color()
46
+ curses.use_default_colors()
47
+ self.screen.border(0)
48
+ while True:
49
+ self.displayScreen()
50
+ # get user command
51
+ c = self.screen.getch()
52
+ if c == curses.KEY_UP or c == ord('k'):
53
+ self.updown(self.UP)
54
+ elif c == curses.KEY_DOWN or c == ord('j'):
55
+ self.updown(self.DOWN)
56
+ elif c == self.ENTER_KEY:
57
+ return self.selectLine()
58
+ elif c == self.ESC_KEY or c == ord('q'):
59
+ sys.exit()
60
+
61
+ def markLine(self):
62
+ linenum = self.topLineNum + self.highlightLineNum
63
+ if linenum in self.markedLineNums:
64
+ self.markedLineNums.remove(linenum)
65
+ else:
66
+ self.markedLineNums.append(linenum)
67
+
68
+ def selectLine(self):
69
+ linenum = self.topLineNum + self.highlightLineNum
70
+ self.screen.erase()
71
+ self.restoreScreen()
72
+ return self.commands[linenum]
73
+
74
+ def displayScreen(self):
75
+ # clear screen
76
+ self.screen.erase()
77
+
78
+ # now paint the rows
79
+ top = self.topLineNum
80
+ bottom = self.topLineNum + curses.LINES
81
+ for (index, line, ) in enumerate(self.outputLines[top:bottom]):
82
+ line = '%s' % (line, )
83
+
84
+ # highlight current line
85
+ if index != self.highlightLineNum:
86
+ self.screen.addstr(index, 0, line)
87
+ else:
88
+ self.screen.addstr(index, 0, line, curses.A_STANDOUT)
89
+ self.screen.refresh()
90
+
91
+ # move highlight up/down one line
92
+ def updown(self, increment):
93
+ nextLineNum = self.highlightLineNum + increment
94
+
95
+ # paging
96
+ if increment == self.UP and self.highlightLineNum == 0 and self.topLineNum != 0:
97
+ self.topLineNum += self.UP
98
+ return
99
+ elif increment == self.DOWN and nextLineNum == curses.LINES and (
100
+ self.topLineNum + curses.LINES) != self.nOutputLines:
101
+ self.topLineNum += self.DOWN
102
+ return
103
+
104
+ # scroll highlight line
105
+ if increment == self.UP and (self.topLineNum != 0 or
106
+ self.highlightLineNum != 0):
107
+ self.highlightLineNum = nextLineNum
108
+ elif increment == self.DOWN and (
109
+ self.topLineNum + self.highlightLineNum + 1
110
+ ) != self.nOutputLines and self.highlightLineNum != curses.LINES:
111
+ self.highlightLineNum = nextLineNum
112
+
113
+ def restoreScreen(self):
114
+ curses.nocbreak()
115
+ curses.echo()
116
+ curses.endwin()
117
+
118
+ # catch any weird termination situations
119
+ def __del__(self):
120
+ self.restoreScreen()
@@ -0,0 +1,6 @@
1
+ from .command import *
2
+ from .command_form import *
3
+ from .system import *
4
+ from .min_command import MinCommand
5
+ from .status_view import StatusView
6
+ from .serializable import Serializable
@@ -0,0 +1,55 @@
1
+ #!/usr/bin/python
2
+ from .min_command import MinCommand
3
+ from time import *
4
+ import jsonpickle
5
+ import sys
6
+ import uuid
7
+ from .serializable import Serializable
8
+
9
+
10
+ class Command(Serializable):
11
+ def __init__(self,
12
+ command,
13
+ path,
14
+ uuid,
15
+ username,
16
+ system_name,
17
+ session_id,
18
+ created,
19
+ id,
20
+ exit_status=None):
21
+ self.command = command
22
+ self.path = path
23
+ self.uuid = uuid
24
+ self.exit_status = exit_status
25
+ self.username = username
26
+ self.system_name = system_name
27
+ self.session_id = session_id
28
+ self.created = created
29
+ self.id = id
30
+
31
+ # Optional fields not set by jsonpickle.
32
+ exit_status = None
33
+
34
+ def to_min_command(self):
35
+ return MinCommand(self.command, self.created, self.uuid)
36
+
37
+
38
+ class RegisterUser(Serializable):
39
+ def __init__(self, email, username, password, registration_code=""):
40
+ self.email = email
41
+ self.username = username
42
+ self.password = password
43
+ self.registration_code = registration_code
44
+
45
+
46
+ class LoginForm(Serializable):
47
+ def __init__(self, username, password, mac=None):
48
+ self.username = username
49
+ self.password = password
50
+ self.mac = mac
51
+
52
+
53
+ class LoginResponse(Serializable):
54
+ def __init__(self, access_token):
55
+ self.access_token = access_token
@@ -0,0 +1,15 @@
1
+ from time import *
2
+ import uuid
3
+ from .serializable import Serializable
4
+
5
+
6
+ class CommandForm(Serializable):
7
+ def __init__(self, command, path, exit_status, process_id,
8
+ process_start_time):
9
+ self.uuid = uuid.uuid4().__str__()
10
+ self.command = command
11
+ self.path = path
12
+ self.exit_status = exit_status
13
+ self.process_id = int(process_id)
14
+ self.process_start_time = process_start_time
15
+ self.created = int(round(time() * 1000))
@@ -0,0 +1,13 @@
1
+ import json
2
+ import requests
3
+ from .serializable import Serializable
4
+
5
+
6
+ class MinCommand(Serializable):
7
+ def __init__(self, command, created, uuid):
8
+ self.command = command
9
+ self.created = created
10
+ self.uuid = uuid
11
+
12
+ def __str__(self):
13
+ return self.command
@@ -0,0 +1,47 @@
1
+ import jsonpickle
2
+ import json
3
+ import requests
4
+ import inflection
5
+
6
+
7
+ class Serializable(object):
8
+ def to_JSON(self):
9
+ underscores = jsonpickle.encode(self)
10
+ temp = json.loads(underscores)
11
+ camel_case = self.convert_json(temp, self.lower_camelize)
12
+ return jsonpickle.encode(camel_case)
13
+
14
+ @classmethod
15
+ def lower_camelize(cls, string):
16
+ return inflection.camelize(string, False)
17
+
18
+ @classmethod
19
+ def convert_json(cls, d, convert):
20
+ new_d = {}
21
+ for k, v in d.items():
22
+ new_d[convert(k)] = cls.convert_json(v, convert) if isinstance(
23
+ v, dict) else v
24
+ return new_d
25
+
26
+ @classmethod
27
+ def from_JSON(cls, response):
28
+ temp_camel_case = json.loads(response)
29
+ temp = cls.convert_json(temp_camel_case, inflection.underscore)
30
+
31
+ # Add back our python classname so jsonpickle
32
+ # knows what class to deserialize it as
33
+ class_name = cls.__module__ + '.' + cls.__name__
34
+ temp['py/object'] = class_name
35
+
36
+ pickle = json.dumps(temp)
37
+ return jsonpickle.decode(pickle)
38
+
39
+ @classmethod
40
+ def from_JSON_list(cls, response):
41
+
42
+ #response = json.load(response)
43
+
44
+ # Use list comprehension to map every json object
45
+ # back to its object with from_JSON
46
+ items = [cls.from_JSON(json.dumps(item)) for item in response]
47
+ return items
@@ -0,0 +1,15 @@
1
+ from .serializable import Serializable
2
+
3
+
4
+ class StatusView(Serializable):
5
+ def __init__(self, username, total_commands, total_sessions, total_systems,
6
+ total_commands_today, session_name, session_start_time,
7
+ session_total_commands):
8
+ self.username = username
9
+ self.total_commands = total_commands
10
+ self.total_sessions = total_sessions
11
+ self.total_systems = total_systems
12
+ self.total_commands_today = total_commands_today
13
+ self.session_name = session_name
14
+ self.session_start_time = session_start_time
15
+ self.session_total_commands = session_total_commands
@@ -0,0 +1,42 @@
1
+ import jsonpickle
2
+ import json
3
+ import requests
4
+ from .serializable import Serializable
5
+
6
+
7
+ class System(Serializable):
8
+ def __init__(self, name, mac, id, created, updated, hostname,
9
+ client_version):
10
+ self.name = name
11
+ self.mac = mac
12
+ self.id = id
13
+ self.created = created
14
+ self.updated = updated
15
+ self.hostname = hostname
16
+ self.client_version = client_version
17
+
18
+ def __str__(self):
19
+ return self.name + " " + self.id
20
+
21
+
22
+ class RegisterSystem(Serializable):
23
+ def __init__(self, name, mac, hostname, client_version):
24
+ self.name = name
25
+ self.mac = mac
26
+ self.hostname = hostname
27
+ self.client_version = client_version
28
+
29
+
30
+ class SystemPatch(Serializable):
31
+ def __init__(self,
32
+ name=None,
33
+ mac=None,
34
+ hostname=None,
35
+ client_version=None):
36
+ self.name = name
37
+ self.mac = mac
38
+ self.hostname = hostname
39
+ self.client_version = client_version
40
+
41
+ def __str__(self):
42
+ return self.name + " " + self.mac