Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils / __init__.py @ 58602137

History | View | Annotate | Download (14.2 kB)

1 e3f01d64 Stavros Sachtouris
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 7493ccb6 Stavros Sachtouris
#
3 7493ccb6 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 7493ccb6 Stavros Sachtouris
# without modification, are permitted provided that the following
5 7493ccb6 Stavros Sachtouris
# conditions are met:
6 7493ccb6 Stavros Sachtouris
#
7 7493ccb6 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 7493ccb6 Stavros Sachtouris
#      disclaimer.
10 7493ccb6 Stavros Sachtouris
#
11 7493ccb6 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 7493ccb6 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 7493ccb6 Stavros Sachtouris
#      provided with the distribution.
15 7493ccb6 Stavros Sachtouris
#
16 7493ccb6 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 7493ccb6 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 7493ccb6 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 7493ccb6 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 7493ccb6 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 7493ccb6 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 7493ccb6 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 7493ccb6 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 7493ccb6 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 7493ccb6 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 7493ccb6 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 7493ccb6 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 7493ccb6 Stavros Sachtouris
#
29 7493ccb6 Stavros Sachtouris
# The views and conclusions contained in the software and
30 7493ccb6 Stavros Sachtouris
# documentation are those of the authors and should not be
31 7493ccb6 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 7493ccb6 Stavros Sachtouris
# or implied, of GRNET S.A.
33 3dabe5d2 Stavros Sachtouris
34 fa9c0c38 Stavros Sachtouris
from sys import stdout, stdin
35 efbcdc41 Stavros Sachtouris
from re import compile as regex_compile
36 14b25e00 Stavros Sachtouris
from os import walk, path
37 0399ac7e Stavros Sachtouris
from json import dumps
38 02846a75 Stavros Sachtouris
39 2ff0b7bd Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError
40 3dabe5d2 Stavros Sachtouris
41 f55d3a15 Stavros Sachtouris
42 a0608786 Stavros Sachtouris
INDENT_TAB = 4
43 f55d3a15 Stavros Sachtouris
44 f55d3a15 Stavros Sachtouris
45 362adf50 Stavros Sachtouris
suggest = dict(ansicolors=dict(
46 6fb4af77 Stavros Sachtouris
        active=False,
47 6fb4af77 Stavros Sachtouris
        url='#install-ansicolors-progress',
48 362adf50 Stavros Sachtouris
        description='Add colors to console responses'))
49 6fb4af77 Stavros Sachtouris
50 dfee2caf Stavros Sachtouris
try:
51 dfee2caf Stavros Sachtouris
    from colors import magenta, red, yellow, bold
52 dfee2caf Stavros Sachtouris
except ImportError:
53 f93854ae Stavros Sachtouris
    def dummy(val):
54 dfee2caf Stavros Sachtouris
        return val
55 f93854ae Stavros Sachtouris
    red = yellow = magenta = bold = dummy
56 6fb4af77 Stavros Sachtouris
    suggest['ansicolors']['active'] = True
57 6fb4af77 Stavros Sachtouris
58 6fb4af77 Stavros Sachtouris
59 69691087 Stavros Sachtouris
def suggest_missing(miss=None, exclude=[]):
60 6fb4af77 Stavros Sachtouris
    global suggest
61 69691087 Stavros Sachtouris
    sgs = dict(suggest)
62 69691087 Stavros Sachtouris
    for exc in exclude:
63 69691087 Stavros Sachtouris
        try:
64 69691087 Stavros Sachtouris
            sgs.pop(exc)
65 69691087 Stavros Sachtouris
        except KeyError:
66 69691087 Stavros Sachtouris
            pass
67 6fb4af77 Stavros Sachtouris
    kamaki_docs = 'http://www.synnefo.org/docs/kamaki/latest'
68 69691087 Stavros Sachtouris
    for k, v in (miss, sgs[miss]) if miss else sgs.items():
69 6fb4af77 Stavros Sachtouris
        if v['active'] and stdout.isatty():
70 6fb4af77 Stavros Sachtouris
            print('Suggestion: for better user experience install %s' % k)
71 6fb4af77 Stavros Sachtouris
            print('\t%s' % v['description'])
72 6fb4af77 Stavros Sachtouris
            print('\tIt is easy, here are the instructions:')
73 6fb4af77 Stavros Sachtouris
            print('\t%s/installation.html%s' % (kamaki_docs, v['url']))
74 6fb4af77 Stavros Sachtouris
            print('')
75 f997679d Stavros Sachtouris
76 fd5db045 Stavros Sachtouris
77 f8426b5c Stavros Sachtouris
def guess_mime_type(
78 f8426b5c Stavros Sachtouris
        filename,
79 f8426b5c Stavros Sachtouris
        default_content_type='application/octet-stream',
80 f8426b5c Stavros Sachtouris
        default_encoding=None):
81 f8426b5c Stavros Sachtouris
    assert filename, 'Cannot guess mimetype for empty filename'
82 f8426b5c Stavros Sachtouris
    try:
83 f8426b5c Stavros Sachtouris
        from mimetypes import guess_type
84 f8426b5c Stavros Sachtouris
        ctype, cenc = guess_type(filename)
85 f8426b5c Stavros Sachtouris
        return ctype or default_content_type, cenc or default_encoding
86 f8426b5c Stavros Sachtouris
    except ImportError:
87 f8426b5c Stavros Sachtouris
        print 'WARNING: Cannot import mimetypes, using defaults'
88 f8426b5c Stavros Sachtouris
        return (default_content_type, default_encoding)
89 f8426b5c Stavros Sachtouris
90 f8426b5c Stavros Sachtouris
91 67cea04c Stavros Sachtouris
def remove_colors():
92 67cea04c Stavros Sachtouris
    global bold
93 3dabe5d2 Stavros Sachtouris
    global red
94 3dabe5d2 Stavros Sachtouris
    global yellow
95 3dabe5d2 Stavros Sachtouris
    global magenta
96 fd5db045 Stavros Sachtouris
97 67cea04c Stavros Sachtouris
    def dummy(val):
98 67cea04c Stavros Sachtouris
        return val
99 3dabe5d2 Stavros Sachtouris
    red = yellow = magenta = bold = dummy
100 7493ccb6 Stavros Sachtouris
101 fd5db045 Stavros Sachtouris
102 cdeadadc Stavros Sachtouris
def pretty_keys(d, delim='_', recursive=False):
103 cdeadadc Stavros Sachtouris
    """<term>delim<term> to <term> <term> transformation"""
104 cdeadadc Stavros Sachtouris
    new_d = dict(d)
105 cdeadadc Stavros Sachtouris
    for k, v in d.items():
106 cdeadadc Stavros Sachtouris
        new_v = new_d.pop(k)
107 cdeadadc Stavros Sachtouris
        new_d[k.replace(delim, ' ').strip()] = pretty_keys(
108 cdeadadc Stavros Sachtouris
            new_v, delim, True) if (
109 cdeadadc Stavros Sachtouris
                recursive and isinstance(v, dict)) else new_v
110 7493ccb6 Stavros Sachtouris
    return new_d
111 7493ccb6 Stavros Sachtouris
112 fd5db045 Stavros Sachtouris
113 fa9c0c38 Stavros Sachtouris
def print_json(data, out=stdout):
114 0399ac7e Stavros Sachtouris
    """Print a list or dict as json in console
115 0399ac7e Stavros Sachtouris

116 0399ac7e Stavros Sachtouris
    :param data: json-dumpable data
117 0399ac7e Stavros Sachtouris

118 fa9c0c38 Stavros Sachtouris
    :param out: Input/Output stream to dump values into
119 fa9c0c38 Stavros Sachtouris
    """
120 6acfcec4 Stavros Sachtouris
    out.write(unicode(dumps(data, indent=INDENT_TAB) + '\n'))
121 6acfcec4 Stavros Sachtouris
    out.flush()
122 545c6c29 Stavros Sachtouris
123 545c6c29 Stavros Sachtouris
124 de73876b Stavros Sachtouris
def print_dict(
125 f55d3a15 Stavros Sachtouris
        d,
126 f55d3a15 Stavros Sachtouris
        exclude=(), indent=0,
127 fa9c0c38 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False, out=stdout):
128 f55d3a15 Stavros Sachtouris
    """Pretty-print a dictionary object
129 f55d3a15 Stavros Sachtouris
    <indent>key: <non iterable item>
130 f55d3a15 Stavros Sachtouris
    <indent>key:
131 a0608786 Stavros Sachtouris
    <indent + INDENT_TAB><pretty-print iterable>
132 f8681ec8 Stavros Sachtouris

133 f55d3a15 Stavros Sachtouris
    :param d: (dict)
134 f8681ec8 Stavros Sachtouris

135 f55d3a15 Stavros Sachtouris
    :param exclude: (iterable of strings) keys to exclude from printing
136 f8681ec8 Stavros Sachtouris

137 f55d3a15 Stavros Sachtouris
    :param indent: (int) initial indentation (recursive)
138 f8681ec8 Stavros Sachtouris

139 f55d3a15 Stavros Sachtouris
    :param with_enumeration: (bool) enumerate 1st-level keys
140 f8681ec8 Stavros Sachtouris

141 f55d3a15 Stavros Sachtouris
    :param recursive_enumeration: (bool) recursively enumerate iterables (does
142 f55d3a15 Stavros Sachtouris
        not enumerate 1st level keys)
143 f8681ec8 Stavros Sachtouris

144 fa9c0c38 Stavros Sachtouris
    :param out: Input/Output stream to dump values into
145 fa9c0c38 Stavros Sachtouris

146 f55d3a15 Stavros Sachtouris
    :raises CLIError: if preconditions fail
147 f8681ec8 Stavros Sachtouris
    """
148 f55d3a15 Stavros Sachtouris
    assert isinstance(d, dict), 'print_dict input must be a dict'
149 f55d3a15 Stavros Sachtouris
    assert indent >= 0, 'print_dict indent must be >= 0'
150 7493ccb6 Stavros Sachtouris
151 f55d3a15 Stavros Sachtouris
    for i, (k, v) in enumerate(d.items()):
152 f55d3a15 Stavros Sachtouris
        k = ('%s' % k).strip()
153 f55d3a15 Stavros Sachtouris
        if k in exclude:
154 7493ccb6 Stavros Sachtouris
            continue
155 fa9c0c38 Stavros Sachtouris
        print_str = u' ' * indent
156 fa9c0c38 Stavros Sachtouris
        print_str += u'%s.' % (i + 1) if with_enumeration else u''
157 fa9c0c38 Stavros Sachtouris
        print_str += u'%s:' % k
158 f55d3a15 Stavros Sachtouris
        if isinstance(v, dict):
159 6acfcec4 Stavros Sachtouris
            out.write(print_str + '\n')
160 de73876b Stavros Sachtouris
            print_dict(
161 a0608786 Stavros Sachtouris
                v, exclude, indent + INDENT_TAB,
162 fa9c0c38 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration, out)
163 f55d3a15 Stavros Sachtouris
        elif isinstance(v, list) or isinstance(v, tuple):
164 6acfcec4 Stavros Sachtouris
            out.write(print_str + '\n')
165 de73876b Stavros Sachtouris
            print_list(
166 a0608786 Stavros Sachtouris
                v, exclude, indent + INDENT_TAB,
167 fa9c0c38 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration, out)
168 7493ccb6 Stavros Sachtouris
        else:
169 6acfcec4 Stavros Sachtouris
            out.write(u'%s %s\n' % (print_str, v))
170 6acfcec4 Stavros Sachtouris
        out.flush()
