tools (common/utils): new methods to parse and generate file size with symbols:

- `parseSize` lets parse a size which can be either a int, or a string with a symbol like
  `Mio`
- `getSizeMultiplier` returns a tuple of size with it's multiplier symbol
- `getHumanSize` returns a string with size and adapted multiplier.
This commit is contained in:
Goffi 2021-05-05 15:37:33 +02:00
commit 4e36667134

View file

@ -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}"