Mercurial > libervia-backend
comparison frontends/src/jp/common.py @ 2345:c57bc0fe17d9
jp (common): added use_buffer argument in Table:
when use_buffer is True, the Table is not printed but put in a buffer. A unicode string can then be computed when string property is used.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 23 Aug 2017 00:10:09 +0200 |
parents | 78ffb9ce57a4 |
children | 3c0a3fae1862 |
comparison
equal
deleted
inserted
replaced
2344:78ffb9ce57a4 | 2345:c57bc0fe17d9 |
---|---|
503 return pubsub_service, pubsub_node, pubsub_item, content_file_path, content_file_obj | 503 return pubsub_service, pubsub_node, pubsub_item, content_file_path, content_file_obj |
504 | 504 |
505 | 505 |
506 class Table(object): | 506 class Table(object): |
507 | 507 |
508 def __init__(self, host, data, headers=None, filters=None): | 508 def __init__(self, host, data, headers=None, filters=None, use_buffer=False): |
509 """ | 509 """ |
510 @param data(list[list]): table data | 510 @param data(list[list]): table data |
511 all lines must have the same number of columns | 511 all lines must have the same number of columns |
512 @param headers(iterable[unicode], None): names/titles of the columns | 512 @param headers(iterable[unicode], None): names/titles of the columns |
513 if not None, must have same number of columns as data | 513 if not None, must have same number of columns as data |
514 @param filters(iterable[(callable, unicode)], None): values filters | 514 @param filters(iterable[(callable, unicode)], None): values filters |
515 the callable will get col value as argument and must return a string | 515 the callable will get col value as argument and must return a string |
516 if it's unicode, it will be used with .format and must countain u'{}' which will be replaced with the string | 516 if it's unicode, it will be used with .format and must countain u'{}' which will be replaced with the string |
517 if not None, must have same number of columns as data | 517 if not None, must have same number of columns as data |
518 @param use_buffer(bool): if True, bufferise output instead of printing it directly | |
518 """ | 519 """ |
519 self.host = host | 520 self.host = host |
521 self._buffer = [] if use_buffer else None | |
520 # headers are columns names/titles, can be None | 522 # headers are columns names/titles, can be None |
521 self.headers = headers | 523 self.headers = headers |
522 # sizes fof columns without headers, | 524 # sizes fof columns without headers, |
523 # headers may be larger | 525 # headers may be larger |
524 self.sizes = [] | 526 self.sizes = [] |
557 | 559 |
558 if not data and headers is not None: | 560 if not data and headers is not None: |
559 # the table is empty, we print headers at their lenght | 561 # the table is empty, we print headers at their lenght |
560 self.sizes = [len(h) for h in headers] | 562 self.sizes = [len(h) for h in headers] |
561 | 563 |
564 @property | |
565 def string(self): | |
566 if self._buffer is None: | |
567 raise exceptions.InternalError(u'buffer must be used to get a string') | |
568 return u'\n'.join(self._buffer) | |
569 | |
562 @staticmethod | 570 @staticmethod |
563 def readDictValues(data, keys, defaults=None): | 571 def readDictValues(data, keys, defaults=None): |
564 if defaults is None: | 572 if defaults is None: |
565 defaults = {} | 573 defaults = {} |
566 for key in keys: | 574 for key in keys: |
623 if style: | 631 if style: |
624 args = style + [rendered] | 632 args = style + [rendered] |
625 rendered = A.color(*args) | 633 rendered = A.color(*args) |
626 headers.append(rendered) | 634 headers.append(rendered) |
627 return head_sep.join(headers) | 635 return head_sep.join(headers) |
636 | |
637 def _disp(self, data): | |
638 """output data (can be either bufferised or printed)""" | |
639 if self._buffer is not None: | |
640 self._buffer.append(data) | |
641 else: | |
642 self.host.disp(data) | |
628 | 643 |
629 def display(self, | 644 def display(self, |
630 head_alignment = u'left', | 645 head_alignment = u'left', |
631 columns_alignment = u'left', | 646 columns_alignment = u'left', |
632 head_style = None, | 647 head_style = None, |
645 head_line_sep=u'┄┼┄', | 660 head_line_sep=u'┄┼┄', |
646 head_line_right=u'┤', | 661 head_line_right=u'┤', |
647 bottom_left=u'└', | 662 bottom_left=u'└', |
648 bottom=None, | 663 bottom=None, |
649 bottom_sep=u'─┴─', | 664 bottom_sep=u'─┴─', |
650 bottom_right=u'┘' | 665 bottom_right=u'┘', |
651 ): | 666 ): |
652 """Print the table | 667 """Print the table |
653 | 668 |
654 @param show_header(bool): True if header need no be shown | 669 @param show_header(bool): True if header need no be shown |
655 @param show_borders(bool): True if borders need no be shown | 670 @param show_borders(bool): True if borders need no be shown |
656 @param head_alignment(unicode): how to align headers, can be left, center or right | 671 @param head_alignment(unicode): how to align headers, can be left, center or right |
657 @param columns_alignment(unicode): how to align columns, can be left, center or right | 672 @param columns_alignment(unicode): how to align columns, can be left, center or right |
658 @param col_sep(unicode): separator betweens columns | 673 @param col_sep(unicode): separator betweens columns |
659 @param head_line(unicode): character to use to make line under head | 674 @param head_line(unicode): character to use to make line under head |
675 @param disp(callable, None): method to use to display the table | |
676 None to use self.host.disp | |
660 """ | 677 """ |
661 col_sep_size = len(regex.ansiRemove(col_sep)) | 678 col_sep_size = len(regex.ansiRemove(col_sep)) |
662 if right is None: | 679 if right is None: |
663 right = left | 680 right = left |
664 if top_sep is None: | 681 if top_sep is None: |
671 bottom_sep = col_sep_size * bottom | 688 bottom_sep = col_sep_size * bottom |
672 if not show_borders: | 689 if not show_borders: |
673 left = right = head_line_left = head_line_right = u'' | 690 left = right = head_line_left = head_line_right = u'' |
674 # top border | 691 # top border |
675 if show_borders: | 692 if show_borders: |
676 self.host.disp( | 693 self._disp( |
677 top_left | 694 top_left |
678 + top_sep.join([top*size for size in self.sizes]) | 695 + top_sep.join([top*size for size in self.sizes]) |
679 + top_right | 696 + top_right |
680 ) | 697 ) |
681 | 698 |
682 # headers | 699 # headers |
683 if show_header: | 700 if show_header: |
684 self.host.disp( | 701 self._disp( |
685 left | 702 left |
686 + self._headers(head_sep, head_alignment, head_style) | 703 + self._headers(head_sep, head_alignment, head_style) |
687 + right | 704 + right |
688 ) | 705 ) |
689 # header line | 706 # header line |
690 self.host.disp( | 707 self._disp( |
691 head_line_left | 708 head_line_left |
692 + head_line_sep.join([head_line*size for size in self.sizes]) | 709 + head_line_sep.join([head_line*size for size in self.sizes]) |
693 + head_line_right | 710 + head_line_right |
694 ) | 711 ) |
695 | 712 |
702 alignment = lambda idx, s: ansi_rjust(s, self.sizes[idx]) | 719 alignment = lambda idx, s: ansi_rjust(s, self.sizes[idx]) |
703 else: | 720 else: |
704 raise exceptions.InternalError(u'bad columns alignment argument') | 721 raise exceptions.InternalError(u'bad columns alignment argument') |
705 | 722 |
706 for row in self.rows: | 723 for row in self.rows: |
707 self.host.disp(left + col_sep.join([alignment(idx,c) for idx,c in enumerate(row)]) + right) | 724 self._disp(left + col_sep.join([alignment(idx,c) for idx,c in enumerate(row)]) + right) |
708 | 725 |
709 if show_borders: | 726 if show_borders: |
710 # bottom border | 727 # bottom border |
711 self.host.disp( | 728 self._disp( |
712 bottom_left | 729 bottom_left |
713 + bottom_sep.join([bottom*size for size in self.sizes]) | 730 + bottom_sep.join([bottom*size for size in self.sizes]) |
714 + bottom_right | 731 + bottom_right |
715 ) | 732 ) |
733 # we return self so string can be used after display (table.display().string) | |
734 return self | |
716 | 735 |
717 def display_blank(self, **kwargs): | 736 def display_blank(self, **kwargs): |
718 """Display table without visible borders""" | 737 """Display table without visible borders""" |
719 kwargs_ = {'col_sep':u' ', 'head_line_sep':u' ', 'show_borders':False} | 738 kwargs_ = {'col_sep':u' ', 'head_line_sep':u' ', 'show_borders':False} |
720 kwargs_.update(kwargs) | 739 kwargs_.update(kwargs) |
721 self.display(self, | 740 return self.display(self, |
722 **kwargs_ | 741 **kwargs_ |
723 ) | 742 ) |