Esempio n. 1
0
    def _repr_tty_(self) -> str:
        """Return a summary of this sample sheet in a TTY compatible codec."""
        header_description = ['Sample_ID', 'Description']
        header_samples = [
            'Sample_ID',
            'Sample_Name',
            'Library_ID',
            'index',
            'index2',
        ]

        header = SingleTable([], 'Header')
        setting = SingleTable([], 'Settings')
        sample_main = SingleTable([header_samples], 'Identifiers')
        sample_desc = SingleTable([header_description], 'Descriptions')

        # All key:value pairs found in the [Header] section.
        max_header_width = max(MIN_WIDTH, sample_desc.column_max_width(-1))
        for key in self.Header.keys():
            if 'Description' in key:
                value = '\n'.join(
                    wrap(getattr(self.Header, key), max_header_width))
            else:
                value = getattr(self.Header, key)
            header.table_data.append([key, value])

        # All key:value pairs found in the [Settings] and [Reads] sections.
        for key in self.Settings.keys():
            setting.table_data.append((key, getattr(self.Settings, key) or ''))
        setting.table_data.append(('Reads', ', '.join(map(str, self.Reads))))

        # Descriptions are wrapped to the allowable space remaining.
        description_width = max(MIN_WIDTH, sample_desc.column_max_width(-1))
        for sample in self.samples:
            # Add all key:value pairs for this sample
            sample_main.table_data.append(
                [getattr(sample, title) or '' for title in header_samples])
            # Wrap and add the sample descrption
            sample_desc.table_data.append((
                sample.Sample_ID,
                '\n'.join(wrap(sample.Description or '', description_width)),
            ))

        # These tables do not have horizontal headers so remove the frame.
        header.inner_heading_row_border = False
        setting.inner_heading_row_border = False

        table = '\n'.join([
            header.table, setting.table, sample_main.table, sample_desc.table
        ])

        return table
Esempio n. 2
0
    def errors(self, crawler, error=None, **options):
        errors = crawler.task.errors.all()

        if not errors.exists():
            self.stdout.write('No errors.')
            return

        # error detail
        if error is not None:
            return self.instance_error(errors[error])

        # error list
        tz = errors[0].timestamp.strftime('%Z')
        HEADER = ['n', f'Timestamp ({tz})', 'Message']
        data = [[i, error.timestamp.strftime('%Y-%m-%d %H:%M:%S'), '']
                for i, error in enumerate(errors, start=1)]
        data.insert(0, HEADER)

        table = SingleTable(data, title='Errors: ' + str(errors.count()))
        table.justify_columns[0] = 'right'

        # truncate error messages to max column width.
        max_width = table.column_max_width(2)

        # first row contains headers
        for row, error in zip(table.table_data[1:], errors):
            row[2] = truncate_message(error.message, max_width)

        self.stdout.write(table.table)
Esempio n. 3
0
def list(long_list):
    """List all tracked habits."""
    from terminaltables import SingleTable
    from textwrap import wrap

    terminal_width, terminal_height = click.get_terminal_size()

    nr_of_dates = terminal_width // 10 - 4
    if nr_of_dates < 1:
        logger.debug("list: Actual terminal width = {0}.".format(
            click.get_terminal_size()[0]))
        logger.debug(
            "list: Observed terminal width = {0}.".format(terminal_width))
        click.echo(
            "Your terminal window is too small. Please make it wider and try again"
        )
        raise SystemExit(1)

    table_title = ["Habit", "Goal", "Streak"]
    minimal = not long_list
    if minimal:
        table_title.append("Activities")
    else:
        for d in range(0, nr_of_dates):
            date_mod = datetime.today() - timedelta(days=d)
            table_title.append("{0}/{1}".format(date_mod.month, date_mod.day))

    table_rows = [table_title]
    for habit_data in models.get_daily_activities(nr_of_dates):
        habit = habit_data[0]
        habit_row = [str(habit.id) + ": " + habit.name, str(habit.quantum)]
        progress = ""
        for daily_data in habit_data[1]:
            column_text = CROSS
            quanta = daily_data[1]

            if quanta is not None:
                column_text = click.style(PARTIAL)
                if quanta >= habit.quantum:
                    column_text = click.style(TICK, fg="green")
            if minimal:
                progress += column_text + " "
            else:
                habit_row.append(quanta)
        if minimal:
            habit_row.append(progress)

        current_streak = habit.summary.get().get_streak()
        habit_row.insert(2, current_streak)
        table_rows.append(habit_row)

    table = SingleTable(table_rows)

    max_col_width = table.column_max_width(0)
    max_col_width = max_col_width if max_col_width > 0 else 20

    for r in table_rows:
        r[0] = '\n'.join(wrap(r[0], max_col_width))

    click.echo(table.table)
Esempio n. 4
0
def print_table(title: str, header: List[str], rows: List[List[str]],
                overhead_col: int) -> None:
    table = SingleTable([header] + rows)
    for row in table.table_data:
        row[overhead_col] = fill(row[overhead_col],
                                 width=table.column_max_width(overhead_col))
    table.outer_border = False
    table.title = title
    print(table.table)
Esempio n. 5
0
File: utils.py Progetto: bhyvex/keep
def list_commands(ctx):
    table_data = [['Command', 'Description', 'Alias']]
    commands = read_commands()

    for cmd, fields in commands.items():
        table_data.append(['$ ' + cmd, fields['desc'], fields['alias']])

    table = SingleTable(table_data)
    max_widths = [table.column_max_width(0), table.column_max_width(1)]

    for i in range(len(table_data) - 1):
        for j in [0, 1]:
            data = table.table_data[i + 1][j]
            if len(data) > max_widths[j]:
                table.table_data[i + 1][j] = '\n'.join(
                    wrap(data, max_widths[j]))

    table.inner_row_border = True
    print(table.table)
