From 229d672dbb68c5e25612f744595febc60ef6e3cb Mon Sep 17 00:00:00 2001 From: "Kali Kaneko (leap communications)" Date: Sat, 4 Feb 2017 23:08:40 +0100 Subject: [feature] add bytes2human conversion --- src/leap/bitmask/vpn/_human.py | 122 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/leap/bitmask/vpn/_human.py diff --git a/src/leap/bitmask/vpn/_human.py b/src/leap/bitmask/vpn/_human.py new file mode 100644 index 00000000..1b2ba64c --- /dev/null +++ b/src/leap/bitmask/vpn/_human.py @@ -0,0 +1,122 @@ +## {{{ http://code.activestate.com/recipes/578019/ (r15) +#!/usr/bin/env python + +""" +Bytes-to-human / human-to-bytes converter. +Based on: http://goo.gl/kTQMs +Working with Python 2.x and 3.x. + +Author: Giampaolo Rodola' +License: MIT +""" + +# see: http://goo.gl/kTQMs +SYMBOLS = { + 'customary' : ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'), + 'customary_ext' : ('byte', 'kilo', 'mega', 'giga', 'tera', 'peta', 'exa', + 'zetta', 'iotta'), + 'iec' : ('Bi', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'), + 'iec_ext' : ('byte', 'kibi', 'mebi', 'gibi', 'tebi', 'pebi', 'exbi', + 'zebi', 'yobi'), +} + +def bytes2human(n, format='%(value).1f %(symbol)s', symbols='customary'): + """ + Convert n bytes into a human readable string based on format. + symbols can be either "customary", "customary_ext", "iec" or "iec_ext", + see: http://goo.gl/kTQMs + + >>> bytes2human(0) + '0.0 B' + >>> bytes2human(0.9) + '0.0 B' + >>> bytes2human(1) + '1.0 B' + >>> bytes2human(1.9) + '1.0 B' + >>> bytes2human(1024) + '1.0 K' + >>> bytes2human(1048576) + '1.0 M' + >>> bytes2human(1099511627776127398123789121) + '909.5 Y' + + >>> bytes2human(9856, symbols="customary") + '9.6 K' + >>> bytes2human(9856, symbols="customary_ext") + '9.6 kilo' + >>> bytes2human(9856, symbols="iec") + '9.6 Ki' + >>> bytes2human(9856, symbols="iec_ext") + '9.6 kibi' + + >>> bytes2human(10000, "%(value).1f %(symbol)s/sec") + '9.8 K/sec' + + >>> # precision can be adjusted by playing with %f operator + >>> bytes2human(10000, format="%(value).5f %(symbol)s") + '9.76562 K' + """ + n = int(n) + if n < 0: + raise ValueError("n < 0") + symbols = SYMBOLS[symbols] + prefix = {} + for i, s in enumerate(symbols[1:]): + prefix[s] = 1 << (i+1)*10 + for symbol in reversed(symbols[1:]): + if n >= prefix[symbol]: + value = float(n) / prefix[symbol] + return format % locals() + return format % dict(symbol=symbols[0], value=n) + +def human2bytes(s): + """ + Attempts to guess the string format based on default symbols + set and return the corresponding bytes as an integer. + When unable to recognize the format ValueError is raised. + + >>> human2bytes('0 B') + 0 + >>> human2bytes('1 K') + 1024 + >>> human2bytes('1 M') + 1048576 + >>> human2bytes('1 Gi') + 1073741824 + >>> human2bytes('1 tera') + 1099511627776 + + >>> human2bytes('0.5kilo') + 512 + >>> human2bytes('0.1 byte') + 0 + >>> human2bytes('1 k') # k is an alias for K + 1024 + >>> human2bytes('12 foo') + Traceback (most recent call last): + ... + ValueError: can't interpret '12 foo' + """ + init = s + num = "" + while s and s[0:1].isdigit() or s[0:1] == '.': + num += s[0] + s = s[1:] + num = float(num) + letter = s.strip() + for name, sset in SYMBOLS.items(): + if letter in sset: + break + else: + if letter == 'k': + # treat 'k' as an alias for 'K' as per: http://goo.gl/kTQMs + sset = SYMBOLS['customary'] + letter = letter.upper() + else: + raise ValueError("can't interpret %r" % init) + prefix = {sset[0]:1} + for i, s in enumerate(sset[1:]): + prefix[s] = 1 << (i+1)*10 + return int(num * prefix[letter]) + -- cgit v1.2.3