diff --git a/sat/plugins/plugin_misc_file.py b/sat/plugins/plugin_misc_file.py index 6837d484..c553d811 100644 --- a/sat/plugins/plugin_misc_file.py +++ b/sat/plugins/plugin_misc_file.py @@ -29,6 +29,7 @@ from sat.core import exceptions from sat.tools import xml_tools from sat.tools import stream from sat.tools import utils +from sat.tools.common import utils as common_utils log = getLogger(__name__) @@ -321,9 +322,7 @@ class FilePlugin: assert filename and not "/" in filename assert PROGRESS_ID_KEY in file_data # human readable size - file_data["size_human"] = "{:.6n} Mio".format( - float(file_data["size"]) / (1024 ** 2) - ) + file_data["size_human"] = common_utils.getHumanSize(file_data["size"]) d = xml_tools.deferDialog( self.host, _(CONFIRM).format(peer=peer_jid.full(), **file_data), diff --git a/sat/tools/common/utils.py b/sat/tools/common/utils.py index e2f2853f..2345ccda 100644 --- a/sat/tools/common/utils.py +++ b/sat/tools/common/utils.py @@ -19,6 +19,42 @@ """Misc utils for both backend and frontends""" import collections.abc +size_units = { + "b": 1, + "kb": 1000, + "mb": 1000**2, + "gb": 1000**3, + "tb": 1000**4, + "pb": 1000**5, + "eb": 1000**6, + "zb": 1000**7, + "yb": 1000**8, + "o": 1, + "ko": 1000, + "mo": 1000**2, + "go": 1000**3, + "to": 1000**4, + "po": 1000**5, + "eo": 1000**6, + "zo": 1000**7, + "yo": 1000**8, + "kib": 1024, + "mib": 1024**2, + "gib": 1024**3, + "tib": 1024**4, + "pib": 1024**5, + "eib": 1024**6, + "zib": 1024**7, + "yib": 1024**8, + "kio": 1024, + "mio": 1024**2, + "gio": 1024**3, + "tio": 1024**4, + "pio": 1024**5, + "eio": 1024**6, + "zio": 1024**7, + "yio": 1024**8, +} def per_luminance(red, green, blue): @@ -73,3 +109,51 @@ class OrderedSet(collections.abc.MutableSet): def update(self, items): self._dict.update({i: None for i in items}) + + +def parseSize(size): + """Parse a file size with optional multiple symbole""" + try: + return int(size) + except ValueError: + number = [] + symbol = [] + try: + for c in size: + if c == " ": + continue + if c.isdigit(): + number.append(c) + elif c.isalpha(): + symbol.append(c) + else: + raise ValueError("unexpected char in size: {c!r} (size: {size!r})") + number = int("".join(number)) + symbol = "".join(symbol) + if symbol: + try: + multiplier = size_units[symbol.lower()] + except KeyError: + raise ValueError( + "unknown size multiplier symbole: {symbol!r} (size: {size!r})") + else: + return number * multiplier + return number + except Exception as e: + raise ValueError(f"invalid size: {e}") + + +def getSizeMultiplier(size, suffix="o"): + """Get multiplier of a file size""" + size = int(size) + #  cf. https://stackoverflow.com/a/1094933 (thanks) + for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]: + if abs(size) < 1024.0: + return size, f"{unit}{suffix}" + size /= 1024.0 + return size, f"Yi{suffix}" + + +def getHumanSize(size, suffix="o", sep=" "): + size, symbol = getSizeMultiplier(size, suffix) + return f"{size:.2f}{sep}{symbol}" diff --git a/sat_frontends/jp/cmd_file.py b/sat_frontends/jp/cmd_file.py index d4fa1b79..4420d6a7 100644 --- a/sat_frontends/jp/cmd_file.py +++ b/sat_frontends/jp/cmd_file.py @@ -30,6 +30,7 @@ from sat_frontends.jp.constants import Const as C from sat_frontends.jp import common from sat_frontends.tools import jid from sat.tools.common.ansi import ANSI as A +from sat.tools.common import utils from urllib.parse import urlparse from pathlib import Path import tempfile @@ -864,15 +865,7 @@ class ShareList(base.CommandBase): def _size_filter(self, size, row): if not size: return "" - size = int(size) - #  cf. https://stackoverflow.com/a/1094933 (thanks) - suffix = "o" - for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]: - if abs(size) < 1024.0: - return A.color(A.BOLD, "{:.2f}".format(size), unit, suffix) - size /= 1024.0 - - return A.color(A.BOLD, "{:.2f}".format(size), "Yi", suffix) + return A.color(A.BOLD, utils.getHumanSize(size)) def default_output(self, files_data): """display files a way similar to ls"""