Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ 0399ac7e

History | View | Annotate | Download (14.9 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 de73876b Stavros Sachtouris
def print_dict(
113 24ff0a35 Stavros Sachtouris
        d, exclude=(), ident=0,
114 24ff0a35 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False):
115 f8681ec8 Stavros Sachtouris
    """
116 f8681ec8 Stavros Sachtouris
    Pretty-print a dictionary object
117 f8681ec8 Stavros Sachtouris

118 f8681ec8 Stavros Sachtouris
    :param d: (dict) the input
119 f8681ec8 Stavros Sachtouris

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

122 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
123 f8681ec8 Stavros Sachtouris

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

126 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
127 f8681ec8 Stavros Sachtouris
        2nd level or deeper
128 f8681ec8 Stavros Sachtouris

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

177 f8681ec8 Stavros Sachtouris
    :param l: (list) the input
178 f8681ec8 Stavros Sachtouris

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

181 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
182 f8681ec8 Stavros Sachtouris

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

185 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
186 f8681ec8 Stavros Sachtouris
        2nd level or deeper
187 f8681ec8 Stavros Sachtouris

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

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

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

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

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

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