mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-27 10:31:29 +00:00
[utils] Allow alignment in render_table
and add tests
This commit is contained in:
parent
c45b87419f
commit
c5e3f84972
|
@ -1222,12 +1222,49 @@ def test_is_html(self):
|
||||||
def test_render_table(self):
|
def test_render_table(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
render_table(
|
render_table(
|
||||||
['a', 'bcd'],
|
['a', 'empty', 'bcd'],
|
||||||
[[123, 4], [9999, 51]]),
|
[[123, '', 4], [9999, '', 51]]),
|
||||||
|
'a empty bcd\n'
|
||||||
|
'123 4\n'
|
||||||
|
'9999 51')
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
render_table(
|
||||||
|
['a', 'empty', 'bcd'],
|
||||||
|
[[123, '', 4], [9999, '', 51]],
|
||||||
|
hide_empty=True),
|
||||||
'a bcd\n'
|
'a bcd\n'
|
||||||
'123 4\n'
|
'123 4\n'
|
||||||
'9999 51')
|
'9999 51')
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
render_table(
|
||||||
|
['\ta', 'bcd'],
|
||||||
|
[['1\t23', 4], ['\t9999', 51]]),
|
||||||
|
' a bcd\n'
|
||||||
|
'1 23 4\n'
|
||||||
|
'9999 51')
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
render_table(
|
||||||
|
['a', 'bcd'],
|
||||||
|
[[123, 4], [9999, 51]],
|
||||||
|
delim='-'),
|
||||||
|
'a bcd\n'
|
||||||
|
'--------\n'
|
||||||
|
'123 4\n'
|
||||||
|
'9999 51')
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
render_table(
|
||||||
|
['a', 'bcd'],
|
||||||
|
[[123, 4], [9999, 51]],
|
||||||
|
delim='-', extra_gap=2),
|
||||||
|
'a bcd\n'
|
||||||
|
'----------\n'
|
||||||
|
'123 4\n'
|
||||||
|
'9999 51')
|
||||||
|
|
||||||
def test_match_str(self):
|
def test_match_str(self):
|
||||||
# Unary
|
# Unary
|
||||||
self.assertFalse(match_str('xy', {'x': 1200}))
|
self.assertFalse(match_str('xy', {'x': 1200}))
|
||||||
|
|
|
@ -3229,37 +3229,36 @@ def list_formats(self, info_dict):
|
||||||
formats = info_dict.get('formats', [info_dict])
|
formats = info_dict.get('formats', [info_dict])
|
||||||
new_format = self.params.get('listformats_table', True) is not False
|
new_format = self.params.get('listformats_table', True) is not False
|
||||||
if new_format:
|
if new_format:
|
||||||
tbr_digits = number_of_digits(max(f.get('tbr') or 0 for f in formats))
|
|
||||||
vbr_digits = number_of_digits(max(f.get('vbr') or 0 for f in formats))
|
|
||||||
abr_digits = number_of_digits(max(f.get('abr') or 0 for f in formats))
|
|
||||||
delim = self._format_screen('\u2502', self.Styles.DELIM, '|', test_encoding=True)
|
delim = self._format_screen('\u2502', self.Styles.DELIM, '|', test_encoding=True)
|
||||||
table = [
|
table = [
|
||||||
[
|
[
|
||||||
self._format_screen(format_field(f, 'format_id'), self.Styles.ID),
|
self._format_screen(format_field(f, 'format_id'), self.Styles.ID),
|
||||||
format_field(f, 'ext'),
|
format_field(f, 'ext'),
|
||||||
self.format_resolution(f),
|
self.format_resolution(f),
|
||||||
format_field(f, 'fps', '%3d'),
|
format_field(f, 'fps', '\t%d'),
|
||||||
format_field(f, 'dynamic_range', '%s', ignore=(None, 'SDR')).replace('HDR', ''),
|
format_field(f, 'dynamic_range', '%s', ignore=(None, 'SDR')).replace('HDR', ''),
|
||||||
delim,
|
delim,
|
||||||
format_field(f, 'filesize', ' %s', func=format_bytes) + format_field(f, 'filesize_approx', '~%s', func=format_bytes),
|
format_field(f, 'filesize', ' \t%s', func=format_bytes) + format_field(f, 'filesize_approx', '~\t%s', func=format_bytes),
|
||||||
format_field(f, 'tbr', f'%{tbr_digits}dk'),
|
format_field(f, 'tbr', '\t%dk'),
|
||||||
shorten_protocol_name(f.get('protocol', '').replace("native", "n")),
|
shorten_protocol_name(f.get('protocol', '').replace('native', 'n')),
|
||||||
delim,
|
delim,
|
||||||
format_field(f, 'vcodec', default='unknown').replace('none', ''),
|
format_field(f, 'vcodec', default='unknown').replace('none', ''),
|
||||||
format_field(f, 'vbr', f'%{vbr_digits}dk'),
|
format_field(f, 'vbr', '\t%dk'),
|
||||||
format_field(f, 'acodec', default='unknown').replace('none', ''),
|
format_field(f, 'acodec', default='unknown').replace('none', ''),
|
||||||
format_field(f, 'abr', f'%{abr_digits}dk'),
|
format_field(f, 'abr', '\t%dk'),
|
||||||
format_field(f, 'asr', '%5dHz'),
|
format_field(f, 'asr', '\t%dHz'),
|
||||||
join_nonempty(
|
join_nonempty(
|
||||||
self._format_screen('UNSUPPORTED', 'light red') if f.get('ext') in ('f4f', 'f4m') else None,
|
self._format_screen('UNSUPPORTED', 'light red') if f.get('ext') in ('f4f', 'f4m') else None,
|
||||||
format_field(f, 'language', '[%s]'),
|
format_field(f, 'language', '[%s]'),
|
||||||
format_field(f, 'format_note'),
|
join_nonempty(
|
||||||
format_field(f, 'container', ignore=(None, f.get('ext'))),
|
format_field(f, 'format_note'),
|
||||||
delim=', '),
|
format_field(f, 'container', ignore=(None, f.get('ext'))),
|
||||||
|
delim=', '),
|
||||||
|
delim=' '),
|
||||||
] for f in formats if f.get('preference') is None or f['preference'] >= -1000]
|
] for f in formats if f.get('preference') is None or f['preference'] >= -1000]
|
||||||
header_line = self._list_format_headers(
|
header_line = self._list_format_headers(
|
||||||
'ID', 'EXT', 'RESOLUTION', 'FPS', 'HDR', delim, ' FILESIZE', ' TBR', 'PROTO',
|
'ID', 'EXT', 'RESOLUTION', '\tFPS', 'HDR', delim, '\tFILESIZE', '\tTBR', 'PROTO',
|
||||||
delim, 'VCODEC', ' VBR', 'ACODEC', ' ABR', ' ASR', 'MORE INFO')
|
delim, 'VCODEC', '\tVBR', 'ACODEC', '\tABR', '\tASR', 'MORE INFO')
|
||||||
else:
|
else:
|
||||||
table = [
|
table = [
|
||||||
[
|
[
|
||||||
|
@ -3275,8 +3274,8 @@ def list_formats(self, info_dict):
|
||||||
'[info] Available formats for %s:' % info_dict['id'])
|
'[info] Available formats for %s:' % info_dict['id'])
|
||||||
self.to_stdout(render_table(
|
self.to_stdout(render_table(
|
||||||
header_line, table,
|
header_line, table,
|
||||||
extraGap=(0 if new_format else 1),
|
extra_gap=(0 if new_format else 1),
|
||||||
hideEmpty=new_format,
|
hide_empty=new_format,
|
||||||
delim=new_format and self._format_screen('\u2500', self.Styles.DELIM, '-', test_encoding=True)))
|
delim=new_format and self._format_screen('\u2500', self.Styles.DELIM, '-', test_encoding=True)))
|
||||||
|
|
||||||
def list_thumbnails(self, info_dict):
|
def list_thumbnails(self, info_dict):
|
||||||
|
@ -3307,7 +3306,7 @@ def _row(lang, formats):
|
||||||
self.to_stdout(render_table(
|
self.to_stdout(render_table(
|
||||||
self._list_format_headers('Language', 'Name', 'Formats'),
|
self._list_format_headers('Language', 'Name', 'Formats'),
|
||||||
[_row(lang, formats) for lang, formats in subtitles.items()],
|
[_row(lang, formats) for lang, formats in subtitles.items()],
|
||||||
hideEmpty=True))
|
hide_empty=True))
|
||||||
|
|
||||||
def urlopen(self, req):
|
def urlopen(self, req):
|
||||||
""" Start an HTTP download """
|
""" Start an HTTP download """
|
||||||
|
|
|
@ -4805,10 +4805,11 @@ def determine_protocol(info_dict):
|
||||||
return compat_urllib_parse_urlparse(url).scheme
|
return compat_urllib_parse_urlparse(url).scheme
|
||||||
|
|
||||||
|
|
||||||
def render_table(header_row, data, delim=False, extraGap=0, hideEmpty=False):
|
def render_table(header_row, data, delim=False, extra_gap=0, hide_empty=False):
|
||||||
""" Render a list of rows, each as a list of values """
|
""" Render a list of rows, each as a list of values.
|
||||||
|
Text after a \t will be right aligned """
|
||||||
def width(string):
|
def width(string):
|
||||||
return len(remove_terminal_sequences(string))
|
return len(remove_terminal_sequences(string).replace('\t', ''))
|
||||||
|
|
||||||
def get_max_lens(table):
|
def get_max_lens(table):
|
||||||
return [max(width(str(v)) for v in col) for col in zip(*table)]
|
return [max(width(str(v)) for v in col) for col in zip(*table)]
|
||||||
|
@ -4816,21 +4817,24 @@ def get_max_lens(table):
|
||||||
def filter_using_list(row, filterArray):
|
def filter_using_list(row, filterArray):
|
||||||
return [col for (take, col) in zip(filterArray, row) if take]
|
return [col for (take, col) in zip(filterArray, row) if take]
|
||||||
|
|
||||||
if hideEmpty:
|
if hide_empty:
|
||||||
max_lens = get_max_lens(data)
|
max_lens = get_max_lens(data)
|
||||||
header_row = filter_using_list(header_row, max_lens)
|
header_row = filter_using_list(header_row, max_lens)
|
||||||
data = [filter_using_list(row, max_lens) for row in data]
|
data = [filter_using_list(row, max_lens) for row in data]
|
||||||
|
|
||||||
table = [header_row] + data
|
table = [header_row] + data
|
||||||
max_lens = get_max_lens(table)
|
max_lens = get_max_lens(table)
|
||||||
extraGap += 1
|
extra_gap += 1
|
||||||
if delim:
|
if delim:
|
||||||
table = [header_row] + [[delim * (ml + extraGap) for ml in max_lens]] + data
|
table = [header_row, [delim * (ml + extra_gap) for ml in max_lens]] + data
|
||||||
max_lens[-1] = 0
|
table[1][-1] = table[1][-1][:-extra_gap] # Remove extra_gap from end of delimiter
|
||||||
for row in table:
|
for row in table:
|
||||||
for pos, text in enumerate(map(str, row)):
|
for pos, text in enumerate(map(str, row)):
|
||||||
row[pos] = text + (' ' * (max_lens[pos] - width(text) + extraGap))
|
if '\t' in text:
|
||||||
ret = '\n'.join(''.join(row) for row in table)
|
row[pos] = text.replace('\t', ' ' * (max_lens[pos] - width(text))) + ' ' * extra_gap
|
||||||
|
else:
|
||||||
|
row[pos] = text + ' ' * (max_lens[pos] - width(text) + extra_gap)
|
||||||
|
ret = '\n'.join(''.join(row).rstrip() for row in table)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue