Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ a57402cd

History | View | Annotate | Download (15.4 kB)

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

110 0399ac7e Stavros Sachtouris
    :param data: json-dumpable data
111 0399ac7e Stavros Sachtouris
    """
112 0399ac7e Stavros Sachtouris
    print(dumps(data, indent=2))
113 0399ac7e Stavros Sachtouris
114 0399ac7e Stavros Sachtouris
115 545c6c29 Stavros Sachtouris
def pretty_dict(d, *args, **kwargs):
116 545c6c29 Stavros Sachtouris
    print_dict(pretty_keys(d, *args, **kwargs))
117 545c6c29 Stavros Sachtouris
118 545c6c29 Stavros Sachtouris
119 de73876b Stavros Sachtouris
def print_dict(
120 24ff0a35 Stavros Sachtouris
        d, exclude=(), ident=0,
121 24ff0a35 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False):
122 f8681ec8 Stavros Sachtouris
    """
123 f8681ec8 Stavros Sachtouris
    Pretty-print a dictionary object
124 f8681ec8 Stavros Sachtouris

125 f8681ec8 Stavros Sachtouris
    :param d: (dict) the input
126 f8681ec8 Stavros Sachtouris

127 f8681ec8 Stavros Sachtouris
    :param excelude: (set or list) keys to exclude from printing
128 f8681ec8 Stavros Sachtouris

129 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
130 f8681ec8 Stavros Sachtouris

131 f8681ec8 Stavros Sachtouris
    :param with_enumeration: (bool) enumerate each 1st level key if true
132 f8681ec8 Stavros Sachtouris

133 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
134 f8681ec8 Stavros Sachtouris
        2nd level or deeper
135 f8681ec8 Stavros Sachtouris

136 f8681ec8 Stavros Sachtouris
    :raises CLIError: (TypeError wrapper) non-dict input
137 f8681ec8 Stavros Sachtouris
    """
138 7493ccb6 Stavros Sachtouris
    if not isinstance(d, dict):
139 2ff0b7bd Stavros Sachtouris
        raiseCLIError(TypeError('Cannot dict_print a non-dict object'))
140 f551841a Stavros Sachtouris
141 db950b10 Stavros Sachtouris
    if d:
142 24ff0a35 Stavros Sachtouris
        margin = max(len(('%s' % key).strip()) for key in d.keys() if (
143 24ff0a35 Stavros Sachtouris
            key not in exclude))
144 7493ccb6 Stavros Sachtouris
145 f8681ec8 Stavros Sachtouris
    counter = 1
146 7493ccb6 Stavros Sachtouris
    for key, val in sorted(d.items()):
147 a517ff50 Stavros Sachtouris
        key = '%s' % key
148 7493ccb6 Stavros Sachtouris
        if key in exclude:
149 7493ccb6 Stavros Sachtouris
            continue
150 f8681ec8 Stavros Sachtouris
        print_str = ''
151 f8681ec8 Stavros Sachtouris
        if with_enumeration:
152 f8681ec8 Stavros Sachtouris
            print_str = '%s. ' % counter
153 f8681ec8 Stavros Sachtouris
            counter += 1
154 f8681ec8 Stavros Sachtouris
        print_str = '%s%s' % (' ' * (ident - len(print_str)), print_str)
155 a517ff50 Stavros Sachtouris
        print_str += key.strip()
156 fa382f9e Stavros Sachtouris
        print_str += ':'
157 a517ff50 Stavros Sachtouris
        print_str += ' ' * (margin - len(key.strip()))
158 fa382f9e Stavros Sachtouris
        #print_str += ':'
159 7493ccb6 Stavros Sachtouris
        if isinstance(val, dict):
160 f551841a Stavros Sachtouris
            print(print_str)
161 de73876b Stavros Sachtouris
            print_dict(
162 de73876b Stavros Sachtouris
                val,
163 f8681ec8 Stavros Sachtouris
                exclude=exclude,
164 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
165 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
166 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
167 7493ccb6 Stavros Sachtouris
        elif isinstance(val, list):
168 f551841a Stavros Sachtouris
            print(print_str)
169 de73876b Stavros Sachtouris
            print_list(
170 de73876b Stavros Sachtouris
                val,
171 f8681ec8 Stavros Sachtouris
                exclude=exclude,
172 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
173 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
174 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
175 7493ccb6 Stavros Sachtouris
        else:
176 a517ff50 Stavros Sachtouris
            print print_str + ' ' + ('%s' % val).strip()
177 fd5db045 Stavros Sachtouris
178 7493ccb6 Stavros Sachtouris
179 de73876b Stavros Sachtouris
def print_list(
180 24ff0a35 Stavros Sachtouris
        l, exclude=(), ident=0,
181 24ff0a35 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False):
182 f8681ec8 Stavros Sachtouris
    """
