Statistics
| Branch: | Tag: | Revision:

root / kamaki / cli / utils.py @ c17b8bc0

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