Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ 8c54338a

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

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

122 f8681ec8 Stavros Sachtouris
    :param d: (dict) the input
123 f8681ec8 Stavros Sachtouris

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

126 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
127 f8681ec8 Stavros Sachtouris

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

130 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
131 f8681ec8 Stavros Sachtouris
        2nd level or deeper
132 f8681ec8 Stavros Sachtouris

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

181 f8681ec8 Stavros Sachtouris
    :param l: (list) the input
182 f8681ec8 Stavros Sachtouris

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

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

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

189 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
190 f8681ec8 Stavros Sachtouris
        2nd level or deeper
191 f8681ec8 Stavros Sachtouris

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

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

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

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

430 001200c3 Stavros Sachtouris
    :param true_resp: (tuple of chars)
431 7147e1ca Stavros Sachtouris

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