Statistics
| Branch: | Tag: | Revision:

root / snf-common / synnefo / util / units.py @ ff5edb80

History | View | Annotate | Download (4.2 kB)

1 ff5edb80 Giorgos Korfiatis
# Copyright 2013-2014 GRNET S.A. All rights reserved.
2 44f510e1 Giorgos Korfiatis
#
3 44f510e1 Giorgos Korfiatis
# Redistribution and use in source and binary forms, with or
4 44f510e1 Giorgos Korfiatis
# without modification, are permitted provided that the following
5 44f510e1 Giorgos Korfiatis
# conditions are met:
6 44f510e1 Giorgos Korfiatis
#
7 44f510e1 Giorgos Korfiatis
#   1. Redistributions of source code must retain the above
8 44f510e1 Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
9 44f510e1 Giorgos Korfiatis
#      disclaimer.
10 44f510e1 Giorgos Korfiatis
#
11 44f510e1 Giorgos Korfiatis
#   2. Redistributions in binary form must reproduce the above
12 44f510e1 Giorgos Korfiatis
#      copyright notice, this list of conditions and the following
13 44f510e1 Giorgos Korfiatis
#      disclaimer in the documentation and/or other materials
14 44f510e1 Giorgos Korfiatis
#      provided with the distribution.
15 44f510e1 Giorgos Korfiatis
#
16 44f510e1 Giorgos Korfiatis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 44f510e1 Giorgos Korfiatis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 44f510e1 Giorgos Korfiatis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 44f510e1 Giorgos Korfiatis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 44f510e1 Giorgos Korfiatis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 44f510e1 Giorgos Korfiatis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 44f510e1 Giorgos Korfiatis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 44f510e1 Giorgos Korfiatis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 44f510e1 Giorgos Korfiatis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 44f510e1 Giorgos Korfiatis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 44f510e1 Giorgos Korfiatis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 44f510e1 Giorgos Korfiatis
# POSSIBILITY OF SUCH DAMAGE.
28 44f510e1 Giorgos Korfiatis
#
29 44f510e1 Giorgos Korfiatis
# The views and conclusions contained in the software and
30 44f510e1 Giorgos Korfiatis
# documentation are those of the authors and should not be
31 44f510e1 Giorgos Korfiatis
# interpreted as representing official policies, either expressed
32 44f510e1 Giorgos Korfiatis
# or implied, of GRNET S.A.
33 44f510e1 Giorgos Korfiatis
34 44f510e1 Giorgos Korfiatis
from synnefo.lib.ordereddict import OrderedDict
35 44f510e1 Giorgos Korfiatis
import re
36 44f510e1 Giorgos Korfiatis
37 3c98e3a5 Giorgos Korfiatis
PRACTICALLY_INFINITE = 2**63 - 1
38 44f510e1 Giorgos Korfiatis
DEFAULT_PARSE_BASE = 1024
39 44f510e1 Giorgos Korfiatis
PARSE_EXPONENTS = {
40 44f510e1 Giorgos Korfiatis
    '':      0,
41 44f510e1 Giorgos Korfiatis
    'bytes': 0,
42 44f510e1 Giorgos Korfiatis
    'K':     1,
43 44f510e1 Giorgos Korfiatis
    'KB':    1,
44 44f510e1 Giorgos Korfiatis
    'KIB':   1,
45 44f510e1 Giorgos Korfiatis
    'M':     2,
46 44f510e1 Giorgos Korfiatis
    'MB':    2,
47 44f510e1 Giorgos Korfiatis
    'MIB':   2,
48 44f510e1 Giorgos Korfiatis
    'G':     3,
49 44f510e1 Giorgos Korfiatis
    'GB':    3,
50 44f510e1 Giorgos Korfiatis
    'GIB':   3,
51 44f510e1 Giorgos Korfiatis
    'T':     4,
52 44f510e1 Giorgos Korfiatis
    'TB':    4,
53 44f510e1 Giorgos Korfiatis
    'TIB':   4,
54 44f510e1 Giorgos Korfiatis
    'P':     5,
55 44f510e1 Giorgos Korfiatis
    'PB':    5,
56 44f510e1 Giorgos Korfiatis
    'PIB':   5,
57 44f510e1 Giorgos Korfiatis
}
58 44f510e1 Giorgos Korfiatis
59 44f510e1 Giorgos Korfiatis
_MATCHER = re.compile('^(\d+\.?\d*)(.*)$')
60 44f510e1 Giorgos Korfiatis
61 44f510e1 Giorgos Korfiatis
62 44f510e1 Giorgos Korfiatis
class ParseError(Exception):
63 44f510e1 Giorgos Korfiatis
    pass