171 fd5db045 Stavros Sachtouris
172 7493ccb6 Stavros Sachtouris
173 de73876b Stavros Sachtouris
def print_list(
174 f55d3a15 Stavros Sachtouris
        l,
175 f55d3a15 Stavros Sachtouris
        exclude=(), indent=0,
176 fa9c0c38 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False, out=stdout):
177 f55d3a15 Stavros Sachtouris
    """Pretty-print a list of items
178 f55d3a15 Stavros Sachtouris
    <indent>key: <non iterable item>
179 f55d3a15 Stavros Sachtouris
    <indent>key:
180 a0608786 Stavros Sachtouris
    <indent + INDENT_TAB><pretty-print iterable>
181 f8681ec8 Stavros Sachtouris

182 f55d3a15 Stavros Sachtouris
    :param l: (list)
183 f8681ec8 Stavros Sachtouris

184 f55d3a15 Stavros Sachtouris
    :param exclude: (iterable of strings) items to exclude from printing
185 f8681ec8 Stavros Sachtouris

186 f55d3a15 Stavros Sachtouris
    :param indent: (int) initial indentation (recursive)
187 f8681ec8 Stavros Sachtouris

188 f55d3a15 Stavros Sachtouris
    :param with_enumeration: (bool) enumerate 1st-level items
189 f8681ec8 Stavros Sachtouris

190 f55d3a15 Stavros Sachtouris
    :param recursive_enumeration: (bool) recursively enumerate iterables (does
191 f55d3a15 Stavros Sachtouris
        not enumerate 1st level keys)
192 f8681ec8 Stavros Sachtouris

193 fa9c0c38 Stavros Sachtouris
    :param out: Input/Output stream to dump values into
194 fa9c0c38 Stavros Sachtouris

195 f55d3a15 Stavros Sachtouris
    :raises CLIError: if preconditions fail
196 f8681ec8 Stavros Sachtouris
    """
197 f55d3a15 Stavros Sachtouris
    assert isinstance(l, list) or isinstance(l, tuple), (
198 f55d3a15 Stavros Sachtouris
        'print_list prinbts a list or tuple')
199 f55d3a15 Stavros Sachtouris
    assert indent >= 0, 'print_list indent must be >= 0'
200 f551841a Stavros Sachtouris
201 f55d3a15 Stavros Sachtouris
    for i, item in enumerate(l):
202 fa9c0c38 Stavros Sachtouris
        print_str = u' ' * indent
203 fa9c0c38 Stavros Sachtouris
        print_str += u'%s.' % (i + 1) if with_enumeration else u''
204 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
205 c17b8bc0 Stavros Sachtouris
            if with_enumeration:
206 6acfcec4 Stavros Sachtouris
                out.write(print_str + '\n')
207 0f383dcc Stavros Sachtouris
            elif i and i < len(l):
208 6acfcec4 Stavros Sachtouris
                out.write(u'\n')
209 de73876b Stavros Sachtouris
            print_dict(
210 a0608786 Stavros Sachtouris
                item, exclude,
211 a0608786 Stavros Sachtouris
                indent + (INDENT_TAB if with_enumeration else 0),
212 fa9c0c38 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration, out)
213 f55d3a15 Stavros Sachtouris
        elif isinstance(item, list) or isinstance(item, tuple):
214 c17b8bc0 Stavros Sachtouris
            if with_enumeration:
215 6acfcec4 Stavros Sachtouris
                out.write(print_str + '\n')
216 0f383dcc Stavros Sachtouris
            elif i and i < len(l):
217 6acfcec4 Stavros Sachtouris
                out.write(u'\n')
218 de73876b Stavros Sachtouris
            print_list(
219 a0608786 Stavros Sachtouris
                item, exclude, indent + INDENT_TAB,
220 fa9c0c38 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration, out)
221 7493ccb6 Stavros Sachtouris
        else:
222 f55d3a15 Stavros Sachtouris
            item = ('%s' % item).strip()
223 f55d3a15 Stavros Sachtouris
            if item in exclude:
224 f55d3a15 Stavros Sachtouris
                continue
225 c49188b7 Stavros Sachtouris
            out.write(u'%s%s\n' % (print_str, item))
226 6acfcec4 Stavros Sachtouris
        out.flush()
227 6acfcec4 Stavros Sachtouris
    out.flush()
228 439826ec Stavros Sachtouris
229 439826ec Stavros Sachtouris
230 de73876b Stavros Sachtouris
def print_items(
231 24ff0a35 Stavros Sachtouris
        items, title=('id', 'name'),
232 fa9c0c38 Stavros Sachtouris
        with_enumeration=False, with_redundancy=False, out=stdout):
233 a494a741 Stavros Sachtouris
    """print dict or list items in a list, using some values as title
234 a494a741 Stavros Sachtouris
    Objects of next level don't inherit enumeration (default: off) or titles
235 a494a741 Stavros Sachtouris

236 a494a741 Stavros Sachtouris
    :param items: (list) items are lists or dict
237 f55d3a15 Stavros Sachtouris

238 a494a741 Stavros Sachtouris
    :param title: (tuple) keys to use their values as title
239 f55d3a15 Stavros Sachtouris

240 a494a741 Stavros Sachtouris
    :param with_enumeration: (boolean) enumerate items (order id on title)
241 f55d3a15 Stavros Sachtouris

242 a494a741 Stavros Sachtouris
    :param with_redundancy: (boolean) values in title also appear on body
243 f55d3a15 Stavros Sachtouris

244 fa9c0c38 Stavros Sachtouris
    :param out: Input/Output stream to dump values into
245 a494a741 Stavros Sachtouris
    """
246 daedfe3c Stavros Sachtouris
    if not items:
247 daedfe3c Stavros Sachtouris
        return
248 46d130c9 Stavros Sachtouris
    if not (isinstance(items, dict) or isinstance(items, list) or isinstance(
249 46d130c9 Stavros Sachtouris
                items, tuple)):
250 6acfcec4 Stavros Sachtouris
        out.write(u'%s\n' % items)
251 6acfcec4 Stavros Sachtouris
        out.flush()
252 31618e2a Stavros Sachtouris
        return
253 31618e2a Stavros Sachtouris
254 54d800e8 Stavros Sachtouris
    for i, item in enumerate(items):
255 a494a741 Stavros Sachtouris
        if with_enumeration:
256 fa9c0c38 Stavros Sachtouris
            out.write(u'%s. ' % (i + 1))
257 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
258 46d130c9 Stavros Sachtouris
            item = dict(item)
259 46d130c9 Stavros Sachtouris
            title = sorted(set(title).intersection(item))
260 46d130c9 Stavros Sachtouris
            pick = item.get if with_redundancy else item.pop
261 fa9c0c38 Stavros Sachtouris
            header = u' '.join(u'%s' % pick(key) for key in title)
262 6acfcec4 Stavros Sachtouris
            out.write((unicode(bold(header) if header else '') + '\n'))
263 fa9c0c38 Stavros Sachtouris
            print_dict(item, indent=INDENT_TAB, out=out)
264 46d130c9 Stavros Sachtouris
        elif isinstance(item, list) or isinstance(item, tuple):
265 fa9c0c38 Stavros Sachtouris
            print_list(item, indent=INDENT_TAB, out=out)
266 a494a741 Stavros Sachtouris
        else:
267 6acfcec4 Stavros Sachtouris
            out.write(u' %s\n' % item)
268 6acfcec4 Stavros Sachtouris
        out.flush()
269 6acfcec4 Stavros Sachtouris
    out.flush()
270 7493ccb6 Stavros Sachtouris
271 fd5db045 Stavros Sachtouris
272 23963422 Stavros Sachtouris
def format_size(size, decimal_factors=False):
273 23963422 Stavros Sachtouris
    units = ('B', 'KB', 'MB', 'GB', 'TB') if decimal_factors else (
274 23963422 Stavros Sachtouris
        'B', 'KiB', 'MiB', 'GiB', 'TiB')
275 23963422 Stavros Sachtouris
    step = 1000 if decimal_factors else 1024
276 23963422 Stavros Sachtouris
    fstep = float(step)
277 7493ccb6 Stavros Sachtouris
    try:
278 7493ccb6 Stavros Sachtouris
        size = float(size)
279 23963422 Stavros Sachtouris
    except (ValueError, TypeError) as err:
280 23963422 Stavros Sachtouris
        raiseCLIError(err, 'Cannot format %s in bytes' % (
281 23963422 Stavros Sachtouris
            ','.join(size) if isinstance(size, tuple) else size))
282 23963422 Stavros Sachtouris
    for i, unit in enumerate(units):
283 23963422 Stavros Sachtouris
        if size < step or i + 1 == len(units):
284 7493ccb6 Stavros Sachtouris
            break
285 23963422 Stavros Sachtouris
        size /= fstep
286 001200c3 Stavros Sachtouris
    s = ('%.2f' % size)