Esempio n. 6
0
def walk(stream_name, shard_id, sequence_number=None, get_records_limit=5):
    kinesis_client = boto3.client("kinesis")

    if not shard_id.startswith(constants.SHARD_ID_PREFIX):
        shard_id = constants.SHARD_ID_PREFIX + shard_id

    shard_iterator_type = "AT_SEQUENCE_NUMBER" if sequence_number else "TRIM_HORIZON"

    get_shard_iterator_args = {
        "StreamName": stream_name,
        "ShardId": shard_id,
        "ShardIteratorType": shard_iterator_type,
    }

    if sequence_number:
        get_shard_iterator_args["StartingSequenceNumber"] = sequence_number

    click.echo(
        f"Creating shard iterator with arguments = {get_shard_iterator_args}")
    shard_iterator_response = kinesis_client.get_shard_iterator(
        **get_shard_iterator_args)

    shard_iterator = shard_iterator_response["ShardIterator"]
    fetch_more = True
    while fetch_more:

        records_response = kinesis_client.get_records(
            ShardIterator=shard_iterator, Limit=get_records_limit)

        for record in records_response["Records"]:
            parsed_data = base64.b64decode(record["Data"]).decode("utf-8")
            table_data = [
                ["SequenceNumber", record["SequenceNumber"]],
                [
                    "ApproximateArrivalTimestamp",
                    record["ApproximateArrivalTimestamp"]
                ],
                ["PartitionKey", record["PartitionKey"]],
                ["EncryptionType",
                 record.get("EncryptionType")],
                ["Decoded Data", parsed_data],
            ]

            table = SingleTable(table_data)
            max_width = table.column_max_width(1)
            wrapped_string = "\n".join(wrap(parsed_data, max_width))
            table.table_data[4][1] = wrapped_string
            print(table.table)

        if not records_response["Records"]:
            print("No records found for this api call 😔")

        fetch_more = click.confirm("Fetch more records?", default=True)
        shard_iterator = records_response["NextShardIterator"]
Esempio n. 7
0
def main():
    """Main function."""
    table_data = [
        ['Long String', ''],  # One row. Two columns. Long string will replace this empty string.
    ]
    table = SingleTable(table_data)

    # Calculate newlines.
    max_width = table.column_max_width(1)
    wrapped_string = '\n'.join(wrap(LONG_STRING, max_width))
    table.table_data[0][1] = wrapped_string

    print(table.table)
Esempio n. 8
0
def hinton_diagram(arr, max_arr=None):
    max_arr = arr if max_arr is None else max_arr
    max_val = max(abs(np.max(max_arr)), abs(np.min(max_arr)))
    diagram = [list([hinton_diagram_value(x, max_val) for x in _arr]) for _arr in arr]

    table = SingleTable(diagram)
    table.inner_heading_row_border = False
    table.inner_footing_row_border = False
    table.inner_column_border = False
    table.inner_row_border = False
    table.column_max_width = 1

    return table.table
Esempio n. 9
0
def walk(stream_name, shard_id, sequence_number=None, get_records_limit=5, timestamp=None):
    kinesis_client = boto3.client('kinesis')

    if not shard_id.startswith(common.SHARD_ID_PREFIX):
        shard_id = common.SHARD_ID_PREFIX + shard_id

    shard_iterator_type = 'AT_SEQUENCE_NUMBER' if sequence_number else 'TRIM_HORIZON'

    get_shard_iterator_args = {
        'StreamName': stream_name,
        'ShardId': shard_id,
        'ShardIteratorType': shard_iterator_type,
    }

    if sequence_number:
        get_shard_iterator_args['StartingSequenceNumber'] = sequence_number

    click.echo(f"Creating shard iterator with arguments = {get_shard_iterator_args}")
    response = kinesis_client.get_shard_iterator(**get_shard_iterator_args)

    shard_iterator = response['ShardIterator']
    while True:

        records_response = kinesis_client.get_records(
            ShardIterator=shard_iterator,
            Limit=get_records_limit
        )

        for record in records_response['Records']:
            parsed_data = base64.b64decode(record['Data']).decode('utf-8')
            table_data = [
                ['SequenceNumber', record['SequenceNumber']],
                ['ApproximateArrivalTimestamp', record['ApproximateArrivalTimestamp']],
                ['PartitionKey', record['PartitionKey']],
                ['EncryptionType', record.get('EncryptionType')],
                ['Decoded Data', parsed_data]
            ]

            table = SingleTable(table_data)
            max_width = table.column_max_width(1)
            wrapped_string = '\n'.join(wrap(parsed_data, max_width))
            table.table_data[4][1] = wrapped_string
            print(table.table)

        if not records_response['Records']:
            print("No records found for this api call 😔")

        click.confirm('Fetch more records?', abort=True, default=True)
        shard_iterator = records_response['NextShardIterator']
Esempio n. 10
0
File: k.py Progetto: ottacom/vaas
def main():
    """Main function."""
    table_data = [
        [
            'Long String', ''
        ],  # One row. Two columns. Long string will replace this empty string.
    ]
    table = SingleTable(table_data)

    # Calculate newlines.
    max_width = table.column_max_width(1)
    wrapped_string = '\n'.join(wrap(LONG_STRING, max_width))
    table.table_data[0][1] = wrapped_string

    print(table.table)
Esempio n. 11
0
    def info(self, dictionary=None, **options):
        dictionaries = documents.Dictionary.search()
        instances = [d for d in dictionaries.scan()]

        data = [[colorize(d.meta.id, fg='cyan'), d.name, ''] for d in instances]
        data.insert(0, ['Elasticsearch ID', 'Name', 'Terms'])

        table = SingleTable(data, title='Dictionaries: ' + str(dictionaries.count()))

        max_width = table.column_max_width(2)

        # first row contains headers
        for row, dictionary in zip(table.table_data[1:], instances):
            row[2] = truncate_message(', '.join(dictionary.terms), max_width)

        self.stdout.write(table.table)
Esempio n. 12
0
def print_run_table(table_data):
    table = SingleTable(table_data)
    table.justify_columns = {0: 'left', 1: 'center', 2: 'left'}
    table.inner_heading_row_border = False
    table.inner_column_border = False
    table.outer_border = False
    max_width = table.column_max_width(2)
    for index, row in enumerate(table_data):
        table.table_data[index][2] = str(row[2][0:max_width].splitlines()[0])
        if row[1] == 0:
            table.table_data[index][1] = colored(str(row[1]), 'green')
        elif row[1] == 1:
            table.table_data[index][2] = colored(str(row[1]), 'yellow')
        elif row[1] == 3:
            table.table_data[index][2] = colored(str(row[1]), 'grey')
        else:
            table.table_data[index][2] = colored(str(row[1]), 'red')
    print table.table
Esempio n. 13
0
def print_run_table(table_data):
    table = SingleTable(table_data)
    table.justify_columns = {0: 'left', 1: 'center', 2: 'left'}
    table.inner_heading_row_border = False
    table.inner_column_border = False
    table.outer_border = False
    max_width = table.column_max_width(2)
    for index, row in enumerate(table_data):
        table.table_data[index][2] = str(row[2][0:max_width].splitlines()[0])
        if row[1] == 0:
            table.table_data[index][1] = colored(str(row[1]), 'green')
        elif row[1] == 1:
            table.table_data[index][2] = colored(str(row[1]), 'yellow')
        elif row[1] == 3:
            table.table_data[index][2] = colored(str(row[1]), 'grey')
        else:
            table.table_data[index][2] = colored(str(row[1]), 'red')
    print table.table
