class MonitorsTable(object): def __init__(self, model_name: str, max_width): self.model_name = model_name self._training_monitors = {} self._validation_monitors = {} self._test_monitors = {} self._max_width = max_width self.table = BeautifulTable(max_width) def append(self, values: dict, old_values: dict): self.table.rows.append( list( map( lambda key: self.color(values[key], old_values.get(key, None)), values.keys()))) def update(self, training_monitors: dict, validation_monitors: dict, test_monitors: Optional[dict] = None): self.table.clear() self.append(training_monitors, self._training_monitors) self.append(validation_monitors, self._validation_monitors) if test_monitors is not None: self.append(test_monitors, self._test_monitors) self.table.rows.header = ["Training", "Validation", "Test"] else: self.table.rows.header = ["Training", "Validation"] self.table.columns.header = training_monitors.keys() self._training_monitors = dict(training_monitors) self._validation_monitors = dict(validation_monitors) self._test_monitors = dict(test_monitors) def show(self): self.table._compute_width() width = self.table._width - 2 if self.table._width == self._max_width else self.table._width + 11 topline = "".join(["+", "-" * width, "+"]) print(topline) spc = (len(topline) - 2 - len(self.model_name)) / 2 print("%s%s%s%s%s" % ("|", " " * math.ceil(spc), self.model_name, " " * math.floor(spc), "|")) print(self.table) def color(self, value, old_value): if old_value is not None: if value > old_value: return crayons.green("{} \u2197".format(value), bold=True) if value < old_value: return crayons.red("{} \u2198".format(value), bold=True) return crayons.white("{} \u2192".format(value), bold=True)
class MonitorsTable(object): def __init__(self, model_name: str): self.model_name = model_name self._monitors = {} self._new_monitors = {} self.table = BeautifulTable(200) def append(self, values: dict, old_values: dict): self.table.rows.append( list( map( lambda key: self.color(values[key], old_values.get(key, None)), values.keys()))) def update(self, monitors: dict, phase: Phase): self.table.clear() if phase not in self._monitors: self._monitors[phase] = monitors self._new_monitors[phase] = monitors for key, value in self._monitors.items(): self.append(self._new_monitors[key], self._monitors[key]) self.table.columns.header = monitors.keys() self.table.rows.header = list( map(lambda key: str(key), self._monitors.keys())) def show(self): self.table._compute_width() topline = "".join([ "+", "-" * (self.table._width + 1 + max(list(map(lambda key: len(str(key)), self._monitors.keys())))), "+" ]) print(topline) spc = (len(topline) - 2 - len(self.model_name)) / 2 print("%s%s%s%s%s" % ("|", " " * math.ceil(spc), self.model_name, " " * math.floor(spc), "|")) print(self.table) def color(self, value, old_value): if old_value is not None: if value > old_value: return crayons.green("{} \u2197".format(value), bold=True) if value < old_value: return crayons.red("{} \u2198".format(value), bold=True) return crayons.white("{} \u2192".format(value), bold=True)
def do_grep_regs(self, arg): ''' Search all process registry requests by key name or value Ex: grep_regs *MACHINE\SYSTEM* ''' if (self.sqlite_conn is None): sys.stderr.write( "Please load a database first with the load_db command\n") return if not arg: if self.process_context: arg = self.process_context else: sys.stderr.write( "Please specify a process id or descriptor address\n") return arg = arg.strip() cursor = self.sqlite_conn.cursor() table = BeautifulTable(max_width=160) table.column_headers = [ "Time", "PID", "Process Descriptor", "Image", "Operation", "Key", "Aux Data" ] regs = cursor.execute("SELECT time, pid, desc_address, COALESCE(image, ''), \ op, name, COALESCE(data, '') FROM operation \ JOIN resource ON r_id = resource.id JOIN process ON p_id = process.id \ WHERE (name LIKE '%s' OR data LIKE '%s') AND type = 'R'" \ % (arg.replace("*", "%"), arg.replace("*", "%"))) for rowIni in regs: table.append_row(rowIni) print(table) print("Total: %d\n" % len(table)) table.clear()
class TableOperationsTestCase(unittest.TestCase): def setUp(self): self.create_table() def create_table(self, maxwidth=80): table = BeautifulTable(maxwidth=maxwidth) table.rows.append(["Jacob", 1, "boy"]) table.rows.append(["Isabella", 1, "girl"]) table.rows.append(["Ethan", 2, "boy"]) table.rows.append(["Sophia", 2, "girl"]) table.rows.append(["Michael", 3, "boy"]) table.columns.header = ["name", "rank", "gender"] table.rows.header = ["S1", "S2", "S3", "S4", "S5"] self.table = table def create_dataframe(self): return self.table.to_df() def compare_iterable(self, iterable1, iterable2): for item1, item2 in itertools.zip_longest(iterable1, iterable2): self.assertEqual(item1, item2) # Test for table operations def test_filter(self): new_table = self.table.rows.filter(lambda x: x["rank"] > 1) self.assertEqual(len(self.table.rows), 5) rows = [ ["Ethan", 2, "boy"], ["Sophia", 2, "girl"], ["Michael", 3, "boy"], ] for row_t, row in zip(new_table.rows, rows): self.compare_iterable(row_t, row) def test_sort_by_index(self): self.table.rows.sort(0) rows = [ ["Ethan", 2, "boy"], ["Isabella", 1, "girl"], ["Jacob", 1, "boy"], ["Michael", 3, "boy"], ["Sophia", 2, "girl"], ] for row_t, row in zip(self.table.rows, rows): self.compare_iterable(row_t, row) def test_sort_by_index_reversed(self): self.table.rows.sort(0, reverse=True) rows = [ ["Ethan", 2, "boy"], ["Isabella", 1, "girl"], ["Jacob", 1, "boy"], ["Michael", 3, "boy"], ["Sophia", 2, "girl"], ] for row_t, row in zip(self.table.rows, reversed(rows)): self.compare_iterable(row_t, row) def test_sort_by_header(self): self.table.rows.sort("name") rows = [ ["Ethan", 2, "boy"], ["Isabella", 1, "girl"], ["Jacob", 1, "boy"], ["Michael", 3, "boy"], ["Sophia", 2, "girl"], ] for row_t, row in zip(self.table.rows, rows): self.compare_iterable(row_t, row) def test_sort_by_callable(self): self.table.rows.sort(lambda x: (x[1], x[0])) rows = [ ["Isabella", 1, "girl"], ["Jacob", 1, "boy"], ["Ethan", 2, "boy"], ["Sophia", 2, "girl"], ["Michael", 3, "boy"], ] for row_t, row in zip(self.table.rows, rows): self.compare_iterable(row_t, row) def test_sort_raises_exception(self): with self.assertRaises(TypeError): self.table.rows.sort(None) # Tests for column operations def test_column_aslist(self): self.assertEqual( [column.aslist() for column in self.table.columns], [ ["Jacob", "Isabella", "Ethan", "Sophia", "Michael"], [1, 1, 2, 2, 3], ["boy", "girl", "boy", "girl", "boy"], ], ) def test_column_asdict(self): with self.assertRaises(NotImplementedError): header_colval_map = [ column.asdict() for column in self.table.columns ] def test_column_count(self): self.assertEqual(len(self.table.columns), 3) def test_access_column_by_header(self): column = ["Jacob", "Isabella", "Ethan", "Sophia", "Michael"] self.compare_iterable(column, self.table.columns["name"]) with self.assertRaises(KeyError): self.table.columns["name1"] def test_access_column_element_by_index(self): self.assertEqual(self.table.columns[0][2], "Ethan") def test_access_column_element_by_header(self): self.assertEqual(self.table.columns["name"][2], "Ethan") def test_get_column_index(self): self.assertEqual(self.table.columns.header.index("gender"), 2) with self.assertRaises(KeyError): self.table.columns.header.index("rank1") def test_get_column_header(self): self.assertEqual(self.table.columns.header[2], "gender") with self.assertRaises(IndexError): self.table.columns.header[len(self.table.columns)] def test_append_column(self): title = "year" column = ["2010", "2012", "2008", "2010", "2011"] self.table.columns.append(column, title) self.assertEqual(len(self.table.columns), 4) last_column = self.table.columns[len(self.table.columns) - 1] self.compare_iterable(column, last_column) def test_append_column_empty_table(self): self.table = BeautifulTable() title = "year" column = ["2010", "2012", "2008", "2010", "2011"] self.table.columns.append(column, header=title) string = """+------+ | year | +------+ | 2010 | +------+ | 2012 | +------+ | 2008 | +------+ | 2010 | +------+ | 2011 | +------+""" self.assertEqual(string, str(self.table)) def test_insert_column(self): column = ["2010", "2012", "2008", "2010", "2011"] title = "year" position = 2 self.table.columns.insert(position, column, title) self.assertEqual(len(self.table.columns), 4) self.compare_iterable(column, self.table.columns[position]) def test_pop_column_by_position(self): position = 2 header = self.table.columns.header[position] self.table.columns.pop(position) self.assertEqual(len(self.table.columns), 2) with self.assertRaises(KeyError): self.table.columns[header] def test_pop_column_by_header(self): header = "gender" self.table.columns.pop(header) self.assertEqual(len(self.table.columns), 2) with self.assertRaises(KeyError): self.table.columns[header] def test_update_column_by_index(self): index = 1 column = [3, 2, 1, 2, 4] self.table.columns.update(index, column) self.assertEqual(len(self.table.columns), 3) self.compare_iterable(column, self.table.columns[index]) def test_update_column_by_header(self): header = "rank" column = [3, 2, 1, 2, 4] self.table.columns.update(header, column) self.assertEqual(len(self.table.columns), 3) self.compare_iterable(column, self.table.columns[header]) def test_update_column_slice(self): columns = [ [5, "girl"], [4, "boy"], [4, "boy"], [2, "girl"], [1, "boy"], ] self.table.columns.update(slice(1, 3, 1), columns) self.assertEqual(len(self.table.columns), 3) self.compare_iterable(self.table.columns[1], [c[0] for c in columns]) self.compare_iterable(self.table.columns[2], [c[1] for c in columns]) # Tests for row operations def test_row_asdict(self): self.assertEqual( [row.asdict() for row in self.table.rows], [ { "name": "Jacob", "rank": 1, "gender": "boy" }, { "name": "Isabella", "rank": 1, "gender": "girl" }, { "name": "Ethan", "rank": 2, "gender": "boy" }, { "name": "Sophia", "rank": 2, "gender": "girl" }, { "name": "Michael", "rank": 3, "gender": "boy" }, ], ) def test_row_aslist(self): self.assertEqual( [row.aslist() for row in self.table.rows], [ ["Jacob", 1, "boy"], ["Isabella", 1, "girl"], ["Ethan", 2, "boy"], ["Sophia", 2, "girl"], ["Michael", 3, "boy"], ], ) def test_row_count(self): self.assertEqual(len(self.table.rows), 5) def test_access_row_by_index(self): row = ["Sophia", 2, "girl"] self.compare_iterable(row, self.table.rows[3]) with self.assertRaises(IndexError): self.table.rows[len(self.table.rows)] def test_access_row_by_header(self): row = ["Sophia", 2, "girl"] self.compare_iterable(row, self.table.rows["S4"]) with self.assertRaises(IndexError): self.table.rows[len(self.table.rows)] def test_access_row_element_by_index(self): self.assertEqual(self.table.rows[2][0], "Ethan") def test_access_row_element_by_header(self): self.assertEqual(self.table.rows[2]["name"], "Ethan") def test_append_row(self): row = ["Gary", 2, "boy"] self.table.rows.append(row, header="S6") self.assertEqual(len(self.table.rows), 6) self.compare_iterable(self.table.rows[5], row) def test_insert_row(self): row = ["Gary", 2, "boy"] position = 2 self.table.rows.insert(position, row, header="S6") self.assertEqual(len(self.table.rows), 6) self.compare_iterable(self.table.rows[position], row) def test_pop_row_by_position(self): position = 2 self.table.rows.pop(position) self.assertEqual(len(self.table.rows), 4) def test_pop_row_by_header(self): header = "S3" self.table.rows.pop(header) self.assertEqual(len(self.table.rows), 4) def test_update_row_by_index(self): row = ["Sophie", 5, "girl"] position = 3 self.table.rows.update(position, row) self.compare_iterable(self.table.rows[position], row) def test_update_row_by_header(self): row = ["Sophie", 5, "girl"] header = "S4" self.table.rows.update(header, row) self.compare_iterable(self.table.rows[header], row) def test_update_row_slice(self): rows = [["Sophie", 5, "girl"], ["Mike", 4, "boy"]] self.table.rows.update(slice(3, 5, 1), rows) self.assertEqual(len(self.table.rows), 5) self.compare_iterable(self.table.rows[3], rows[0]) self.compare_iterable(self.table.rows[4], rows[1]) # Tests for special row methods def test_row_getitem_slice(self): new_table = self.table.rows[:3] self.assertEqual(len(new_table.rows), 3) self.assertEqual(len(self.table.rows), 5) def test_row_delitem_int(self): del self.table.rows[1] self.assertEqual(len(self.table.rows), 4) def test_row_delitem_slice(self): del self.table.rows[2:] self.assertEqual(len(self.table.rows), 2) def test_row_delitem_str(self): del self.table.rows["S2"] self.assertEqual(len(self.table.rows), 4) with self.assertRaises(KeyError): self.table.rows["S2"] def test_row_setitem_int(self): position = 3 row = ["Sophie", 5, "girl"] self.table.rows[position] = row self.compare_iterable(self.table.rows[position], row) def test_row_setitem_slice(self): rows = [["Sophie", 5, "girl"], ["Mike", 4, "boy"]] self.table.rows[3:] = rows self.assertEqual(len(self.table.rows), 5) self.compare_iterable(self.table.rows[3], rows[0]) self.compare_iterable(self.table.rows[4], rows[1]) def test_row_setitem_str(self): header = "S2" row = ["Mike", 4, "Boy"] self.table.rows[header] = row self.assertEqual(len(self.table.rows), 5) self.compare_iterable(row, self.table.rows[header]) def test_row_contains(self): self.assertTrue(["Isabella", 1, "girl"] in self.table.rows) self.assertFalse(["Ethan", 3, "boy"] in self.table.rows) def test_row_header_contains(self): self.assertTrue("S3" in self.table.rows.header) self.assertFalse("S6" in self.table.rows.header) # Test for special column methods def test_column_getitem_slice(self): new_table = self.table.columns[:2] self.assertEqual(len(self.table.columns), 3) self.assertEqual(len(new_table.columns), 2) def test_column_delitem_int(self): del self.table.columns[1] self.assertEqual(len(self.table.columns), 2) def test_column_delitem_slice(self): del self.table.columns[2:] self.assertEqual(len(self.table.columns), 2) def test_column_delitem_str(self): del self.table.columns["rank"] self.assertEqual(len(self.table.columns), 2) with self.assertRaises(KeyError): self.table.columns["rank"] def test_column_setitem_int(self): position = 2 row = [3, 4, 5, 6, 7] self.table.columns[position] = row self.compare_iterable(self.table.columns[position], row) def test_column_setitem_slice(self): columns = [ [5, "girl"], [4, "boy"], [4, "boy"], [2, "girl"], [1, "boy"], ] self.table.columns[1:] = columns self.assertEqual(len(self.table.columns), 3) self.compare_iterable(self.table.columns[1], [c[0] for c in columns]) self.compare_iterable(self.table.columns[2], [c[1] for c in columns]) def test_column_setitem_str(self): header = "rank" column = [3, 2, 1, 2, 4] self.table.columns[header] = column self.assertEqual(len(self.table.columns), 3) self.compare_iterable(column, self.table.columns[header]) def test_column_header_contains(self): self.assertTrue("rank" in self.table.columns.header) self.assertFalse("score" in self.table.columns.header) def test_column_contains(self): self.assertTrue( ["boy", "girl", "boy", "girl", "boy"] in self.table.columns) self.assertFalse( ["boy", "girl", "girl", "girl", "boy"] in self.table.columns) # Test for printing operations def test_get_string(self): string = """+----+----------+------+--------+ | | name | rank | gender | +----+----------+------+--------+ | S1 | Jacob | 1 | boy | +----+----------+------+--------+ | S2 | Isabella | 1 | girl | +----+----------+------+--------+ | S3 | Ethan | 2 | boy | +----+----------+------+--------+ | S4 | Sophia | 2 | girl | +----+----------+------+--------+ | S5 | Michael | 3 | boy | +----+----------+------+--------+""" self.assertEqual(string, str(self.table)) def test_stream(self): def generator(): for i in range(1, 6): yield [i, i**2] table = BeautifulTable() table.columns.header = ["Number", "It's Square"] self.compare_iterable( table.stream(generator()), [ "+--------+-------------+", "| Number | It's Square |", "+--------+-------------+", "| 1 | 1 |", "+--------+-------------+", "| 2 | 4 |", "+--------+-------------+", "| 3 | 9 |", "+--------+-------------+", "| 4 | 16 |", "+--------+-------------+", "| 5 | 25 |", "+--------+-------------+", ], ) def test_left_align(self): self.table.columns.alignment[0] = self.table.ALIGN_LEFT string = """+----+----------+------+--------+ | | name | rank | gender | +----+----------+------+--------+ | S1 | Jacob | 1 | boy | +----+----------+------+--------+ | S2 | Isabella | 1 | girl | +----+----------+------+--------+ | S3 | Ethan | 2 | boy | +----+----------+------+--------+ | S4 | Sophia | 2 | girl | +----+----------+------+--------+ | S5 | Michael | 3 | boy | +----+----------+------+--------+""" self.assertEqual(string, str(self.table)) def test_right_align(self): self.table.columns.alignment[0] = self.table.ALIGN_RIGHT string = """+----+----------+------+--------+ | | name | rank | gender | +----+----------+------+--------+ | S1 | Jacob | 1 | boy | +----+----------+------+--------+ | S2 | Isabella | 1 | girl | +----+----------+------+--------+ | S3 | Ethan | 2 | boy | +----+----------+------+--------+ | S4 | Sophia | 2 | girl | +----+----------+------+--------+ | S5 | Michael | 3 | boy | +----+----------+------+--------+""" self.assertEqual(string, str(self.table)) def test_mixed_align(self): self.table.columns.alignment = [ self.table.ALIGN_LEFT, self.table.ALIGN_CENTER, self.table.ALIGN_RIGHT, ] string = """+----+----------+------+--------+ | | name | rank | gender | +----+----------+------+--------+ | S1 | Jacob | 1 | boy | +----+----------+------+--------+ | S2 | Isabella | 1 | girl | +----+----------+------+--------+ | S3 | Ethan | 2 | boy | +----+----------+------+--------+ | S4 | Sophia | 2 | girl | +----+----------+------+--------+ | S5 | Michael | 3 | boy | +----+----------+------+--------+""" self.assertEqual(string, str(self.table)) def test_align_all(self): self.table.columns.alignment = self.table.ALIGN_LEFT string = """+----+----------+------+--------+ | | name | rank | gender | +----+----------+------+--------+ | S1 | Jacob | 1 | boy | +----+----------+------+--------+ | S2 | Isabella | 1 | girl | +----+----------+------+--------+ | S3 | Ethan | 2 | boy | +----+----------+------+--------+ | S4 | Sophia | 2 | girl | +----+----------+------+--------+ | S5 | Michael | 3 | boy | +----+----------+------+--------+""" self.assertEqual(string, str(self.table)) def test_sign_plus(self): self.table.sign = self.table.SM_PLUS string = """+----+----------+------+--------+ | | name | rank | gender | +----+----------+------+--------+ | S1 | Jacob | +1 | boy | +----+----------+------+--------+ | S2 | Isabella | +1 | girl | +----+----------+------+--------+ | S3 | Ethan | +2 | boy | +----+----------+------+--------+ | S4 | Sophia | +2 | girl | +----+----------+------+--------+ | S5 | Michael | +3 | boy | +----+----------+------+--------+""" self.assertEqual(string, str(self.table)) def test_wep_wrap(self): self.create_table(20) self.table.columns.width_exceed_policy = self.table.WEP_WRAP string = """+---+------+---+---+ | | name | r | g | | | | a | e | | | | n | n | | | | k | d | | | | | e | | | | | r | +---+------+---+---+ | S | Jaco | 1 | b | | 1 | b | | o | | | | | y | +---+------+---+---+ | S | Isab | 1 | g | | 2 | ella | | i | | | | | r | | | | | l | +---+------+---+---+ | S | Etha | 2 | b | | 3 | n | | o | | | | | y | +---+------+---+---+ | S | Soph | 2 | g | | 4 | ia | | i | | | | | r | | | | | l | +---+------+---+---+ | S | Mich | 3 | b | | 5 | ael | | o | | | | | y | +---+------+---+---+""" self.assertEqual(string, str(self.table)) def test_wep_strip(self): self.create_table(20) self.table.columns.width_exceed_policy = self.table.WEP_STRIP string = """+---+------+---+---+ | | name | r | g | +---+------+---+---+ | S | Jaco | 1 | b | +---+------+---+---+ | S | Isab | 1 | g | +---+------+---+---+ | S | Etha | 2 | b | +---+------+---+---+ | S | Soph | 2 | g | +---+------+---+---+ | S | Mich | 3 | b | +---+------+---+---+""" self.assertEqual(string, str(self.table)) def test_wep_ellipsis(self): self.create_table(20) self.table.columns.width_exceed_policy = self.table.WEP_ELLIPSIS string = """+---+------+---+---+ | | name | . | . | +---+------+---+---+ | . | J... | 1 | . | +---+------+---+---+ | . | I... | 1 | . | +---+------+---+---+ | . | E... | 2 | . | +---+------+---+---+ | . | S... | 2 | . | +---+------+---+---+ | . | M... | 3 | . | +---+------+---+---+""" self.assertEqual(string, str(self.table)) def test_empty_header(self): self.table.columns.header = ["", " ", " "] string = """+----+----------+---+------+ | S1 | Jacob | 1 | boy | +----+----------+---+------+ | S2 | Isabella | 1 | girl | +----+----------+---+------+ | S3 | Ethan | 2 | boy | +----+----------+---+------+ | S4 | Sophia | 2 | girl | +----+----------+---+------+ | S5 | Michael | 3 | boy | +----+----------+---+------+""" self.assertEqual(string, str(self.table)) def test_eastasian_characters(self): string = """+----+------------+------+--------+ | | name | rank | gender | +----+------------+------+--------+ | S1 | Jacob | 1 | boy | +----+------------+------+--------+ | S2 | Isabella | 1 | girl | +----+------------+------+--------+ | S3 | Ethan | 2 | boy | +----+------------+------+--------+ | S4 | Sophia | 2 | girl | +----+------------+------+--------+ | S5 | Michael | 3 | boy | +----+------------+------+--------+ | S6 | こんにちは | 2 | boy | +----+------------+------+--------+""" self.table.rows.append(["こんにちは", 2, "boy"], header="S6") self.assertEqual(string, str(self.table)) def test_newline(self): string = """+---+---+ | 0 | a | | | b | +---+---+""" table = BeautifulTable() table.rows.append(["0", "a\nb"]) self.assertEqual(string, str(table)) def test_newline_multiple_columns(self): string = """+---+---+ | a | p | | b | q | | c | | +---+---+""" table = BeautifulTable() table.rows.append(["a\nb\nc", "p\nq"]) self.assertEqual(string, str(table)) # Test for ANSI sequences def test_ansi_sequences(self): table = BeautifulTable() string = """+------+---+-----+ | \x1b[31mAdam\x1b[0m | 2 | boy | +------+---+-----+""" table.rows.append(["\x1b[31mAdam\x1b[0m", 2, "boy"]) self.assertEqual(string, str(table)) def test_ansi_wrap(self): table = BeautifulTable(maxwidth=30) string = """+-----------------+---+------+ | \x1b[31mThis is a very \x1b[0m | 2 | girl | | \x1b[32mlong name\x1b[0m | | | +-----------------+---+------+""" long_string = "\x1b[31mThis is a very \x1b[0m\x1b[32mlong name\x1b[0m" table.rows.append([long_string, 2, "girl"]) self.assertEqual(string, str(table)) def test_ansi_wrap_mb(self): table = BeautifulTable(maxwidth=30) string = """+-----------------+---+------+ | \x1b[31mこれは非常に長\x1b[0m | 2 | girl | | \x1b[31mい\x1b[0m\x1b[32m名前です\x1b[0m | | | +-----------------+---+------+""" long_string = "\x1b[31mこれは非常に長い\x1b[0m\x1b[32m名前です\x1b[0m" table.rows.append([long_string, 2, "girl"]) self.assertEqual(string, str(table)) def test_ansi_ellipsis(self): table = BeautifulTable(maxwidth=30) table.columns.width_exceed_policy = table.WEP_ELLIPSIS string = """+-----------------+---+------+ | \x1b[31mThis is a ve\x1b[0m... | 2 | girl | +-----------------+---+------+""" long_string = "\x1b[31mThis is a very \x1b[0m\x1b[32mlong name\x1b[0m" table.rows.append([long_string, 2, "girl"]) self.assertEqual(string, str(table)) def test_ansi_ellipsis_mb(self): table = BeautifulTable(maxwidth=30) table.columns.width_exceed_policy = table.WEP_ELLIPSIS string = """+-----------------+---+------+ | \x1b[31mこれは非常に\x1b[0m... | 2 | girl | +-----------------+---+------+""" long_string = "\x1b[31mこれは非常に長い\x1b[0m\x1b[32m名前です\x1b[0m" table.rows.append([long_string, 2, "girl"]) self.assertEqual(string, str(table)) def test_ansi_strip(self): table = BeautifulTable(maxwidth=30) table.columns.width_exceed_policy = table.WEP_STRIP string = """+-----------------+---+------+ | \x1b[31mThis is a very \x1b[0m | 2 | girl | +-----------------+---+------+""" long_string = "\x1b[31mThis is a very \x1b[0m\x1b[32mlong name\x1b[0m" table.rows.append([long_string, 2, "girl"]) self.assertEqual(string, str(table)) def test_ansi_strip_mb(self): table = BeautifulTable(maxwidth=30) table.columns.width_exceed_policy = table.WEP_STRIP string = """+-----------------+---+------+ | \x1b[31mこれは非常に長\x1b[0m | 2 | girl | +-----------------+---+------+""" long_string = "\x1b[31mこれは非常に長い\x1b[0m\x1b[32m名前です\x1b[0m" table.rows.append([long_string, 2, "girl"]) self.assertEqual(string, str(table)) # Test on empty table def test_empty_table_by_column(self): self.create_table(20) for i in range(3): self.table.columns.pop() self.assertEqual(str(self.table), "") def test_empty_table_by_row(self): self.create_table(20) for i in range(5): self.table.rows.pop() self.assertEqual(str(self.table), "") def test_table_width_zero(self): self.create_table(20) self.table.clear(True) self.assertEqual(self.table._width, 0) def test_table_auto_width(self): row_list = ["abcdefghijklmopqrstuvwxyz", 1234, "none"] self.create_table(200) self.table.rows.append(row_list) len_for_max_width_200 = len(str(self.table)) self.create_table(80) self.table.rows.append(row_list) len_for_max_width_80 = len(str(self.table)) self.assertEqual(len_for_max_width_80, len_for_max_width_200) def test_csv_export(self): # Create csv files in path. self.table.to_csv("beautiful_table.csv") self.table.to_csv("./docs/beautiful_table.csv") with self.assertRaises(ValueError): self.table.to_csv(1) # Check if csv files exist. self.assertTrue(os.path.exists("beautiful_table.csv")) self.assertTrue(os.path.exists("./docs/beautiful_table.csv")) # Teardown step. os.remove("beautiful_table.csv") os.remove("./docs/beautiful_table.csv") def test_csv_import(self): # Export table as CSV file and import it back. self.table.to_csv("beautiful_table.csv") test_table = BeautifulTable() test_table.from_csv("beautiful_table.csv") with self.assertRaises(ValueError): self.table.from_csv(1) self.assertEqual(len(self.table.rows), len(test_table.rows)) self.assertEqual(self.table.columns.header, test_table.columns.header) test_table = BeautifulTable() test_table.from_csv("beautiful_table.csv", header=False) self.assertEqual(len(self.table.rows), len(test_table.rows) - 1) # Teardown step. os.remove("beautiful_table.csv") @unittest.skipUnless(PANDAS_INSTALLED, REQUIRED_PANDAS_MESSAGE) def test_df_export(self): df = self.table.to_df() self.assertEqual(self.table.rows.header, df.index) self.assertEqual(self.table.columns.header, list(df.columns)) self.assertEqual( [list(row) for row in list(df.values)], [list(row) for row in list(self.table._data)], ) @unittest.skipUnless(PANDAS_INSTALLED, REQUIRED_PANDAS_MESSAGE) def test_df_import(self): df = self.create_dataframe() table = BeautifulTable() table = table.from_df(df) self.assertEqual(table.rows.header, df.index) self.assertEqual(table.columns.header, list(df.columns)) self.assertEqual( [list(row) for row in list(df.values)], [list(row) for row in list(table.rows)], ) @unittest.skipUnless(PANDAS_INSTALLED, REQUIRED_PANDAS_MESSAGE) def test_df_export_scenario1(self): table = BeautifulTable() table.rows.append(["Jacob", 1, "boy"]) table.rows.append(["Isabella", 2, "girl"]) df = table.to_df() self.assertEqual(table.rows.header, [None, None]) self.assertEqual(table.columns.header, [None, None, None]) self.assertEqual(list(df.index), [0, 1]) self.assertEqual(list(df.columns), [0, 1, 2]) @unittest.skipUnless(PANDAS_INSTALLED, REQUIRED_PANDAS_MESSAGE) def test_df_export_scenario2(self): table = BeautifulTable() table.rows.append(["Jacob", 1, "boy"]) table.rows.append(["Isabella", 2, "girl"]) table.columns.header = [None, "rank", "gender"] df = table.to_df() self.assertEqual(table.rows.header, [None, None]) self.assertEqual(table.columns.header, [None, "rank", "gender"]) self.assertEqual(list(df.index), [0, 1]) self.assertEqual(list(df.columns), [None, "rank", "gender"])
def do_ps_reqs(self, arg): ''' Lists the process requests made by the specified process using the process PID or address descriptor. Note that if you use the PID, due to the OS possibly reusing the PID, you may get more than one process back Examples: ps_reqs 4608 ps_reqs 0x00000073 ps_reqs if already in a process context (using ps_cd) ''' if (self.sqlite_conn is None): sys.stderr.write( "Please load a database first with the load_db command\n") return if not arg: if self.process_context: arg = self.process_context else: sys.stderr.write( "Please specify a process id or descriptor address\n") return arg = arg.strip() process_filter = "" if (arg): try: int(arg) process_filter = "WHERE pid = %s" % arg except ValueError: #assume its a process descriptor process_filter = "WHERE desc_address = '%s'" % arg cursor = self.sqlite_conn.cursor() resp = cursor.execute( "SELECT id, desc_address, COALESCE(image,''), pid FROM process %s" % process_filter).fetchall() if not len(resp): sys.stderr.write("Invalid process pid, %s, specified\n" % arg) return table = BeautifulTable(max_width=160) for row in resp: table.column_headers = [ "Time", "Operation", "Target PID", "Target Descriptor", "Target Image" ] initiating = cursor.execute( "SELECT time, data, pid, desc_address, COALESCE(image, '') FROM operation \ JOIN process ON target_p_id = process.id WHERE p_id = %s AND op = 'PROCESS-ACCESS-REQ'" % row[0]) for rowIni in initiating: table.append_row(rowIni) print("\n") print(banner("Process %s (%s)" % (row[3], row[1]))) print("Image: %s\n" % row[2]) print("Operations Initiated By This Process:") print(table) print("Total: %d\n" % len(table)) table.clear() table.column_headers = [ "Time", "Operation", "Initiator PID", "Initiator Descriptor", "Initiator Image" ] initiating = cursor.execute( "SELECT time, data, pid, desc_address, COALESCE(image, '') FROM operation \ JOIN process ON p_id = process.id WHERE target_p_id = %s AND op = 'PROCESS-ACCESS-REQ'" % row[0]) for rowIni in initiating: table.append_row(rowIni) print("\nOperations In Which This Process Is The Target:") print(table) print("Total: %d\n" % len(table)) table.clear()
def do_ls(self, arg): ''' List the file resources contained in the database. The returned files can be filtered by using globs. Example: ls *ntdll.dll* If in a process context (via ps_cd <pid>), shows only the file resources accessed by this process in addition to the type of access, i.e. READ, WRITE, etc. You can also filter for specific files in this context using ls *NickVirus* ''' if (self.sqlite_conn is None): sys.stderr.write( "Please load a database first with the load_db command\n") return if self.prompt == self.CONST_DEFAULT_PROMPT: query = "SELECT id, name, first_seen FROM resource WHERE type = 'F'" cursor = self.sqlite_conn.cursor() arg = arg.strip() if arg: query = "SELECT id, name, first_seen FROM resource WHERE type = 'F' AND name LIKE '%s'" % arg.replace( "*", "%") try: table = BeautifulTable(max_width=160) table.column_headers = ["Resource Id", "Name", "First Seen"] for row in cursor.execute(query): table.append_row(row) if not len(table): sys.stderr.write("No file with name %s found\n" % arg) return print(table) print("\n") print("Total: %d\n" % len(table)) if arg: table.clear(True) table.column_headers = [ "Time", "PID", "Process Descriptor", "Process Image", "Target PID", "Target Descriptor", "Target Image", "Operation", "Aux Data" ] for row in cursor.execute( "SELECT time, p1.pid, p1.desc_address, COALESCE(p1.image, ''), \ COALESCE(p2.pid, ''), COALESCE(p2.desc_address, ''), COALESCE(p2.image, ''), op, COALESCE(data,'') \ FROM operation JOIN process p1 ON p_id = p1.id LEFT JOIN \ process p2 ON target_p_id = p2.id JOIN resource ON \ r_id = resource.id WHERE name LIKE '%s'" % arg.replace("*", "%")): table.append_row(row) if len(table): print("Accessed by process(es) ...") print(table) print("\n") print("Total: %d\n" % len(table)) except Exception as e: print(e) sys.stderr.write("Invalid file name specified") else: searchOnNameClause = "" arg = arg.strip() if arg: searchOnNameClause = "AND name LIKE '%s'" % arg.replace( "*", "%") process_filter = "" try: int(self.process_context) process_filter = "WHERE pid = %s" % self.process_context except: process_filter = "WHERE desc_address = '%s'" % self.process_context cursor = self.sqlite_conn.cursor() resp = cursor.execute( "SELECT id, pid, desc_address FROM process %s" % process_filter).fetchall() for pRow in resp: ''' This query accounts for both image loads + file i/o ''' query = "SELECT name, COALESCE(op, ''), COALESCE(process.pid, ''), COALESCE(desc_address, ''), COALESCE(data, ''), \ time FROM operation LEFT JOIN process ON target_p_id = process.id JOIN \ resource ON r_id = resource.id WHERE target_p_id = %s AND type = 'F' %s \ UNION \ SELECT name, COALESCE(op, ''), '', '', COALESCE(data, ''), \ time FROM operation JOIN process ON p_id = process.id JOIN \ resource ON r_id = resource.id WHERE p_id = %s AND type = 'F' AND target_p_id IS NULL %s ORDER BY time" % \ (pRow[0], searchOnNameClause, pRow[0], searchOnNameClause) print("\n") print(banner("Process %s (%s)" % (pRow[1], pRow[2]))) table = BeautifulTable(max_width=160) table.column_headers = [ "Name", "Operation", "Target PID", "Target PID Descriptor", "Aux Data", "First Seen" ] for row in cursor.execute(query): table.append_row(row) print(table) print("Total: %d\n" % len(table))