287 23963422 Stavros Sachtouris
    s = s.replace('%s' % step, '%s.99' % (step - 1)) if size <= fstep else s
288 001200c3 Stavros Sachtouris
    while '.' in s and s[-1] in ('0', '.'):
289 001200c3 Stavros Sachtouris
        s = s[:-1]
290 7493ccb6 Stavros Sachtouris
    return s + unit
291 7493ccb6 Stavros Sachtouris
292 fd5db045 Stavros Sachtouris
293 001200c3 Stavros Sachtouris
def to_bytes(size, format):
294 001200c3 Stavros Sachtouris
    """
295 001200c3 Stavros Sachtouris
    :param size: (float) the size in the given format
296 001200c3 Stavros Sachtouris
    :param format: (case insensitive) KiB, KB, MiB, MB, GiB, GB, TiB, TB
297 001200c3 Stavros Sachtouris

298 001200c3 Stavros Sachtouris
    :returns: (int) the size in bytes
299 23963422 Stavros Sachtouris
    :raises ValueError: if invalid size or format
300 23963422 Stavros Sachtouris
    :raises AttributeError: if format is not str
301 23963422 Stavros Sachtouris
    :raises TypeError: if size is not arithmetic or convertible to arithmetic
302 001200c3 Stavros Sachtouris
    """
303 001200c3 Stavros Sachtouris
    format = format.upper()
304 001200c3 Stavros Sachtouris
    if format == 'B':
305 001200c3 Stavros Sachtouris
        return int(size)
306 001200c3 Stavros Sachtouris
    size = float(size)
307 001200c3 Stavros Sachtouris
    units_dc = ('KB', 'MB', 'GB', 'TB')
308 001200c3 Stavros Sachtouris
    units_bi = ('KIB', 'MIB', 'GIB', 'TIB')
309 001200c3 Stavros Sachtouris
310 001200c3 Stavros Sachtouris
    factor = 1024 if format in units_bi else 1000 if format in units_dc else 0
311 001200c3 Stavros Sachtouris
    if not factor:
312 001200c3 Stavros Sachtouris
        raise ValueError('Invalid data size format %s' % format)
313 001200c3 Stavros Sachtouris
    for prefix in ('K', 'M', 'G', 'T'):
314 001200c3 Stavros Sachtouris
        size *= factor
315 001200c3 Stavros Sachtouris
        if format.startswith(prefix):
316 001200c3 Stavros Sachtouris
            break
317 001200c3 Stavros Sachtouris
    return int(size)
318 001200c3 Stavros Sachtouris
319 001200c3 Stavros Sachtouris
320 fd5db045 Stavros Sachtouris
def dict2file(d, f, depth=0):
321 7493ccb6 Stavros Sachtouris
    for k, v in d.items():
322 23963422 Stavros Sachtouris
        f.write('%s%s: ' % (' ' * INDENT_TAB * depth, k))
323 fd5db045 Stavros Sachtouris
        if isinstance(v, dict):
324 7493ccb6 Stavros Sachtouris
            f.write('\n')
325 fd5db045 Stavros Sachtouris
            dict2file(v, f, depth + 1)
326 23963422 Stavros Sachtouris
        elif isinstance(v, list) or isinstance(v, tuple):
327 7493ccb6 Stavros Sachtouris
            f.write('\n')
328 fd5db045 Stavros Sachtouris
            list2file(v, f, depth + 1)
329 7493ccb6 Stavros Sachtouris
        else:
330 23963422 Stavros Sachtouris
            f.write('%s\n' % v)
331 fd5db045 Stavros Sachtouris
332 7493ccb6 Stavros Sachtouris
333 fd5db045 Stavros Sachtouris
def list2file(l, f, depth=1):
334 7493ccb6 Stavros Sachtouris
    for item in l:
335 fd5db045 Stavros Sachtouris
        if isinstance(item, dict):
336 fd5db045 Stavros Sachtouris
            dict2file(item, f, depth + 1)
337 23963422 Stavros Sachtouris
        elif isinstance(item, list) or isinstance(item, tuple):
338 fd5db045 Stavros Sachtouris
            list2file(item, f, depth + 1)
339 7493ccb6 Stavros Sachtouris
        else:
