codekingpro/portable-devtools
114k
1# coding: utf-82"""Functions for reporting filesizes. Borrowed from https://github.com/PyFilesystem/pyfilesystem23 4The functions declared in this module should cover the different5use cases needed to generate a string representation of a file size6using several different units. Since there are many standards regarding7file size units, three different functions have been implemented.8 9See Also:10 * `Wikipedia: Binary prefix <https://en.wikipedia.org/wiki/Binary_prefix>`_11 12"""13 14__all__ = ["decimal"]15 16from typing import Iterable, List, Optional, Tuple17 18 19def _to_str(20 size: int,21 suffixes: Iterable[str],22 base: int,23 *,24 precision: Optional[int] = 1,25 separator: Optional[str] = " ",26) -> str:27 if size == 1:28 return "1 byte"29 elif size < base:30 return "{:,} bytes".format(size)31 32 for i, suffix in enumerate(suffixes, 2): # noqa: B00733 unit = base**i34 if size < unit:35 break36 return "{:,.{precision}f}{separator}{}".format(37 (base * size / unit),38 suffix,39 precision=precision,40 separator=separator,41 )42 43 44def pick_unit_and_suffix(size: int, suffixes: List[str], base: int) -> Tuple[int, str]:45 """Pick a suffix and base for the given size."""46 for i, suffix in enumerate(suffixes):47 unit = base**i48 if size < unit * base:49 break50 return unit, suffix51 52 53def decimal(54 size: int,55 *,56 precision: Optional[int] = 1,57 separator: Optional[str] = " ",58) -> str:59 """Convert a filesize in to a string (powers of 1000, SI prefixes).60 61 In this convention, ``1000 B = 1 kB``.62 63 This is typically the format used to advertise the storage64 capacity of USB flash drives and the like (*256 MB* meaning65 actually a storage capacity of more than *256 000 000 B*),66 or used by **Mac OS X** since v10.6 to report file sizes.67 68 Arguments:69 int (size): A file size.70 int (precision): The number of decimal places to include (default = 1).71 str (separator): The string to separate the value from the units (default = " ").72 73 Returns:74 `str`: A string containing a abbreviated file size and units.75 76 Example:77 >>> filesize.decimal(30000)78 '30.0 kB'79 >>> filesize.decimal(30000, precision=2, separator="")80 '30.00kB'81 82 """83 return _to_str(84 size,85 ("kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"),86 1000,87 precision=precision,88 separator=separator,89 )90 