def get_result(self, results=None, index=0): """Returns a terminal representation of a YouTube Video result.""" if results is None: results = self.results try: vid = pafy.new(results[index]) except Exception: return str(index + 1) + ") This video is not available.\n" string = "" string += str(index + 1) + ") " string += str(color.bold(color.underline(vid.title))) + "\n" more_info = "Time: {} | Rating: {:.2f} | Views: {:,}\n" string += more_info.format(vid.duration, vid.rating, vid.viewcount) utils.term.bgcolor = 'white' thumbnail = requests.get(vid.thumb) image = fi.Image(StringIO(thumbnail.content)) width = min(utils.term.width, self.MAX_WIDTH) image.resize(width) string += textwrap.fill(vid.description[:500] + "...", width) + "\n" string += str(image) string += "/"*width + "\n" return string
def testSimpleMatch(self): line = '+tag' expected = str(underline(blue(line))) self.assertEqual(expected, self.dball.colorize(line))
class CliFormatter(string.Formatter): """ Extends string.Formatter to provide some bells and whistles: Tabular Data - `{foo:table}`: tabular_data = [('foo-header', 'bar-header'), ('row1, col1', 'row1, col2)'] # and so on... formatter.format('Here is a table\n{totally_tabular:table}', totally_tabular=tabular_data) ANSI Style Markup - `{foo:bold}`: formatter.format('{good:256_bright_green}, {bad:256_bright_red}', good="Awesome!", bad="Oh no!") Format raw text without an explicit value: formatter.format('{Awesome!:256_bright_green}, {Oh no!:256_bright_red}') # normally would raise a KeyError Auto de-dent - dedent=True (default): multiline_string = ''' Normally this would be printed with the leading/trailing \\n and spaces. You could call textwrap.dedent() on the resulting string but the formatter handles it for you. ''' formatter.format('No indention:\n{}', multiline_string) # dedent=true by default formatter.format('Indention:\n{}', multiline_string, dedent=False) """ STYLES = { 'bold': lambda text: color.bold(text), 'italic': lambda text: color.italic(text), 'strike': lambda text: color.strike(text), 'underline': lambda text: color.underline(text), '256_bright_green': lambda text: color.bold(color.fg256('#00FF00', text)), '256_green': lambda text: color.bold(color.fg256('#00FF00', text)), '256_light_green': lambda text: color.fg256('#99ff00', text), '256_bright_yellow': lambda text: color.bold(color.fg256('#ffdd00', text)), '256_yellow': lambda text: color.fg256('#ffdd00', text), '256_light_yellow': lambda text: color.fg256('#ffff00', text), '256_bright_red': lambda text: color.bold(color.fg256('#ff0000', text)), '256_red': lambda text: color.bold(color.fg256('#ff0000', text)), '256_light_red': lambda text: color.fg256('#ff5500', text), } def __init__(self): super(CliFormatter, self).__init__() self.indent_level = 0 self.dedent = True def format(self, *args, **kwargs): """ You can use 'dedent' to have the formatter de-indent the final string for you which is nice when you are using heredoc style strings that preserve white space in a multiline string. :param args: :param kwargs: :return: """ if 'dedent' in kwargs: self.dedent = kwargs['dedent'] del kwargs['dedent'] formatted = super(CliFormatter, self).format(*args, **kwargs) if self.dedent: formatted = textwrap.dedent(formatted).strip('\n') self.dedent = True self.indent_level = 0 return formatted def vformat(self, format_string, args, kwargs): """ Need to keep track of the indent level incase we generate new rows of text, e.g. a Table, so the indention level of the generated row matches :param format_string: :param args: :param kwargs: :return: """ if isinstance(format_string, str): self.indent_level = len(format_string) - len(format_string.lstrip()) - 1 return super(CliFormatter, self).vformat(format_string, args, kwargs) def get_value(self, key, args, kwargs): """ Normally a key without a matching value would raise an error, but I want to be able to stylize plain text without having to make a variable and stick it in a map, e.g. formatter.format('{This is a string:bold}') instead of formatter.format('{placehold:bold}', {'placeholder': 'This is a string'}) :param key: :param args: :param kwargs: :return: """ try: return super(CliFormatter, self).get_value(key, args, kwargs) except (IndexError, KeyError) as e: return key def format_field(self, value, format_spec): if format_spec == 'table' or format_spec == 'table_no_header': header = format_spec == 'table' return tabulate(value, first_row_header=header, indent_level=self.indent_level) elif format_spec in CliFormatter.STYLES: stylized = CliFormatter.STYLES[format_spec](value) return str(stylized) else: return super(CliFormatter, self).format_field(value, format_spec)
def _individual_colorize(self, line, pattern, match): if match not in self.color_assignments: self.color_assignments[match] = self.get_next_color() return line.replace(match, str(underline(self.color_assignments[match](match))))
def _group_colorize(self, line, pattern, match): if pattern not in self.color_assignments: self.color_assignments[pattern] = self.get_next_color() return line.replace(match, str(underline(self.color_assignments[pattern](match))))
def _one_colorize(self, line, pattern, match): return line.replace(match, str(underline(blue(match))))
def underline(self): return ansi(c.underline(self.txt))