Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ cdeadadc

History | View | Annotate | Download (15.1 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 f93854ae Stavros Sachtouris
    def dummy(val):
55 dfee2caf Stavros Sachtouris
        return val
56 f93854ae Stavros Sachtouris
    red = yellow = magenta = bold = dummy
57 6fb4af77 Stavros Sachtouris
    suggest['ansicolors']['active'] = True
58 6fb4af77 Stavros Sachtouris
59 6fb4af77 Stavros Sachtouris
60 69691087 Stavros Sachtouris
def suggest_missing(miss=None, exclude=[]):
61 6fb4af77 Stavros Sachtouris
    global suggest
62 69691087 Stavros Sachtouris
    sgs = dict(suggest)
63 69691087 Stavros Sachtouris
    for exc in exclude:
64 69691087 Stavros Sachtouris
        try:
65 69691087 Stavros Sachtouris
            sgs.pop(exc)
66 69691087 Stavros Sachtouris
        except KeyError:
67 69691087 Stavros Sachtouris
            pass
68 6fb4af77 Stavros Sachtouris
    kamaki_docs = 'http://www.synnefo.org/docs/kamaki/latest'
69 69691087 Stavros Sachtouris
    for k, v in (miss, sgs[miss]) if miss else sgs.items():
70 6fb4af77 Stavros Sachtouris
        if v['active'] and stdout.isatty():
71 6fb4af77 Stavros Sachtouris
            print('Suggestion: for better user experience install %s' % k)
72 6fb4af77 Stavros Sachtouris
            print('\t%s' % v['description'])
73 6fb4af77 Stavros Sachtouris
            print('\tIt is easy, here are the instructions:')
74 6fb4af77 Stavros Sachtouris
            print('\t%s/installation.html%s' % (kamaki_docs, v['url']))
75 6fb4af77 Stavros Sachtouris
            print('')
76 f997679d Stavros Sachtouris
77 fd5db045 Stavros Sachtouris
78 f8426b5c Stavros Sachtouris
def guess_mime_type(
79 f8426b5c Stavros Sachtouris
        filename,
80 f8426b5c Stavros Sachtouris
        default_content_type='application/octet-stream',
81 f8426b5c Stavros Sachtouris
        default_encoding=None):
82 f8426b5c Stavros Sachtouris
    assert filename, 'Cannot guess mimetype for empty filename'
83 f8426b5c Stavros Sachtouris
    try:
84 f8426b5c Stavros Sachtouris
        from mimetypes import guess_type
85 f8426b5c Stavros Sachtouris
        ctype, cenc = guess_type(filename)
86 f8426b5c Stavros Sachtouris
        return ctype or default_content_type, cenc or default_encoding
87 f8426b5c Stavros Sachtouris
    except ImportError:
88 f8426b5c Stavros Sachtouris
        print 'WARNING: Cannot import mimetypes, using defaults'
89 f8426b5c Stavros Sachtouris
        return (default_content_type, default_encoding)
90 f8426b5c Stavros Sachtouris
91 f8426b5c Stavros Sachtouris
92 67cea04c Stavros Sachtouris
def remove_colors():
93 67cea04c Stavros Sachtouris
    global bold
94 3dabe5d2 Stavros Sachtouris
    global red
95 3dabe5d2 Stavros Sachtouris
    global yellow
96 3dabe5d2 Stavros Sachtouris
    global magenta
97 fd5db045 Stavros Sachtouris
98 67cea04c Stavros Sachtouris
    def dummy(val):
99 67cea04c Stavros Sachtouris
        return val
100 3dabe5d2 Stavros Sachtouris
    red = yellow = magenta = bold = dummy
101 7493ccb6 Stavros Sachtouris
102 fd5db045 Stavros Sachtouris
103 cdeadadc Stavros Sachtouris
def pretty_keys(d, delim='_', recursive=False):
104 cdeadadc Stavros Sachtouris
    """<term>delim<term> to <term> <term> transformation"""
105 cdeadadc Stavros Sachtouris
    new_d = dict(d)
106 cdeadadc Stavros Sachtouris
    for k, v in d.items():
107 cdeadadc Stavros Sachtouris
        new_v = new_d.pop(k)
108 cdeadadc Stavros Sachtouris
        new_d[k.replace(delim, ' ').strip()] = pretty_keys(
109 cdeadadc Stavros Sachtouris
            new_v, delim, True) if (
110 cdeadadc Stavros Sachtouris
                recursive and isinstance(v, dict)) else new_v
111 7493ccb6 Stavros Sachtouris
    return new_d
112 7493ccb6 Stavros Sachtouris
113 fd5db045 Stavros Sachtouris
114 0399ac7e Stavros Sachtouris
def print_json(data):
115 0399ac7e Stavros Sachtouris
    """Print a list or dict as json in console
116 0399ac7e Stavros Sachtouris

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

135 f55d3a15 Stavros Sachtouris
    :param d: (dict)
136 f8681ec8 Stavros Sachtouris

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

139 f55d3a15 Stavros Sachtouris
    :param indent: (int) initial indentation (recursive)
140 f8681ec8 Stavros Sachtouris

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

143 f55d3a15 Stavros Sachtouris
    :param recursive_enumeration: (bool) recursively enumerate iterables (does
144 f55d3a15 Stavros Sachtouris
        not enumerate 1st level keys)
145 f8681ec8 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 f55d3a15 Stavros Sachtouris
        print_str = ' ' * indent
156 f55d3a15 Stavros Sachtouris
        print_str += '%s.' % (i + 1) if with_enumeration else ''
157 f55d3a15 Stavros Sachtouris
        print_str += '%s:' % k
158 f55d3a15 Stavros Sachtouris
        if isinstance(v, dict):
159 f55d3a15 Stavros Sachtouris
            print print_str
160 de73876b Stavros Sachtouris
            print_dict(
161 a0608786 Stavros Sachtouris
                v, exclude, indent + INDENT_TAB,
162 f55d3a15 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration)
163 f55d3a15 Stavros Sachtouris
        elif isinstance(v, list) or isinstance(v, tuple):
164 f55d3a15 Stavros Sachtouris
            print print_str
165 de73876b Stavros Sachtouris
            print_list(
166 a0608786 Stavros Sachtouris
                v, exclude, indent + INDENT_TAB,
167 f55d3a15 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration)
168 7493ccb6 Stavros Sachtouris
        else:
169 f55d3a15 Stavros Sachtouris
            print '%s %s' % (print_str, v)
170 fd5db045 Stavros Sachtouris
171 7493ccb6 Stavros Sachtouris
172 de73876b Stavros Sachtouris
def print_list(
173 f55d3a15 Stavros Sachtouris
        l,
174 f55d3a15 Stavros Sachtouris
        exclude=(), indent=0,
175 24ff0a35 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False):
176 f55d3a15 Stavros Sachtouris
    """Pretty-print a list of items
177 f55d3a15 Stavros Sachtouris
    <indent>key: <non iterable item>
178 f55d3a15 Stavros Sachtouris
    <indent>key:
179 a0608786 Stavros Sachtouris
    <indent + INDENT_TAB><pretty-print iterable>
180 f8681ec8 Stavros Sachtouris

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

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

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

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

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

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

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

255 a494a741 Stavros Sachtouris
    :param items: (list) items are lists or dict
256 f55d3a15 Stavros Sachtouris

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

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

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

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

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

428 001200c3 Stavros Sachtouris
    :param true_resp: (tuple of chars)
429 7147e1ca Stavros Sachtouris

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