Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils / __init__.py @ 0f383dcc

History | View | Annotate | Download (15.2 kB)

1 e3f01d64 Stavros Sachtouris
# Copyright 2011-2013 GRNET S.A. All rights reserved.
2 7493ccb6 Stavros Sachtouris
#
3 7493ccb6 Stavros Sachtouris
# Redistribution and use in source and binary forms, with or
4 7493ccb6 Stavros Sachtouris
# without modification, are permitted provided that the following
5 7493ccb6 Stavros Sachtouris
# conditions are met:
6 7493ccb6 Stavros Sachtouris
#
7 7493ccb6 Stavros Sachtouris
#   1. Redistributions of source code must retain the above
8 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
9 7493ccb6 Stavros Sachtouris
#      disclaimer.
10 7493ccb6 Stavros Sachtouris
#
11 7493ccb6 Stavros Sachtouris
#   2. Redistributions in binary form must reproduce the above
12 7493ccb6 Stavros Sachtouris
#      copyright notice, this list of conditions and the following
13 7493ccb6 Stavros Sachtouris
#      disclaimer in the documentation and/or other materials
14 7493ccb6 Stavros Sachtouris
#      provided with the distribution.
15 7493ccb6 Stavros Sachtouris
#
16 7493ccb6 Stavros Sachtouris
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 7493ccb6 Stavros Sachtouris
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 7493ccb6 Stavros Sachtouris
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 7493ccb6 Stavros Sachtouris
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 7493ccb6 Stavros Sachtouris
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 7493ccb6 Stavros Sachtouris
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 7493ccb6 Stavros Sachtouris
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 7493ccb6 Stavros Sachtouris
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 7493ccb6 Stavros Sachtouris
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 7493ccb6 Stavros Sachtouris
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 7493ccb6 Stavros Sachtouris
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 7493ccb6 Stavros Sachtouris
# POSSIBILITY OF SUCH DAMAGE.
28 7493ccb6 Stavros Sachtouris
#
29 7493ccb6 Stavros Sachtouris
# The views and conclusions contained in the software and
30 7493ccb6 Stavros Sachtouris
# documentation are those of the authors and should not be
31 7493ccb6 Stavros Sachtouris
# interpreted as representing official policies, either expressed
32 7493ccb6 Stavros Sachtouris
# or implied, of GRNET S.A.
33 3dabe5d2 Stavros Sachtouris
34 bd40efdf Stavros Sachtouris
from sys import stdout, stdin
35 efbcdc41 Stavros Sachtouris
from re import compile as regex_compile
36 02846a75 Stavros Sachtouris
from time import sleep
37 14b25e00 Stavros Sachtouris
from os import walk, path
38 0399ac7e Stavros Sachtouris
from json import dumps
39 02846a75 Stavros Sachtouris
40 2ff0b7bd Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError
41 3dabe5d2 Stavros Sachtouris
42 f55d3a15 Stavros Sachtouris
43 a0608786 Stavros Sachtouris
INDENT_TAB = 4
44 f55d3a15 Stavros Sachtouris
45 f55d3a15 Stavros Sachtouris
46 362adf50 Stavros Sachtouris
suggest = dict(ansicolors=dict(
47 6fb4af77 Stavros Sachtouris
        active=False,
48 6fb4af77 Stavros Sachtouris
        url='#install-ansicolors-progress',
49 362adf50 Stavros Sachtouris
        description='Add colors to console responses'))
50 6fb4af77 Stavros Sachtouris
51 dfee2caf Stavros Sachtouris
try:
52 dfee2caf Stavros Sachtouris
    from colors import magenta, red, yellow, bold
53 dfee2caf Stavros Sachtouris
except ImportError:
54 f93854ae Stavros Sachtouris
    def dummy(val):
55 dfee2caf Stavros Sachtouris
        return val
56 f93854ae Stavros Sachtouris
    red = yellow = magenta = bold = dummy
57 6fb4af77 Stavros Sachtouris
    suggest['ansicolors']['active'] = True
58 6fb4af77 Stavros Sachtouris
59 6fb4af77 Stavros Sachtouris
60 0f383dcc Stavros Sachtouris
def _print(w):
61 0f383dcc Stavros Sachtouris
    """Print wrapper is used to help unittests check what is printed"""