64 44f510e1 Giorgos Korfiatis
65 44f510e1 Giorgos Korfiatis
66 44f510e1 Giorgos Korfiatis
def _parse_number_with_unit(s):
67 44f510e1 Giorgos Korfiatis
    match = _MATCHER.match(s)
68 44f510e1 Giorgos Korfiatis
    if not match:
69 44f510e1 Giorgos Korfiatis
        raise ParseError()
70 44f510e1 Giorgos Korfiatis
    number, unit = match.groups()
71 44f510e1 Giorgos Korfiatis
    try:
72 44f510e1 Giorgos Korfiatis
        number = long(number)
73 44f510e1 Giorgos Korfiatis
    except ValueError:
74 44f510e1 Giorgos Korfiatis
        number = float(number)
75 44f510e1 Giorgos Korfiatis
76 44f510e1 Giorgos Korfiatis
    return number, unit.strip().upper()
77 44f510e1 Giorgos Korfiatis
78 44f510e1 Giorgos Korfiatis
79 44f510e1 Giorgos Korfiatis
def parse_with_style(s):
80 362dadaa Giorgos Korfiatis
    if isinstance(s, (int, long)):
81 362dadaa Giorgos Korfiatis
        return s, 0
82 362dadaa Giorgos Korfiatis
83 3c98e3a5 Giorgos Korfiatis
    if s in ['inf', 'infinite']:
84 3c98e3a5 Giorgos Korfiatis
        return PRACTICALLY_INFINITE, 0
85 3c98e3a5 Giorgos Korfiatis
86 44f510e1 Giorgos Korfiatis
    n, unit = _parse_number_with_unit(s)
87 44f510e1 Giorgos Korfiatis
    try:
88 44f510e1 Giorgos Korfiatis
        exponent = PARSE_EXPONENTS[unit]
89 44f510e1 Giorgos Korfiatis
    except KeyError:
90 44f510e1 Giorgos Korfiatis
        raise ParseError()
91 44f510e1 Giorgos Korfiatis
    multiplier = DEFAULT_PARSE_BASE ** exponent
92 44f510e1 Giorgos Korfiatis
    return long(n * multiplier), exponent
93 44f510e1 Giorgos Korfiatis
94 44f510e1 Giorgos Korfiatis
95 44f510e1 Giorgos Korfiatis
def parse(s):
96 44f510e1 Giorgos Korfiatis
    n, _ = parse_with_style(s)
97 44f510e1 Giorgos Korfiatis
    return n
98 44f510e1 Giorgos Korfiatis
99 44f510e1 Giorgos Korfiatis
100 44f510e1 Giorgos Korfiatis
UNITS = {
101 44f510e1 Giorgos Korfiatis
    'bytes': {
102 44f510e1 Giorgos Korfiatis
        'DISPLAY': ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
103 44f510e1 Giorgos Korfiatis
        'BASE': 1024,
104 44f510e1 Giorgos Korfiatis
    }
105 44f510e1 Giorgos Korfiatis
}
106 44f510e1 Giorgos Korfiatis
107 44f510e1 Giorgos Korfiatis
STYLE_TO_EXP = OrderedDict(
108 44f510e1 Giorgos Korfiatis
    [('b',  0),
109 44f510e1 Giorgos Korfiatis
     ('kb', 1),
110 44f510e1 Giorgos Korfiatis
     ('mb', 2),
111 44f510e1 Giorgos Korfiatis
     ('gb', 3),
112 44f510e1 Giorgos Korfiatis
     ('tb', 4),
113 44f510e1 Giorgos Korfiatis
     ('pb', 5),
114 44f510e1 Giorgos Korfiatis
     ]
115 44f510e1 Giorgos Korfiatis
)
116 44f510e1 Giorgos Korfiatis
117 44f510e1 Giorgos Korfiatis
STYLES = STYLE_TO_EXP.keys() + ['auto', 'none']
118 44f510e1 Giorgos Korfiatis
119 44f510e1 Giorgos Korfiatis
120 44f510e1 Giorgos Korfiatis
class StyleError(Exception):
121 44f510e1 Giorgos Korfiatis
    pass
