Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ f8681ec8

History | View | Annotate | Download (8.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 08c63ef5 Stavros Sachtouris
from sys import stdout
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 d4abd11c Stavros Sachtouris
            print('%s' % prefix)
176 f8681ec8 Stavros Sachtouris
            print_dict(item,
177 f8681ec8 Stavros Sachtouris
                exclude=exclude,
178 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
179 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
180 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
181 7493ccb6 Stavros Sachtouris
        elif isinstance(item, list):
182 d4abd11c Stavros Sachtouris
            print('%s' % prefix)
183 f8681ec8 Stavros Sachtouris
            print_list(item,
184 f8681ec8 Stavros Sachtouris
                exclude=exclude,
185 f8681ec8 Stavros Sachtouris
                ident=margin + ident,
186 f8681ec8 Stavros Sachtouris
                with_enumeration=recursive_enumeration,
187 f8681ec8 Stavros Sachtouris
                recursive_enumeration=recursive_enumeration)
188 7493ccb6 Stavros Sachtouris
        else:
189 d4abd11c Stavros Sachtouris
            print('%s%s' % (prefix, item))
190 7493ccb6 Stavros Sachtouris
191 fd5db045 Stavros Sachtouris
192 7493ccb6 Stavros Sachtouris
def print_items(items, title=('id', 'name')):
193 7493ccb6 Stavros Sachtouris
    for item in items:
194 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict) or isinstance(item, list):
195 aa25346e Stavros Sachtouris
            header = ' '.join(unicode(item.pop(key))\
196 fd5db045 Stavros Sachtouris
                for key in title if key in item)
197 aa25346e Stavros Sachtouris
            print(' ')
198 aa25346e Stavros Sachtouris
            print(bold(header))
199 7493ccb6 Stavros Sachtouris
        if isinstance(item, dict):
200 08c63ef5 Stavros Sachtouris
            print_dict(item, ident=1)
201 aa25346e Stavros Sachtouris
        elif isinstance(item, list):
202 08c63ef5 Stavros Sachtouris
            print_list(item, ident=1)
203 7493ccb6 Stavros Sachtouris
204 fd5db045 Stavros Sachtouris
205 7493ccb6 Stavros Sachtouris
def format_size(size):
206 7493ccb6 Stavros Sachtouris
    units = ('B', 'K', 'M', 'G', 'T')
207 7493ccb6 Stavros Sachtouris
    try:
208 7493ccb6 Stavros Sachtouris
        size = float(size)
209 2ff0b7bd Stavros Sachtouris
    except ValueError as err:
210 2ff0b7bd Stavros Sachtouris
        raiseCLIError(err, 'Cannot format %s in bytes' % size)
211 7493ccb6 Stavros Sachtouris
    for unit in units:
212 7493ccb6 Stavros Sachtouris
        if size < 1024:
213 7493ccb6 Stavros Sachtouris
            break
214 7493ccb6 Stavros Sachtouris
        size /= 1024
215 7493ccb6 Stavros Sachtouris
    s = ('%.1f' % size)
216 7493ccb6 Stavros Sachtouris
    if '.0' == s[-2:]:
217 7493ccb6 Stavros Sachtouris
        s = s[:-2]
218 7493ccb6 Stavros Sachtouris
    return s + unit
219 7493ccb6 Stavros Sachtouris
220 fd5db045 Stavros Sachtouris
221 fd5db045 Stavros Sachtouris
def dict2file(d, f, depth=0):
222 7493ccb6 Stavros Sachtouris
    for k, v in d.items():
223 fd5db045 Stavros Sachtouris
        f.write('%s%s: ' % ('\t' * depth, k))
224 fd5db045 Stavros Sachtouris
        if isinstance(v, dict):
225 7493ccb6 Stavros Sachtouris
            f.write('\n')
226 fd5db045 Stavros Sachtouris
            dict2file(v, f, depth + 1)
227 fd5db045 Stavros Sachtouris
        elif isinstance(v, list):
228 7493ccb6 Stavros Sachtouris
            f.write('\n')
229 fd5db045 Stavros Sachtouris
            list2file(v, f, depth + 1)
230 7493ccb6 Stavros Sachtouris
        else:
231 fd5db045 Stavros Sachtouris
            f.write(' %s\n' % unicode(v))
232 fd5db045 Stavros Sachtouris
233 7493ccb6 Stavros Sachtouris
234 fd5db045 Stavros Sachtouris
def list2file(l, f, depth=1):
235 7493ccb6 Stavros Sachtouris
    for item in l:
236 fd5db045 Stavros Sachtouris
        if isinstance(item, dict):
237 fd5db045 Stavros Sachtouris
            dict2file(item, f, depth + 1)
238 fd5db045 Stavros Sachtouris
        elif isinstance(item, list):
239 fd5db045 Stavros Sachtouris
            list2file(item, f, depth + 1)
240 7493ccb6 Stavros Sachtouris
        else:
241 fd5db045 Stavros Sachtouris
            f.write('%s%s\n' % ('\t' * depth, unicode(item)))
242 efbcdc41 Stavros Sachtouris
243 efbcdc41 Stavros Sachtouris
# Split input auxiliary
244 efbcdc41 Stavros Sachtouris
245 efbcdc41 Stavros Sachtouris
246 efbcdc41 Stavros Sachtouris
def _parse_with_regex(line, regex):
247 efbcdc41 Stavros Sachtouris
    re_parser = regex_compile(regex)
248 efbcdc41 Stavros Sachtouris
    return (re_parser.split(line), re_parser.findall(line))
249 efbcdc41 Stavros Sachtouris
250 efbcdc41 Stavros Sachtouris
251 efbcdc41 Stavros Sachtouris
def _sub_split(line):
252 efbcdc41 Stavros Sachtouris
    terms = []
253 efbcdc41 Stavros Sachtouris
    (sub_trivials, sub_interesting) = _parse_with_regex(line, ' ".*?" ')
254 efbcdc41 Stavros Sachtouris
    for subi, subipart in enumerate(sub_interesting):
255 efbcdc41 Stavros Sachtouris
        terms += sub_trivials[subi].split()
256 efbcdc41 Stavros Sachtouris
        terms.append(subipart[2:-2])
257 efbcdc41 Stavros Sachtouris
    terms += sub_trivials[-1].split()
258 efbcdc41 Stavros Sachtouris
    return terms
259 efbcdc41 Stavros Sachtouris
260 efbcdc41 Stavros Sachtouris
261 efbcdc41 Stavros Sachtouris
def split_input(line):
262 efbcdc41 Stavros Sachtouris
    """Use regular expressions to split a line correctly
263 efbcdc41 Stavros Sachtouris
    """
264 efbcdc41 Stavros Sachtouris
    line = ' %s ' % line
265 efbcdc41 Stavros Sachtouris
    (trivial_parts, interesting_parts) = _parse_with_regex(line, ' \'.*?\' ')
266 efbcdc41 Stavros Sachtouris
    terms = []
267 efbcdc41 Stavros Sachtouris
    for i, ipart in enumerate(interesting_parts):
268 efbcdc41 Stavros Sachtouris
        terms += _sub_split(trivial_parts[i])
269 efbcdc41 Stavros Sachtouris
        terms.append(ipart[2:-2])
270 efbcdc41 Stavros Sachtouris
    terms += _sub_split(trivial_parts[-1])
271 efbcdc41 Stavros Sachtouris
    return terms