def print_formatted_table(delimiter): """Read tabular data from standard input and print a table.""" data = [] for line in sys.stdin: line = line.rstrip() data.append(line.split(delimiter)) output(format_table(data))
def __exit__(self, exc_type=None, exc_value=None, traceback=None): """Stop capturing output and convert the output to HTML (when applicable).""" if self.is_enabled: if not self.is_silent: # Only call output() when we captured something useful. text = self.capturer.get_text() if text and not text.isspace(): output(convert(text)) self.capturer.__exit__(exc_type, exc_value, traceback)
def convert_command_output(*command): """ Command line interface for ``coloredlogs --to-html``. Takes a command (and its arguments) and runs the program under ``script`` (emulating an interactive terminal), intercepts the output of the command and converts ANSI escape sequences in the output to HTML. """ captured_output = capture(command) converted_output = convert(captured_output) if connected_to_terminal(): fd, temporary_file = tempfile.mkstemp(suffix='.html') with open(temporary_file, 'w') as handle: handle.write(converted_output) webbrowser.open(temporary_file) elif captured_output and not captured_output.isspace(): output(converted_output)
def demonstrate_ansi_formatting(): """Demonstrate the use of ANSI escape sequences.""" # First we demonstrate the supported text styles. output('%s', ansi_wrap('Text styles:', bold=True)) styles = ['normal', 'bright'] styles.extend(ANSI_TEXT_STYLES.keys()) for style_name in sorted(styles): options = dict(color=HIGHLIGHT_COLOR) if style_name != 'normal': options[style_name] = True style_label = style_name.replace('_', ' ').capitalize() output(' - %s', ansi_wrap(style_label, **options)) # Now we demonstrate named foreground and background colors. for color_type, color_label in (('color', 'Foreground colors'), ('background', 'Background colors')): intensities = [ ('normal', dict()), ('bright', dict(bright=True)), ] if color_type != 'background': intensities.insert(0, ('faint', dict(faint=True))) output('\n%s' % ansi_wrap('%s:' % color_label, bold=True)) output(format_smart_table([ [color_name] + [ ansi_wrap( 'XXXXXX' if color_type != 'background' else (' ' * 6), **dict(list(kw.items()) + [(color_type, color_name)]) ) for label, kw in intensities ] for color_name in sorted(ANSI_COLOR_CODES.keys()) ], column_names=['Color'] + [ label.capitalize() for label, kw in intensities ])) # Demonstrate support for 256 colors as well. demonstrate_256_colors(0, 7, 'standard colors') demonstrate_256_colors(8, 15, 'high-intensity colors') demonstrate_256_colors(16, 231, '216 colors') demonstrate_256_colors(232, 255, 'gray scale colors')
def demonstrate_256_colors(i, j, group=None): """Demonstrate 256 color mode support.""" # Generate the label. label = '256 color mode' if group: label += ' (%s)' % group output('\n' + ansi_wrap('%s:' % label, bold=True)) # Generate a simple rendering of the colors in the requested range and # check if it will fit on a single line (given the terminal's width). single_line = ''.join(' ' + ansi_wrap(str(n), color=n) for n in range(i, j + 1)) lines, columns = find_terminal_size() if columns >= len(ansi_strip(single_line)): output(single_line) else: # Generate a more complex rendering of the colors that will nicely wrap # over multiple lines without using too many lines. width = len(str(j)) + 1 colors_per_line = int(columns / width) colors = [ansi_wrap(str(n).rjust(width), color=n) for n in range(i, j + 1)] blocks = [colors[n:n + colors_per_line] for n in range(0, len(colors), colors_per_line)] output('\n'.join(''.join(b) for b in blocks))
def print_formatted_timespan(value): """Print a human readable timespan.""" output(format_timespan(float(value)))
def run_benchmark(self): """Benchmark the effectiveness of the delta transfer implementation.""" # Make sure the operator realizes what we're going to do, before it happens. if os.environ.get("PDIFFCOPY_BENCHMARK") != "allowed": logger.notice("Set $PDIFFCOPY_BENCHMARK=allowed to bypass the following interactive prompt.") question = """ This will mutate the target file and then restore its original contents. Are you sure this is okay? """ if not prompt_for_confirmation(compact(question), default=False): raise BenchmarkAbortedError("Permission to run benchmark denied.") samples = [] logger.info("Performing initial synchronization to level the playing ground ..") self.synchronize_once() # If the target file didn't exist before we created it then # self.target.exists may have cached the value False. self.clear_cached_properties() # Get the rsync configuration from environment variables. rsync_server = os.environ.get("PDIFFCOPY_BENCHMARK_RSYNC_SERVER") rsync_module = os.environ.get("PDIFFCOPY_BENCHMARK_RSYNC_MODULE") rsync_root = os.environ.get("PDIFFCOPY_BENCHMARK_RSYNC_ROOT") have_rsync = rsync_server and rsync_module and rsync_root # Run the benchmark for the requested number of iterations. for i in range(1, self.benchmark + 1): # Initialize timers to compare pdiffcopy and rsync runtime. pdiffcopy_timer = Timer(resumable=True) rsync_timer = Timer(resumable=True) # Mutate the target file. difference = 100 / self.benchmark * i self.mutate_target(difference) # Synchronize using pdiffcopy. with Timer(resumable=True) as pdiffcopy_timer: num_blocks = self.synchronize_once() # Synchronize using rsync? if have_rsync: self.mutate_target(difference) with rsync_timer: rsync_command_line = [ "rsync", "--inplace", format( "rsync://%s/%s", rsync_server, os.path.join(rsync_module, os.path.relpath(self.source.filename, rsync_root)), ), self.target.filename, ] logger.info("Synchronizing changes using %s ..", " ".join(map(pipes.quote, rsync_command_line))) subprocess.check_call(rsync_command_line) logger.info("Synchronized changes using rsync in %s ..", rsync_timer) # Summarize the results of this iteration. metrics = ["%i%%" % difference] metrics.append(format_size(num_blocks * self.block_size, binary=True)) metrics.append(str(pdiffcopy_timer)) if have_rsync: metrics.append(str(rsync_timer)) samples.append(metrics) # Render an overview of the results in the form of a table. column_names = ["Delta size", "Data transferred", "Runtime of pdiffcopy"] if have_rsync: column_names.append("Runtime of rsync") output(format_pretty_table(samples, column_names=column_names))
def print_formatted_size(value, binary): """Print a human readable size.""" output(format_size(int(value), binary=binary))
def report_best_mirror(updater): """Print the URL of the "best" mirror.""" output(updater.best_mirror)
def print_formatted_size(value, binary): """Print a human readable size.""" output(format_size(int(value), binary=binary))
def print_formatted_number(value): """Print large numbers in a human readable format.""" output(format_number(float(value)))
def report_current_mirror(updater): """Print the URL of the currently configured ``apt-get`` mirror.""" output(updater.current_mirror)
def print_formatted_length(value): """Print a human readable length.""" if '.' in value: output(format_length(float(value))) else: output(format_length(int(value)))
def print_parsed_length(value): """Parse a human readable length and print the number of metres.""" output(parse_length(value))
def print_formatted_timespan(value): """Print a human readable timespan.""" output(format_timespan(float(value)))
def print_parsed_size(value): """Parse a human readable data size and print the number of bytes.""" output(parse_size(value))
def print_parsed_length(value): """Parse a human readable length and print the number of metres.""" output(parse_length(value))
def print_parsed_size(value): """Parse a human readable data size and print the number of bytes.""" output(parse_size(value))
def main(): """Command line interface for the ``apt-smart`` program.""" # Initialize logging to the terminal and system log. coloredlogs.install(syslog=True) # Command line option defaults. context = LocalContext() updater = AptMirrorUpdater(context=context) limit = MAX_MIRRORS url_char_len = URL_CHAR_LEN actions = [] # Parse the command line arguments. try: options, arguments = getopt.getopt(sys.argv[1:], 'r:fF:blL:c:aux:m:vVR:qh', [ 'remote-host=', 'find-current-mirror', 'find-best-mirror', 'file-to-read=', 'list-mirrors', 'url-char-len=', 'change-mirror=', 'auto-change-mirror', 'update', 'update-package-lists', 'exclude=', 'max=', 'verbose', 'version', 'create-chroot=', 'quiet', 'help', ]) for option, value in options: if option in ('-r', '--remote-host'): if actions: msg = "The %s option should be the first option given on the command line!" raise Exception(msg % option) context = RemoteContext(value) updater = AptMirrorUpdater(context=context) elif option in ('-f', '--find-current-mirror'): actions.append( functools.partial(report_current_mirror, updater)) elif option in ('-F', '--file-to-read'): updater.custom_mirror_file_path = value elif option in ('-b', '--find-best-mirror'): actions.append(functools.partial(report_best_mirror, updater)) elif option in ('-l', '--list-mirrors'): actions.append( functools.partial(report_available_mirrors, updater)) elif option in ('-L', '--url-char-len'): url_char_len = int(value) elif option in ('-c', '--change-mirror'): if value.strip().startswith(('http://', 'https://', 'ftp://')): actions.append( functools.partial(updater.change_mirror, value)) else: raise Exception("\'%s\' is not a valid mirror URL" % value) elif option in ('-a', '--auto-change-mirror'): actions.append(updater.change_mirror) elif option in ('-u', '--update', '--update-package-lists'): actions.append(updater.smart_update) elif option in ('-x', '--exclude'): actions.insert(0, functools.partial(updater.ignore_mirror, value)) elif option in ('-m', '--max'): limit = int(value) elif option in ('-v', '--verbose'): coloredlogs.increase_verbosity() elif option in ('-V', '--version'): output("Version: %s on Python %i.%i", updater_version, sys.version_info[0], sys.version_info[1]) return elif option in ('-R', '--create-chroot'): actions.append(functools.partial(updater.create_chroot, value)) elif option in ('-q', '--quiet'): coloredlogs.decrease_verbosity() elif option in ('-h', '--help'): usage(__doc__) return else: assert False, "Unhandled option!" if not actions: usage(__doc__) return # Propagate options to the Python API. updater.max_mirrors = limit updater.url_char_len = url_char_len except Exception as e: warning("Error: Failed to parse command line arguments! (%s)" % e) sys.exit(1) # Perform the requested action(s). try: for callback in actions: callback() except Exception: logger.exception("Encountered unexpected exception! Aborting ..") sys.exit(1)
def print_formatted_number(value): """Print large numbers in a human readable format.""" output(format_number(float(value)))
def print_formatted_length(value): """Print a human readable length.""" if '.' in value: output(format_length(float(value))) else: output(format_length(int(value)))