122 44f510e1 Giorgos Korfiatis
123 44f510e1 Giorgos Korfiatis
124 44f510e1 Giorgos Korfiatis
def show_float(n):
125 44f510e1 Giorgos Korfiatis
    if n < 1:
126 44f510e1 Giorgos Korfiatis
        return "%.3f" % n
127 44f510e1 Giorgos Korfiatis
    if n < 10:
128 44f510e1 Giorgos Korfiatis
        return "%.2f" % n
129 44f510e1 Giorgos Korfiatis
    return "%.1f" % n
130 44f510e1 Giorgos Korfiatis
131 44f510e1 Giorgos Korfiatis
132 44f510e1 Giorgos Korfiatis
def get_exponent(style):
133 44f510e1 Giorgos Korfiatis
    if isinstance(style, (int, long)):
134 44f510e1 Giorgos Korfiatis
        if style in STYLE_TO_EXP.values():
135 44f510e1 Giorgos Korfiatis
            return style
136 44f510e1 Giorgos Korfiatis
        else:
137 44f510e1 Giorgos Korfiatis
            raise StyleError()
138 44f510e1 Giorgos Korfiatis
    else:
139 44f510e1 Giorgos Korfiatis
        try:
140 44f510e1 Giorgos Korfiatis
            return STYLE_TO_EXP[style]
141 44f510e1 Giorgos Korfiatis
        except KeyError:
142 44f510e1 Giorgos Korfiatis
            raise StyleError()
143 44f510e1 Giorgos Korfiatis
144 44f510e1 Giorgos Korfiatis
145 44f510e1 Giorgos Korfiatis
def show(n, unit, style=None):
146 3c98e3a5 Giorgos Korfiatis
    if style == 'none':
147 3c98e3a5 Giorgos Korfiatis
        return str(n)
148 3c98e3a5 Giorgos Korfiatis
149 3c98e3a5 Giorgos Korfiatis
    if n == PRACTICALLY_INFINITE:
150 3c98e3a5 Giorgos Korfiatis
        return 'inf'
151 3c98e3a5 Giorgos Korfiatis
152 44f510e1 Giorgos Korfiatis
    try:
153 44f510e1 Giorgos Korfiatis
        unit_dict = UNITS[unit]
154 44f510e1 Giorgos Korfiatis
    except KeyError:
155 44f510e1 Giorgos Korfiatis
        return str(n)
156 44f510e1 Giorgos Korfiatis
157 44f510e1 Giorgos Korfiatis
    BASE = unit_dict['BASE']
158 44f510e1 Giorgos Korfiatis
    DISPLAY = unit_dict['DISPLAY']
159 44f510e1 Giorgos Korfiatis
160 44f510e1 Giorgos Korfiatis
    if style is None or style == 'auto':
161 44f510e1 Giorgos Korfiatis
        if n < BASE:
162 44f510e1 Giorgos Korfiatis
            return "%d %s" % (n, DISPLAY[0])
163 44f510e1 Giorgos Korfiatis
        n = float(n)
164 44f510e1 Giorgos Korfiatis
        for i in DISPLAY[1:]:
165 44f510e1 Giorgos Korfiatis
            n = n / BASE
166 44f510e1 Giorgos Korfiatis
            if n < BASE:
167 44f510e1 Giorgos Korfiatis
                break
168 44f510e1 Giorgos Korfiatis
        return "%s %s" % (show_float(n), i)
169 44f510e1 Giorgos Korfiatis
170 44f510e1 Giorgos Korfiatis
    exponent = get_exponent(style)
171 44f510e1 Giorgos Korfiatis
    unit_display = DISPLAY[exponent]
172 44f510e1 Giorgos Korfiatis
    if exponent == 0:
173 44f510e1 Giorgos Korfiatis
        return "%d %s" % (n, unit_display)
174 44f510e1 Giorgos Korfiatis
175 44f510e1 Giorgos Korfiatis
    divisor = BASE ** exponent
176 44f510e1 Giorgos Korfiatis
    n = float(n)
177 44f510e1 Giorgos Korfiatis
    n = n / divisor
178 44f510e1 Giorgos Korfiatis
    return "%s %s" % (show_float(n), unit_display)