340 23963422 Stavros Sachtouris
            f.write('%s%s\n' % (' ' * INDENT_TAB * depth, item))
341 efbcdc41 Stavros Sachtouris
342 efbcdc41 Stavros Sachtouris
# Split input auxiliary
343 efbcdc41 Stavros Sachtouris
344 efbcdc41 Stavros Sachtouris
345 efbcdc41 Stavros Sachtouris
def _parse_with_regex(line, regex):
346 efbcdc41 Stavros Sachtouris
    re_parser = regex_compile(regex)
347 efbcdc41 Stavros Sachtouris
    return (re_parser.split(line), re_parser.findall(line))
348 efbcdc41 Stavros Sachtouris
349 efbcdc41 Stavros Sachtouris
350 0ba7b031 Stavros Sachtouris
def _get_from_parsed(parsed_str):
351 0ba7b031 Stavros Sachtouris
    try:
352 0ba7b031 Stavros Sachtouris
        parsed_str = parsed_str.strip()
353 0ba7b031 Stavros Sachtouris
    except:
354 0ba7b031 Stavros Sachtouris
        return None
355 23963422 Stavros Sachtouris
    return ([parsed_str[1:-1]] if (
356 23963422 Stavros Sachtouris
        parsed_str[0] == parsed_str[-1] and parsed_str[0] in ("'", '"')) else (
357 23963422 Stavros Sachtouris
            parsed_str.split(' '))) if parsed_str else None
358 0ba7b031 Stavros Sachtouris
359 0ba7b031 Stavros Sachtouris
360 0ba7b031 Stavros Sachtouris
def split_input(line):
361 0ba7b031 Stavros Sachtouris
    if not line:
362 0ba7b031 Stavros Sachtouris
        return []
363 0ba7b031 Stavros Sachtouris
    reg_expr = '\'.*?\'|".*?"|^[\S]*$'
364 0ba7b031 Stavros Sachtouris
    (trivial_parts, interesting_parts) = _parse_with_regex(line, reg_expr)
365 0ba7b031 Stavros Sachtouris
    assert(len(trivial_parts) == 1 + len(interesting_parts))
366 0ba7b031 Stavros Sachtouris
    terms = []
367 0ba7b031 Stavros Sachtouris
    for i, tpart in enumerate(trivial_parts):
368 0ba7b031 Stavros Sachtouris
        part = _get_from_parsed(tpart)
369 0ba7b031 Stavros Sachtouris
        if part:
370 0ba7b031 Stavros Sachtouris
            terms += part
371 0ba7b031 Stavros Sachtouris
        try:
372 0ba7b031 Stavros Sachtouris
            part = _get_from_parsed(interesting_parts[i])
373 0ba7b031 Stavros Sachtouris
        except IndexError:
374 0ba7b031 Stavros Sachtouris
            break
375 0ba7b031 Stavros Sachtouris
        if part:
376 b9eebf2a Stavros Sachtouris
            if tpart and not tpart[-1].endswith(' '):
377 b9eebf2a Stavros Sachtouris
                terms[-1] += ' '.join(part)
378 b9eebf2a Stavros Sachtouris
            else:
379 b9eebf2a Stavros Sachtouris
                terms += part
380 0ba7b031 Stavros Sachtouris
    return terms
381 0ba7b031 Stavros Sachtouris
382 0ba7b031 Stavros Sachtouris
383 fa9c0c38 Stavros Sachtouris
def ask_user(msg, true_resp=('y', ), out=stdout, user_in=stdin):
384 7147e1ca Stavros Sachtouris
    """Print msg and read user response
385 7147e1ca Stavros Sachtouris

386 001200c3 Stavros Sachtouris
    :param true_resp: (tuple of chars)
387 7147e1ca Stavros Sachtouris

388 7147e1ca Stavros Sachtouris
    :returns: (bool) True if reponse in true responses, False otherwise
389 7147e1ca Stavros Sachtouris
    """
390 fa9c0c38 Stavros Sachtouris
    yep = ', '.join(true_resp)
391 fa9c0c38 Stavros Sachtouris
    nope = '<not %s>' % yep if 'n' in true_resp or 'N' in true_resp else 'N'
