Exemplo n.º 1
0
def test_terminal_size(monkeypatch):
    """Test terminal_size(). In CIs the default height/width is returned since there is no terminal."""
    width, height = terminal_size()
    assert width > 0
    assert height > 0

    if hasattr(ctypes, 'windll'):
        monkeypatch.setattr('ctypes.windll.kernel32.GetConsoleScreenBufferInfo', fake_csbi)
    else:
        monkeypatch.setattr('fcntl.ioctl', lambda *_: b'\x1d\x00w\x00\xca\x02\x96\x01')
    width, height = terminal_size()
    assert width == 119
    assert height == 29
Exemplo n.º 2
0
def test_terminal_size(monkeypatch):
    """Test terminal_size(). In CIs the default height/width is returned since there is no terminal."""
    width, height = terminal_size()
    assert width > 0
    assert height > 0

    if hasattr(ctypes, 'windll'):
        monkeypatch.setattr(
            'ctypes.windll.kernel32.GetConsoleScreenBufferInfo', fake_csbi)
    else:
        monkeypatch.setattr('fcntl.ioctl',
                            lambda *_: b'\x1d\x00w\x00\xca\x02\x96\x01')
    width, height = terminal_size()
    assert width == 119
    assert height == 29
Exemplo n.º 3
0
def test_nix(monkeypatch):
    """Test function with IS_WINDOWS=False.

    :param monkeypatch: pytest fixture.
    """
    # Test exception (no terminal within pytest).
    width, height = terminal_size()
    assert width == DEFAULT_WIDTH
    assert height == DEFAULT_HEIGHT

    # Test mocked.
    monkeypatch.setattr('fcntl.ioctl', lambda *_: b'\x1d\x00w\x00\xca\x02\x96\x01')
    width, height = terminal_size()
    assert width == 119
    assert height == 29
Exemplo n.º 4
0
def column_max_width(table_data, column_number, outer_border, inner_border,
                     padding):
    """Determine the maximum width of a column based on the current terminal width.

    :param iter table_data: List of list of strings (unmodified table data).
    :param int column_number: The column number to query.
    :param int outer_border: Sum of left and right outer border visible widths.
    :param int inner_border: Visible width of the inner border character.
    :param int padding: Total padding per cell (left + right padding).

    :return: The maximum width the column can be without causing line wrapping.
    """
    column_widths = max_dimensions(table_data)[0]
    column_count = len(column_widths)
    terminal_width = terminal_size()[0]

    # Count how much space padding, outer, and inner borders take up.
    non_data_space = outer_border
    if column_count:
        non_data_space += inner_border * (column_count - 1)
        non_data_space += column_count * padding

    # Exclude selected column's width.
    data_space = sum(column_widths) - column_widths[column_number]

    return terminal_width - data_space - non_data_space
Exemplo n.º 5
0
def test_nix(monkeypatch):
    """Test function with IS_WINDOWS=False.

    :param monkeypatch: pytest fixture.
    """
    # Test exception (no terminal within pytest).
    width, height = terminal_size()
    assert width == DEFAULT_WIDTH
    assert height == DEFAULT_HEIGHT

    # Test mocked.
    monkeypatch.setattr('fcntl.ioctl',
                        lambda *_: b'\x1d\x00w\x00\xca\x02\x96\x01')
    width, height = terminal_size()
    assert width == 119
    assert height == 29
def column_max_width(table_data, column_number, outer_border, inner_border, padding):
    """Determine the maximum width of a column based on the current terminal width.

    :param iter table_data: List of list of strings (unmodified table data).
    :param int column_number: The column number to query.
    :param int outer_border: Sum of left and right outer border visible widths.
    :param int inner_border: Visible width of the inner border character.
    :param int padding: Total padding per cell (left + right padding).

    :return: The maximum width the column can be without causing line wrapping.
    """
    column_widths = max_dimensions(table_data)[0]
    column_count = len(column_widths)
    terminal_width = terminal_size()[0]

    # Count how much space padding, outer, and inner borders take up.
    non_data_space = outer_border
    if column_count:
        non_data_space += inner_border * (column_count - 1)
        non_data_space += column_count * padding

    # Exclude selected column's width.
    data_space = sum(column_widths) - column_widths[column_number]

    return terminal_width - data_space - non_data_space
Exemplo n.º 7
0
 def wrap_long_strings(self, table_data):
     while self.table_width > terminal_size()[0]:
         longest = 0
         for rowindex, row in enumerate(table_data):
             for columnindex, column in enumerate(row):
                 if len(column) > longest:
                     longest = len(column)
                     longestrow = rowindex
                     longestcollumn = columnindex
         max_width = self.column_max_width(longestcollumn)
         longstring = self.table_data[longestrow][longestcollumn]
         wrapped_string = '\n'.join(wrap(longstring, max_width))
         self.table_data[longestrow][longestcollumn] = wrapped_string
Exemplo n.º 8
0
def render_table(table: AsciiTable, interactive=True):
    '''Do all wrapping to make the table fit in screen'''
    MAX_WIDTH = terminal_size()[0]
    table.inner_row_border = True
    if not table.table_width < MAX_WIDTH:
        non_negative = True
        i = 0
        while table.table_width > MAX_WIDTH and non_negative and i < 50:
            non_negative = fix_iteration(table, MAX_WIDTH)
            i += 1

    if interactive:
        pager = getpager()
        pager(table.table)
    else:
        print(table.table)
Exemplo n.º 9
0
    def column_max_width(self, column_number):
        """Return the maximum width of a column based on the current terminal width.

        :param int column_number: The column number to query.

        :return: The max width of the column.
        :rtype: int
        """
        column_widths = self.column_widths
        borders_padding = (len(column_widths) * self.padding_left) + (len(column_widths) * self.padding_right)
        if self.outer_border:
            borders_padding += 2
        if self.inner_column_border and column_widths:
            borders_padding += len(column_widths) - 1
        other_column_widths = sum(column_widths) - column_widths[column_number]
        return terminal_size()[0] - other_column_widths - borders_padding
Exemplo n.º 10
0
    def column_max_width(self, column_number):
        """Return the maximum width of a column based on the current terminal width.

        :param int column_number: The column number to query.

        :return: The max width of the column.
        :rtype: int
        """
        widths = self.column_widths
        borders_padding = (len(widths) * self.padding_left) + (
            len(widths) * self.padding_right)
        if self.outer_border:
            borders_padding += 2
        if self.inner_column_border and widths:
            borders_padding += len(widths) - 1
        other_column_widths = sum(widths) - widths[column_number]
        return terminal_size()[0] - other_column_widths - borders_padding
Exemplo n.º 11
0
 def _calc_wrap(self):
     """
     :return: Calculated wrap value to be used for self.wrap_columns.
         If wraps are not defined None is returned
     """
     if not self.wrap_columns:
         return None
     longest = self._longest_rows()
     margin = self._columns * 2 + self._columns + 1
     static_columns = sum(longest.values())
     for wrap in self.wrap_columns:
         static_columns -= longest[wrap]
     space_left = terminal_size()[0] - static_columns - margin
     """
     print('margin: %s' % margin)
     print('static_columns: %s' % static_columns)
     print('space_left: %s' % space_left)
     print('self.table.table_width: %s' % self.table.table_width)
     print(longest)
     """
     # TODO: This is a bit dumb if wrapped columns have huge disparity
     # for example in flexget plugins the phases and flags
     return int(space_left / len(self.wrap_columns))
Exemplo n.º 12
0
 def _calc_wrap(self):
     """
     :return: Calculated wrap value to be used for self.wrap_columns.
         If wraps are not defined None is returned
     """
     if not self.wrap_columns:
         return None
     longest = self._longest_rows()
     margin = self._columns * 2 + self._columns + 1
     static_columns = sum(longest.values())
     for wrap in self.wrap_columns:
         static_columns -= longest[wrap]
     space_left = terminal_size()[0] - static_columns - margin
     """
     print('margin: %s' % margin)
     print('static_columns: %s' % static_columns)
     print('space_left: %s' % space_left)
     print('self.table.table_width: %s' % self.table.table_width)
     print(longest)
     """
     # TODO: This is a bit dumb if wrapped columns have huge disparity
     # for example in flexget plugins the phases and flags
     return int(space_left/len(self.wrap_columns))
Exemplo n.º 13
0
def test_windows(monkeypatch, stderr, stdout):
    """Test function with IS_WINDOWS=True.

    :param monkeypatch: pytest fixture.
    :param int stderr: Mock handle value.
    :param int stdout: Mock handle value.
    """
    monkeypatch.setattr('terminaltables.terminal_io.IS_WINDOWS', True)

    kernel32 = MockKernel32(stderr=stderr, stdout=stdout)
    width, height = terminal_size(kernel32)

    if stderr == INVALID_HANDLE_VALUE and stdout == INVALID_HANDLE_VALUE:
        assert width == DEFAULT_WIDTH
        assert height == DEFAULT_HEIGHT
    elif stdout == INVALID_HANDLE_VALUE:
        assert width == 119
        assert height == 29
    elif stderr == INVALID_HANDLE_VALUE:
        assert width == 75
        assert height == 28
    else:
        assert width == 119
        assert height == 29
Exemplo n.º 14
0
def test_windows(monkeypatch, stderr, stdout):
    """Test function with IS_WINDOWS=True.

    :param monkeypatch: pytest fixture.
    :param int stderr: Mock handle value.
    :param int stdout: Mock handle value.
    """
    monkeypatch.setattr('terminaltables.terminal_io.IS_WINDOWS', True)

    kernel32 = MockKernel32(stderr=stderr, stdout=stdout)
    width, height = terminal_size(kernel32)

    if stderr == INVALID_HANDLE_VALUE and stdout == INVALID_HANDLE_VALUE:
        assert width == DEFAULT_WIDTH
        assert height == DEFAULT_HEIGHT
    elif stdout == INVALID_HANDLE_VALUE:
        assert width == 119
        assert height == 29
    elif stderr == INVALID_HANDLE_VALUE:
        assert width == 75
        assert height == 28
    else:
        assert width == 119
        assert height == 29
Exemplo n.º 15
0
 def exposed_terminal_info(self):
     return {'size': terminal_size(), 'isatty': sys.stdout.isatty()}
Exemplo n.º 16
0
def test_terminal_width_height():
    """Test terminal width/height functions."""
    assert terminal_size() == (80, 24)
Exemplo n.º 17
0
 def ok(self):  # Too late to change API. # pylint: disable=invalid-name
     """Return True if the table fits within the terminal width, False if the table breaks."""
     return self.table_width <= terminal_size()[0]
Exemplo n.º 18
0
 def exposed_terminal_info(self):
     return {'size': terminal_size(), 'isatty': sys.stdout.isatty()}
Exemplo n.º 19
0
 def ok(self):  # Too late to change API. # pylint: disable=invalid-name
     """Return True if the table fits within the terminal width, False if the table breaks."""
     return self.table_width <= terminal_size()[0]
Exemplo n.º 20
0
def test_terminal_width_height():
    """Test terminal width/height functions."""
    assert (80, 24) == terminal_size()
