Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ dcfe7455

History | View | Annotate | Download (14.7 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 02846a75 Stavros Sachtouris
39 2ff0b7bd Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError
40 3dabe5d2 Stavros Sachtouris
41 6fb4af77 Stavros Sachtouris
suggest = dict(
42 6fb4af77 Stavros Sachtouris
    ansicolors=dict(
43 6fb4af77 Stavros Sachtouris
        active=False,
44 6fb4af77 Stavros Sachtouris
        url='#install-ansicolors-progress',
45 6fb4af77 Stavros Sachtouris
        description='Add colors to console responses'),
46 6fb4af77 Stavros Sachtouris
    progress=dict(
47 6fb4af77 Stavros Sachtouris
        active=False,
48 6fb4af77 Stavros Sachtouris
        url='#install-ansicolors-progress',
49 6fb4af77 Stavros Sachtouris
        description='Add progress bars to some commands'))
50 6fb4af77 Stavros Sachtouris
51 dfee2caf Stavros Sachtouris
try:
52 dfee2caf Stavros Sachtouris
    from colors import magenta, red, yellow, bold
53 dfee2caf Stavros Sachtouris
except ImportError:
54 3dabe5d2 Stavros Sachtouris
    # No colours? No worries, use dummy foo instead
55 f93854ae Stavros Sachtouris
    def dummy(val):
56 dfee2caf Stavros Sachtouris
        return val
57 f93854ae Stavros Sachtouris
    red = yellow = magenta = bold = dummy
58 6fb4af77 Stavros Sachtouris
    suggest['ansicolors']['active'] = True
59 6fb4af77 Stavros Sachtouris
60 6fb4af77 Stavros Sachtouris
try:
61 6fb4af77 Stavros Sachtouris
    from progress.bar import ShadyBar
62 6fb4af77 Stavros Sachtouris
except ImportError:
63 6fb4af77 Stavros Sachtouris
    suggest['progress']['active'] = True
64 6fb4af77 Stavros Sachtouris
65 6fb4af77 Stavros Sachtouris
66 6fb4af77 Stavros Sachtouris
def suggest_missing(miss=None):
67 6fb4af77 Stavros Sachtouris
    global suggest
68 6fb4af77 Stavros Sachtouris
    kamaki_docs = 'http://www.synnefo.org/docs/kamaki/latest'
69 6fb4af77 Stavros Sachtouris
    for k, v in (miss, suggest[miss]) if miss else suggest.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 67cea04c Stavros Sachtouris
def remove_colors():
79 67cea04c Stavros Sachtouris
    global bold
80 3dabe5d2 Stavros Sachtouris
    global red
81 3dabe5d2 Stavros Sachtouris
    global yellow
82 3dabe5d2 Stavros Sachtouris
    global magenta
83 fd5db045 Stavros Sachtouris
84 67cea04c Stavros Sachtouris
    def dummy(val):
85 67cea04c Stavros Sachtouris
        return val
86 3dabe5d2 Stavros Sachtouris
    red = yellow = magenta = bold = dummy
87 7493ccb6 Stavros Sachtouris
88 fd5db045 Stavros Sachtouris
89 7493ccb6 Stavros Sachtouris
def pretty_keys(d, delim='_', recurcive=False):
90 f23a5cdb Stavros Sachtouris
    """<term>delim<term> to <term> <term> transformation
91 7493ccb6 Stavros Sachtouris
    """
92 7493ccb6 Stavros Sachtouris
    new_d = {}
93 7493ccb6 Stavros Sachtouris
    for key, val in d.items():
94 7493ccb6 Stavros Sachtouris
        new_key = key.split(delim)[-1]
95 7493ccb6 Stavros Sachtouris
        if recurcive and isinstance(val, dict):
96 fd5db045 Stavros Sachtouris
            new_val = pretty_keys(val, delim, recurcive)
97 7493ccb6 Stavros Sachtouris
        else:
98 7493ccb6 Stavros Sachtouris
            new_val = val
99 7493ccb6 Stavros Sachtouris
        new_d[new_key] = new_val
100 7493ccb6 Stavros Sachtouris
    return new_d
101 7493ccb6 Stavros Sachtouris
102 fd5db045 Stavros Sachtouris
103 de73876b Stavros Sachtouris
def print_dict(
104 24ff0a35 Stavros Sachtouris
        d, exclude=(), ident=0,
105 24ff0a35 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False):
106 f8681ec8 Stavros Sachtouris
    """
107 f8681ec8 Stavros Sachtouris
    Pretty-print a dictionary object
108 f8681ec8 Stavros Sachtouris

109 f8681ec8 Stavros Sachtouris
    :param d: (dict) the input
110 f8681ec8 Stavros Sachtouris

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

113 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
114 f8681ec8 Stavros Sachtouris

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

117 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
118 f8681ec8 Stavros Sachtouris
        2nd level or deeper
119 f8681ec8 Stavros Sachtouris

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

168 f8681ec8 Stavros Sachtouris
    :param l: (list) the input
169 f8681ec8 Stavros Sachtouris

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

172 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
173 f8681ec8 Stavros Sachtouris

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

176 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
177 f8681ec8 Stavros Sachtouris
        2nd level or deeper
178 f8681ec8 Stavros Sachtouris

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

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

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

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

417 001200c3 Stavros Sachtouris
    :param true_resp: (tuple of chars)
418 7147e1ca Stavros Sachtouris

419 7147e1ca Stavros Sachtouris
    :returns: (bool) True if reponse in true responses, False otherwise
420 7147e1ca Stavros Sachtouris
    """
421 001200c3 Stavros Sachtouris
    stdout.write('%s (%s or enter for yes):' % (msg, ', '.join(true_resp)))
422 7147e1ca Stavros Sachtouris
    stdout.flush()
423 001200c3 Stavros Sachtouris
    user_response = stdin.readline()
424 001200c3 Stavros Sachtouris
    return user_response[0] in true_resp + ['\n']
425 0ba7b031 Stavros Sachtouris
426 0ba7b031 Stavros Sachtouris
427 02846a75 Stavros Sachtouris
def spiner(size=None):
428 b482315a Stavros Sachtouris
    spins = ('/', '-', '\\', '|')
429 b482315a Stavros Sachtouris
    stdout.write(' ')
430 02846a75 Stavros Sachtouris
    size = size or -1
431 02846a75 Stavros Sachtouris
    i = 0
432 02846a75 Stavros Sachtouris
    while size - i:
433 b482315a Stavros Sachtouris
        stdout.write('\b%s' % spins[i % len(spins)])
434 b482315a Stavros Sachtouris
        stdout.flush()
435 b482315a Stavros Sachtouris
        i += 1
436 02846a75 Stavros Sachtouris
        sleep(0.1)
437 b482315a Stavros Sachtouris
        yield
438 b58c1078 Stavros Sachtouris
    yield
439 b482315a Stavros Sachtouris
440 0ba7b031 Stavros Sachtouris
if __name__ == '__main__':
441 de73876b Stavros Sachtouris
    examples = [
442 de73876b Stavros Sachtouris
        'la_la le_le li_li',
443 0ba7b031 Stavros Sachtouris
        '\'la la\' \'le le\' \'li li\'',
444 0ba7b031 Stavros Sachtouris
        '\'la la\' le_le \'li li\'',
445 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' li_li',
446 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' \'li li\'',
447 0ba7b031 Stavros Sachtouris
        '"la la" "le le" "li li"',
448 0ba7b031 Stavros Sachtouris
        '"la la" le_le "li li"',
449 0ba7b031 Stavros Sachtouris
        'la_la "le le" li_li',
450 0ba7b031 Stavros Sachtouris
        '"la_la" "le le" "li li"',
451 0ba7b031 Stavros Sachtouris
        '\'la la\' "le le" \'li li\'',
452 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' "li li"',
453 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' li_li',
454 0ba7b031 Stavros Sachtouris
        '\'la la\' le_le "li li"',
455 0ba7b031 Stavros Sachtouris
        '"la la" le_le \'li li\'',
456 0ba7b031 Stavros Sachtouris
        '"la la" \'le le\' li_li',
457 0ba7b031 Stavros Sachtouris
        'la_la \'le\'le\' "li\'li"',
458 0ba7b031 Stavros Sachtouris
        '"la \'le le\' la"',
459 0ba7b031 Stavros Sachtouris
        '\'la "le le" la\'',
460 0ba7b031 Stavros Sachtouris
        '\'la "la" la\' "le \'le\' le" li_"li"_li',
461 de73876b Stavros Sachtouris
        '\'\' \'L\' "" "A"']
462 0ba7b031 Stavros Sachtouris
463 0ba7b031 Stavros Sachtouris
    for i, example in enumerate(examples):
464 0ba7b031 Stavros Sachtouris
        print('%s. Split this: (%s)' % (i + 1, example))
465 0ba7b031 Stavros Sachtouris
        ret = old_split_input(example)
466 0ba7b031 Stavros Sachtouris
        print('\t(%s) of size %s' % (ret, len(ret)))
467 14b25e00 Stavros Sachtouris
468 14b25e00 Stavros Sachtouris
469 14b25e00 Stavros Sachtouris
def get_path_size(testpath):
470 14b25e00 Stavros Sachtouris
    if path.isfile(testpath):
471 14b25e00 Stavros Sachtouris
        return path.getsize(testpath)
472 14b25e00 Stavros Sachtouris
    total_size = 0
473 14b25e00 Stavros Sachtouris
    for top, dirs, files in walk(path.abspath(testpath)):
474 14b25e00 Stavros Sachtouris
        for f in files:
475 14b25e00 Stavros Sachtouris
            f = path.join(top, f)
476 14b25e00 Stavros Sachtouris
            if path.isfile(f):
477 14b25e00 Stavros Sachtouris
                total_size += path.getsize(f)
478 14b25e00 Stavros Sachtouris
    return total_size