Esempio n. 14
0
def legend_print():
    data = [["Legend", '']]
    pretty_table = SingleTable(data)
    legend = (
        "•%s  Items with no upgrade required" %
        stylize(" ⇄ ", _color_noupgrade),
        "•%s  Items ignored in the vRO merge process" %
        stylize(" ⇄ ", _color_nosupported),
        "•%s  New items (will be imported)" % stylize(" + ", _color_new),
        "•%s  Items that will be upgraded in import process" %
        stylize(" ⇉ ", _color_upgrade), "•%s  Items with a version conflict" %
        stylize(" ≠ ", _color_conflict), "       For items with conflict:",
        "       ‣ Check that the version in file A is lower than in the file B.",
        "       ‣ If versions are the same, the content is not. Upgrade version on file B to overwrite",
        "         item during the import process.")
    max_width = pretty_table.column_max_width(1)
    wrapped_legend = '\n'.join(legend)
    pretty_table.table_data[0][1] = wrapped_legend
    print("\n%s" % pretty_table.table)
Esempio n. 15
0
    def buildQuipTable(self, quip):
        tags = ''
        quip = json.loads(quip)

        for tag in quip['tags']:
            tag += ' '
            tags += tag

        table_data = [
            [Color("TAGS\n{}".format(tags)), ''],
        ]

        table = SingleTable(
            table_data, "(ID: {}) {} -- {}".format(quip['id'], quip['title'],
                                                   quip['date']))
        max_width = table.column_max_width(1)
        wrapped_string = '\n'.join(wrap(quip['contents'], max_width))
        table.table_data[0][1] = wrapped_string

        return (table.table)
Esempio n. 16
0
def table(title, data, headers=None, wraped_col=1):
    if not headers:
        headers = ["Name", "Value"]

    map(lambda x: click.style(x, fg="blue"), headers)

    if isinstance(data, dict):
        data = [[k, v] for k, v in data.items()]

    _data = [headers] + data

    _table = SingleTable(_data, click.style(title, fg="blue"))
    _table.inner_row_border = True

    max_width = _table.column_max_width(wraped_col)
    for i, val in enumerate(_data):
        wrapped_string = '\n'.join(wrap(str(val[wraped_col]), max_width))
        _table.table_data[i][wraped_col] = wrapped_string

    return _table
Esempio n. 17
0
    def print_node_id_table(self, json, **kwargs):

        for struct in json['results']['nodes']:
            table_data_host = str(struct['hostname'])
            table_data_city = str(struct['city'])
            table_data_countrycode = str(struct['countrycode'])
            table_data_datacenter = str(struct['datacenter'])
            table_data_asn = str(struct['asn'])
            table_data_id = str(struct['id'])
            table_data_ipv4 = str(struct['ipv4'])
            table_data_ipv6 = str(struct['ipv6'])

        if not self.quiet:
            table_data_url = self.ring.build_api_url(
                self.ringconfig.RING_GET_NODE_BY_ID, id=table_data_id)

            Windows.enable(auto_colors=True, reset_atexit=True)
            table_data = [[
                Color('{autogreen}' + str(table_data_host) + '{/autogreen}'),
                Color('{autoblue}' + table_data_url + '{/autoblue}')
            ], [table_data_ipv4 + '\n' + table_data_ipv6, '']]
            table_instance = SingleTable(table_data)
            column_max_width = table_instance.column_max_width(1)
            table_dc_location = table_data_datacenter + " (ASN: " + table_data_asn + ") " + table_data_city + ", " + table_data_countrycode
            table_dc_location = '\n'.join(
                wrap(table_dc_location, column_max_width))
            table_instance.table_data[1][1] = table_dc_location

            print(table_instance.table)

        if self.quiet:
            line_title = Color('{green}' + table_data_host + '{/green}')
            api_url = self.ring.build_api_url(
                self.ringconfig.RING_GET_NODE_BY_ID, id=table_data_id)
            api_url = Color('{blue}' + api_url + '{/blue}')
            print("Node: " + line_title + " ASN " + table_data_asn + " " +
                  table_data_city + " " + table_data_countrycode + " @ " +
                  api_url)
Esempio n. 18
0
def display():
    """clikan display"""

    config = read_config_yaml()

    dd = read_data(config)

    todos, inprogs, dones = split_items(config, dd)

    if 'limits' in config and 'done' in config['limits']:
        dones = dones[0:int(config['limits']['done'])]
    else:
        dones = dones[0:10]

    todos = '\n'.join([str(x) for x in todos])
    inprogs = '\n'.join([str(x) for x in inprogs])
    dones = '\n'.join([str(x) for x in dones])

    td = [
        ['todo', 'in-progress', 'done'],
        ['', '', ''],
    ]

    table = SingleTable(td, 'clikan')
    table.inner_heading_row_border = False
    table.inner_row_border = True
    table.justify_columns = {0: 'center', 1: 'center', 2: 'center'}
    #table.padding_left = 5
    #table.padding_right = 5

    # todos wrapping
    max_width = table.column_max_width(0)

    wrapped_string = '\n'.join([
        '\n'.join(
            wrap(line,
                 max_width,
                 break_long_words=False,
                 replace_whitespace=False)) for line in todos.splitlines()
        if line.strip() != ''
    ])

    table.table_data[1][0] = wrapped_string

    # inprogs wrapping
    max_width = table.column_max_width(1)
    wrapped_inprogs = '\n'.join([
        '\n'.join(
            wrap(line,
                 max_width,
                 break_long_words=False,
                 replace_whitespace=False)) for line in inprogs.splitlines()
        if line.strip() != ''
    ])
    table.table_data[1][1] = wrapped_inprogs

    # dones wrapping
    max_width = table.column_max_width(2)
    wrapped_dones = '\n'.join([
        '\n'.join(
            wrap(line,
                 max_width,
                 break_long_words=False,
                 replace_whitespace=False)) for line in dones.splitlines()
        if line.strip() != ''
    ])
    table.table_data[1][2] = wrapped_dones

    print(table.table)
Esempio n. 19
0

list1 = []
mgntList = []
list1.append(['Index', 'Title', 'Date Added', 'Size', 'Seeders', 'Leechers'])
for i in range(int(num)):
    item = items[i]
    tempList = []
    tempList.append(str(i + 1))
    tempList.append(item.title.text)
    mgntList.append(item.magneturl.text)
    tempList.append(item.pubDate.text[5:16])
    tempList.append(convertSize(int(item.size.text)))
    seeders = item.find(attrs={'name': 'seeders'})
    tempList.append(seeders['value'])
    peers = item.find(attrs={'name': 'peers'})
    tempList.append(peers['value'])
    list1.append(tempList)

cuteTable = SingleTable(list1)
max_width = cuteTable.column_max_width(1)
for i in range(1, len(list1)):
    row = list1[i]
    wrappedString = '\n'.join(wrap(row[1], max_width))
    cuteTable.table_data[i][1] = wrappedString + '\n'