183 f8681ec8 Stavros Sachtouris
    Pretty-print a list object
184 f8681ec8 Stavros Sachtouris

185 f8681ec8 Stavros Sachtouris
    :param l: (list) the input
186 f8681ec8 Stavros Sachtouris

187 f8681ec8 Stavros Sachtouris
    :param excelude: (object - anytype) values to exclude from printing
188 f8681ec8 Stavros Sachtouris

189 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
190 f8681ec8 Stavros Sachtouris

191 f8681ec8 Stavros Sachtouris
    :param with_enumeration: (bool) enumerate each 1st level value if true
192 f8681ec8 Stavros Sachtouris

193 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
194 f8681ec8 Stavros Sachtouris
        2nd level or deeper
195 f8681ec8 Stavros Sachtouris

196 f8681ec8 Stavros Sachtouris
    :raises CLIError: (TypeError wrapper) non-list input
197 f8681ec8 Stavros Sachtouris
    """
198 7493ccb6 Stavros Sachtouris
    if not isinstance(l, list):
199 2ff0b7bd Stavros Sachtouris
        raiseCLIError(TypeError('Cannot list_print a non-list object'))
200 f551841a Stavros Sachtouris
201 db950b10 Stavros Sachtouris
    if l:
202 f91bc6b1 Stavros Sachtouris
        try:
203 24ff0a35 Stavros Sachtouris
            margin = max(len(('%s' % item).strip()) for item in l if not (
204 24ff0a35 Stavros Sachtouris
                isinstance(item, dict) or
205 24ff0a35 Stavros Sachtouris
                isinstance(item, list) or
206 24ff0a35 Stavros Sachtouris
                item in exclude))
207 f91bc6b1 Stavros Sachtouris
        except ValueError:
208 a517ff50 Stavros Sachtouris
            margin = (2 + len(('%s' % len(l)))) if enumerate else 1
209 7493ccb6 Stavros Sachtouris
210 d4abd11c Stavros Sachtouris
    counter = 1
211 d4abd11c Stavros Sachtouris
    prefix = ''
212 8fe9ed4e Stavros Sachtouris
    item_sep = False
213 7493ccb6 Stavros Sachtouris
    for item in sorted(l):
214 d0f431bb Stavros Sachtouris
        if ('%s' % item) in exclude:
215 7493ccb6 Stavros Sachtouris
            continue
216 f8681ec8 Stavros Sachtouris
        elif with_enumeration:
217 d4abd11c Stavros Sachtouris
            prefix = '%s. ' % counter
218 d4abd11c Stavros Sachtouris
            counter += 1
219 d4abd11c Stavros Sachtouris
            prefix = '%s%s' % (' ' * (ident - len(prefix)), prefix)
220 d4abd11c Stavros Sachtouris
        else:
221 d4abd11c Stavros Sachtouris
            prefix = ' ' * ident
222 8fe9ed4e Stavros Sachtouris
        if item_sep:
223 8fe9ed4e Stavros Sachtouris
            print '%s. . . . . . .' % prefix
224 8fe9ed4e Stavros Sachtouris
        else:
225 8fe9ed4e Stavros Sachtouris
            item_sep = True
226 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
227 c17b8bc0 Stavros Sachtouris
            if with_enumeration:
228 c17b8bc0 Stavros Sachtouris
                print(prefix)
229 de73876b Stavros Sachtouris
            print_dict(
230 de73876b Stavros Sachtouris
                item,
231 f8681ec8 Stavros Sachtouris
                exclude=exclude,
232 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
233 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
234 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
235 7493ccb6 Stavros Sachtouris
        elif isinstance(item, list):
236 c17b8bc0 Stavros Sachtouris
            if with_enumeration:
237 c17b8bc0 Stavros Sachtouris
                print(prefix)
238 de73876b Stavros Sachtouris
            print_list(
239 de73876b Stavros Sachtouris
                item,
240 f8681ec8 Stavros Sachtouris
                exclude=exclude,
241 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
242 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
243 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
244 7493ccb6 Stavros Sachtouris
        else:
245 d4abd11c Stavros Sachtouris
            print('%s%s' % (prefix, item))
246 7493ccb6 Stavros Sachtouris
247 fd5db045 Stavros Sachtouris
248 439826ec Stavros Sachtouris
def page_hold(index, limit, maxlen):
249 439826ec Stavros Sachtouris
    """Check if there are results to show, and hold the page when needed
