1import locale 2from natural.constant import FILESIZE_SUFFIX 3from natural.number import _format 4 5FILESIZE_BASE = dict( 6 decimal=1024, 7 binary=1000, 8 gnu=1024, 9) 10 11 12def filesize(value, format='decimal', digits=2): 13 ''' 14 Convert a file size into natural readable format. Multiple formats are 15 supported. 16 17 :param value: size 18 :param format: default ``decimal``, choices ``binary``, ``decimal`` or 19 ``gnu`` 20 :param digits: default ``2`` 21 22 >>> filesize(123) 23 '123.00 B' 24 >>> filesize(123456) 25 '120.56 kB' 26 >>> filesize(1234567890) 27 '1.15 GB' 28 ''' 29 30 if format not in FILESIZE_SUFFIX: 31 raise TypeError 32 33 base = FILESIZE_BASE[format] 34 size = int(value) 35 sign = size < 0 and u'-' or '' 36 size = abs(size) 37 38 for i, suffix in enumerate(FILESIZE_SUFFIX[format]): 39 unit = base ** (i + 1) 40 if size < unit: 41 result = u''.join([ 42 sign, 43 _format(base * size / float(unit), digits), 44 u' ', 45 suffix, 46 ]) 47 if format == 'gnu': 48 result = result.replace(' ', '') 49 return result 50 51 raise OverflowError 52 53 54def decimalsize(value): 55 ''' 56 Wrapper for :py:func:`filesize`. 57 58 >>> decimalsize(123) 59 '123.00 B' 60 >>> decimalsize(123456) 61 '120.56 kB' 62 >>> decimalsize(1234567890) 63 '1.15 GB' 64 ''' 65 return filesize(value, format='decimal') 66 67 68def binarysize(value): 69 ''' 70 Wrapper for :py:func:`filesize`. 71 72 >>> binarysize(123) 73 '123.00 iB' 74 >>> binarysize(123456) 75 '123.46 KiB' 76 >>> binarysize(1234567890) 77 '1.23 GiB' 78 ''' 79 return filesize(value, format='binary') 80 81 82def gnusize(value, digits=1): 83 ''' 84 Wrapper for :py:func:`filesize`. 85 86 >>> gnusize(123) 87 '123.0B' 88 >>> gnusize(123456) 89 '120.6K' 90 >>> gnusize(1234567890) 91 '1.1G' 92 ''' 93 return filesize(value, format='gnu', digits=digits) 94