print(cuteTable.table)
choice = int(input('\nEnter the index--->'))
print('\nThe magnet link is :\n')
print(mgntList[choice])
Esempio n. 20
0
table_data = make_table(tasks_dic)

prepend_list = ['priority']
append_list = ['tags']
tmp_table = [[a[0], a[1],
              [' '.join([x for x in [a[2].get(y) for y in prepend_list] if x]),
               ' '.join([x for x in [a[2].get(y) for y in ['description']] if x]),
               ' '.join([x for x in [a[2].get(y) for y in append_list] if x])]] for a in table_data]
# tmp_table = [[a[0], a[1]] for a in table_data]


t = SingleTable([[a[0], a[1], ' '.join([x for x in a[2] if x])] for a in tmp_table])
t.inner_heading_row_border = False
# print to newly created buffer
# t = SingleTable(table)
max_width = t.column_max_width(2)
for i in range(len(t.table_data)):
    row = t.table_data[i]
    wrapped_string = '\n'.join(wrap(row[2], max_width))
    if row[0]:
        row[0] = decorate_text(row[0], COLORS['status'])
    if row[1]:
        row[1] = decorate_text(row[1], COLORS['meta'])
    row[2] = wrapped_string
    prepend_length = len(tmp_table[i][2][0]) + 1 if tmp_table[i][2][0] else 0
    append_length = len(tmp_table[i][2][2]) + 1 if tmp_table[i][2][2] else 0
    if not (prepend_length or append_length):
        row[2] = wrapped_string
    else:
        row[2] = wrapped_string[prepend_length:-append_length]
        for prepend in prepend_list:
Esempio n. 21
0
#!/usr/bin/env python
"""Simple example usage of terminaltables and column_max_width().

Just prints sample text and exits.
"""

from __future__ import print_function
from terminaltables import SingleTable
from textwrap import wrap


# Setup string and table.
long_string = ('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore '
               'et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut '
               'aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum '
               'dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui '
               'officia deserunt mollit anim id est laborum.')
table = SingleTable([['Long String', '']])

# Calculate newlines.
max_width = table.column_max_width(1)
wrapped_string = '\n'.join(wrap(long_string, max_width))
table.table_data[0][1] = wrapped_string

