Statistics
| Branch: | Tag: | Revision:

root / snf-common / synnefo / util / units.py @ 3c98e3a5

History | View | Annotate | Download (4.2 kB)

1 44f510e1 Giorgos Korfiatis
# Copyright 2013 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 3c98e3a5 Giorgos Korfiatis
    if s in ['inf', 'infinite']:
81 3c98e3a5 Giorgos Korfiatis
        return PRACTICALLY_INFINITE, 0
82 3c98e3a5 Giorgos Korfiatis
83 44f510e1 Giorgos Korfiatis
    n, unit = _parse_number_with_unit(s)
84 44f510e1 Giorgos Korfiatis
    try:
85 44f510e1 Giorgos Korfiatis
        exponent = PARSE_EXPONENTS[unit]
86 44f510e1 Giorgos Korfiatis
    except KeyError:
87 44f510e1 Giorgos Korfiatis
        raise ParseError()
88 44f510e1 Giorgos Korfiatis
    multiplier = DEFAULT_PARSE_BASE ** exponent
89 44f510e1 Giorgos Korfiatis
    return long(n * multiplier), exponent
90 44f510e1 Giorgos Korfiatis
91 44f510e1 Giorgos Korfiatis
92 44f510e1 Giorgos Korfiatis
def parse(s):
93 44f510e1 Giorgos Korfiatis
    n, _ = parse_with_style(s)
94 44f510e1 Giorgos Korfiatis
    return n
95 44f510e1 Giorgos Korfiatis
96 44f510e1 Giorgos Korfiatis
97 44f510e1 Giorgos Korfiatis
UNITS = {
98 44f510e1 Giorgos Korfiatis
    'bytes': {
99 44f510e1 Giorgos Korfiatis
        'DISPLAY': ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
100 44f510e1 Giorgos Korfiatis
        'BASE': 1024,
101 44f510e1 Giorgos Korfiatis
    }
102 44f510e1 Giorgos Korfiatis
}
103 44f510e1 Giorgos Korfiatis
104 44f510e1 Giorgos Korfiatis
STYLE_TO_EXP = OrderedDict(
105 44f510e1 Giorgos Korfiatis
    [('b',  0),
106 44f510e1 Giorgos Korfiatis
     ('kb', 1),
107 44f510e1 Giorgos Korfiatis
     ('mb', 2),
108 44f510e1 Giorgos Korfiatis
     ('gb', 3),
109 44f510e1 Giorgos Korfiatis
     ('tb', 4),
110 44f510e1 Giorgos Korfiatis
     ('pb', 5),
111 44f510e1 Giorgos Korfiatis
     ]
112 44f510e1 Giorgos Korfiatis
)
113 44f510e1 Giorgos Korfiatis
114 44f510e1 Giorgos Korfiatis
STYLES = STYLE_TO_EXP.keys() + ['auto', 'none']
115 44f510e1 Giorgos Korfiatis
116 44f510e1 Giorgos Korfiatis
117 44f510e1 Giorgos Korfiatis
class StyleError(Exception):
118 44f510e1 Giorgos Korfiatis
    pass
119 44f510e1 Giorgos Korfiatis
120 44f510e1 Giorgos Korfiatis
121 44f510e1 Giorgos Korfiatis
def show_float(n):
122 44f510e1 Giorgos Korfiatis
    if n < 1:
123 44f510e1 Giorgos Korfiatis
        return "%.3f" % n
124 44f510e1 Giorgos Korfiatis
    if n < 10:
125 44f510e1 Giorgos Korfiatis
        return "%.2f" % n
126 44f510e1 Giorgos Korfiatis
    return "%.1f" % n
127 44f510e1 Giorgos Korfiatis
128 44f510e1 Giorgos Korfiatis
129 44f510e1 Giorgos Korfiatis
def get_exponent(style):
130 44f510e1 Giorgos Korfiatis
    if isinstance(style, (int, long)):
131 44f510e1 Giorgos Korfiatis
        if style in STYLE_TO_EXP.values():
132 44f510e1 Giorgos Korfiatis
            return style
133 44f510e1 Giorgos Korfiatis
        else:
134 44f510e1 Giorgos Korfiatis
            raise StyleError()
135 44f510e1 Giorgos Korfiatis
    else:
136 44f510e1 Giorgos Korfiatis
        try:
137 44f510e1 Giorgos Korfiatis
            return STYLE_TO_EXP[style]
138 44f510e1 Giorgos Korfiatis
        except KeyError:
139 44f510e1 Giorgos Korfiatis
            raise StyleError()
140 44f510e1 Giorgos Korfiatis
141 44f510e1 Giorgos Korfiatis
142 44f510e1 Giorgos Korfiatis
def show(n, unit, style=None):
143 3c98e3a5 Giorgos Korfiatis
    if style == 'none':
144 3c98e3a5 Giorgos Korfiatis
        return str(n)
145 3c98e3a5 Giorgos Korfiatis
146 3c98e3a5 Giorgos Korfiatis
    if n == PRACTICALLY_INFINITE:
147 3c98e3a5 Giorgos Korfiatis
        return 'inf'
148 3c98e3a5 Giorgos Korfiatis
149 44f510e1 Giorgos Korfiatis
    try:
150 44f510e1 Giorgos Korfiatis
        unit_dict = UNITS[unit]
151 44f510e1 Giorgos Korfiatis
    except KeyError:
152 44f510e1 Giorgos Korfiatis
        return str(n)
153 44f510e1 Giorgos Korfiatis
154 44f510e1 Giorgos Korfiatis
    BASE = unit_dict['BASE']
155 44f510e1 Giorgos Korfiatis
    DISPLAY = unit_dict['DISPLAY']
156 44f510e1 Giorgos Korfiatis
157 44f510e1 Giorgos Korfiatis
    if style is None or style == 'auto':
158 44f510e1 Giorgos Korfiatis
        if n < BASE:
159 44f510e1 Giorgos Korfiatis
            return "%d %s" % (n, DISPLAY[0])
160 44f510e1 Giorgos Korfiatis
        n = float(n)
161 44f510e1 Giorgos Korfiatis
        for i in DISPLAY[1:]:
162 44f510e1 Giorgos Korfiatis
            n = n / BASE
163 44f510e1 Giorgos Korfiatis
            if n < BASE:
164 44f510e1 Giorgos Korfiatis
                break
165 44f510e1 Giorgos Korfiatis
        return "%s %s" % (show_float(n), i)
166 44f510e1 Giorgos Korfiatis
167 44f510e1 Giorgos Korfiatis
    exponent = get_exponent(style)
168 44f510e1 Giorgos Korfiatis
    unit_display = DISPLAY[exponent]
169 44f510e1 Giorgos Korfiatis
    if exponent == 0:
170 44f510e1 Giorgos Korfiatis
        return "%d %s" % (n, unit_display)
171 44f510e1 Giorgos Korfiatis
172 44f510e1 Giorgos Korfiatis
    divisor = BASE ** exponent
173 44f510e1 Giorgos Korfiatis
    n = float(n)
174 44f510e1 Giorgos Korfiatis
    n = n / divisor
175 44f510e1 Giorgos Korfiatis
    return "%s %s" % (show_float(n), unit_display)