Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ b482315a

History | View | Annotate | Download (13.3 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 2ff0b7bd Stavros Sachtouris
from kamaki.cli.errors import raiseCLIError
37 3dabe5d2 Stavros Sachtouris
38 dfee2caf Stavros Sachtouris
try:
39 dfee2caf Stavros Sachtouris
    from colors import magenta, red, yellow, bold
40 dfee2caf Stavros Sachtouris
except ImportError:
41 3dabe5d2 Stavros Sachtouris
    # No colours? No worries, use dummy foo instead
42 f93854ae Stavros Sachtouris
    def dummy(val):
43 dfee2caf Stavros Sachtouris
        return val
44 f93854ae Stavros Sachtouris
    red = yellow = magenta = bold = dummy
45 f997679d Stavros Sachtouris
46 fd5db045 Stavros Sachtouris
47 67cea04c Stavros Sachtouris
def remove_colors():
48 67cea04c Stavros Sachtouris
    global bold
49 3dabe5d2 Stavros Sachtouris
    global red
50 3dabe5d2 Stavros Sachtouris
    global yellow
51 3dabe5d2 Stavros Sachtouris
    global magenta
52 fd5db045 Stavros Sachtouris
53 67cea04c Stavros Sachtouris
    def dummy(val):
54 67cea04c Stavros Sachtouris
        return val
55 3dabe5d2 Stavros Sachtouris
    red = yellow = magenta = bold = dummy
56 7493ccb6 Stavros Sachtouris
57 fd5db045 Stavros Sachtouris
58 7493ccb6 Stavros Sachtouris
def pretty_keys(d, delim='_', recurcive=False):
59 f23a5cdb Stavros Sachtouris
    """<term>delim<term> to <term> <term> transformation
60 7493ccb6 Stavros Sachtouris
    """
61 7493ccb6 Stavros Sachtouris
    new_d = {}
62 7493ccb6 Stavros Sachtouris
    for key, val in d.items():
63 7493ccb6 Stavros Sachtouris
        new_key = key.split(delim)[-1]
64 7493ccb6 Stavros Sachtouris
        if recurcive and isinstance(val, dict):
65 fd5db045 Stavros Sachtouris
            new_val = pretty_keys(val, delim, recurcive)
66 7493ccb6 Stavros Sachtouris
        else:
67 7493ccb6 Stavros Sachtouris
            new_val = val
68 7493ccb6 Stavros Sachtouris
        new_d[new_key] = new_val
69 7493ccb6 Stavros Sachtouris
    return new_d
70 7493ccb6 Stavros Sachtouris
71 fd5db045 Stavros Sachtouris
72 f8681ec8 Stavros Sachtouris
def print_dict(d,
73 f8681ec8 Stavros Sachtouris
    exclude=(),
74 f8681ec8 Stavros Sachtouris
    ident=0,
75 f8681ec8 Stavros Sachtouris
    with_enumeration=False,
76 f8681ec8 Stavros Sachtouris
    recursive_enumeration=False):
77 f8681ec8 Stavros Sachtouris
    """
78 f8681ec8 Stavros Sachtouris
    Pretty-print a dictionary object
79 f8681ec8 Stavros Sachtouris

80 f8681ec8 Stavros Sachtouris
    :param d: (dict) the input
81 f8681ec8 Stavros Sachtouris

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

84 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
85 f8681ec8 Stavros Sachtouris

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

88 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
89 f8681ec8 Stavros Sachtouris
        2nd level or deeper
90 f8681ec8 Stavros Sachtouris

91 f8681ec8 Stavros Sachtouris
    :raises CLIError: (TypeError wrapper) non-dict input
92 f8681ec8 Stavros Sachtouris
    """
93 7493ccb6 Stavros Sachtouris
    if not isinstance(d, dict):
94 2ff0b7bd Stavros Sachtouris
        raiseCLIError(TypeError('Cannot dict_print a non-dict object'))
95 f551841a Stavros Sachtouris
96 db950b10 Stavros Sachtouris
    if d:
97 db950b10 Stavros Sachtouris
        margin = max(len(unicode(key).strip())\
98 db950b10 Stavros Sachtouris
            for key in d.keys() if key not in exclude)
99 7493ccb6 Stavros Sachtouris
100 f8681ec8 Stavros Sachtouris
    counter = 1
101 7493ccb6 Stavros Sachtouris
    for key, val in sorted(d.items()):
102 7493ccb6 Stavros Sachtouris
        if key in exclude:
103 7493ccb6 Stavros Sachtouris
            continue
104 f8681ec8 Stavros Sachtouris
        print_str = ''
105 f8681ec8 Stavros Sachtouris
        if with_enumeration:
106 f8681ec8 Stavros Sachtouris
            print_str = '%s. ' % counter
107 f8681ec8 Stavros Sachtouris
            counter += 1
108 f8681ec8 Stavros Sachtouris
        print_str = '%s%s' % (' ' * (ident - len(print_str)), print_str)
109 f551841a Stavros Sachtouris
        print_str += ('%s' % key).strip()
110 f551841a Stavros Sachtouris
        print_str += ' ' * (margin - len(unicode(key).strip()))
111 f551841a Stavros Sachtouris
        print_str += ': '
112 7493ccb6 Stavros Sachtouris
        if isinstance(val, dict):
113 f551841a Stavros Sachtouris
            print(print_str)
114 f8681ec8 Stavros Sachtouris
            print_dict(val,
115 f8681ec8 Stavros Sachtouris
                exclude=exclude,
116 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
117 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
118 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
119 7493ccb6 Stavros Sachtouris
        elif isinstance(val, list):
120 f551841a Stavros Sachtouris
            print(print_str)
121 f8681ec8 Stavros Sachtouris
            print_list(val,
122 f8681ec8 Stavros Sachtouris
                exclude=exclude,
123 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
124 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
125 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
126 7493ccb6 Stavros Sachtouris
        else:
127 0d249b3e Stavros Sachtouris
            print print_str + ' ' + unicode(val).strip()
128 fd5db045 Stavros Sachtouris
129 7493ccb6 Stavros Sachtouris
130 f8681ec8 Stavros Sachtouris
def print_list(l,
131 f8681ec8 Stavros Sachtouris
    exclude=(),
132 f8681ec8 Stavros Sachtouris
    ident=0,
133 f8681ec8 Stavros Sachtouris
    with_enumeration=False,
134 f8681ec8 Stavros Sachtouris
    recursive_enumeration=False):
135 f8681ec8 Stavros Sachtouris
    """
136 f8681ec8 Stavros Sachtouris
    Pretty-print a list object
137 f8681ec8 Stavros Sachtouris

138 f8681ec8 Stavros Sachtouris
    :param l: (list) the input
139 f8681ec8 Stavros Sachtouris

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

142 f8681ec8 Stavros Sachtouris
    :param ident: (int) initial indentation (recursive)
143 f8681ec8 Stavros Sachtouris

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

146 f8681ec8 Stavros Sachtouris
    :recursive_enumeration: (bool) recursively enumerate dicts and lists of
147 f8681ec8 Stavros Sachtouris
        2nd level or deeper
148 f8681ec8 Stavros Sachtouris

149 f8681ec8 Stavros Sachtouris
    :raises CLIError: (TypeError wrapper) non-list input
150 f8681ec8 Stavros Sachtouris
    """
151 7493ccb6 Stavros Sachtouris
    if not isinstance(l, list):
152 2ff0b7bd Stavros Sachtouris
        raiseCLIError(TypeError('Cannot list_print a non-list object'))
153 f551841a Stavros Sachtouris
154 db950b10 Stavros Sachtouris
    if l:
155 f91bc6b1 Stavros Sachtouris
        try:
156 f91bc6b1 Stavros Sachtouris
            margin = max(len(unicode(item).strip()) for item in l\
157 f91bc6b1 Stavros Sachtouris
                if not (isinstance(item, dict)\
158 f91bc6b1 Stavros Sachtouris
                or isinstance(item, list)\
159 f91bc6b1 Stavros Sachtouris
                or item in exclude))
160 f91bc6b1 Stavros Sachtouris
        except ValueError:
161 d4abd11c Stavros Sachtouris
            margin = (2 + len(unicode(len(l)))) if enumerate else 1
162 7493ccb6 Stavros Sachtouris
163 d4abd11c Stavros Sachtouris
    counter = 1
164 d4abd11c Stavros Sachtouris
    prefix = ''
165 7493ccb6 Stavros Sachtouris
    for item in sorted(l):
166 7493ccb6 Stavros Sachtouris
        if item in exclude:
167 7493ccb6 Stavros Sachtouris
            continue
168 f8681ec8 Stavros Sachtouris
        elif with_enumeration:
169 d4abd11c Stavros Sachtouris
            prefix = '%s. ' % counter
170 d4abd11c Stavros Sachtouris
            counter += 1
171 d4abd11c Stavros Sachtouris
            prefix = '%s%s' % (' ' * (ident - len(prefix)), prefix)
172 d4abd11c Stavros Sachtouris
        else:
173 d4abd11c Stavros Sachtouris
            prefix = ' ' * ident
174 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
175 c17b8bc0 Stavros Sachtouris
            if with_enumeration:
176 c17b8bc0 Stavros Sachtouris
                print(prefix)
177 f8681ec8 Stavros Sachtouris
            print_dict(item,
178 f8681ec8 Stavros Sachtouris
                exclude=exclude,
179 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
180 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
181 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
182 7493ccb6 Stavros Sachtouris
        elif isinstance(item, list):
183 c17b8bc0 Stavros Sachtouris
            if with_enumeration:
184 c17b8bc0 Stavros Sachtouris
                print(prefix)
185 f8681ec8 Stavros Sachtouris
            print_list(item,
186 f8681ec8 Stavros Sachtouris
                exclude=exclude,
187 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
188 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
189 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
190 7493ccb6 Stavros Sachtouris
        else:
191 d4abd11c Stavros Sachtouris
            print('%s%s' % (prefix, item))
192 7493ccb6 Stavros Sachtouris
193 fd5db045 Stavros Sachtouris
194 439826ec Stavros Sachtouris
def page_hold(index, limit, maxlen):
195 439826ec Stavros Sachtouris
    """Check if there are results to show, and hold the page when needed
196 439826ec Stavros Sachtouris
    :param index: (int) > 0
197 439826ec Stavros Sachtouris
    :param limit: (int) 0 < limit <= max, page hold if limit mod index == 0
198 439826ec Stavros Sachtouris
    :param maxlen: (int) Don't hold if index reaches maxlen
199 439826ec Stavros Sachtouris

200 439826ec Stavros Sachtouris
    :returns: True if there are more to show, False if all results are shown
201 439826ec Stavros Sachtouris
    """
202 439826ec Stavros Sachtouris
    if index >= limit and index % limit == 0:
203 439826ec Stavros Sachtouris
        if index >= maxlen:
204 439826ec Stavros Sachtouris
            return False
205 439826ec Stavros Sachtouris
        else:
206 439826ec Stavros Sachtouris
            print('(%s listed - %s more - "enter" to continue)' % (
207 439826ec Stavros Sachtouris
                index,
208 439826ec Stavros Sachtouris
                maxlen - index))
209 439826ec Stavros Sachtouris
            c = ' '
210 439826ec Stavros Sachtouris
            while c != '\n':
211 439826ec Stavros Sachtouris
                c = stdin.read(1)
212 439826ec Stavros Sachtouris
    return True
213 439826ec Stavros Sachtouris
214 439826ec Stavros Sachtouris
215 a494a741 Stavros Sachtouris
def print_items(items,
216 a494a741 Stavros Sachtouris
    title=('id', 'name'),
217 a494a741 Stavros Sachtouris
    with_enumeration=False,
218 bd40efdf Stavros Sachtouris
    with_redundancy=False,
219 bd40efdf Stavros Sachtouris
    page_size=0):
220 a494a741 Stavros Sachtouris
    """print dict or list items in a list, using some values as title
221 a494a741 Stavros Sachtouris
    Objects of next level don't inherit enumeration (default: off) or titles
222 a494a741 Stavros Sachtouris

223 a494a741 Stavros Sachtouris
    :param items: (list) items are lists or dict
224 a494a741 Stavros Sachtouris
    :param title: (tuple) keys to use their values as title
225 a494a741 Stavros Sachtouris
    :param with_enumeration: (boolean) enumerate items (order id on title)
226 a494a741 Stavros Sachtouris
    :param with_redundancy: (boolean) values in title also appear on body
227 bd40efdf Stavros Sachtouris
    :param page_size: (int) show results in pages of page_size items, enter to
228 bd40efdf Stavros Sachtouris
        continue
229 a494a741 Stavros Sachtouris
    """
230 0e806947 Stavros Sachtouris
    if not items:
231 0e806947 Stavros Sachtouris
        return
232 bd40efdf Stavros Sachtouris
    try:
233 bd40efdf Stavros Sachtouris
        page_size = int(page_size) if int(page_size) > 0 else len(items)
234 bd40efdf Stavros Sachtouris
    except:
235 bd40efdf Stavros Sachtouris
        page_size = len(items)
236 bd40efdf Stavros Sachtouris
    num_of_pages = len(items) // page_size
237 bd40efdf Stavros Sachtouris
    num_of_pages += 1 if len(items) % page_size else 0
238 54d800e8 Stavros Sachtouris
    for i, item in enumerate(items):
239 a494a741 Stavros Sachtouris
        if with_enumeration:
240 a494a741 Stavros Sachtouris
            stdout.write('%s. ' % (i + 1))
241 a494a741 Stavros Sachtouris
        if isinstance(item, dict):
242 a494a741 Stavros Sachtouris
            title = sorted(set(title).intersection(item.keys()))
243 a494a741 Stavros Sachtouris
            if with_redundancy:
244 a494a741 Stavros Sachtouris
                header = ' '.join(unicode(item[key]) for key in title)
245 a494a741 Stavros Sachtouris
            else:
246 a494a741 Stavros Sachtouris
                header = ' '.join(unicode(item.pop(key)) for key in title)
247 aa25346e Stavros Sachtouris
            print(bold(header))
248 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
249 08c63ef5 Stavros Sachtouris
            print_dict(item, ident=1)
250 aa25346e Stavros Sachtouris
        elif isinstance(item, list):
251 08c63ef5 Stavros Sachtouris
            print_list(item, ident=1)
252 a494a741 Stavros Sachtouris
        else:
253 a494a741 Stavros Sachtouris
            print(' %s' % item)
254 439826ec Stavros Sachtouris
        page_hold(i + 1, page_size, len(items))
255 7493ccb6 Stavros Sachtouris
256 fd5db045 Stavros Sachtouris
257 7493ccb6 Stavros Sachtouris
def format_size(size):
258 001200c3 Stavros Sachtouris
    units = ('B', 'KiB', 'MiB', 'GiB', 'TiB')
259 7493ccb6 Stavros Sachtouris
    try:
260 7493ccb6 Stavros Sachtouris
        size = float(size)
261 2ff0b7bd Stavros Sachtouris
    except ValueError as err:
262 2ff0b7bd Stavros Sachtouris
        raiseCLIError(err, 'Cannot format %s in bytes' % size)
263 7493ccb6 Stavros Sachtouris
    for unit in units:
264 7493ccb6 Stavros Sachtouris
        if size < 1024:
265 7493ccb6 Stavros Sachtouris
            break
266 001200c3 Stavros Sachtouris
        size /= 1024.0
267 001200c3 Stavros Sachtouris
    s = ('%.2f' % size)
268 001200c3 Stavros Sachtouris
    while '.' in s and s[-1] in ('0', '.'):
269 001200c3 Stavros Sachtouris
        s = s[:-1]
270 7493ccb6 Stavros Sachtouris
    return s + unit
271 7493ccb6 Stavros Sachtouris
272 fd5db045 Stavros Sachtouris
273 001200c3 Stavros Sachtouris
def to_bytes(size, format):
274 001200c3 Stavros Sachtouris
    """
275 001200c3 Stavros Sachtouris
    :param size: (float) the size in the given format
276 001200c3 Stavros Sachtouris
    :param format: (case insensitive) KiB, KB, MiB, MB, GiB, GB, TiB, TB
277 001200c3 Stavros Sachtouris

278 001200c3 Stavros Sachtouris
    :returns: (int) the size in bytes
279 001200c3 Stavros Sachtouris
    """
280 001200c3 Stavros Sachtouris
    format = format.upper()
281 001200c3 Stavros Sachtouris
    if format == 'B':
282 001200c3 Stavros Sachtouris
        return int(size)
283 001200c3 Stavros Sachtouris
    size = float(size)
284 001200c3 Stavros Sachtouris
    units_dc = ('KB', 'MB', 'GB', 'TB')
285 001200c3 Stavros Sachtouris
    units_bi = ('KIB', 'MIB', 'GIB', 'TIB')
286 001200c3 Stavros Sachtouris
287 001200c3 Stavros Sachtouris
    factor = 1024 if format in units_bi else 1000 if format in units_dc else 0
288 001200c3 Stavros Sachtouris
    if not factor:
289 001200c3 Stavros Sachtouris
        raise ValueError('Invalid data size format %s' % format)
290 001200c3 Stavros Sachtouris
    for prefix in ('K', 'M', 'G', 'T'):
291 001200c3 Stavros Sachtouris
        size *= factor
292 001200c3 Stavros Sachtouris
        if format.startswith(prefix):
293 001200c3 Stavros Sachtouris
            break
294 001200c3 Stavros Sachtouris
    return int(size)
295 001200c3 Stavros Sachtouris
296 001200c3 Stavros Sachtouris
297 fd5db045 Stavros Sachtouris
def dict2file(d, f, depth=0):
298 7493ccb6 Stavros Sachtouris
    for k, v in d.items():
299 fd5db045 Stavros Sachtouris
        f.write('%s%s: ' % ('\t' * depth, k))
300 fd5db045 Stavros Sachtouris
        if isinstance(v, dict):
301 7493ccb6 Stavros Sachtouris
            f.write('\n')
302 fd5db045 Stavros Sachtouris
            dict2file(v, f, depth + 1)
303 fd5db045 Stavros Sachtouris
        elif isinstance(v, list):
304 7493ccb6 Stavros Sachtouris
            f.write('\n')
305 fd5db045 Stavros Sachtouris
            list2file(v, f, depth + 1)
306 7493ccb6 Stavros Sachtouris
        else:
307 fd5db045 Stavros Sachtouris
            f.write(' %s\n' % unicode(v))
308 fd5db045 Stavros Sachtouris
309 7493ccb6 Stavros Sachtouris
310 fd5db045 Stavros Sachtouris
def list2file(l, f, depth=1):
311 7493ccb6 Stavros Sachtouris
    for item in l:
312 fd5db045 Stavros Sachtouris
        if isinstance(item, dict):
313 fd5db045 Stavros Sachtouris
            dict2file(item, f, depth + 1)
314 fd5db045 Stavros Sachtouris
        elif isinstance(item, list):
315 fd5db045 Stavros Sachtouris
            list2file(item, f, depth + 1)
316 7493ccb6 Stavros Sachtouris
        else:
317 fd5db045 Stavros Sachtouris
            f.write('%s%s\n' % ('\t' * depth, unicode(item)))
318 efbcdc41 Stavros Sachtouris
319 efbcdc41 Stavros Sachtouris
# Split input auxiliary
320 efbcdc41 Stavros Sachtouris
321 efbcdc41 Stavros Sachtouris
322 efbcdc41 Stavros Sachtouris
def _parse_with_regex(line, regex):
323 efbcdc41 Stavros Sachtouris
    re_parser = regex_compile(regex)
324 efbcdc41 Stavros Sachtouris
    return (re_parser.split(line), re_parser.findall(line))
325 efbcdc41 Stavros Sachtouris
326 efbcdc41 Stavros Sachtouris
327 efbcdc41 Stavros Sachtouris
def _sub_split(line):
328 efbcdc41 Stavros Sachtouris
    terms = []
329 efbcdc41 Stavros Sachtouris
    (sub_trivials, sub_interesting) = _parse_with_regex(line, ' ".*?" ')
330 efbcdc41 Stavros Sachtouris
    for subi, subipart in enumerate(sub_interesting):
331 efbcdc41 Stavros Sachtouris
        terms += sub_trivials[subi].split()
332 efbcdc41 Stavros Sachtouris
        terms.append(subipart[2:-2])
333 efbcdc41 Stavros Sachtouris
    terms += sub_trivials[-1].split()
334 efbcdc41 Stavros Sachtouris
    return terms
335 efbcdc41 Stavros Sachtouris
336 efbcdc41 Stavros Sachtouris
337 0ba7b031 Stavros Sachtouris
def old_split_input(line):
338 0ba7b031 Stavros Sachtouris
    """Use regular expressions to split a line correctly"""
339 efbcdc41 Stavros Sachtouris
    line = ' %s ' % line
340 efbcdc41 Stavros Sachtouris
    (trivial_parts, interesting_parts) = _parse_with_regex(line, ' \'.*?\' ')
341 efbcdc41 Stavros Sachtouris
    terms = []
342 efbcdc41 Stavros Sachtouris
    for i, ipart in enumerate(interesting_parts):
343 efbcdc41 Stavros Sachtouris
        terms += _sub_split(trivial_parts[i])
344 efbcdc41 Stavros Sachtouris
        terms.append(ipart[2:-2])
345 efbcdc41 Stavros Sachtouris
    terms += _sub_split(trivial_parts[-1])
346 efbcdc41 Stavros Sachtouris
    return terms
347 7147e1ca Stavros Sachtouris
348 7147e1ca Stavros Sachtouris
349 0ba7b031 Stavros Sachtouris
def _get_from_parsed(parsed_str):
350 0ba7b031 Stavros Sachtouris
    try:
351 0ba7b031 Stavros Sachtouris
        parsed_str = parsed_str.strip()
352 0ba7b031 Stavros Sachtouris
    except:
353 0ba7b031 Stavros Sachtouris
        return None
354 0ba7b031 Stavros Sachtouris
    if parsed_str:
355 0ba7b031 Stavros Sachtouris
        if parsed_str[0] == parsed_str[-1] and parsed_str[0] in ("'", '"'):
356 0ba7b031 Stavros Sachtouris
            return [parsed_str[1:-1]]
357 0ba7b031 Stavros Sachtouris
        return parsed_str.split(' ')
358 0ba7b031 Stavros Sachtouris
    return None
359 0ba7b031 Stavros Sachtouris
360 0ba7b031 Stavros Sachtouris
361 0ba7b031 Stavros Sachtouris
def split_input(line):
362 0ba7b031 Stavros Sachtouris
    if not line:
363 0ba7b031 Stavros Sachtouris
        return []
364 0ba7b031 Stavros Sachtouris
    reg_expr = '\'.*?\'|".*?"|^[\S]*$'
365 0ba7b031 Stavros Sachtouris
    (trivial_parts, interesting_parts) = _parse_with_regex(line, reg_expr)
366 0ba7b031 Stavros Sachtouris
    assert(len(trivial_parts) == 1 + len(interesting_parts))
367 0ba7b031 Stavros Sachtouris
    #print('  [split_input] trivial_parts %s are' % trivial_parts)
368 0ba7b031 Stavros Sachtouris
    #print('  [split_input] interesting_parts %s are' % interesting_parts)
369 0ba7b031 Stavros Sachtouris
    terms = []
370 0ba7b031 Stavros Sachtouris
    for i, tpart in enumerate(trivial_parts):
371 0ba7b031 Stavros Sachtouris
        part = _get_from_parsed(tpart)
372 0ba7b031 Stavros Sachtouris
        if part:
373 0ba7b031 Stavros Sachtouris
            terms += part
374 0ba7b031 Stavros Sachtouris
        try:
375 0ba7b031 Stavros Sachtouris
            part = _get_from_parsed(interesting_parts[i])
376 0ba7b031 Stavros Sachtouris
        except IndexError:
377 0ba7b031 Stavros Sachtouris
            break
378 0ba7b031 Stavros Sachtouris
        if part:
379 0ba7b031 Stavros Sachtouris
            terms += part
380 0ba7b031 Stavros Sachtouris
    return terms
381 0ba7b031 Stavros Sachtouris
382 0ba7b031 Stavros Sachtouris
383 001200c3 Stavros Sachtouris
def ask_user(msg, true_resp=['Y', 'y']):
384 7147e1ca Stavros Sachtouris
    """Print msg and read user response
385 7147e1ca Stavros Sachtouris

386 001200c3 Stavros Sachtouris
    :param true_resp: (tuple of chars)
387 7147e1ca Stavros Sachtouris

388 7147e1ca Stavros Sachtouris
    :returns: (bool) True if reponse in true responses, False otherwise
389 7147e1ca Stavros Sachtouris
    """
390 001200c3 Stavros Sachtouris
    stdout.write('%s (%s or enter for yes):' % (msg, ', '.join(true_resp)))
391 7147e1ca Stavros Sachtouris
    stdout.flush()
392 001200c3 Stavros Sachtouris
    user_response = stdin.readline()
393 001200c3 Stavros Sachtouris
    return user_response[0] in true_resp + ['\n']
394 0ba7b031 Stavros Sachtouris
395 0ba7b031 Stavros Sachtouris
396 b482315a Stavros Sachtouris
def spiner():
397 b482315a Stavros Sachtouris
    spins = ('/', '-', '\\', '|')
398 b482315a Stavros Sachtouris
    i = 0
399 b482315a Stavros Sachtouris
    stdout.write(' ')
400 b482315a Stavros Sachtouris
    while True:
401 b482315a Stavros Sachtouris
        stdout.write('\b%s' % spins[i % len(spins)])
402 b482315a Stavros Sachtouris
        stdout.flush()
403 b482315a Stavros Sachtouris
        i += 1
404 b482315a Stavros Sachtouris
        yield
405 b482315a Stavros Sachtouris
406 0ba7b031 Stavros Sachtouris
if __name__ == '__main__':
407 0ba7b031 Stavros Sachtouris
    examples = ['la_la le_le li_li',
408 0ba7b031 Stavros Sachtouris
        '\'la la\' \'le le\' \'li li\'',
409 0ba7b031 Stavros Sachtouris
        '\'la la\' le_le \'li li\'',
410 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' li_li',
411 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' \'li li\'',
412 0ba7b031 Stavros Sachtouris
        '"la la" "le le" "li li"',
413 0ba7b031 Stavros Sachtouris
        '"la la" le_le "li li"',
414 0ba7b031 Stavros Sachtouris
        'la_la "le le" li_li',
415 0ba7b031 Stavros Sachtouris
        '"la_la" "le le" "li li"',
416 0ba7b031 Stavros Sachtouris
        '\'la la\' "le le" \'li li\'',
417 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' "li li"',
418 0ba7b031 Stavros Sachtouris
        'la_la \'le le\' li_li',
419 0ba7b031 Stavros Sachtouris
        '\'la la\' le_le "li li"',
420 0ba7b031 Stavros Sachtouris
        '"la la" le_le \'li li\'',
421 0ba7b031 Stavros Sachtouris
        '"la la" \'le le\' li_li',
422 0ba7b031 Stavros Sachtouris
        'la_la \'le\'le\' "li\'li"',
423 0ba7b031 Stavros Sachtouris
        '"la \'le le\' la"',
424 0ba7b031 Stavros Sachtouris
        '\'la "le le" la\'',
425 0ba7b031 Stavros Sachtouris
        '\'la "la" la\' "le \'le\' le" li_"li"_li',
426 0ba7b031 Stavros Sachtouris
        '\'\' \'L\' "" "A"'
427 0ba7b031 Stavros Sachtouris
    ]
428 0ba7b031 Stavros Sachtouris
429 0ba7b031 Stavros Sachtouris
    for i, example in enumerate(examples):
430 0ba7b031 Stavros Sachtouris
        print('%s. Split this: (%s)' % (i + 1, example))
431 0ba7b031 Stavros Sachtouris
        ret = old_split_input(example)
432 0ba7b031 Stavros Sachtouris
        print('\t(%s) of size %s' % (ret, len(ret)))