Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ f17d6cb5

History | View | Annotate | Download (14.9 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 bd40efdf Stavros Sachtouris
from sys import stdout, stdin
35 efbcdc41 Stavros Sachtouris
from re import compile as regex_compile
36 02846a75 Stavros Sachtouris
from time import sleep
37 14b25e00 Stavros Sachtouris
from os import walk, path
38 0399ac7e Stavros Sachtouris
from json import dumps
39 02846a75 Stavros Sachtouris
40 2ff0b7bd Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError
41 3dabe5d2 Stavros Sachtouris
42 f55d3a15 Stavros Sachtouris
43 a0608786 Stavros Sachtouris
INDENT_TAB = 4
44 f55d3a15 Stavros Sachtouris
45 f55d3a15 Stavros Sachtouris
46 362adf50 Stavros Sachtouris
suggest = dict(ansicolors=dict(
47 6fb4af77 Stavros Sachtouris
        active=False,
48 6fb4af77 Stavros Sachtouris
        url='#install-ansicolors-progress',
49 362adf50 Stavros Sachtouris
        description='Add colors to console responses'))
50 6fb4af77 Stavros Sachtouris
51 dfee2caf Stavros Sachtouris
try:
52 dfee2caf Stavros Sachtouris
    from colors import magenta, red, yellow, bold
53 dfee2caf Stavros Sachtouris
except ImportError:
54 3dabe5d2 Stavros Sachtouris
    # No colours? No worries, use dummy foo instead
55 f93854ae Stavros Sachtouris
    def dummy(val):
56 dfee2caf Stavros Sachtouris
        return val
57 f93854ae Stavros Sachtouris
    red = yellow = magenta = bold = dummy
58 69691087 Stavros Sachtouris
    #from kamaki.cli import _colors
59 69691087 Stavros Sachtouris
    #if _colors.lower() == 'on':
60 6fb4af77 Stavros Sachtouris
    suggest['ansicolors']['active'] = True
61 6fb4af77 Stavros Sachtouris
62 6fb4af77 Stavros Sachtouris
try:
63 6fb4af77 Stavros Sachtouris
    from progress.bar import ShadyBar
64 6fb4af77 Stavros Sachtouris
except ImportError:
65 6fb4af77 Stavros Sachtouris
    suggest['progress']['active'] = True
66 6fb4af77 Stavros Sachtouris
67 6fb4af77 Stavros Sachtouris
68 69691087 Stavros Sachtouris
def suggest_missing(miss=None, exclude=[]):
69 6fb4af77 Stavros Sachtouris
    global suggest
70 69691087 Stavros Sachtouris
    sgs = dict(suggest)
71 69691087 Stavros Sachtouris
    for exc in exclude:
72 69691087 Stavros Sachtouris
        try:
73 69691087 Stavros Sachtouris
            sgs.pop(exc)
74 69691087 Stavros Sachtouris
        except KeyError:
75 69691087 Stavros Sachtouris
            pass
76 6fb4af77 Stavros Sachtouris
    kamaki_docs = 'http://www.synnefo.org/docs/kamaki/latest'
77 69691087 Stavros Sachtouris
    for k, v in (miss, sgs[miss]) if miss else sgs.items():
78 6fb4af77 Stavros Sachtouris
        if v['active'] and stdout.isatty():
79 6fb4af77 Stavros Sachtouris
            print('Suggestion: for better user experience install %s' % k)
80 6fb4af77 Stavros Sachtouris
            print('\t%s' % v['description'])
81 6fb4af77 Stavros Sachtouris
            print('\tIt is easy, here are the instructions:')
82 6fb4af77 Stavros Sachtouris
            print('\t%s/installation.html%s' % (kamaki_docs, v['url']))
83 6fb4af77 Stavros Sachtouris
            print('')
84 f997679d Stavros Sachtouris
85 fd5db045 Stavros Sachtouris
86 67cea04c Stavros Sachtouris
def remove_colors():
87 67cea04c Stavros Sachtouris
    global bold
88 3dabe5d2 Stavros Sachtouris
    global red
89 3dabe5d2 Stavros Sachtouris
    global yellow
90 3dabe5d2 Stavros Sachtouris
    global magenta
91 fd5db045 Stavros Sachtouris
92 67cea04c Stavros Sachtouris
    def dummy(val):
93 67cea04c Stavros Sachtouris
        return val
94 3dabe5d2 Stavros Sachtouris
    red = yellow = magenta = bold = dummy
95 7493ccb6 Stavros Sachtouris
96 fd5db045 Stavros Sachtouris
97 7493ccb6 Stavros Sachtouris
def pretty_keys(d, delim='_', recurcive=False):
98 f23a5cdb Stavros Sachtouris
    """<term>delim<term> to <term> <term> transformation
99 7493ccb6 Stavros Sachtouris
    """
100 7493ccb6 Stavros Sachtouris
    new_d = {}
101 7493ccb6 Stavros Sachtouris
    for key, val in d.items():
102 7493ccb6 Stavros Sachtouris
        new_key = key.split(delim)[-1]
103 7493ccb6 Stavros Sachtouris
        if recurcive and isinstance(val, dict):
104 fd5db045 Stavros Sachtouris
            new_val = pretty_keys(val, delim, recurcive)
105 7493ccb6 Stavros Sachtouris
        else:
106 7493ccb6 Stavros Sachtouris
            new_val = val
107 7493ccb6 Stavros Sachtouris
        new_d[new_key] = new_val
108 7493ccb6 Stavros Sachtouris
    return new_d
109 7493ccb6 Stavros Sachtouris
110 fd5db045 Stavros Sachtouris
111 0399ac7e Stavros Sachtouris
def print_json(data):
112 0399ac7e Stavros Sachtouris
    """Print a list or dict as json in console
113 0399ac7e Stavros Sachtouris

114 0399ac7e Stavros Sachtouris
    :param data: json-dumpable data
115 0399ac7e Stavros Sachtouris
    """
116 a0608786 Stavros Sachtouris
    print(dumps(data, indent=INDENT_TAB))
117 0399ac7e Stavros Sachtouris
118 0399ac7e Stavros Sachtouris
119 545c6c29 Stavros Sachtouris
def pretty_dict(d, *args, **kwargs):
120 545c6c29 Stavros Sachtouris
    print_dict(pretty_keys(d, *args, **kwargs))
121 545c6c29 Stavros Sachtouris
122 545c6c29 Stavros Sachtouris
123 de73876b Stavros Sachtouris
def print_dict(
124 f55d3a15 Stavros Sachtouris
        d,
125 f55d3a15 Stavros Sachtouris
        exclude=(), indent=0,
126 24ff0a35 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False):
127 f55d3a15 Stavros Sachtouris
    """Pretty-print a dictionary object
128 f55d3a15 Stavros Sachtouris
    <indent>key: <non iterable item>
129 f55d3a15 Stavros Sachtouris
    <indent>key:
130 a0608786 Stavros Sachtouris
    <indent + INDENT_TAB><pretty-print iterable>
131 f8681ec8 Stavros Sachtouris

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

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

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

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

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

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

178 f55d3a15 Stavros Sachtouris
    :param l: (list)
179 f8681ec8 Stavros Sachtouris

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

182 f55d3a15 Stavros Sachtouris
    :param indent: (int) initial indentation (recursive)
183 f8681ec8 Stavros Sachtouris

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

186 f55d3a15 Stavros Sachtouris
    :param recursive_enumeration: (bool) recursively enumerate iterables (does
187 f55d3a15 Stavros Sachtouris
        not enumerate 1st level keys)
188 f8681ec8 Stavros Sachtouris

189 f55d3a15 Stavros Sachtouris
    :raises CLIError: if preconditions fail
190 f8681ec8 Stavros Sachtouris
    """
191 f55d3a15 Stavros Sachtouris
    assert isinstance(l, list) or isinstance(l, tuple), (
192 f55d3a15 Stavros Sachtouris
        'print_list prinbts a list or tuple')
193 f55d3a15 Stavros Sachtouris
    assert indent >= 0, 'print_list indent must be >= 0'
194 f551841a Stavros Sachtouris
195 a0608786 Stavros Sachtouris
    counter = 0
196 f55d3a15 Stavros Sachtouris
    for i, item in enumerate(l):
197 f55d3a15 Stavros Sachtouris
        print_str = ' ' * indent
198 f55d3a15 Stavros Sachtouris
        print_str += '%s.' % (i + 1) if with_enumeration else ''
199 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
200 c17b8bc0 Stavros Sachtouris
            if with_enumeration:
201 f55d3a15 Stavros Sachtouris
                print print_str
202 a0608786 Stavros Sachtouris
            elif counter and counter < len(l):
203 a0608786 Stavros Sachtouris
                print
204 de73876b Stavros Sachtouris
            print_dict(
205 a0608786 Stavros Sachtouris
                item, exclude,
206 a0608786 Stavros Sachtouris
                indent + (INDENT_TAB if with_enumeration else 0),
207 f55d3a15 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration)
208 f55d3a15 Stavros Sachtouris
        elif isinstance(item, list) or isinstance(item, tuple):
209 c17b8bc0 Stavros Sachtouris
            if with_enumeration:
210 f55d3a15 Stavros Sachtouris
                print print_str
211 a0608786 Stavros Sachtouris
            elif counter and counter < len(l):
212 a0608786 Stavros Sachtouris
                print
213 de73876b Stavros Sachtouris
            print_list(
214 a0608786 Stavros Sachtouris
                item, exclude, indent + INDENT_TAB,
215 f55d3a15 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration)
216 7493ccb6 Stavros Sachtouris
        else:
217 f55d3a15 Stavros Sachtouris
            item = ('%s' % item).strip()
218 f55d3a15 Stavros Sachtouris
            if item in exclude:
219 f55d3a15 Stavros Sachtouris
                continue
220 f55d3a15 Stavros Sachtouris
            print '%s%s' % (print_str, item)
221 a0608786 Stavros Sachtouris
        counter += 1
222 7493ccb6 Stavros Sachtouris
223 fd5db045 Stavros Sachtouris
224 439826ec Stavros Sachtouris
def page_hold(index, limit, maxlen):
225 439826ec Stavros Sachtouris
    """Check if there are results to show, and hold the page when needed
226 439826ec Stavros Sachtouris
    :param index: (int) > 0
227 439826ec Stavros Sachtouris
    :param limit: (int) 0 < limit <= max, page hold if limit mod index == 0
228 439826ec Stavros Sachtouris
    :param maxlen: (int) Don't hold if index reaches maxlen
229 439826ec Stavros Sachtouris

230 439826ec Stavros Sachtouris
    :returns: True if there are more to show, False if all results are shown
231 439826ec Stavros Sachtouris
    """
232 439826ec Stavros Sachtouris
    if index >= limit and index % limit == 0:
233 439826ec Stavros Sachtouris
        if index >= maxlen:
234 439826ec Stavros Sachtouris
            return False
235 439826ec Stavros Sachtouris
        else:
236 439826ec Stavros Sachtouris
            print('(%s listed - %s more - "enter" to continue)' % (
237 439826ec Stavros Sachtouris
                index,
238 439826ec Stavros Sachtouris
                maxlen - index))
239 439826ec Stavros Sachtouris
            c = ' '
240 439826ec Stavros Sachtouris
            while c != '\n':
241 439826ec Stavros Sachtouris
                c = stdin.read(1)
242 439826ec Stavros Sachtouris
    return True
243 439826ec Stavros Sachtouris
244 439826ec Stavros Sachtouris
245 de73876b Stavros Sachtouris
def print_items(
246 24ff0a35 Stavros Sachtouris
        items, title=('id', 'name'),
247 24ff0a35 Stavros Sachtouris
        with_enumeration=False, with_redundancy=False,
248 24ff0a35 Stavros Sachtouris
        page_size=0):
249 a494a741 Stavros Sachtouris
    """print dict or list items in a list, using some values as title
250 a494a741 Stavros Sachtouris
    Objects of next level don't inherit enumeration (default: off) or titles
251 a494a741 Stavros Sachtouris

252 a494a741 Stavros Sachtouris
    :param items: (list) items are lists or dict
253 f55d3a15 Stavros Sachtouris

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

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

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

260 bd40efdf Stavros Sachtouris
    :param page_size: (int) show results in pages of page_size items, enter to
261 bd40efdf Stavros Sachtouris
        continue
262 a494a741 Stavros Sachtouris
    """
263 0e806947 Stavros Sachtouris
    if not items:
264 0e806947 Stavros Sachtouris
        return
265 31618e2a Stavros Sachtouris
    elif not (
266 31618e2a Stavros Sachtouris
            isinstance(items, dict) or isinstance(
267 31618e2a Stavros Sachtouris
                items, list) or isinstance(items, dict)):
268 31618e2a Stavros Sachtouris
        print '%s' % items
269 31618e2a Stavros Sachtouris
        return
270 31618e2a Stavros Sachtouris
271 bd40efdf Stavros Sachtouris
    try:
272 bd40efdf Stavros Sachtouris
        page_size = int(page_size) if int(page_size) > 0 else len(items)
273 bd40efdf Stavros Sachtouris
    except:
274 bd40efdf Stavros Sachtouris
        page_size = len(items)
275 bd40efdf Stavros Sachtouris
    num_of_pages = len(items) // page_size
276 bd40efdf Stavros Sachtouris
    num_of_pages += 1 if len(items) % page_size else 0
277 54d800e8 Stavros Sachtouris
    for i, item in enumerate(items):
278 a494a741 Stavros Sachtouris
        if with_enumeration:
279 a494a741 Stavros Sachtouris
            stdout.write('%s. ' % (i + 1))
280 a494a741 Stavros Sachtouris
        if isinstance(item, dict):
281 a494a741 Stavros Sachtouris
            title = sorted(set(title).intersection(item.keys()))
282 a494a741 Stavros Sachtouris
            if with_redundancy:
283 a517ff50 Stavros Sachtouris
                header = ' '.join('%s' % item[key] for key in title)
284 a494a741 Stavros Sachtouris
            else:
285 a517ff50 Stavros Sachtouris
                header = ' '.join('%s' % item.pop(key) for key in title)
286 aa25346e Stavros Sachtouris
            print(bold(header))
287 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
288 a0608786 Stavros Sachtouris
            print_dict(item, indent=INDENT_TAB)
289 aa25346e Stavros Sachtouris
        elif isinstance(item, list):
290 a0608786 Stavros Sachtouris
            print_list(item, indent=INDENT_TAB)
291 a494a741 Stavros Sachtouris
        else:
292 a494a741 Stavros Sachtouris
            print(' %s' % item)
293 439826ec Stavros Sachtouris
        page_hold(i + 1, page_size, len(items))
294 7493ccb6 Stavros Sachtouris
295 fd5db045 Stavros Sachtouris
296 7493ccb6 Stavros Sachtouris
def format_size(size):
297 001200c3 Stavros Sachtouris
    units = ('B', 'KiB', 'MiB', 'GiB', 'TiB')
298 7493ccb6 Stavros Sachtouris
    try:
299 7493ccb6 Stavros Sachtouris
        size = float(size)
300 2ff0b7bd Stavros Sachtouris
    except ValueError as err:
301 2ff0b7bd Stavros Sachtouris
        raiseCLIError(err, 'Cannot format %s in bytes' % size)
302 7493ccb6 Stavros Sachtouris
    for unit in units:
303 7493ccb6 Stavros Sachtouris
        if size < 1024:
304 7493ccb6 Stavros Sachtouris
            break
305 001200c3 Stavros Sachtouris
        size /= 1024.0
306 001200c3 Stavros Sachtouris
    s = ('%.2f' % size)
307 001200c3 Stavros Sachtouris
    while '.' in s and s[-1] in ('0', '.'):
308 001200c3 Stavros Sachtouris
        s = s[:-1]
309 7493ccb6 Stavros Sachtouris
    return s + unit
310 7493ccb6 Stavros Sachtouris
311 fd5db045 Stavros Sachtouris
312 001200c3 Stavros Sachtouris
def to_bytes(size, format):
313 001200c3 Stavros Sachtouris
    """
314 001200c3 Stavros Sachtouris
    :param size: (float) the size in the given format
315 001200c3 Stavros Sachtouris
    :param format: (case insensitive) KiB, KB, MiB, MB, GiB, GB, TiB, TB
316 001200c3 Stavros Sachtouris

317 001200c3 Stavros Sachtouris
    :returns: (int) the size in bytes
318 001200c3 Stavros Sachtouris
    """
319 001200c3 Stavros Sachtouris
    format = format.upper()
320 001200c3 Stavros Sachtouris
    if format == 'B':
321 001200c3 Stavros Sachtouris
        return int(size)
322 001200c3 Stavros Sachtouris
    size = float(size)
323 001200c3 Stavros Sachtouris
    units_dc = ('KB', 'MB', 'GB', 'TB')
324 001200c3 Stavros Sachtouris
    units_bi = ('KIB', 'MIB', 'GIB', 'TIB')
325 001200c3 Stavros Sachtouris
326 001200c3 Stavros Sachtouris
    factor = 1024 if format in units_bi else 1000 if format in units_dc else 0
327 001200c3 Stavros Sachtouris
    if not factor:
328 001200c3 Stavros Sachtouris
        raise ValueError('Invalid data size format %s' % format)
329 001200c3 Stavros Sachtouris
    for prefix in ('K', 'M', 'G', 'T'):
330 001200c3 Stavros Sachtouris
        size *= factor
331 001200c3 Stavros Sachtouris
        if format.startswith(prefix):
332 001200c3 Stavros Sachtouris
            break
333 001200c3 Stavros Sachtouris
    return int(size)
334 001200c3 Stavros Sachtouris
335 001200c3 Stavros Sachtouris
336 fd5db045 Stavros Sachtouris
def dict2file(d, f, depth=0):
337 7493ccb6 Stavros Sachtouris
    for k, v in d.items():
338 fd5db045 Stavros Sachtouris
        f.write('%s%s: ' % ('\t' * depth, k))
339 fd5db045 Stavros Sachtouris
        if isinstance(v, dict):
340 7493ccb6 Stavros Sachtouris
            f.write('\n')
341 fd5db045 Stavros Sachtouris
            dict2file(v, f, depth + 1)
342 fd5db045 Stavros Sachtouris
        elif isinstance(v, list):
343 7493ccb6 Stavros Sachtouris
            f.write('\n')
344 fd5db045 Stavros Sachtouris
            list2file(v, f, depth + 1)
345 7493ccb6 Stavros Sachtouris
        else:
346 a517ff50 Stavros Sachtouris
            f.write(' %s\n' % v)
347 fd5db045 Stavros Sachtouris
348 7493ccb6 Stavros Sachtouris
349 fd5db045 Stavros Sachtouris
def list2file(l, f, depth=1):
350 7493ccb6 Stavros Sachtouris
    for item in l:
351 fd5db045 Stavros Sachtouris
        if isinstance(item, dict):
352 fd5db045 Stavros Sachtouris
            dict2file(item, f, depth + 1)
353 fd5db045 Stavros Sachtouris
        elif isinstance(item, list):
354 fd5db045 Stavros Sachtouris
            list2file(item, f, depth + 1)
355 7493ccb6 Stavros Sachtouris
        else:
356 a517ff50 Stavros Sachtouris
            f.write('%s%s\n' % ('\t' * depth, item))
357 efbcdc41 Stavros Sachtouris
358 efbcdc41 Stavros Sachtouris
# Split input auxiliary
359 efbcdc41 Stavros Sachtouris
360 efbcdc41 Stavros Sachtouris
361 efbcdc41 Stavros Sachtouris
def _parse_with_regex(line, regex):
362 efbcdc41 Stavros Sachtouris
    re_parser = regex_compile(regex)
363 efbcdc41 Stavros Sachtouris
    return (re_parser.split(line), re_parser.findall(line))
364 efbcdc41 Stavros Sachtouris
365 efbcdc41 Stavros Sachtouris
366 efbcdc41 Stavros Sachtouris
def _sub_split(line):
367 efbcdc41 Stavros Sachtouris
    terms = []
368 efbcdc41 Stavros Sachtouris
    (sub_trivials, sub_interesting) = _parse_with_regex(line, ' ".*?" ')
369 efbcdc41 Stavros Sachtouris
    for subi, subipart in enumerate(sub_interesting):
370 efbcdc41 Stavros Sachtouris
        terms += sub_trivials[subi].split()
371 efbcdc41 Stavros Sachtouris
        terms.append(subipart[2:-2])
372 efbcdc41 Stavros Sachtouris
    terms += sub_trivials[-1].split()
373 efbcdc41 Stavros Sachtouris
    return terms
374 efbcdc41 Stavros Sachtouris
375 efbcdc41 Stavros Sachtouris
376 0ba7b031 Stavros Sachtouris
def old_split_input(line):
377 0ba7b031 Stavros Sachtouris
    """Use regular expressions to split a line correctly"""
378 efbcdc41 Stavros Sachtouris
    line = ' %s ' % line
379 efbcdc41 Stavros Sachtouris
    (trivial_parts, interesting_parts) = _parse_with_regex(line, ' \'.*?\' ')
380 efbcdc41 Stavros Sachtouris
    terms = []
381 efbcdc41 Stavros Sachtouris
    for i, ipart in enumerate(interesting_parts):
382 efbcdc41 Stavros Sachtouris
        terms += _sub_split(trivial_parts[i])
383 efbcdc41 Stavros Sachtouris
        terms.append(ipart[2:-2])
384 efbcdc41 Stavros Sachtouris
    terms += _sub_split(trivial_parts[-1])
385 efbcdc41 Stavros Sachtouris
    return terms
386 7147e1ca Stavros Sachtouris
387 7147e1ca Stavros Sachtouris
388 0ba7b031 Stavros Sachtouris
def _get_from_parsed(parsed_str):
389 0ba7b031 Stavros Sachtouris
    try:
390 0ba7b031 Stavros Sachtouris
        parsed_str = parsed_str.strip()
391 0ba7b031 Stavros Sachtouris
    except:
392 0ba7b031 Stavros Sachtouris
        return None
393 0ba7b031 Stavros Sachtouris
    if parsed_str:
394 0ba7b031 Stavros Sachtouris
        if parsed_str[0] == parsed_str[-1] and parsed_str[0] in ("'", '"'):
395 0ba7b031 Stavros Sachtouris
            return [parsed_str[1:-1]]
396 0ba7b031 Stavros Sachtouris
        return parsed_str.split(' ')
397 0ba7b031 Stavros Sachtouris
    return None
398 0ba7b031 Stavros Sachtouris
399 0ba7b031 Stavros Sachtouris
400 0ba7b031 Stavros Sachtouris
def split_input(line):
401 0ba7b031 Stavros Sachtouris
    if not line:
402 0ba7b031 Stavros Sachtouris
        return []
403 0ba7b031 Stavros Sachtouris
    reg_expr = '\'.*?\'|".*?"|^[\S]*$'
404 0ba7b031 Stavros Sachtouris
    (trivial_parts, interesting_parts) = _parse_with_regex(line, reg_expr)
405 0ba7b031 Stavros Sachtouris
    assert(len(trivial_parts) == 1 + len(interesting_parts))
406 0ba7b031 Stavros Sachtouris
    #print('  [split_input] trivial_parts %s are' % trivial_parts)
407 0ba7b031 Stavros Sachtouris
    #print('  [split_input] interesting_parts %s are' % interesting_parts)
408 0ba7b031 Stavros Sachtouris
    terms = []
409 0ba7b031 Stavros Sachtouris
    for i, tpart in enumerate(trivial_parts):
410 0ba7b031 Stavros Sachtouris
        part = _get_from_parsed(tpart)
411 0ba7b031 Stavros Sachtouris
        if part:
412 0ba7b031 Stavros Sachtouris
            terms += part
413 0ba7b031 Stavros Sachtouris
        try:
414 0ba7b031 Stavros Sachtouris
            part = _get_from_parsed(interesting_parts[i])
415 0ba7b031 Stavros Sachtouris
        except IndexError:
416 0ba7b031 Stavros Sachtouris
            break
417 0ba7b031 Stavros Sachtouris
        if part:
418 0ba7b031 Stavros Sachtouris
            terms += part
419 0ba7b031 Stavros Sachtouris
    return terms
420 0ba7b031 Stavros Sachtouris
421 0ba7b031 Stavros Sachtouris
422 f55d3a15 Stavros Sachtouris
def ask_user(msg, true_resp=('y', )):
423 7147e1ca Stavros Sachtouris
    """Print msg and read user response
424 7147e1ca Stavros Sachtouris

425 001200c3 Stavros Sachtouris
    :param true_resp: (tuple of chars)
426 7147e1ca Stavros Sachtouris

427 7147e1ca Stavros Sachtouris
    :returns: (bool) True if reponse in true responses, False otherwise
428 7147e1ca Stavros Sachtouris
    """
429 f55d3a15 Stavros Sachtouris
    stdout.write('%s [%s/N]: ' % (msg, ', '.join(true_resp)))
430 7147e1ca Stavros Sachtouris
    stdout.flush()
431 001200c3 Stavros Sachtouris
    user_response = stdin.readline()
432 f55d3a15 Stavros Sachtouris
    return user_response[0].lower() in true_resp
433 0ba7b031 Stavros Sachtouris
434 0ba7b031 Stavros Sachtouris
435 02846a75 Stavros Sachtouris
def spiner(size=None):
436 b482315a Stavros Sachtouris
    spins = ('/', '-', '\\', '|')
437 b482315a Stavros Sachtouris
    stdout.write(' ')
438 02846a75 Stavros Sachtouris
    size = size or -1
439 02846a75 Stavros Sachtouris
    i = 0
440 02846a75 Stavros Sachtouris
    while size - i:
441 b482315a Stavros Sachtouris
        stdout.write('\b%s' % spins[i % len(spins)])
442 b482315a Stavros Sachtouris
        stdout.flush()
443 b482315a Stavros Sachtouris
        i += 1
444 02846a75 Stavros Sachtouris
        sleep(0.1)
445 b482315a Stavros Sachtouris
        yield
446 b58c1078 Stavros Sachtouris
    yield
447 b482315a Stavros Sachtouris
448 0ba7b031 Stavros Sachtouris
if __name__ == '__main__':
449 de73876b Stavros Sachtouris
    examples = [
450 de73876b Stavros Sachtouris
        'la_la le_le li_li',
451 0ba7b031 Stavros Sachtouris
        '\'la la\' \'le le\' \'li li\'',
452 0ba7b031 Stavros Sachtouris
        '\'la la\' le_le \'li li\'',
453 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' li_li',
454 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' \'li li\'',
455 0ba7b031 Stavros Sachtouris
        '"la la" "le le" "li li"',
456 0ba7b031 Stavros Sachtouris
        '"la la" le_le "li li"',
457 0ba7b031 Stavros Sachtouris
        'la_la "le le" li_li',
458 0ba7b031 Stavros Sachtouris
        '"la_la" "le le" "li li"',
459 0ba7b031 Stavros Sachtouris
        '\'la la\' "le le" \'li li\'',
460 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' "li li"',
461 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' li_li',
462 0ba7b031 Stavros Sachtouris
        '\'la la\' le_le "li li"',
463 0ba7b031 Stavros Sachtouris
        '"la la" le_le \'li li\'',
464 0ba7b031 Stavros Sachtouris
        '"la la" \'le le\' li_li',
465 0ba7b031 Stavros Sachtouris
        'la_la \'le\'le\' "li\'li"',
466 0ba7b031 Stavros Sachtouris
        '"la \'le le\' la"',
467 0ba7b031 Stavros Sachtouris
        '\'la "le le" la\'',
468 0ba7b031 Stavros Sachtouris
        '\'la "la" la\' "le \'le\' le" li_"li"_li',
469 de73876b Stavros Sachtouris
        '\'\' \'L\' "" "A"']
470 0ba7b031 Stavros Sachtouris
471 0ba7b031 Stavros Sachtouris
    for i, example in enumerate(examples):
472 0ba7b031 Stavros Sachtouris
        print('%s. Split this: (%s)' % (i + 1, example))
473 0ba7b031 Stavros Sachtouris
        ret = old_split_input(example)
474 0ba7b031 Stavros Sachtouris
        print('\t(%s) of size %s' % (ret, len(ret)))
475 14b25e00 Stavros Sachtouris
476 14b25e00 Stavros Sachtouris
477 14b25e00 Stavros Sachtouris
def get_path_size(testpath):
478 14b25e00 Stavros Sachtouris
    if path.isfile(testpath):
479 14b25e00 Stavros Sachtouris
        return path.getsize(testpath)
480 14b25e00 Stavros Sachtouris
    total_size = 0
481 14b25e00 Stavros Sachtouris
    for top, dirs, files in walk(path.abspath(testpath)):
482 14b25e00 Stavros Sachtouris
        for f in files:
483 14b25e00 Stavros Sachtouris
            f = path.join(top, f)
484 14b25e00 Stavros Sachtouris
            if path.isfile(f):
485 14b25e00 Stavros Sachtouris
                total_size += path.getsize(f)
486 14b25e00 Stavros Sachtouris
    return total_size
487 7ba195e5 Stavros Sachtouris
488 7ba195e5 Stavros Sachtouris
489 7ba195e5 Stavros Sachtouris
def remove_from_items(list_of_dicts, key_to_remove):
490 7ba195e5 Stavros Sachtouris
    for item in list_of_dicts:
491 7ba195e5 Stavros Sachtouris
        assert isinstance(item, dict), 'Item %s not a dict' % item
492 7ba195e5 Stavros Sachtouris
        item.pop(key_to_remove, None)