62 0f383dcc Stavros Sachtouris
    print w
63 0f383dcc Stavros Sachtouris
64 0f383dcc Stavros Sachtouris
65 69691087 Stavros Sachtouris
def suggest_missing(miss=None, exclude=[]):
66 6fb4af77 Stavros Sachtouris
    global suggest
67 69691087 Stavros Sachtouris
    sgs = dict(suggest)
68 69691087 Stavros Sachtouris
    for exc in exclude:
69 69691087 Stavros Sachtouris
        try:
70 69691087 Stavros Sachtouris
            sgs.pop(exc)
71 69691087 Stavros Sachtouris
        except KeyError:
72 69691087 Stavros Sachtouris
            pass
73 6fb4af77 Stavros Sachtouris
    kamaki_docs = 'http://www.synnefo.org/docs/kamaki/latest'
74 69691087 Stavros Sachtouris
    for k, v in (miss, sgs[miss]) if miss else sgs.items():
75 6fb4af77 Stavros Sachtouris
        if v['active'] and stdout.isatty():
76 6fb4af77 Stavros Sachtouris
            print('Suggestion: for better user experience install %s' % k)
77 6fb4af77 Stavros Sachtouris
            print('\t%s' % v['description'])
78 6fb4af77 Stavros Sachtouris
            print('\tIt is easy, here are the instructions:')
79 6fb4af77 Stavros Sachtouris
            print('\t%s/installation.html%s' % (kamaki_docs, v['url']))
80 6fb4af77 Stavros Sachtouris
            print('')
81 f997679d Stavros Sachtouris
82 fd5db045 Stavros Sachtouris
83 f8426b5c Stavros Sachtouris
def guess_mime_type(
84 f8426b5c Stavros Sachtouris
        filename,
85 f8426b5c Stavros Sachtouris
        default_content_type='application/octet-stream',
86 f8426b5c Stavros Sachtouris
        default_encoding=None):
87 f8426b5c Stavros Sachtouris
    assert filename, 'Cannot guess mimetype for empty filename'
88 f8426b5c Stavros Sachtouris
    try:
89 f8426b5c Stavros Sachtouris
        from mimetypes import guess_type
90 f8426b5c Stavros Sachtouris
        ctype, cenc = guess_type(filename)
91 f8426b5c Stavros Sachtouris
        return ctype or default_content_type, cenc or default_encoding
92 f8426b5c Stavros Sachtouris
    except ImportError:
93 f8426b5c Stavros Sachtouris
        print 'WARNING: Cannot import mimetypes, using defaults'
94 f8426b5c Stavros Sachtouris
        return (default_content_type, default_encoding)
95 f8426b5c Stavros Sachtouris
96 f8426b5c Stavros Sachtouris
97 67cea04c Stavros Sachtouris
def remove_colors():
98 67cea04c Stavros Sachtouris
    global bold
99 3dabe5d2 Stavros Sachtouris
    global red
100 3dabe5d2 Stavros Sachtouris
    global yellow
101 3dabe5d2 Stavros Sachtouris
    global magenta
102 fd5db045 Stavros Sachtouris
103 67cea04c Stavros Sachtouris
    def dummy(val):
104 67cea04c Stavros Sachtouris
        return val
105 3dabe5d2 Stavros Sachtouris
    red = yellow = magenta = bold = dummy
106 7493ccb6 Stavros Sachtouris
107 fd5db045 Stavros Sachtouris
108 cdeadadc Stavros Sachtouris
def pretty_keys(d, delim='_', recursive=False):
109 cdeadadc Stavros Sachtouris
    """<term>delim<term> to <term> <term> transformation"""
110 cdeadadc Stavros Sachtouris
    new_d = dict(d)
111 cdeadadc Stavros Sachtouris
    for k, v in d.items():
112 cdeadadc Stavros Sachtouris
        new_v = new_d.pop(k)
113 cdeadadc Stavros Sachtouris
        new_d[k.replace(delim, ' ').strip()] = pretty_keys(
114 cdeadadc Stavros Sachtouris
            new_v, delim, True) if (
115 cdeadadc Stavros Sachtouris
                recursive and isinstance(v, dict)) else new_v
116 7493ccb6 Stavros Sachtouris
    return new_d
