root / snf-webproject / synnefo / webproject / management / util.py @ 225cea18
History | View | Annotate | Download (4.7 kB)
1 | 225cea18 | Christos Stavrakakis | # Copyright 2012 - 2013 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 225cea18 | Christos Stavrakakis | #
|
3 | 225cea18 | Christos Stavrakakis | # Redistribution and use in source and binary forms, with or
|
4 | 225cea18 | Christos Stavrakakis | # without modification, are permitted provided that the following
|
5 | 225cea18 | Christos Stavrakakis | # conditions are met:
|
6 | 225cea18 | Christos Stavrakakis | #
|
7 | 225cea18 | Christos Stavrakakis | # 1. Redistributions of source code must retain the above
|
8 | 225cea18 | Christos Stavrakakis | # copyright notice, this list of conditions and the following
|
9 | 225cea18 | Christos Stavrakakis | # disclaimer.
|
10 | 225cea18 | Christos Stavrakakis | #
|
11 | 225cea18 | Christos Stavrakakis | # 2. Redistributions in binary form must reproduce the above
|
12 | 225cea18 | Christos Stavrakakis | # copyright notice, this list of conditions and the following
|
13 | 225cea18 | Christos Stavrakakis | # disclaimer in the documentation and/or other materials
|
14 | 225cea18 | Christos Stavrakakis | # provided with the distribution.
|
15 | 225cea18 | Christos Stavrakakis | #
|
16 | 225cea18 | Christos Stavrakakis | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 225cea18 | Christos Stavrakakis | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 225cea18 | Christos Stavrakakis | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 225cea18 | Christos Stavrakakis | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 225cea18 | Christos Stavrakakis | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 225cea18 | Christos Stavrakakis | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 225cea18 | Christos Stavrakakis | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 225cea18 | Christos Stavrakakis | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 225cea18 | Christos Stavrakakis | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 225cea18 | Christos Stavrakakis | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 225cea18 | Christos Stavrakakis | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 225cea18 | Christos Stavrakakis | # POSSIBILITY OF SUCH DAMAGE.
|
28 | 225cea18 | Christos Stavrakakis | #
|
29 | 225cea18 | Christos Stavrakakis | # The views and conclusions contained in the software and
|
30 | 225cea18 | Christos Stavrakakis | # documentation are those of the authors and should not be
|
31 | 225cea18 | Christos Stavrakakis | # interpreted as representing official policies, either expressed
|
32 | 225cea18 | Christos Stavrakakis | # or implied, of GRNET S.A.
|
33 | 225cea18 | Christos Stavrakakis | |
34 | 225cea18 | Christos Stavrakakis | from datetime import datetime |
35 | 225cea18 | Christos Stavrakakis | from django.utils.timesince import timesince, timeuntil |
36 | 225cea18 | Christos Stavrakakis | |
37 | 225cea18 | Christos Stavrakakis | from synnefo.util.text import uenc, udec |
38 | 225cea18 | Christos Stavrakakis | |
39 | 225cea18 | Christos Stavrakakis | |
40 | 225cea18 | Christos Stavrakakis | def parse_bool(value, strict=True): |
41 | 225cea18 | Christos Stavrakakis | """Convert a string to boolen value.
|
42 | 225cea18 | Christos Stavrakakis |
|
43 | 225cea18 | Christos Stavrakakis | If string is True, then ValueError will be raised, if the string can not be
|
44 | 225cea18 | Christos Stavrakakis | converted to boolean. Otherwise the string will be returned as is.
|
45 | 225cea18 | Christos Stavrakakis |
|
46 | 225cea18 | Christos Stavrakakis | """
|
47 | 225cea18 | Christos Stavrakakis | if value.lower() in ("yes", "true", "t", "1"): |
48 | 225cea18 | Christos Stavrakakis | return True |
49 | 225cea18 | Christos Stavrakakis | if value.lower() in ("no", "false", "f", "0"): |
50 | 225cea18 | Christos Stavrakakis | return False |
51 | 225cea18 | Christos Stavrakakis | |
52 | 225cea18 | Christos Stavrakakis | if strict:
|
53 | 225cea18 | Christos Stavrakakis | raise ValueError("Can convert '%s' to boolean value") |
54 | 225cea18 | Christos Stavrakakis | else:
|
55 | 225cea18 | Christos Stavrakakis | return value
|
56 | 225cea18 | Christos Stavrakakis | |
57 | 225cea18 | Christos Stavrakakis | |
58 | 225cea18 | Christos Stavrakakis | def format_bool(b): |
59 | 225cea18 | Christos Stavrakakis | """Convert a boolean value to YES or NO."""
|
60 | 225cea18 | Christos Stavrakakis | return "YES" if b else "NO" |
61 | 225cea18 | Christos Stavrakakis | |
62 | 225cea18 | Christos Stavrakakis | |
63 | 225cea18 | Christos Stavrakakis | def format_date(d): |
64 | 225cea18 | Christos Stavrakakis | if not d: |
65 | 225cea18 | Christos Stavrakakis | return "" |
66 | 225cea18 | Christos Stavrakakis | |
67 | 225cea18 | Christos Stavrakakis | if d < datetime.now():
|
68 | 225cea18 | Christos Stavrakakis | return timesince(d) + " ago" |
69 | 225cea18 | Christos Stavrakakis | else:
|
70 | 225cea18 | Christos Stavrakakis | return "in " + timeuntil(d) |
71 | 225cea18 | Christos Stavrakakis | |
72 | 225cea18 | Christos Stavrakakis | |
73 | 225cea18 | Christos Stavrakakis | def parse_filters(filter_by): |
74 | 225cea18 | Christos Stavrakakis | """Parse a string into lookup parameters for QuerySet.filter(**kwargs).
|
75 | 225cea18 | Christos Stavrakakis |
|
76 | 225cea18 | Christos Stavrakakis | This functions converts a string of comma-separated key 'cond' val triples
|
77 | 225cea18 | Christos Stavrakakis | to two dictionaries, containing lookup parameters to be used for filter
|
78 | 225cea18 | Christos Stavrakakis | and exclude functions of QuerySet.
|
79 | 225cea18 | Christos Stavrakakis |
|
80 | 225cea18 | Christos Stavrakakis | e.g. filter_by="foo>=2, baz!=4" -> ({"foo__gte": "2"}, {"baz": "4"})
|
81 | 225cea18 | Christos Stavrakakis |
|
82 | 225cea18 | Christos Stavrakakis | """
|
83 | 225cea18 | Christos Stavrakakis | |
84 | 225cea18 | Christos Stavrakakis | filter_dict = {} |
85 | 225cea18 | Christos Stavrakakis | exclude_dict = {} |
86 | 225cea18 | Christos Stavrakakis | |
87 | 225cea18 | Christos Stavrakakis | filter_list = filter_by.split(",")
|
88 | 225cea18 | Christos Stavrakakis | |
89 | 225cea18 | Christos Stavrakakis | def map_field_type(query): |
90 | 225cea18 | Christos Stavrakakis | if "!=" in query: |
91 | 225cea18 | Christos Stavrakakis | key, val = query.split("!=")
|
92 | 225cea18 | Christos Stavrakakis | exclude_dict[key] = parse_bool(val, strict=False)
|
93 | 225cea18 | Christos Stavrakakis | return
|
94 | 225cea18 | Christos Stavrakakis | |
95 | 225cea18 | Christos Stavrakakis | OP_MAP = { |
96 | 225cea18 | Christos Stavrakakis | ">=": "__gte", |
97 | 225cea18 | Christos Stavrakakis | "=>": "__gte", |
98 | 225cea18 | Christos Stavrakakis | ">": "__gt", |
99 | 225cea18 | Christos Stavrakakis | "<=": "__lte", |
100 | 225cea18 | Christos Stavrakakis | "=<": "__lte", |
101 | 225cea18 | Christos Stavrakakis | "<": "__lt", |
102 | 225cea18 | Christos Stavrakakis | "=": "", |
103 | 225cea18 | Christos Stavrakakis | } |
104 | 225cea18 | Christos Stavrakakis | |
105 | 225cea18 | Christos Stavrakakis | for op, new_op in OP_MAP.items(): |
106 | 225cea18 | Christos Stavrakakis | if op in query: |
107 | 225cea18 | Christos Stavrakakis | key, val = query.split(op) |
108 | 225cea18 | Christos Stavrakakis | filter_dict[key + new_op] = parse_bool(val, strict=False)
|
109 | 225cea18 | Christos Stavrakakis | return
|
110 | 225cea18 | Christos Stavrakakis | |
111 | 225cea18 | Christos Stavrakakis | map(lambda x: map_field_type(x), filter_list) |
112 | 225cea18 | Christos Stavrakakis | |
113 | 225cea18 | Christos Stavrakakis | return (filter_dict, exclude_dict)
|
114 | 225cea18 | Christos Stavrakakis | |
115 | 225cea18 | Christos Stavrakakis | |
116 | 225cea18 | Christos Stavrakakis | def pprint_table(out, table, headers=None, separator=None): |
117 | 225cea18 | Christos Stavrakakis | """Print a pretty, aligned string representation of table.
|
118 | 225cea18 | Christos Stavrakakis |
|
119 | 225cea18 | Christos Stavrakakis | Works by finding out the max width of each column and padding to data
|
120 | 225cea18 | Christos Stavrakakis | to this value.
|
121 | 225cea18 | Christos Stavrakakis | """
|
122 | 225cea18 | Christos Stavrakakis | |
123 | 225cea18 | Christos Stavrakakis | assert(isinstance(table, (list, tuple))), "Invalid table type" |
124 | 225cea18 | Christos Stavrakakis | sep = separator if separator else " " |
125 | 225cea18 | Christos Stavrakakis | |
126 | 225cea18 | Christos Stavrakakis | if headers:
|
127 | 225cea18 | Christos Stavrakakis | assert(isinstance(headers, (list, tuple))), "Invalid headers type" |
128 | 225cea18 | Christos Stavrakakis | table.insert(0, headers)
|
129 | 225cea18 | Christos Stavrakakis | |
130 | 225cea18 | Christos Stavrakakis | def strignify(obj): |
131 | 225cea18 | Christos Stavrakakis | if isinstance(obj, (unicode, str)): |
132 | 225cea18 | Christos Stavrakakis | return udec(obj)
|
133 | 225cea18 | Christos Stavrakakis | else:
|
134 | 225cea18 | Christos Stavrakakis | return str(obj) |
135 | 225cea18 | Christos Stavrakakis | |
136 | 225cea18 | Christos Stavrakakis | table = [map(strignify, row) for row in table] |
137 | 225cea18 | Christos Stavrakakis | |
138 | 225cea18 | Christos Stavrakakis | # Find out the max width of each column
|
139 | 225cea18 | Christos Stavrakakis | widths = [max(map(len, col)) for col in zip(*table)] |
140 | 225cea18 | Christos Stavrakakis | |
141 | 225cea18 | Christos Stavrakakis | t_length = sum(widths) + len(sep) * (len(widths) - 1) |
142 | 225cea18 | Christos Stavrakakis | if headers:
|
143 | 225cea18 | Christos Stavrakakis | # pretty print the headers
|
144 | 225cea18 | Christos Stavrakakis | line = sep.join(uenc(v.rjust(w)) for v, w in zip(headers, widths)) |
145 | 225cea18 | Christos Stavrakakis | out.write(line + "\n")
|
146 | 225cea18 | Christos Stavrakakis | out.write("-" * t_length + "\n") |
147 | 225cea18 | Christos Stavrakakis | # remove headers
|
148 | 225cea18 | Christos Stavrakakis | table = table[1:]
|
149 | 225cea18 | Christos Stavrakakis | |
150 | 225cea18 | Christos Stavrakakis | # print the rest table
|
151 | 225cea18 | Christos Stavrakakis | for row in table: |
152 | 225cea18 | Christos Stavrakakis | line = sep.join(uenc(v.rjust(w)) for v, w in zip(row, widths)) |
153 | 225cea18 | Christos Stavrakakis | out.write(line + "\n") |