250 439826ec Stavros Sachtouris
    :param index: (int) > 0
251 439826ec Stavros Sachtouris
    :param limit: (int) 0 < limit <= max, page hold if limit mod index == 0
252 439826ec Stavros Sachtouris
    :param maxlen: (int) Don't hold if index reaches maxlen
253 439826ec Stavros Sachtouris

254 439826ec Stavros Sachtouris
    :returns: True if there are more to show, False if all results are shown
255 439826ec Stavros Sachtouris
    """
256 439826ec Stavros Sachtouris
    if index >= limit and index % limit == 0:
257 439826ec Stavros Sachtouris
        if index >= maxlen:
258 439826ec Stavros Sachtouris
            return False
259 439826ec Stavros Sachtouris
        else:
260 439826ec Stavros Sachtouris
            print('(%s listed - %s more - "enter" to continue)' % (
261 439826ec Stavros Sachtouris
                index,
262 439826ec Stavros Sachtouris
                maxlen - index))
263 439826ec Stavros Sachtouris
            c = ' '
264 439826ec Stavros Sachtouris
            while c != '\n':
265 439826ec Stavros Sachtouris
                c = stdin.read(1)
266 439826ec Stavros Sachtouris
    return True
267 439826ec Stavros Sachtouris
268 439826ec Stavros Sachtouris
269 de73876b Stavros Sachtouris
def print_items(
270 24ff0a35 Stavros Sachtouris
        items, title=('id', 'name'),
271 24ff0a35 Stavros Sachtouris
        with_enumeration=False, with_redundancy=False,
272 24ff0a35 Stavros Sachtouris
        page_size=0):
273 a494a741 Stavros Sachtouris
    """print dict or list items in a list, using some values as title
274 a494a741 Stavros Sachtouris
    Objects of next level don't inherit enumeration (default: off) or titles
275 a494a741 Stavros Sachtouris

276 a494a741 Stavros Sachtouris
    :param items: (list) items are lists or dict
277 a494a741 Stavros Sachtouris
    :param title: (tuple) keys to use their values as title
278 a494a741 Stavros Sachtouris
    :param with_enumeration: (boolean) enumerate items (order id on title)
279 a494a741 Stavros Sachtouris
    :param with_redundancy: (boolean) values in title also appear on body
280 bd40efdf Stavros Sachtouris
    :param page_size: (int) show results in pages of page_size items, enter to
281 bd40efdf Stavros Sachtouris
        continue
