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
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)
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)
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)
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)
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"]
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)
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
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']
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)
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)
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
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)
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)
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
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)
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)
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])
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:
#!/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)
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)
#!/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)
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"]