51 lines
1.3 KiB
Python
51 lines
1.3 KiB
Python
import os
|
|
from pathlib import Path
|
|
|
|
|
|
_size_quantifiers = "BKMGTP"
|
|
_size_map: "dict[str, int]" = {
|
|
_size_quantifiers[i]: 2 ** (10 * i) for i in range(len(_size_quantifiers))
|
|
}
|
|
|
|
|
|
def size_for_display(byte_count: int, precision: int = 2, format="short") -> str:
|
|
for qtf in reversed(_size_quantifiers):
|
|
qty = byte_count / _size_map[qtf]
|
|
if qty > 1:
|
|
break
|
|
|
|
size = f"{qty:.{precision}f}"
|
|
if format == "compact":
|
|
size = size.replace("." + "0" * precision, "") # silly hack to remove
|
|
return f"{size:>{4+precision}}{qtf}"
|
|
|
|
tpl = "{{:.{precision}f}} {{}}".format(precision=precision)
|
|
if format == "short":
|
|
pass
|
|
elif format == "long" and qtf != "B":
|
|
tpl += "iB"
|
|
return tpl.format(qty, qtf)
|
|
|
|
|
|
def parse_size(size: str) -> int:
|
|
"""Return the given size converted to byte count.
|
|
|
|
Supported are
|
|
|
|
- plain byte count, e.g. "12345"
|
|
- short format, e.g. "123.45K"
|
|
|
|
not supported: Kb = kBit, KB = kByte, KB = 10**3 B, KiB = 2**10 B
|
|
"""
|
|
if size.isdigit():
|
|
return int(size)
|
|
|
|
d, q = float(size[:-1]), size[-1]
|
|
return int(d * _size_map[q])
|
|
|
|
|
|
def abspath(path: Path) -> Path:
|
|
"""Normalize & make the given path absolute while maintaining symlinks.
|
|
|
|
Similar to Path.resolve(strict=False), but doesn't resolve symlinks."""
|
|
return Path(os.path.abspath(path))
|