shadowbrokers-exploits/windows/Resources/Ops/PyScripts/lib/util/menu.py

176 lines
6.3 KiB
Python
Raw Normal View History

import math
import os
SPACER = None
QUIT_OPTION = 'Done'
INVALID_CHOICE = (-1)
def clear_screen():
os.system(('cls' if (os.name == 'nt') else 'clear'))
class Menu(object, ):
def __init__(self, heading, choices, choice_heading, prompt):
self.heading = heading
self.choices = choices
self.choice_heading = choice_heading
self.prompt = prompt
def __str__(self):
if self.heading:
print ('%s\n' % self.heading)
if self.choice_heading:
settings = [self.choice_heading]
has_heading = True
else:
settings = []
has_heading = False
settings += self._get_table_data()
settings.append([SPACER])
settings.append([QUIT_OPTION])
final_string = self._draw_table(settings, has_heading)
return final_string
def show(self, default=None):
print self
choice = raw_input((('%s [%s] ' % (self.prompt, default)) if (default is not None) else self.prompt))
try:
choice = int(choice)
except ValueError:
if (choice == ''):
choice = default
else:
choice = None
if ((not choice) or (choice > (len(self.choices) + 1)) or (choice < 1)):
return (choice, INVALID_CHOICE)
if (choice == (len(self.choices) + 1)):
return (choice, QUIT_OPTION)
result = self._handle_choice(choice)
return result
def _get_table_data(self):
return self.choices
def _handle_choice(self, choice):
try:
row_data = self.choices[(choice - 1)]
return (choice, row_data)
except KeyError:
return (choice, INVALID_CHOICE)
except IndexError:
return (choice, INVALID_CHOICE)
def _draw_table(self, table, has_heading):
max_column_lengths = self._find_max_column_size(table)
final_string = ''
len_zeroes_rounded_up = math.ceil(math.log10(len(table)))
max_padding = int((len_zeroes_rounded_up + len('1) ')))
row_counter = (0 if has_heading else 1)
for row in table:
if (row[0] == SPACER):
row_string = ''
row_counter -= 1
elif ((row_counter == 0) and has_heading):
row_string = (' ' * max_padding)
row_string += (self._draw_row(row, max_column_lengths).rstrip() + '\n')
row_string += self._draw_heading_dashes(max_column_lengths, max_padding)
else:
padding = ((max_padding - len(str(row_counter))) - len(') '))
row_string = (((' ' * padding) + str(row_counter)) + ') ')
row_string += self._draw_row(row, max_column_lengths)
final_string += ('%s\n' % row_string.rstrip())
row_counter += 1
return final_string
def _find_max_column_size(self, table):
max_row_length = max([len(row) for row in table if row])
max_column_lengths = ([0] * max_row_length)
for row in table:
if (row[0] == SPACER):
break
for row_item_index in range(len(row)):
row_item = str(row[row_item_index])
if (len(row_item) > max_column_lengths[row_item_index]):
max_column_lengths[row_item_index] = len(row_item)
return max_column_lengths
def _draw_heading_dashes(self, max_column_lengths, padding):
dash_string = (' ' * padding)
for column_index in range(len(max_column_lengths)):
dash_string += ('-' * max_column_lengths[column_index])
dash_string += ' '
return dash_string
def _draw_row(self, row, max_column_lengths):
column_counter = 0
row_string = ''
for row_item in row:
if hasattr(row_item, '__iter__'):
row_string += row_item[0]
else:
row_string += row_item
space_between = (' ' * ((max_column_lengths[column_counter] + 2) - len(row_item)))
row_string += space_between
column_counter += 1
return row_string
class ListMenu(Menu, ):
def __init__(self, heading, choices, choice_heading, prompt):
Menu.__init__(self, heading, choices, choice_heading, prompt)
if self.choice_heading:
self.choice_heading = [choice_heading]
def _get_table_data(self):
settings = [[choice] for choice in self.choices]
return settings
def _find_max_column_size(self, table):
max_length = 0
for row in table:
if (row[0] == SPACER):
break
row_item = row[0]
if hasattr(row_item, '__iter__'):
row_item = row_item[0]
if (len(row_item) > max_length):
max_length = len(row_item)
return [max_length]
class FunctionMenu(ListMenu, ):
def _handle_choice(self, choice):
value = self.choices[(choice - 1)]
if (len(value) == 2):
function = value[1]
function_result = function()
else:
function = value[1]
function_result = function(*value[2:])
return (choice, function_result)
class SettingsMenu(Menu, ):
def __init__(self, heading, choices, prompt):
Menu.__init__(self, heading, choices, ['Name', 'Current Value'], prompt)
self.choices = self._map_choice_list(choices)
def show(self):
(choice, result) = Menu.show(self)
while (result != QUIT_OPTION):
(choice, result) = Menu.show(self)
return dict(self.choices)
def _map_choice_list(self, choices):
if hasattr(choices, 'items'):
choice_list = [[k, v] for (k, v) in choices.items()]
else:
choice_list = [[k, v] for (k, v) in choices]
return choice_list
def _handle_choice(self, choice):
name = self.choices[(choice - 1)][0]
new_value = raw_input(("Enter a new value for '%s' > " % name))
self.choices[(choice - 1)][1] = new_value
self.choices = self._map_choice_list(self.choices)
return (self.choices, None)