print(table.table)
Esempio n. 22
0
class TUI:
    def __init__(self):
        self.core = Core()
        self.session = PromptSession(reserve_space_for_menu=7)
        self.tableData = None
        self.table = None
        self.cfSlugs = None
        self.wowiSlugs = None
        self.completer = None
        self.os = platform.system()
        if self.os == 'Windows':
            self.chandle = windll.kernel32.GetStdHandle(-11)
        sys.tracebacklimit = 0

    def start(self):
        self.setup_console()
        self.print_header()
        # Check if executable is in good location
        if not glob.glob('World*.app') and not glob.glob('Wow*.exe') or \
                not os.path.isdir(Path('Interface/AddOns')) or not os.path.isdir('WTF'):
            printft(
                HTML(
                    '<ansibrightred>This executable should be placed in the same directory where Wow.exe, '
                    'WowClassic.exe or World of Warcraft.app is located.</ansibrightred>\n'
                ))
            pause()
            sys.exit(1)
        # Detect Classic client
        if os.path.basename(os.getcwd()) == '_classic_':
            self.core.clientType = 'wow_classic'
            set_terminal_title(f'CurseBreaker v{__version__} - Classic')
        # Check if client have write access
        try:
            with open('PermissionTest', 'w') as _:
                pass
            os.remove('PermissionTest')
        except IOError:
            printft(
                HTML(
                    '<ansibrightred>CurseBreaker doesn\'t have write rights for the current directory.\n'
                    'Try starting it with administrative privileges.</ansibrightred>\n'
                ))
            pause()
            sys.exit(1)
        self.auto_update()
        self.core.init_config()
        self.setup_table()
        # Curse URI Support
        if len(sys.argv) == 2 and 'twitch://' in sys.argv[1]:
            try:
                self.c_install(sys.argv[1].strip())
            except Exception as e:
                self.handle_exception(e)
            timeout()
            sys.exit(0)
        if len(sys.argv) == 2 and '.ccip' in sys.argv[1]:
            try:
                path = sys.argv[1].strip()
                self.c_install(self.core.parse_cf_xml(path))
                if os.path.exists(path):
                    os.remove(path)
            except Exception as e:
                self.handle_exception(e)
            timeout()
            sys.exit(0)
        # CLI command
        if len(sys.argv) >= 2:
            command = ' '.join(sys.argv[1:]).split(' ', 1)
            if getattr(self, f'c_{command[0].lower()}', False):
                try:
                    getattr(self, f'c_{command[0].lower()}')(
                        command[1].strip() if len(command) > 1 else False)
                except Exception as e:
                    self.handle_exception(e)
            else:
                printft('Command not found.')
            sys.exit(0)
        # Addons auto update
        if len(self.core.config['Addons']) > 0:
            printft('Automatic update of all addons will start in 5 seconds.\n'
                    'Press any button to enter interactive mode.')
            starttime = time.time()
            keypress = None
            while True:
                if kbhit():
                    keypress = getch()
                    break
                elif time.time() - starttime > 5:
                    break
            if not keypress:
                if len(self.core.config['Addons']) > 35:
                    self.setup_console(len(self.core.config['Addons']))
                self.print_header()
                try:
                    self.c_update(None, True)
                    if self.core.backup_check():
                        self.setup_table()
                        printft(
                            HTML(
                                '\n<ansigreen>Backing up WTF directory:</ansigreen>'
                            ))
                        self.core.backup_wtf()
                    if self.core.config['WAUsername'] != 'DISABLED':
                        self.setup_table()
                        self.c_wa_update(None, False)
                except Exception as e:
                    self.handle_exception(e)
                printft('')
                pause()
                sys.exit(0)
        self.setup_completer()
        self.setup_console(len(self.core.config['Addons']))
        self.print_header()
        printft(
            HTML(
                'Use command <ansigreen>help</ansigreen> or press <ansigreen>TAB</ansigreen> to see a list of avai'
                'lable commands.\nCommand <ansigreen>exit</ansigreen> or pressing <ansigreen>CTRL+D</ansigreen> wi'
                'll close the application.\n'))
        if len(self.core.config['Addons']) == 0:
            printft(
                HTML(
                    'Command <ansigreen>import</ansigreen> might be used to detect already installed addons.\n'
                ))
        # Prompt session
        while True:
            try:
                command = self.session.prompt(
                    HTML('<ansibrightgreen>CB></ansibrightgreen> '),
                    completer=self.completer)
            except KeyboardInterrupt:
                continue
            except EOFError:
                break
            else:
                command = command.split(' ', 1)
                if getattr(self, f'c_{command[0].lower()}', False):
                    try:
                        self.setup_table()
                        getattr(self, f'c_{command[0].lower()}')(
                            command[1].strip() if len(command) > 1 else False)
                        self.setup_completer()
                    except Exception as e:
                        self.handle_exception(e)
                else:
                    printft('Command not found.')

    def auto_update(self):
        if getattr(sys, 'frozen', False):
            try:
                if os.path.isfile(sys.executable + '.old'):
                    try:
                        os.remove(sys.executable + '.old')
                    except PermissionError:
                        pass
                payload = requests.get(
                    'https://api.github.com/repos/AcidWeb/CurseBreaker/releases/latest',
                    headers=HEADERS).json()
                remoteversion = payload['name']
                changelog = payload['body']
                url = None
                for binary in payload['assets']:
                    if (self.os == 'Windows' and '.exe' in binary['name'])\
                            or (self.os == 'Darwin' and '.zip' in binary['name'])\
                            or (self.os == 'Linux' and '.gz' in binary['name']):
                        url = binary['browser_download_url']
                        break
                if url and StrictVersion(
                        remoteversion[1:]) > StrictVersion(__version__):
                    printft(
                        HTML(
                            '<ansigreen>Updating CurseBreaker...</ansigreen>'))
                    shutil.move(sys.executable, sys.executable + '.old')
                    payload = requests.get(url, headers=HEADERS)
                    if self.os == 'Darwin':
                        zipfile.ZipFile(io.BytesIO(
                            payload.content)).extractall()
                    else:
                        with open(sys.executable, 'wb') as f:
                            if self.os == 'Windows':
                                f.write(payload.content)
                            elif self.os == 'Linux':
                                f.write(gzip.decompress(payload.content))
                    os.chmod(sys.executable, 0o775)
                    printft(
                        HTML(
                            f'<ansibrightgreen>Update complete! Please restart the application.</ansibrightgreen'
                            f'>\n\n<ansigreen>Changelog:</ansigreen>\n{changelog}\n'
                        ))
                    pause()
                    sys.exit(0)
            except Exception as e:
                printft(
                    HTML(
                        f'<ansibrightred>Update failed!\n\nReason: {str(e)}</ansibrightred>\n'
                    ))
                pause()
                sys.exit(1)

    def handle_exception(self, e, table=True):
        if len(self.tableData) > 1 and table:
            self.sanitize_table()
            printft(ANSI(self.table.table))
        if getattr(sys, 'frozen', False):
            if isinstance(e, list):
                for es in e:
                    printft(
                        HTML(f'\n<ansibrightred>{str(es)}</ansibrightred>'))
            else:
                printft(HTML(f'\n<ansibrightred>{str(e)}</ansibrightred>'))
        else:
            if isinstance(e, list):
                for es in e:
                    traceback.print_exception(es,
                                              es,
                                              es.__traceback__,
                                              limit=1000)
            else:
                traceback.print_exc(limit=1000)

    def print_header(self):
        clear()
        printft(
            HTML(
                f'<ansibrightblack>~~~ <ansibrightgreen>CurseBreaker</ansibrightgreen> <ansibrightred>v'
                f'{__version__}</ansibrightred> ~~~</ansibrightblack>\n'))

    def setup_console(self, buffer=0):
        if getattr(sys, 'frozen', False) and self.os == 'Windows':
            if buffer > 0:
                windll.kernel32.SetConsoleScreenBufferSize(
                    self.chandle, wintypes._COORD(100,
                                                  100 + round(buffer, -2)))
            else:
                windll.kernel32.SetConsoleWindowInfo(
                    self.chandle, True,
                    byref(wintypes.SMALL_RECT(0, 0, 99, 49)))
                windll.kernel32.SetConsoleScreenBufferSize(
                    self.chandle, wintypes._COORD(100, 50))
        elif self.os == 'Darwin':
            set_terminal_size(100, 50)

    def setup_completer(self):
        if not self.cfSlugs or not self.wowiSlugs:
            # noinspection PyBroadException
            try:
                self.cfSlugs = pickle.load(
                    gzip.open(
                        io.BytesIO(
                            requests.get(
                                'https://storage.googleapis.com/cursebreaker/cfslugs.pickle.gz',
                                headers=HEADERS).content)))
                self.wowiSlugs = pickle.load(
                    gzip.open(
                        io.BytesIO(
                            requests.get(
                                'https://storage.googleapis.com/cursebreaker/wowislugs.pickle.gz',
                                headers=HEADERS).content)))
            except Exception:
                self.cfSlugs = []
                self.wowiSlugs = []
        commands = [
            'install', 'uninstall', 'update', 'force_update', 'wa_update',
            'status', 'orphans', 'search', 'import', 'export', 'toggle_backup',
            'toggle_dev', 'toggle_wa', 'set_wa_api', 'set_wa_wow_account',
            'uri_integration', 'help', 'exit'
        ]
        addons = sorted(self.core.config['Addons'],
                        key=lambda k: k['Name'].lower())
        for addon in addons:
            name = f'"{addon["Name"]}"' if ',' in addon["Name"] else addon[
                "Name"]
            commands.extend([
                f'uninstall {name}', f'update {name}', f'force_update {name}',
                f'toggle_dev {name}', f'status {name}'
            ])
        for item in self.cfSlugs:
            commands.append(f'install cf:{item}')
        for item in self.wowiSlugs:
            commands.append(f'install wowi:{item}')
        commands.extend(
            ['install ElvUI', 'install ElvUI:Dev', 'install Tukui'])
        wa = WeakAuraUpdater('', '', '')
        accounts = wa.get_accounts()
        for account in accounts:
            commands.append(f'set_wa_wow_account {account}')
        self.completer = WordCompleter(commands,
                                       ignore_case=True,
                                       sentence=True)

    def setup_table(self):
        self.tableData = [[
            f'{AC.LIGHTWHITE_EX}Status{AC.RESET}',
            f'{AC.LIGHTWHITE_EX}Name{AC.RESET}',
            f'{AC.LIGHTWHITE_EX}Version{AC.RESET}'
        ]]
        self.table = SingleTable(
            self.tableData) if self.os == 'Windows' else UnicodeSingleTable(
                self.tableData)
        self.table.justify_columns[0] = 'center'

    def sanitize_table(self):
        if not self.table.ok:
            mwidth = self.table.column_max_width(1)
            for row in self.table.table_data[1:]:
                if len(row[1]) > mwidth:
                    row[1] = row[1][:mwidth - 3] + '...'

    def c_install(self, args):
        if args:
            if args.startswith('-i '):
                args = args[3:]
                optignore = True
            else:
                optignore = False
            addons = [
                addon.strip()
                for addon in list(reader([args], skipinitialspace=True))[0]
            ]
            with tqdm(total=len(addons),
                      bar_format='{n_fmt}/{total_fmt} |{bar}|') as pbar:
                for addon in addons:
                    installed, name, version = self.core.add_addon(
                        addon, optignore)
                    if installed:
                        self.tableData.append(
                            [f'{AC.GREEN}Installed{AC.RESET}', name, version])
                    else:
                        self.tableData.append([
                            f'{AC.LIGHTBLACK_EX}Already installed{AC.RESET}',
                            name, version
                        ])
                    pbar.update(1)
            self.sanitize_table()
            printft(ANSI(self.table.table))
        else:
            printft(
                HTML(
                    '<ansigreen>Usage:</ansigreen>\n\tThis command accepts a comma-separated list of links as an a'
                    'rgument.\n\tOption <ansiwhite>-i</ansiwhite> will disable the client version check.\n<ansigre'
                    'en>Supported URLs:</ansigreen>\n\thttps://www.curseforge.com/wow/addons/[addon_name] <ansiwhi'
                    'te>|</ansiwhite> cf:[addon_name]\n\thttps://www.wowinterface.com/downloads/[addon_name] <ansi'
                    'white>|</ansiwhite> wowi:[addon_id]\n\thttps://www.tukui.org/addons.php?id=[addon_id] <ansiwh'
                    'ite>|</ansiwhite> tu:[addon_id]\n\thttps://www.tukui.org/classic-addons.php?id=[addon_id] <an'
                    'siwhite>|</ansiwhite> tuc:[addon_id]\n\tElvUI <ansiwhite>|</ansiwhite> ElvU'
                    'I:Dev\n\tTukui'))

    def c_uninstall(self, args):
        if args:
            addons = [
                addon.strip()
                for addon in list(reader([args], skipinitialspace=True))[0]
            ]
            with tqdm(total=len(addons),
                      bar_format='{n_fmt}/{total_fmt} |{bar}|') as pbar:
                for addon in addons:
                    name, version = self.core.del_addon(addon)
                    if name:
                        self.tableData.append([
                            f'{AC.LIGHTRED_EX}Uninstalled{AC.RESET}', name,
                            version
                        ])
                    else:
                        self.tableData.append([
                            f'{AC.LIGHTBLACK_EX}Not installed{AC.RESET}',
                            addon, ''
                        ])
                    pbar.update(1)
            self.sanitize_table()
            printft(ANSI(self.table.table))
        else:
            printft(
                HTML(
                    '<ansigreen>Usage:</ansigreen>\n\tThis command accepts a comma-separated list of links as an a'
                    'rgument.\n<ansigreen>Supported URLs:</ansigreen>\n\thttps://www.curseforge.com/wow/addons/[ad'
                    'don_name] <ansiwhite>|</ansiwhite> cf:[addon_name]\n\thttps://www.wowinterface.com/downloads/'
                    '[addon_name] <ansiwhite>|</ansiwhite> wowi:[addon_id]\n\thttps://www.tukui.org/addons.php?id='
                    '[addon_id] <ansiwhite>|</ansiwhite> tu:[addon_id]\n\thttps://www.tukui.org/classic-addons.php'
                    '?id=[addon_id] <ansiwhite>|</ansiwhite> tuc:[addon_id]\n\tElvUI <ansiwhite>|</ansiwhite> ElvU'
                    'I:Dev\n\tTukui'))

    def c_update(self, args, addline=False, update=True, force=False):
        if len(self.core.cfCache) > 0 or len(self.core.wowiCache) > 0:
            self.core.cfCache = {}
            self.core.wowiCache = {}
        if args:
            addons = [
                addon.strip()
                for addon in list(reader([args], skipinitialspace=True))[0]
            ]
        else:
            addons = sorted(self.core.config['Addons'],
                            key=lambda k: k['Name'].lower())
            self.core.bulk_check(addons)
        with tqdm(total=len(addons),
                  bar_format='{n_fmt}/{total_fmt} |{bar}|') as pbar:
            exceptions = []
            for addon in addons:
                try:
                    name, versionnew, versionold, modified = self.core.\
                        update_addon(addon if isinstance(addon, str) else addon['URL'], update, force)
                    if versionold:
                        if versionold == versionnew:
                            if modified:
                                self.tableData.append([
                                    f'{AC.LIGHTRED_EX}Modified{AC.RESET}',
                                    name, versionold
                                ])
                            else:
                                self.tableData.append([
                                    f'{AC.GREEN}Up-to-date{AC.RESET}', name,
                                    versionold
                                ])
                        else:
                            if modified:
                                self.tableData.append([
                                    f'{AC.LIGHTRED_EX}Update suppressed{AC.RESET}',
                                    name, versionold
                                ])
                            else:
                                self.tableData.append([
                                    f'{AC.YELLOW}{"Updated " if update else "Update available"}'
                                    f'{AC.RESET}', name,
                                    f'{AC.YELLOW}{versionnew}{AC.RESET}'
                                ])
                    else:
                        self.tableData.append([
                            f'{AC.LIGHTBLACK_EX}Not installed{AC.RESET}',
                            addon, ''
                        ])
                except Exception as e:
                    exceptions.append(e)
                pbar.update(1)
        self.sanitize_table()
        printft(ANSI('\n' + self.table.table if addline else self.table.table))
        if len(exceptions) > 0:
            self.handle_exception(exceptions, False)

    def c_force_update(self, args):
        if args:
            self.c_update(args, False, True, True)
        else:
            printft(
                HTML(
                    '<ansigreen>Usage:</ansigreen>\n\tThis command accepts a comma-separated list of links or addo'
                    'n names as an argument.'))

    def c_status(self, args):
        self.c_update(args, False, False)

    def c_orphans(self, _):
        orphansd, orphansf = self.core.find_orphans()
        printft(
            HTML(
                '<ansigreen>Directories that are not part of any installed addon:</ansigreen>'
            ))
        for orphan in sorted(orphansd):
            printft(
                HTML(orphan.replace('[GIT]',
                                    '<ansiyellow>[GIT]</ansiyellow>')))
        printft(
            HTML(
                '\n<ansigreen>Files that are leftovers after no longer installed addons:</ansigreen>'
            ))
        for orphan in sorted(orphansf):
            printft(orphan)

    def c_uri_integration(self, _):
        if self.os == 'Windows':
            self.core.create_reg()
            printft(
                'CurseBreaker.reg file was created. Attempting to import...')
            out = os.system('"' + str(
                Path(os.path.dirname(sys.executable), 'CurseBreaker.reg')) +
                            '"')
            if out != 0:
                printft(
                    'Import failed. Please try to import REG file manually.')
            else:
                os.remove('CurseBreaker.reg')
        else:
            printft('This feature is available only on Windows.')

    def c_symlink_protection(self, _):
        if self.os == 'Windows':
            printft(HTML('<ansigreen>Directories tweaked:</ansigreen>'))
            for root, dirs, _ in os.walk(self.core.path / '..' / '..'):
                for d in dirs:
                    path = Path(root) / d
                    if os.path.islink(path):
                        set_icon(path, Path("C:/Windows/System32/SHELL32.dll"),
                                 4)
                        print(path.resolve())
        else:
            printft('This feature is available only on Windows.')

    def c_toggle_dev(self, args):
        if args:
            status = self.core.dev_toggle(args)
            if status is None:
                printft(
                    HTML(
                        '<ansibrightred>This addon does not exist or it is not installed yet.</ansibrightred>'
                    ))
            elif status:
                printft('This addon will now prioritize alpha/beta versions.')
            else:
                printft(
                    'This addon will not longer prioritize alpha/beta versions.'
                )
        else:
            printft(
                HTML(
                    '<ansigreen>Usage:</ansigreen>\n\tThis command accepts an addon name as an argument.'
                ))

    def c_toggle_backup(self, _):
        status = self.core.backup_toggle()
        printft(
            'Backup of WTF directory is now:',
            HTML('<ansigreen>ENABLED</ansigreen>')
            if status else HTML('<ansired>DISABLED</ansired>'))

    def c_toggle_wa(self, args):
        if args:
            if args == self.core.config['WAUsername']:
                printft(
                    HTML(
                        f'WeakAuras version check is now: <ansigreen>ENABLED</ansigreen>\n'
                        f'Auras created by <ansiwhite>{self.core.config["WAUsername"]}</ansiwhite>'
                        f' are now included.'))
                self.core.config['WAUsername'] = ''
            else:
                self.core.config['WAUsername'] = args.strip()
                printft(
                    HTML(
                        f'WeakAuras version check is now: <ansigreen>ENABLED</ansigreen>\n'
                        f'Auras created by <ansiwhite>{self.core.config["WAUsername"]}</ansiwhite>'
                        f' are now ignored.'))
        else:
            if self.core.config['WAUsername'] == 'DISABLED':
                self.core.config['WAUsername'] = ''
                printft(
                    HTML(
                        'WeakAuras version check is now: <ansigreen>ENABLED</ansigreen>'
                    ))
            else:
                self.core.config['WAUsername'] = '******'
                shutil.rmtree(Path('Interface/AddOns/WeakAurasCompanion'),
                              ignore_errors=True)
                printft(
                    HTML(
                        'WeakAuras version check is now: <ansired>DISABLED</ansired>'
                    ))
        self.core.save_config()

    def c_set_wa_api(self, args):
        if args:
            printft('Wago API key is now set.')
            self.core.config['WAAPIKey'] = args.strip()
            self.core.save_config()
        elif self.core.config['WAAPIKey'] != '':
            printft('Wago API key is now removed.')
            self.core.config['WAAPIKey'] = ''
            self.core.save_config()
        else:
            printft(
                HTML(
                    '<ansigreen>Usage:</ansigreen>\n\tThis command accepts API key as an argument.'
                ))

    def c_set_wa_wow_account(self, args):
        if args:
            args = args.strip()
            if os.path.isfile(
                    Path(f'WTF/Account/{args}/SavedVariables/WeakAuras.lua')):
                printft(
                    HTML(
                        f'WoW account name set to: <ansiwhite>{args}</ansiwhite>'
                    ))
                self.core.config['WAAccountName'] = args
                self.core.save_config()
            else:
                printft('Incorrect WoW account name.')
        else:
            printft(
                HTML(
                    '<ansigreen>Usage:</ansigreen>\n\tThis command accepts the WoW account name as an argument.'
                ))

    def c_wa_update(self, _, verbose=True):
        if os.path.isdir(Path('Interface/AddOns/WeakAuras')):
            wa = WeakAuraUpdater(
                '' if self.core.config['WAUsername'] == 'DISABLED' else
                self.core.config['WAUsername'],
                self.core.config['WAAccountName'],
                self.core.config['WAAPIKey'])
            accounts = wa.get_accounts()
            if len(accounts) > 1:
                if verbose:
                    printft(
                        HTML(
                            'More than one WoW account detected.\nPlease use <ansiwhite>set_wa_wow_account</ansiwh'
                            'ite> command to set the correct account name.'))
                else:
                    printft(
                        HTML(
                            '\n<ansigreen>More than one WoW account detected.</ansigreen>\nPlease use <ansiwhite>s'
                            'et_wa_wow_account</ansiwhite> command to set the correct account name.'
                        ))
                return
            if wa.accountName:
                if not self.core.config['WAAccountName']:
                    self.core.config['WAAccountName'] = wa.accountName
                    self.core.save_config()
                if self.core.waCompanionVersion != self.core.config[
                        'WACompanionVersion']:
                    self.core.config[
                        'WACompanionVersion'] = self.core.waCompanionVersion
                    self.core.save_config()
                    force = True
                else:
                    force = False
                wa.parse_storage()
                status = wa.check_updates()
                wa.install_companion(self.core.clientType, force)
                wa.install_data()
                if verbose:
                    printft(HTML('<ansigreen>Outdated WeakAuras:</ansigreen>'))
                    for aura in status[0]:
                        printft(aura)
                    printft(
                        HTML('\n<ansigreen>Detected WeakAuras:</ansigreen>'))
                    for aura in status[1]:
                        printft(aura)
                else:
                    printft(
                        HTML(
                            f'\n<ansigreen>The number of outdated WeakAuras:</ansigreen> {len(status[0])}'
                        ))
        elif verbose:
            printft('WeakAuras addon is not installed.')

    def c_search(self, args):
        if args:
            results = self.core.search(args)
            printft(HTML('<ansigreen>Top results of your search:</ansigreen>'))
            for url in results:
                if self.core.check_if_installed(url):
                    printft(
                        HTML(f'{url} <ansiyellow>[Installed]</ansiyellow>'))
                else:
                    printft(url)
        else:
            printft(
                HTML(
                    '<ansigreen>Usage:</ansigreen>\n\tThis command accepts a search query as an argument.'
                ))

    def c_import(self, args):
        hit, partial_hit, miss = self.core.detect_addons()
        if args == 'install' and len(hit) > 0:
            self.c_install(','.join(hit))
        else:
            printft(HTML(f'<ansigreen>Addons found:</ansigreen>'))
            for addon in hit:
                printft(addon)
            printft(HTML(f'\n<ansiyellow>Possible matches:</ansiyellow>'))
            for addon in partial_hit:
                printft(HTML(' <ansiwhite>or</ansiwhite> '.join(addon)))
            printft(HTML(f'\n<ansired>Unknown directories:</ansired>'))
            for addon in miss:
                printft(f'{addon}')
            printft(
                HTML(
                    f'\nExecute <ansiwhite>import install</ansiwhite> command to install all detected addons.\n'
                    f'Possible matches need to be installed manually with the <ansiwhite>install</ansiwhite>'
                    f' command.'))

    def c_export(self, _):
        printft(self.core.export_addons())

    def c_help(self, _):
        printft(
            HTML(
                '<ansigreen>install [URL]</ansigreen>\n\tCommand accepts a comma-separated list of links.\n'
                '<ansigreen>uninstall [URL/Name]</ansigreen>\n\tCommand accepts a comma-separated list of links or'
                ' addon names.\n'
                '<ansigreen>update [URL/Name]</ansigreen>\n\tCommand accepts a comma-separated list of links or ad'
                'don names.\n\tIf no argument is provided all non-modified addons will be updated.\n'
                '<ansigreen>force_update [URL/Name]</ansigreen>\n\tCommand accepts a comma-separated list of links'
                ' or addon names.\n\tSelected addons will be reinstalled or updated regardless of their current st'
                'ate.\n'
                '<ansigreen>wa_update</ansigreen>\n\tCommand detects all installed WeakAuras and generate WeakAura'
                's Companion payload.\n'
                '<ansigreen>status</ansigreen>\n\tPrints the current state of all installed addons.\n'
                '<ansigreen>orphans</ansigreen>\n\tPrints list of orphaned directories and files.\n'
                '<ansigreen>search [Keyword]</ansigreen>\n\tExecutes addon search on CurseForge.\n'
                '<ansigreen>import</ansigreen>\n\tCommand attempts to import already installed addons.\n'
                '<ansigreen>export</ansigreen>\n\tCommand prints list of all installed addons in a form suitable f'
                'or sharing.\n'
                '<ansigreen>toggle_backup</ansigreen>\n\tEnables/disables automatic daily backup of WTF directory.'
                '\n<ansigreen>toggle_dev [Name]</ansigreen>\n\tCommand accepts an addon name as argument.\n\tPrior'
                'itizes alpha/beta versions for the provided addon.\n'
                '<ansigreen>toggle_wa [Username]</ansigreen>\n\tEnables/disables automatic WeakAuras updates.\n\tI'
                'f a username is provided check will start to ignore the specified author.\n'
                '<ansigreen>set_wa_api [API key]</ansigreen>\n\tSets Wago API key required to access private auras'
                '.\n\tIt can be procured here: https://wago.io/account\n'
                '<ansigreen>set_wa_wow_account [Account name]</ansigreen>\n\tSets WoW account used by WeakAuras up'
                'dater.\n\tNeeded only if WeakAuras are used on more than one WoW account.\n'
                '<ansigreen>uri_integration</ansigreen>\n\tEnables integration with CurseForge page. "Install" but'
                'ton will now start this application.\n'
                '\n<ansibrightgreen>Supported URL:</ansibrightgreen>\n\thttps://www.curseforge.com/wow/addons/[add'
                'on_name] <ansiwhite>|</ansiwhite> cf:[addon_name]\n\thttps://www.wowinterface.com/downloads/[addo'
                'n_name] <ansiwhite>|</ansiwhite> wowi:[addon_id]\n\thttps://www.tukui.org/addons.php?id=[addon_id'
                '] <ansiwhite>|</ansiwhite> tu:[addon_id]\n\thttps://www.tukui.org/classic-addons.php?id=[addon_id'
                '] <ansiwhite>|</ansiwhite> tuc:[addon_id]\n\tElvUI <ansiwhite>|</ansiwhite> ElvUI:Dev\n\tTukui'
            ))

    def c_exit(self, _):
        sys.exit(0)