392 fa9c0c38 Stavros Sachtouris
    out.write(u'%s [%s/%s]: ' % (msg, yep, nope))
393 fa9c0c38 Stavros Sachtouris
    out.flush()
394 fa9c0c38 Stavros Sachtouris
    user_response = user_in.readline()
395 fa9c0c38 Stavros Sachtouris
    return user_response[0].lower() in [s.lower() for s in true_resp]
396 b482315a Stavros Sachtouris
397 14b25e00 Stavros Sachtouris
398 14b25e00 Stavros Sachtouris
def get_path_size(testpath):
399 14b25e00 Stavros Sachtouris
    if path.isfile(testpath):
400 14b25e00 Stavros Sachtouris
        return path.getsize(testpath)
401 14b25e00 Stavros Sachtouris
    total_size = 0
402 14b25e00 Stavros Sachtouris
    for top, dirs, files in walk(path.abspath(testpath)):
403 14b25e00 Stavros Sachtouris
        for f in files:
404 14b25e00 Stavros Sachtouris
            f = path.join(top, f)
405 14b25e00 Stavros Sachtouris
            if path.isfile(f):
406 14b25e00 Stavros Sachtouris
                total_size += path.getsize(f)
407 14b25e00 Stavros Sachtouris
    return total_size
408 7ba195e5 Stavros Sachtouris
409 7ba195e5 Stavros Sachtouris
410 7ba195e5 Stavros Sachtouris
def remove_from_items(list_of_dicts, key_to_remove):
411 7ba195e5 Stavros Sachtouris
    for item in list_of_dicts:
412 7ba195e5 Stavros Sachtouris
        assert isinstance(item, dict), 'Item %s not a dict' % item
413 7ba195e5 Stavros Sachtouris
        item.pop(key_to_remove, None)
414 1716a15d Stavros Sachtouris
415 1716a15d Stavros Sachtouris
416 1716a15d Stavros Sachtouris
def filter_dicts_by_dict(
417 1716a15d Stavros Sachtouris
    list_of_dicts, filters,
418 1716a15d Stavros Sachtouris
    exact_match=True, case_sensitive=False):
419 1716a15d Stavros Sachtouris
    """
420 1716a15d Stavros Sachtouris
    :param list_of_dicts: (list) each dict contains "raw" key-value pairs
421 1716a15d Stavros Sachtouris

422 1716a15d Stavros Sachtouris
    :param filters: (dict) filters in key-value form
423 1716a15d Stavros Sachtouris

424 1716a15d Stavros Sachtouris
    :param exact_match: (bool) if false, check if the filter value is part of
425 1716a15d Stavros Sachtouris
        the actual value
426 1716a15d Stavros Sachtouris

427 1716a15d Stavros Sachtouris
    :param case_sensitive: (bool) revers to values only (not keys)
428 1716a15d Stavros Sachtouris

429 1716a15d Stavros Sachtouris
    :returns: (list) only the dicts that match all filters
430 1716a15d Stavros Sachtouris
    """
431 1716a15d Stavros Sachtouris
    new_dicts = []
432 1716a15d Stavros Sachtouris
    for d in list_of_dicts:
433 1716a15d Stavros Sachtouris
        if set(filters).difference(d):
434 1716a15d Stavros Sachtouris
            continue
435 1716a15d Stavros Sachtouris
        match = True
436 1716a15d Stavros Sachtouris
        for k, v in filters.items():
437 1716a15d Stavros Sachtouris
            dv, v = ('%s' % d[k]), ('%s' % v)
438 1716a15d Stavros Sachtouris
            if not case_sensitive:
439 1716a15d Stavros Sachtouris
                dv, v = dv.lower(), v.lower()
440 1716a15d Stavros Sachtouris
            if not ((
441 1716a15d Stavros Sachtouris
                    exact_match and v == dv) or (
442 1716a15d Stavros Sachtouris
                    (not exact_match) and v in dv)):
443 1716a15d Stavros Sachtouris
                match = False
444 1716a15d Stavros Sachtouris
                break
445 1716a15d Stavros Sachtouris
        if match:
446 1716a15d Stavros Sachtouris
            new_dicts.append(d)
447 1716a15d Stavros Sachtouris
    return new_dicts