diff options
| author | 2021-10-05 23:30:05 -0400 | |
|---|---|---|
| committer | 2021-10-05 23:30:05 -0400 | |
| commit | 34ba2951b8c523713425c98addb9256ea05c946f (patch) | |
| tree | 6ec7e96d0c6e6f6e94b6b97ecd8c0a414ceef93d /gallery_dl/output.py | |
| parent | 3f5483df9075ae526f4c54f4cbe80edeabf6d4cc (diff) | |
New upstream version 1.19.0.upstream/1.19.0
Diffstat (limited to 'gallery_dl/output.py')
| -rw-r--r-- | gallery_dl/output.py | 89 |
1 files changed, 73 insertions, 16 deletions
diff --git a/gallery_dl/output.py b/gallery_dl/output.py index 7e1f8c1..d4d295f 100644 --- a/gallery_dl/output.py +++ b/gallery_dl/output.py @@ -10,7 +10,8 @@ import os import sys import shutil import logging -from . import config, util +import unicodedata +from . import config, util, formatter # -------------------------------------------------------------------- @@ -91,13 +92,13 @@ class Formatter(logging.Formatter): if isinstance(fmt, dict): for key in ("debug", "info", "warning", "error"): value = fmt[key] if key in fmt else LOG_FORMAT - fmt[key] = (util.Formatter(value).format_map, + fmt[key] = (formatter.parse(value).format_map, "{asctime" in value) else: if fmt == LOG_FORMAT: fmt = (fmt.format_map, False) else: - fmt = (util.Formatter(fmt).format_map, "{asctime" in fmt) + fmt = (formatter.parse(fmt).format_map, "{asctime" in fmt) fmt = {"debug": fmt, "info": fmt, "warning": fmt, "error": fmt} self.formats = fmt @@ -257,6 +258,9 @@ class NullOutput(): def success(self, path, tries): """Print a message indicating the completion of a download""" + def progress(self, bytes_total, bytes_downloaded, bytes_per_second): + """Display download progress""" + class PipeOutput(NullOutput): @@ -270,9 +274,14 @@ class PipeOutput(NullOutput): class TerminalOutput(NullOutput): def __init__(self): - self.short = config.get(("output",), "shorten", True) - if self.short: - self.width = shutil.get_terminal_size().columns - OFFSET + shorten = config.get(("output",), "shorten", True) + if shorten: + func = shorten_string_eaw if shorten == "eaw" else shorten_string + limit = shutil.get_terminal_size().columns - OFFSET + sep = CHAR_ELLIPSIES + self.shorten = lambda txt: func(txt, limit, sep) + else: + self.shorten = util.identity def start(self, path): print(self.shorten(" " + path), end="", flush=True) @@ -283,16 +292,14 @@ class TerminalOutput(NullOutput): def success(self, path, tries): print("\r", self.shorten(CHAR_SUCCESS + path), sep="") - def shorten(self, txt): - """Reduce the length of 'txt' to the width of the terminal""" - if self.short and len(txt) > self.width: - hwidth = self.width // 2 - OFFSET - return "".join(( - txt[:hwidth-1], - CHAR_ELLIPSIES, - txt[-hwidth-(self.width % 2):] - )) - return txt + def progress(self, bytes_total, bytes_downloaded, bytes_per_second): + bdl = util.format_value(bytes_downloaded) + bps = util.format_value(bytes_per_second) + if bytes_total is None: + print("\r{:>7}B {:>7}B/s ".format(bdl, bps), end="") + else: + print("\r{:>3}% {:>7}B {:>7}B/s ".format( + bytes_downloaded * 100 // bytes_total, bdl, bps), end="") class ColorOutput(TerminalOutput): @@ -307,6 +314,56 @@ class ColorOutput(TerminalOutput): print("\r\033[1;32m", self.shorten(path), "\033[0m", sep="") +class EAWCache(dict): + + def __missing__(self, key): + width = self[key] = \ + 2 if unicodedata.east_asian_width(key) in "WF" else 1 + return width + + +def shorten_string(txt, limit, sep="…"): + """Limit width of 'txt'; assume all characters have a width of 1""" + if len(txt) <= limit: + return txt + limit -= len(sep) + return txt[:limit // 2] + sep + txt[-((limit+1) // 2):] + + +def shorten_string_eaw(txt, limit, sep="…", cache=EAWCache()): + """Limit width of 'txt'; check for east-asian characters with width > 1""" + char_widths = [cache[c] for c in txt] + text_width = sum(char_widths) + + if text_width <= limit: + # no shortening required + return txt + + limit -= len(sep) + if text_width == len(txt): + # all characters have a width of 1 + return txt[:limit // 2] + sep + txt[-((limit+1) // 2):] + + # wide characters + left = 0 + lwidth = limit // 2 + while True: + lwidth -= char_widths[left] + if lwidth < 0: + break + left += 1 + + right = -1 + rwidth = (limit+1) // 2 + (lwidth + char_widths[left]) + while True: + rwidth -= char_widths[right] + if rwidth < 0: + break + right -= 1 + + return txt[:left] + sep + txt[right+1:] + + if util.WINDOWS: ANSI = os.environ.get("TERM") == "ANSI" OFFSET = 1 |