Exemplo n.º 21
0
def execute_status(args):
    status = get_status()
    # First rows, showing daemon status
    if status['status'] == 'running':
        status['status'] = Color('{autogreen}' + '{}'.format(status['status']) + '{/autogreen}')
    elif status['status'] == 'paused':
        status['status'] = Color('{autoyellow}' + '{}'.format(status['status']) + '{/autoyellow}')

    if status['process'] == 'running' or status['process'] == 'paused':
        status['process'] = Color('{autogreen}' + '{}'.format(status['process']) + '{/autogreen}')

    print('Daemon: {}\nProcess status: {} \n'.format(status['status'], status['process']))

    # Handle queue data
    data = status['data']
    if isinstance(data, str):
        print(data)
    elif isinstance(data, dict):
        # Format incomming data to be compatible with Terminaltables
        formatted_data = []
        formatted_data.append(['Index', 'Status', 'Code',
                               'Command', 'Path', 'Start', 'End'])
        for key, entry in sorted(data.items(), key=operator.itemgetter(0)):
            formatted_data.append(
                [
                    '#{}'.format(key),
                    entry['status'],
                    '{}'.format(entry['returncode']),
                    entry['command'],
                    entry['path'],
                    entry['start'],
                    entry['end']
                ]
            )

        # Create AsciiTable instance and define style
        table = AsciiTable(formatted_data)
        table.outer_border = False
        table.inner_column_border = False

        terminal_width = terminal_size()
        customWidth = table.column_widths
        # If the text is wider than the actual terminal size, we
        # compute a new size for the Command and Path column.
        if (reduce(lambda a, b: a+b, table.column_widths) + 10) > terminal_width[0]:
            # We have to subtract 14 because of table paddings
            left_space = math.floor((terminal_width[0] - customWidth[0] - customWidth[1] - customWidth[2] - customWidth[5] - customWidth[6] - 14)/2)

            if customWidth[3] < left_space:
                customWidth[4] = 2*left_space - customWidth[3]
            elif customWidth[4] < left_space:
                customWidth[3] = 2*left_space - customWidth[4]
            else:
                customWidth[3] = left_space
                customWidth[4] = left_space

        # Format long strings to match the console width
        for i, entry in enumerate(table.table_data):
            for j, string in enumerate(entry):
                max_width = customWidth[j]
                wrapped_string = '\n'.join(wrap(string, max_width))
                if j == 1:
                    if wrapped_string == 'done' or wrapped_string == 'running' or wrapped_string == 'paused':
                        wrapped_string = Color('{autogreen}' + '{}'.format(wrapped_string) + '{/autogreen}')
                    elif wrapped_string == 'queued':
                        wrapped_string = Color('{autoyellow}' + '{}'.format(wrapped_string) + '{/autoyellow}')
                    elif wrapped_string in ['errored', 'stopping', 'killing']:
                        wrapped_string = Color('{autored}' + '{}'.format(wrapped_string) + '{/autored}')
                elif j == 2:
                    if wrapped_string == '0' and wrapped_string != 'Code':
                        wrapped_string = Color('{autogreen}' + '{}'.format(wrapped_string) + '{/autogreen}')
                    elif wrapped_string != '0' and wrapped_string != 'Code':
                        wrapped_string = Color('{autored}' + '{}'.format(wrapped_string) + '{/autored}')

                table.table_data[i][j] = wrapped_string

        print(table.table)
    print('')
Exemplo n.º 22
0
 def exposed_terminal_size(self, *args):
     return terminal_size(*args)
Exemplo n.º 23
0

__all__ = ["choice", "colored", "randint", "re", "strip_escape_codes", "term_width", "wrap", "Object", "ObjectTooLarge",
           "FONTS"]

# little patch to available attributes ; may not work for some terminals
ATTRIBUTES['italic'] = 3
ATTRIBUTES['strikethrough'] = 9


with open(join(dirname(__file__), "fonts.txt")) as f:
    FONTS = list(set(f.read().splitlines()))


strip_escape_codes = lambda s: re.sub(r"(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]", "", s)
term_width = lambda: terminal_size()[0] or 79


class Object(object):
    def __repr__(self):
        """ Represent the object with every ASCII escape code removed. """
        return strip_escape_codes(str(self))
    
    @staticmethod
    def check_width(text, width=term_width()):
        """ Generic method for checking if the ASCII art object does not exceed the configured width. """
        if any(len(l) > width for l in text.splitlines()):
            raise ObjectTooLarge("Object does not fit the given width")
    
    @staticmethod
    def wrap(text, width=term_width()):