117 7493ccb6 Stavros Sachtouris
118 fd5db045 Stavros Sachtouris
119 0399ac7e Stavros Sachtouris
def print_json(data):
120 0399ac7e Stavros Sachtouris
    """Print a list or dict as json in console
121 0399ac7e Stavros Sachtouris

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

140 f55d3a15 Stavros Sachtouris
    :param d: (dict)
141 f8681ec8 Stavros Sachtouris

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

144 f55d3a15 Stavros Sachtouris
    :param indent: (int) initial indentation (recursive)
145 f8681ec8 Stavros Sachtouris

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

148 f55d3a15 Stavros Sachtouris
    :param recursive_enumeration: (bool) recursively enumerate iterables (does
149 f55d3a15 Stavros Sachtouris
        not enumerate 1st level keys)
150 f8681ec8 Stavros Sachtouris

151 f55d3a15 Stavros Sachtouris
    :raises CLIError: if preconditions fail
152 f8681ec8 Stavros Sachtouris
    """
153 f55d3a15 Stavros Sachtouris
    assert isinstance(d, dict), 'print_dict input must be a dict'
154 f55d3a15 Stavros Sachtouris
    assert indent >= 0, 'print_dict indent must be >= 0'
155 7493ccb6 Stavros Sachtouris
156 f55d3a15 Stavros Sachtouris
    for i, (k, v) in enumerate(d.items()):
157 f55d3a15 Stavros Sachtouris
        k = ('%s' % k).strip()
158 f55d3a15 Stavros Sachtouris
        if k in exclude:
159 7493ccb6 Stavros Sachtouris
            continue
160 f55d3a15 Stavros Sachtouris
        print_str = ' ' * indent
161 f55d3a15 Stavros Sachtouris
        print_str += '%s.' % (i + 1) if with_enumeration else ''
162 f55d3a15 Stavros Sachtouris
        print_str += '%s:' % k
163 f55d3a15 Stavros Sachtouris
        if isinstance(v, dict):
164 0f383dcc Stavros Sachtouris
            _print(print_str)
165 de73876b Stavros Sachtouris
            print_dict(
166 a0608786 Stavros Sachtouris
                v, exclude, indent + INDENT_TAB,
167 f55d3a15 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration)
168 f55d3a15 Stavros Sachtouris
        elif isinstance(v, list) or isinstance(v, tuple):
169 0f383dcc Stavros Sachtouris
            _print(print_str)
170 de73876b Stavros Sachtouris
            print_list(
171 a0608786 Stavros Sachtouris
                v, exclude, indent + INDENT_TAB,
172 f55d3a15 Stavros Sachtouris
                recursive_enumeration, recursive_enumeration)
173 7493ccb6 Stavros Sachtouris
        else:
174 0f383dcc Stavros Sachtouris
            _print('%s %s' % (print_str, v))
175 fd5db045 Stavros Sachtouris
176 7493ccb6 Stavros Sachtouris
177 de73876b Stavros Sachtouris
def print_list(
178 f55d3a15 Stavros Sachtouris
        l,
179 f55d3a15 Stavros Sachtouris
        exclude=(), indent=0,
180 24ff0a35 Stavros Sachtouris
        with_enumeration=False, recursive_enumeration=False):
181 f55d3a15 Stavros Sachtouris
    """Pretty-print a list of items
182 f55d3a15 Stavros Sachtouris
    <indent>key: <non iterable item>
183 f55d3a15 Stavros Sachtouris
    <indent>key:
184 a0608786 Stavros Sachtouris
    <indent + INDENT_TAB><pretty-print iterable>
185 f8681ec8 Stavros Sachtouris

186 f55d3a15 Stavros Sachtouris
    :param l: (list)
187 f8681ec8 Stavros Sachtouris

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

190 f55d3a15 Stavros Sachtouris
    :param indent: (int) initial indentation (recursive)
191 f8681ec8 Stavros Sachtouris

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

194 f55d3a15 Stavros Sachtouris
    :param recursive_enumeration: (bool) recursively enumerate iterables (does
195 f55d3a15 Stavros Sachtouris
        not enumerate 1st level keys)
196 f8681ec8 Stavros Sachtouris

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

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

258 a494a741 Stavros Sachtouris
    :param items: (list) items are lists or dict
259 f55d3a15 Stavros Sachtouris

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

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

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

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

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

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

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