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) |