diff --git a/evennia/utils/prettytable.py b/evennia/utils/prettytable.py index cecd86c921..7e0a9a8a94 100644 --- a/evennia/utils/prettytable.py +++ b/evennia/utils/prettytable.py @@ -65,10 +65,7 @@ else: from cgi import escape # hrule styles -FRAME = 0 -ALL = 1 -NONE = 2 -HEADER = 3 +FRAME, ALL, NONE, HEADER = range(4) # Table styles DEFAULT = 10 @@ -78,12 +75,13 @@ RANDOM = 20 _re = re.compile("\033\[[0-9;]*m") + def _ansi(method): - "decorator for converting ansi in input" + """decorator for converting ansi in input""" def wrapper(self, *args, **kwargs): def convert(inp): if isinstance(inp, basestring): - return parse_ansi("{n%s{n" % inp) + return parse_ansi("|n%s|n" % inp) elif hasattr(inp, '__iter__'): li = [] for element in inp: @@ -96,19 +94,20 @@ def _ansi(method): return li return inp args = [convert(arg) for arg in args] - #kwargs = dict((key, convert(val)) for key, val in kwargs.items()) + # kwargs = dict((key, convert(val)) for key, val in kwargs.items()) return method(self, *args, **kwargs) return wrapper + def _get_size(text): lines = text.split("\n") height = len(lines) width = max([_str_block_width(line) for line in lines]) - return (width, height) + return width, height + class PrettyTable(object): - @_ansi def __init__(self, field_names=None, **kwargs): @@ -153,9 +152,12 @@ class PrettyTable(object): self._widths = [] # Options - self._options = "start end fields header border sortby reversesort sort_key attributes format hrules vrules".split() - self._options.extend("int_format float_format padding_width left_padding_width right_padding_width".split()) - self._options.extend("vertical_char horizontal_char junction_char header_style valign xhtml print_empty".split()) + self._options = "start end fields header border sortby reversesort" \ + " sort_key attributes format hrules vrules".split() + self._options.extend("int_format float_format padding_width " + "left_padding_width right_padding_width".split()) + self._options.extend("vertical_char horizontal_char junction_char" + " header_style valign xhtml print_empty".split()) for option in self._options: if option in kwargs: self._validate_option(option, kwargs[option]) @@ -263,10 +265,10 @@ class PrettyTable(object): if py3k: def __str__(self): - return self.__unicode__() + return self.__unicode__() else: def __str__(self): - return self.__unicode__().encode(self.encoding) + return self.__unicode__().encode(self.encoding) def __unicode__(self): return self.get_string() @@ -283,31 +285,32 @@ class PrettyTable(object): # Secondly, in the _get_options method, where keyword arguments are mixed with persistent settings def _validate_option(self, option, val): - if option in ("field_names"): + if option in "field_names": self._validate_field_names(val) - elif option in ("start", "end", "max_width", "padding_width", "left_padding_width", "right_padding_width", "format"): + elif option in ("start", "end", "max_width", "padding_width", + "left_padding_width", "right_padding_width", "format"): self._validate_nonnegative_int(option, val) - elif option in ("sortby"): + elif option in "sortby": self._validate_field_name(option, val) - elif option in ("sort_key"): + elif option in "sort_key": self._validate_function(option, val) - elif option in ("hrules"): + elif option in "hrules": self._validate_hrules(option, val) - elif option in ("vrules"): + elif option in "vrules": self._validate_vrules(option, val) - elif option in ("fields"): + elif option in "fields": self._validate_all_field_names(option, val) elif option in ("header", "border", "reversesort", "xhtml", "print_empty"): self._validate_true_or_false(option, val) - elif option in ("header_style"): + elif option in "header_style": self._validate_header_style(val) - elif option in ("int_format"): + elif option in "int_format": self._validate_int_format(option, val) - elif option in ("float_format"): + elif option in "float_format": self._validate_float_format(option, val) elif option in ("vertical_char", "horizontal_char", "junction_char"): self._validate_single_char(option, val) - elif option in ("attributes"): + elif option in "attributes": self._validate_attributes(option, val) else: raise Exception("Unrecognised option: %s!" % option) @@ -316,14 +319,16 @@ class PrettyTable(object): # Check for appropriate length if self._field_names: try: - assert len(val) == len(self._field_names) + assert len(val) == len(self._field_names) except AssertionError: - raise Exception("Field name list has incorrect number of values, (actual) %d!=%d (expected)" % (len(val), len(self._field_names))) + raise Exception("Field name list has incorrect number of values, (actual) %d!=%d (expected)" + % (len(val), len(self._field_names))) if self._rows: try: - assert len(val) == len(self._rows[0]) + assert len(val) == len(self._rows[0]) except AssertionError: - raise Exception("Field name list has incorrect number of values, (actual) %d!=%d (expected)" % (len(val), len(self._rows[0]))) + raise Exception("Field name list has incorrect number of values, (actual) %d!=%d (expected)" + % (len(val), len(self._rows[0]))) # Check for uniqueness try: assert len(val) == len(set(val)) @@ -338,13 +343,13 @@ class PrettyTable(object): def _validate_align(self, val): try: - assert val in ["l","c","r"] + assert val in ["l", "c", "r"] except AssertionError: raise Exception("Alignment %s is invalid, use l, c or r!" % val) def _validate_valign(self, val): try: - assert val in ["t","m","b",None] + assert val in ["t", "m", "b", None] except AssertionError: raise Exception("Alignment %s is invalid, use t, m, b or None!" % val) @@ -436,6 +441,7 @@ class PrettyTable(object): fields - list or tuple of field names""" return self._field_names + def _set_field_names(self, val): val = [self._unicode(x) for x in val] self._validate_option("field_names", val) @@ -461,30 +467,37 @@ class PrettyTable(object): else: for field in self._field_names: self._valign[field] = "t" + field_names = property(_get_field_names, _set_field_names) def _get_align(self): return self._align + def _set_align(self, val): self._validate_align(val) for field in self._field_names: self._align[field] = val + align = property(_get_align, _set_align) def _get_valign(self): return self._valign + def _set_valign(self, val): self._validate_valign(val) for field in self._field_names: self._valign[field] = val + valign = property(_get_valign, _set_valign) def _get_max_width(self): return self._max_width + def _set_max_width(self, val): self._validate_option("max_width", val) for field in self._field_names: self._max_width[field] = val + max_width = property(_get_max_width, _set_max_width) def _get_fields(self): @@ -494,9 +507,11 @@ class PrettyTable(object): fields - list or tuple of field names to include in displays""" return self._fields + def _set_fields(self, val): self._validate_option("fields", val) self._fields = val + fields = property(_get_fields, _set_fields) def _get_start(self): @@ -510,6 +525,7 @@ class PrettyTable(object): def _set_start(self, val): self._validate_option("start", val) self._start = val + start = property(_get_start, _set_start) def _get_end(self): @@ -519,9 +535,11 @@ class PrettyTable(object): end - index of last data row to include in output PLUS ONE (list slice style)""" return self._end + def _set_end(self, val): self._validate_option("end", val) self._end = val + end = property(_get_end, _set_end) def _get_sortby(self): @@ -531,9 +549,11 @@ class PrettyTable(object): sortby - field name to sort by""" return self._sortby + def _set_sortby(self, val): self._validate_option("sortby", val) self._sortby = val + sortby = property(_get_sortby, _set_sortby) def _get_reversesort(self): @@ -543,9 +563,11 @@ class PrettyTable(object): reveresort - set to True to sort by descending order, or False to sort by ascending order""" return self._reversesort + def _set_reversesort(self, val): self._validate_option("reversesort", val) self._reversesort = val + reversesort = property(_get_reversesort, _set_reversesort) def _get_sort_key(self): @@ -555,9 +577,11 @@ class PrettyTable(object): sort_key - a function which takes one argument and returns something to be sorted""" return self._sort_key + def _set_sort_key(self, val): self._validate_option("sort_key", val) self._sort_key = val + sort_key = property(_get_sort_key, _set_sort_key) def _get_header(self): @@ -567,9 +591,11 @@ class PrettyTable(object): header - print a header showing field names (True or False)""" return self._header + def _set_header(self, val): self._validate_option("header", val) self._header = val + header = property(_get_header, _set_header) def _get_header_style(self): @@ -579,9 +605,11 @@ class PrettyTable(object): header_style - stylisation to apply to field names in header ("cap", "title", "upper", "lower" or None)""" return self._header_style + def _set_header_style(self, val): self._validate_header_style(val) self._header_style = val + header_style = property(_get_header_style, _set_header_style) def _get_border(self): @@ -591,9 +619,11 @@ class PrettyTable(object): border - print a border around the table (True or False)""" return self._border + def _set_border(self, val): self._validate_option("border", val) self._border = val + border = property(_get_border, _set_border) def _get_hrules(self): @@ -603,9 +633,11 @@ class PrettyTable(object): hrules - horizontal rules style. Allowed values: FRAME, ALL, HEADER, NONE""" return self._hrules + def _set_hrules(self, val): self._validate_option("hrules", val) self._hrules = val + hrules = property(_get_hrules, _set_hrules) def _get_vrules(self): @@ -615,9 +647,11 @@ class PrettyTable(object): vrules - vertical rules style. Allowed values: FRAME, ALL, NONE""" return self._vrules + def _set_vrules(self, val): self._validate_option("vrules", val) self._vrules = val + vrules = property(_get_vrules, _set_vrules) def _get_int_format(self): @@ -626,10 +660,12 @@ class PrettyTable(object): int_format - integer format string""" return self._int_format + def _set_int_format(self, val): -# self._validate_option("int_format", val) + # self._validate_option("int_format", val) for field in self._field_names: self._int_format[field] = val + int_format = property(_get_int_format, _set_int_format) def _get_float_format(self): @@ -638,10 +674,12 @@ class PrettyTable(object): float_format - floating point format string""" return self._float_format + def _set_float_format(self, val): -# self._validate_option("float_format", val) + # self._validate_option("float_format", val) for field in self._field_names: self._float_format[field] = val + float_format = property(_get_float_format, _set_float_format) def _get_padding_width(self): @@ -651,9 +689,11 @@ class PrettyTable(object): padding_width - number of spaces, must be a positive integer""" return self._padding_width + def _set_padding_width(self, val): self._validate_option("padding_width", val) self._padding_width = val + padding_width = property(_get_padding_width, _set_padding_width) def _get_left_padding_width(self): @@ -663,9 +703,11 @@ class PrettyTable(object): left_padding - number of spaces, must be a positive integer""" return self._left_padding_width + def _set_left_padding_width(self, val): self._validate_option("left_padding_width", val) self._left_padding_width = val + left_padding_width = property(_get_left_padding_width, _set_left_padding_width) def _get_right_padding_width(self): @@ -675,9 +717,11 @@ class PrettyTable(object): right_padding - number of spaces, must be a positive integer""" return self._right_padding_width + def _set_right_padding_width(self, val): self._validate_option("right_padding_width", val) self._right_padding_width = val + right_padding_width = property(_get_right_padding_width, _set_right_padding_width) def _get_vertical_char(self): @@ -687,10 +731,12 @@ class PrettyTable(object): vertical_char - single character string used to draw vertical lines""" return self._vertical_char + def _set_vertical_char(self, val): val = self._unicode(val) self._validate_option("vertical_char", val) self._vertical_char = val + vertical_char = property(_get_vertical_char, _set_vertical_char) def _get_horizontal_char(self): @@ -700,10 +746,12 @@ class PrettyTable(object): horizontal_char - single character string used to draw horizontal lines""" return self._horizontal_char + def _set_horizontal_char(self, val): val = self._unicode(val) self._validate_option("horizontal_char", val) self._horizontal_char = val + horizontal_char = property(_get_horizontal_char, _set_horizontal_char) def _get_junction_char(self): @@ -713,10 +761,12 @@ class PrettyTable(object): junction_char - single character string used to draw line junctions""" return self._junction_char + def _set_junction_char(self, val): val = self._unicode(val) self._validate_option("vertical_char", val) self._junction_char = val + junction_char = property(_get_junction_char, _set_junction_char) def _get_format(self): @@ -726,9 +776,11 @@ class PrettyTable(object): format - True or False""" return self._format + def _set_format(self, val): self._validate_option("format", val) self._format = val + format = property(_get_format, _set_format) def _get_print_empty(self): @@ -738,9 +790,11 @@ class PrettyTable(object): print_empty - True or False""" return self._print_empty + def _set_print_empty(self, val): self._validate_option("print_empty", val) self._print_empty = val + print_empty = property(_get_print_empty, _set_print_empty) def _get_attributes(self): @@ -750,9 +804,11 @@ class PrettyTable(object): attributes - dictionary of attributes""" return self._attributes + def _set_attributes(self, val): self._validate_option("attributes", val) self._attributes = val + attributes = property(_get_attributes, _set_attributes) ############################## @@ -825,8 +881,8 @@ class PrettyTable(object): self.border = random.choice((True, False)) self._hrules = random.choice((ALL, FRAME, HEADER, NONE)) self._vrules = random.choice((ALL, FRAME, NONE)) - self.left_padding_width = random.randint(0,5) - self.right_padding_width = random.randint(0,5) + self.left_padding_width = random.randint(0, 5) + self.right_padding_width = random.randint(0, 5) self.vertical_char = random.choice("~!@#$%^&*()_+|-=\{}[];':\",./;<>?") self.horizontal_char = random.choice("~!@#$%^&*()_+|-=\{}[];':\",./;<>?") self.junction_char = random.choice("~!@#$%^&*()_+|-=\{}[];':\",./;<>?") @@ -846,9 +902,10 @@ class PrettyTable(object): has fields""" if self._field_names and len(row) != len(self._field_names): - raise Exception("Row has incorrect number of values, (actual) %d!=%d (expected)" %(len(row),len(self._field_names))) + raise Exception("Row has incorrect number of values, (actual) %d!=%d (expected)" + % (len(row), len(self._field_names))) if not self._field_names: - self.field_names = [("Field %d" % (n+1)) for n in range(0,len(row))] + self.field_names = [("Field %d" % (n+1)) for n in range(0, len(row))] self._rows.append(list(row)) def del_row(self, row_index): @@ -860,7 +917,7 @@ class PrettyTable(object): row_index - The index of the row you want to delete. Indexing starts at 0.""" if row_index > len(self._rows)-1: - raise Exception("Cant delete row at index %d, table only has %d rows!" % (row_index, len(self._rows))) + raise Exception("Can't delete row at index %d, table only has %d rows!" % (row_index, len(self._rows))) del self._rows[row_index] @_ansi @@ -1113,7 +1170,7 @@ class PrettyTable(object): def _stringify_row(self, row, options): - for index, field, value, width, in zip(range(0,len(row)), self._field_names, row, self._widths): + for index, field, value, width, in zip(range(0, len(row)), self._field_names, row, self._widths): # Enforce max widths lines = value.split("\n") new_lines = [] @@ -1145,14 +1202,14 @@ class PrettyTable(object): valign = self._valign[field] lines = value.split("\n") - dHeight = row_height - len(lines) - if dHeight: + dheight = row_height - len(lines) + if dheight: if valign == "m": - lines = [""] * (dHeight // 2) + lines + [""] * (dHeight - (dHeight // 2)) + lines = [""] * (dheight // 2) + lines + [""] * (dheight - (dheight // 2)) elif valign == "b": - lines = [""] * dHeight + lines + lines = [""] * dheight + lines else: - lines = lines + [""] * dHeight + lines += [""] * dheight y = 0 for l in lines: @@ -1174,7 +1231,7 @@ class PrettyTable(object): bits[y].pop() bits[y].append(options["vertical_char"]) - if options["border"] and options["hrules"]== ALL: + if options["border"] and options["hrules"] == ALL: bits[row_height-1].append("\n") bits[row_height-1].append(self._hrule) @@ -1227,8 +1284,7 @@ class PrettyTable(object): else: linebreak = "
" - open_tag = [] - open_tag.append("%s" % (lpad, rpad, escape(field).replace("\n", linebreak))) + lines.append(" %s" + % (lpad, rpad, escape(field).replace("\n", linebreak))) lines.append(" ") # Data @@ -1306,14 +1363,16 @@ class PrettyTable(object): aligns = [] valigns = [] for field in self._field_names: - aligns.append({ "l" : "left", "r" : "right", "c" : "center" }[self._align[field]]) - valigns.append({"t" : "top", "m" : "middle", "b" : "bottom"}[self._valign[field]]) + aligns.append(dict(l="left", r="right", c="center")[self._align[field]]) + valigns.append(dict(t="top", m="middle", b="bottom")[self._valign[field]]) for row in formatted_rows: lines.append(" ") for field, datum, align, valign in zip(self._field_names, row, aligns, valigns): if options["fields"] and field not in options["fields"]: continue - lines.append(" %s" % (lpad, rpad, align, valign, escape(datum).replace("\n", linebreak))) + lines.append(" %s" + % (lpad, rpad, align, valign, escape(datum).replace("\n", linebreak))) lines.append(" ") lines.append("") @@ -1323,10 +1382,11 @@ class PrettyTable(object): # UNICODE WIDTH FUNCTIONS # ############################## + def _char_block_width(char): # Basic Latin, which is probably the most common case - #if char in xrange(0x0021, 0x007e): - #if char >= 0x0021 and char <= 0x007e: + # if char in xrange(0x0021, 0x007e): + # if char >= 0x0021 and char <= 0x007e: if 0x0021 <= char <= 0x007e: return 1 # Chinese, Japanese, Korean (common) @@ -1356,6 +1416,7 @@ def _char_block_width(char): # Take a guess return 1 + def _str_block_width(val): return sum(itermap(_char_block_width, itermap(ord, _re.sub("", val)))) @@ -1364,7 +1425,8 @@ def _str_block_width(val): # TABLE FACTORIES # ############################## -def from_csv(fp, field_names = None, **kwargs): + +def from_csv(fp, field_names=None, **kwargs): dialect = csv.Sniffer().sniff(fp.read(1024)) fp.seek(0) @@ -1381,6 +1443,7 @@ def from_csv(fp, field_names = None, **kwargs): return table + def from_db_cursor(cursor, **kwargs): if cursor.description: @@ -1390,6 +1453,7 @@ def from_db_cursor(cursor, **kwargs): table.add_row(row) return table + class TableHandler(HTMLParser): def __init__(self, **kwargs): @@ -1403,12 +1467,12 @@ class TableHandler(HTMLParser): self.last_content = "" self.is_last_row_header = False - def handle_starttag(self,tag, attrs): + def handle_starttag(self, tag, attrs): self.active = tag if tag == "th": self.is_last_row_header = True - def handle_endtag(self,tag): + def handle_endtag(self, tag): if tag in ["th", "td"]: stripped_content = self.last_content.strip() self.last_row.append(stripped_content) @@ -1425,7 +1489,6 @@ class TableHandler(HTMLParser): self.last_content = " " self.active = None - def handle_data(self, data): self.last_content += data @@ -1437,10 +1500,10 @@ class TableHandler(HTMLParser): for row in self.rows: if len(row[0]) < self.max_row_width: appends = self.max_row_width - len(row[0]) - for i in range(1,appends): + for _ in range(1, appends): row[0].append("-") - if row[1] == True: + if row[1] is True: self.make_fields_unique(row[0]) table.field_names = row[0] else: @@ -1456,6 +1519,7 @@ class TableHandler(HTMLParser): if fields[i] == fields[j]: fields[j] += "'" + def from_html(html_code, **kwargs): """ Generates a list of PrettyTables from a string of HTML code. Each in @@ -1466,6 +1530,7 @@ def from_html(html_code, **kwargs): parser.feed(html_code) return parser.tables + def from_html_one(html_code, **kwargs): """ Generates a PrettyTables from a string of HTML code which contains only a @@ -1483,6 +1548,7 @@ def from_html_one(html_code, **kwargs): # MAIN (TEST FUNCTION) # ############################## + def main(): x = PrettyTable(["City name", "Area", "Population", "Annual Rainfall"]) @@ -1490,7 +1556,7 @@ def main(): x.reversesort = True x.int_format["Area"] = "04d" x.float_format = "6.1f" - x.align["City name"] = "l" # Left align city names + x.align["City name"] = "l" # Left align city names x.add_row(["Adelaide", 1295, 1158259, 600.5]) x.add_row(["Brisbane", 5905, 1857594, 1146.4]) x.add_row(["Darwin", 112, 120900, 1714.7])