Esempio n. 23
0
#!/usr/bin/env python
"""Simple example usage of terminaltables and column_max_width().

Just prints sample text and exits.
"""

from __future__ import print_function

from textwrap import wrap

from terminaltables import SingleTable


# Setup string and table.
long_string = ('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore '
               'et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut '
               'aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum '
               'dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui '
               'officia deserunt mollit anim id est laborum.')
table = SingleTable([['Long String', '']])

# Calculate newlines.
max_width = table.column_max_width(1)
wrapped_string = '\n'.join(wrap(long_string, max_width))
table.table_data[0][1] = wrapped_string

print(table.table)
Esempio n. 24
0
def walk(
    stream_name,
    shard_id,
    sequence_number=None,
    get_records_limit=5,
    follow=False,
    latest=False,
    timestamp=None,
):
    kinesis_client = boto3.client("kinesis")

    if not shard_id.startswith(constants.SHARD_ID_PREFIX):
        shard_id = constants.SHARD_ID_PREFIX + shard_id

    get_shard_iterator_args = {"StreamName": stream_name, "ShardId": shard_id}

    if sequence_number:
        get_shard_iterator_args["ShardIteratorType"] = "AT_SEQUENCE_NUMBER"
        get_shard_iterator_args["StartingSequenceNumber"] = sequence_number
    elif latest:
        get_shard_iterator_args["ShardIteratorType"] = "LATEST"
    elif timestamp:
        get_shard_iterator_args["ShardIteratorType"] = "AT_TIMESTAMP"
        get_shard_iterator_args["Timestamp"] = date_util.to_iterator_timestamp(
            timestamp)
    else:
        get_shard_iterator_args["ShardIteratorType"] = "TRIM_HORIZON"

    click.echo(
        f"Creating shard iterator with arguments = {get_shard_iterator_args}")
    shard_iterator_response = kinesis_client.get_shard_iterator(
        **get_shard_iterator_args)

    shard_iterator = shard_iterator_response["ShardIterator"]
    fetch_more = True
    while fetch_more:

        records_response = kinesis_client.get_records(
            ShardIterator=shard_iterator, Limit=get_records_limit)

        for record in records_response["Records"]:
            parsed_data = get_parsed_data(record)
            table_data = [
                ["SequenceNumber", record["SequenceNumber"]],
                [
                    "ApproximateArrivalTimestamp",
                    record["ApproximateArrivalTimestamp"]
                ],
                ["PartitionKey", record["PartitionKey"]],
                ["EncryptionType",
                 record.get("EncryptionType")],
                ["Decoded Data", parsed_data],
            ]

            table = SingleTable(table_data)
            max_width = table.column_max_width(1)
            wrapped_string = "\n".join(wrap(parsed_data, max_width))
            table.table_data[4][1] = wrapped_string
            print(table.table)

        if not records_response["Records"]:
            click.echo("No records found for this api call 😔")

        if follow:
            click.echo(f"Waiting for {WAIT_FOR_SECONDS} seconds...")
            time.sleep(WAIT_FOR_SECONDS)
        else:
            fetch_more = click.confirm("Fetch more records?", default=True)

        shard_iterator = records_response["NextShardIterator"]