282 a494a741 Stavros Sachtouris
    """
283 0e806947 Stavros Sachtouris
    if not items:
284 0e806947 Stavros Sachtouris
        return
285 bd40efdf Stavros Sachtouris
    try:
286 bd40efdf Stavros Sachtouris
        page_size = int(page_size) if int(page_size) > 0 else len(items)
287 bd40efdf Stavros Sachtouris
    except:
288 bd40efdf Stavros Sachtouris
        page_size = len(items)
289 bd40efdf Stavros Sachtouris
    num_of_pages = len(items) // page_size
290 bd40efdf Stavros Sachtouris
    num_of_pages += 1 if len(items) % page_size else 0
291 54d800e8 Stavros Sachtouris
    for i, item in enumerate(items):
292 a494a741 Stavros Sachtouris
        if with_enumeration:
293 a494a741 Stavros Sachtouris
            stdout.write('%s. ' % (i + 1))
294 a494a741 Stavros Sachtouris
        if isinstance(item, dict):
295 a494a741 Stavros Sachtouris
            title = sorted(set(title).intersection(item.keys()))
296 a494a741 Stavros Sachtouris
            if with_redundancy:
297 a517ff50 Stavros Sachtouris
                header = ' '.join('%s' % item[key] for key in title)
298 a494a741 Stavros Sachtouris
            else:
299 a517ff50 Stavros Sachtouris
                header = ' '.join('%s' % item.pop(key) for key in title)
300 aa25346e Stavros Sachtouris
            print(bold(header))
301 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
302 08c63ef5 Stavros Sachtouris
            print_dict(item, ident=1)
303 aa25346e Stavros Sachtouris
        elif isinstance(item, list):
304 08c63ef5 Stavros Sachtouris
            print_list(item, ident=1)
305 a494a741 Stavros Sachtouris
        else:
306 a494a741 Stavros Sachtouris
            print(' %s' % item)
307 439826ec Stavros Sachtouris
        page_hold(i + 1, page_size, len(items))
308 7493ccb6 Stavros Sachtouris
309 fd5db045 Stavros Sachtouris
310 7493ccb6 Stavros Sachtouris
def format_size(size):
311 001200c3 Stavros Sachtouris
    units = ('B', 'KiB', 'MiB', 'GiB', 'TiB')
312 7493ccb6 Stavros Sachtouris
    try:
313 7493ccb6 Stavros Sachtouris
        size = float(size)
314 2ff0b7bd Stavros Sachtouris
    except ValueError as err:
315 2ff0b7bd Stavros Sachtouris
        raiseCLIError(err, 'Cannot format %s in bytes' % size)
316 7493ccb6 Stavros Sachtouris
    for unit in units:
317 7493ccb6 Stavros Sachtouris
        if size < 1024:
318 7493ccb6 Stavros Sachtouris
            break
319 001200c3 Stavros Sachtouris
        size /= 1024.0
320 001200c3 Stavros Sachtouris
    s = ('%.2f' % size)
321 001200c3 Stavros Sachtouris
    while '.' in s and s[-1] in ('0', '.'):
322 001200c3 Stavros Sachtouris
        s = s[:-1]
323 7493ccb6 Stavros Sachtouris
    return s + unit
324 7493ccb6 Stavros Sachtouris
325 fd5db045 Stavros Sachtouris
326 001200c3 Stavros Sachtouris
def to_bytes(size, format):
327 001200c3 Stavros Sachtouris
    """
328 001200c3 Stavros Sachtouris
    :param size: (float) the size in the given format
329 001200c3 Stavros Sachtouris
    :param format: (case insensitive) KiB, KB, MiB, MB, GiB, GB, TiB, TB
330 001200c3 Stavros Sachtouris

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

439 001200c3 Stavros Sachtouris
    :param true_resp: (tuple of chars)
440 7147e1ca Stavros Sachtouris

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