Exemplo n.º 24
0
def execute_status(args, root_dir=None):
    """Print the status of the daemon.

    This function displays the current status of the daemon as well
    as the whole queue and all available information about every entry
    in the queue.
    `terminaltables` is used to format and display the queue contents.
    `colorclass` is used to color format the various items in the queue.

    Args:
        root_dir (string): The path to the root directory the daemon is running in.
    """

    status = command_factory('status')({}, root_dir=root_dir)
    # First rows, showing daemon status
    if status['status'] == 'running':
        status['status'] = Color('{autogreen}' +
                                 '{}'.format(status['status']) +
                                 '{/autogreen}')
    elif status['status'] in ['paused']:
        status['status'] = Color('{autoyellow}' +
                                 '{}'.format(status['status']) +
                                 '{/autoyellow}')

    print('Daemon: {}\n'.format(status['status']))

    # Handle queue data
    data = status['data']
    if isinstance(data, str):
        print(data)
    elif isinstance(data, dict):
        # Format incomming data to be compatible with Terminaltables
        formatted_data = []
        formatted_data.append(
            ['Index', 'Status', 'Code', 'Command', 'Path', 'Start', 'End'])
        for key, entry in sorted(data.items(), key=operator.itemgetter(0)):
            formatted_data.append([
                '#{}'.format(key), entry['status'],
                '{}'.format(entry['returncode']), entry['command'],
                entry['path'], entry['start'], entry['end']
            ])

        # Create AsciiTable instance and define style
        table = AsciiTable(formatted_data)
        table.outer_border = False
        table.inner_column_border = False

        terminal_width = terminal_size()
        customWidth = table.column_widths
        # If the text is wider than the actual terminal size, we
        # compute a new size for the Command and Path column.
        if (reduce(lambda a, b: a + b, table.column_widths) +
                10) > terminal_width[0]:
            # We have to subtract 14 because of table paddings
            left_space = math.floor(
                (terminal_width[0] - customWidth[0] - customWidth[1] -
                 customWidth[2] - customWidth[5] - customWidth[6] - 14) / 2)

            if customWidth[3] < left_space:
                customWidth[4] = 2 * left_space - customWidth[3]
            elif customWidth[4] < left_space:
                customWidth[3] = 2 * left_space - customWidth[4]
            else:
                customWidth[3] = left_space
                customWidth[4] = left_space

        # Format long strings to match the console width
        for i, entry in enumerate(table.table_data):
            for j, string in enumerate(entry):
                max_width = customWidth[j]
                wrapped_string = '\n'.join(wrap(string, max_width))
                if j == 1:
                    if wrapped_string == 'done' or wrapped_string == 'running' or wrapped_string == 'paused':
                        wrapped_string = Color('{autogreen}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autogreen}')
                    elif wrapped_string in ['queued', 'stashed']:
                        wrapped_string = Color('{autoyellow}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autoyellow}')
                    elif wrapped_string in ['failed', 'stopping', 'killing']:
                        wrapped_string = Color('{autored}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autored}')
                elif j == 2:
                    if wrapped_string == '0' and wrapped_string != 'Code':
                        wrapped_string = Color('{autogreen}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autogreen}')
                    elif wrapped_string != '0' and wrapped_string != 'Code':
                        wrapped_string = Color('{autored}' +
                                               '{}'.format(wrapped_string) +
                                               '{/autored}')

                table.table_data[i][j] = wrapped_string

        print(table.table)
    print('')
Exemplo n.º 25
0
def terminal_info():
    """
    Returns info we need about the output terminal.
    When called over IPC, this function is monkeypatched to return the info about the client terminal.
    """
    return {'size': terminal_size(), 'isatty': sys.stdout.isatty()}
Exemplo n.º 26
0
 def exposed_terminal_size(self, *args):
     return terminal_size(*args)
Exemplo n.º 27
0
def terminal_info():
    """
    Returns info we need about the output terminal.
    When called over IPC, this function is monkeypatched to return the info about the client terminal.
    """
    return {'size': terminal_size(), 'isatty': sys.stdout.isatty()}
Exemplo n.º 28
0
 def valid_table(self):
     # print('self.table.table_width: %s' % self.table.table_width)
     # print('terminal_size()[0]: %s' % terminal_size()[0])
     return self.table.table_width <= terminal_size()[0]
Exemplo n.º 29
0
 def exposed_terminal_info(self):
     return {"size": terminal_size(), "isatty": sys.stdout.isatty()}
Exemplo n.º 30
0
 def valid_table(self):
     # print('self.table.table_width: %s' % self.table.table_width)
     # print('terminal_size()[0]: %s' % terminal_size()[0])
     return self.table.table_width <= terminal_size()[0]