Statistics
| Branch: | Tag: | Revision:

root / snf-webproject / synnefo / webproject / management / util.py @ b0e7f310

History | View | Annotate | Download (5.3 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 b0e7f310 Christos Stavrakakis
import json
35 225cea18 Christos Stavrakakis
from datetime import datetime
36 225cea18 Christos Stavrakakis
from django.utils.timesince import timesince, timeuntil
37 225cea18 Christos Stavrakakis
38 225cea18 Christos Stavrakakis
from synnefo.util.text import uenc, udec
39 225cea18 Christos Stavrakakis
40 225cea18 Christos Stavrakakis
41 225cea18 Christos Stavrakakis
def parse_bool(value, strict=True):
42 225cea18 Christos Stavrakakis
    """Convert a string to boolen value.
43 225cea18 Christos Stavrakakis

44 225cea18 Christos Stavrakakis
    If string is True, then ValueError will be raised, if the string can not be
45 225cea18 Christos Stavrakakis
    converted to boolean. Otherwise the string will be returned as is.
46 225cea18 Christos Stavrakakis

47 225cea18 Christos Stavrakakis
    """
48 225cea18 Christos Stavrakakis
    if value.lower() in ("yes", "true", "t", "1"):
49 225cea18 Christos Stavrakakis
        return True
50 225cea18 Christos Stavrakakis
    if value.lower() in ("no", "false", "f", "0"):
51 225cea18 Christos Stavrakakis
        return False
52 225cea18 Christos Stavrakakis
53 225cea18 Christos Stavrakakis
    if strict:
54 225cea18 Christos Stavrakakis
        raise ValueError("Can convert '%s' to boolean value")
55 225cea18 Christos Stavrakakis
    else:
56 225cea18 Christos Stavrakakis
        return value
57 225cea18 Christos Stavrakakis
58 225cea18 Christos Stavrakakis
59 225cea18 Christos Stavrakakis
def format_bool(b):
60 225cea18 Christos Stavrakakis
    """Convert a boolean value to YES or NO."""
61 225cea18 Christos Stavrakakis
    return "YES" if b else "NO"
62 225cea18 Christos Stavrakakis
63 225cea18 Christos Stavrakakis
64 225cea18 Christos Stavrakakis
def format_date(d):
65 225cea18 Christos Stavrakakis
    if not d:
66 225cea18 Christos Stavrakakis
        return ""
67 225cea18 Christos Stavrakakis
68 225cea18 Christos Stavrakakis
    if d < datetime.now():
69 225cea18 Christos Stavrakakis
        return timesince(d) + " ago"
70 225cea18 Christos Stavrakakis
    else:
71 225cea18 Christos Stavrakakis
        return "in " + timeuntil(d)
72 225cea18 Christos Stavrakakis
73 225cea18 Christos Stavrakakis
74 225cea18 Christos Stavrakakis
def parse_filters(filter_by):
75 225cea18 Christos Stavrakakis
    """Parse a string into lookup parameters for QuerySet.filter(**kwargs).
76 225cea18 Christos Stavrakakis

77 225cea18 Christos Stavrakakis
    This functions converts a string of comma-separated key 'cond' val triples
78 225cea18 Christos Stavrakakis
    to two dictionaries, containing lookup parameters to be used for filter
79 225cea18 Christos Stavrakakis
    and exclude functions of QuerySet.
80 225cea18 Christos Stavrakakis

81 225cea18 Christos Stavrakakis
    e.g. filter_by="foo>=2, baz!=4" -> ({"foo__gte": "2"}, {"baz": "4"})
82 225cea18 Christos Stavrakakis

83 225cea18 Christos Stavrakakis
    """
84 225cea18 Christos Stavrakakis
85 225cea18 Christos Stavrakakis
    filter_dict = {}
86 225cea18 Christos Stavrakakis
    exclude_dict = {}
87 225cea18 Christos Stavrakakis
88 225cea18 Christos Stavrakakis
    filter_list = filter_by.split(",")
89 225cea18 Christos Stavrakakis
90 225cea18 Christos Stavrakakis
    def map_field_type(query):
91 225cea18 Christos Stavrakakis
        if "!=" in query:
92 225cea18 Christos Stavrakakis
            key, val = query.split("!=")
93 225cea18 Christos Stavrakakis
            exclude_dict[key] = parse_bool(val, strict=False)
94 225cea18 Christos Stavrakakis
            return
95 225cea18 Christos Stavrakakis
96 225cea18 Christos Stavrakakis
        OP_MAP = {
97 225cea18 Christos Stavrakakis
            ">=": "__gte",
98 225cea18 Christos Stavrakakis
            "=>": "__gte",
99 225cea18 Christos Stavrakakis
            ">":  "__gt",
100 225cea18 Christos Stavrakakis
            "<=": "__lte",
101 225cea18 Christos Stavrakakis
            "=<": "__lte",
102 225cea18 Christos Stavrakakis
            "<":  "__lt",
103 225cea18 Christos Stavrakakis
            "=":  "",
104 225cea18 Christos Stavrakakis
        }
105 225cea18 Christos Stavrakakis
106 225cea18 Christos Stavrakakis
        for op, new_op in OP_MAP.items():
107 225cea18 Christos Stavrakakis
            if op in query:
108 225cea18 Christos Stavrakakis
                key, val = query.split(op)
109 225cea18 Christos Stavrakakis
                filter_dict[key + new_op] = parse_bool(val, strict=False)
110 225cea18 Christos Stavrakakis
                return
111 225cea18 Christos Stavrakakis
112 225cea18 Christos Stavrakakis
    map(lambda x: map_field_type(x), filter_list)
113 225cea18 Christos Stavrakakis
114 225cea18 Christos Stavrakakis
    return (filter_dict, exclude_dict)
115 225cea18 Christos Stavrakakis
116 225cea18 Christos Stavrakakis
117 b0e7f310 Christos Stavrakakis
def pprint_table(out, table, headers=None, output_format='pretty',
118 b0e7f310 Christos Stavrakakis
                 separator=None):
119 225cea18 Christos Stavrakakis
    """Print a pretty, aligned string representation of table.
120 225cea18 Christos Stavrakakis

121 225cea18 Christos Stavrakakis
    Works by finding out the max width of each column and padding to data
122 225cea18 Christos Stavrakakis
    to this value.
123 225cea18 Christos Stavrakakis
    """
124 225cea18 Christos Stavrakakis
125 225cea18 Christos Stavrakakis
    assert(isinstance(table, (list, tuple))), "Invalid table type"
126 225cea18 Christos Stavrakakis
    if headers:
127 225cea18 Christos Stavrakakis
        assert(isinstance(headers, (list, tuple))), "Invalid headers type"
128 225cea18 Christos Stavrakakis
129 b0e7f310 Christos Stavrakakis
    sep = separator if separator else "  "
130 b0e7f310 Christos Stavrakakis
131 b0e7f310 Christos Stavrakakis
    def stringnify(obj):
132 225cea18 Christos Stavrakakis
        if isinstance(obj, (unicode, str)):
133 225cea18 Christos Stavrakakis
            return udec(obj)
134 225cea18 Christos Stavrakakis
        else:
135 225cea18 Christos Stavrakakis
            return str(obj)
136 225cea18 Christos Stavrakakis
137 b0e7f310 Christos Stavrakakis
    headers = map(stringnify, headers)
138 b0e7f310 Christos Stavrakakis
    table = [map(stringnify, row) for row in table]
139 b0e7f310 Christos Stavrakakis
140 b0e7f310 Christos Stavrakakis
    if output_format == "json":
141 b0e7f310 Christos Stavrakakis
        table = [dict(zip(headers, row)) for row in table]
142 b0e7f310 Christos Stavrakakis
        out.write(json.dumps(table, indent=4))
143 b0e7f310 Christos Stavrakakis
        out.write("\n")
144 b0e7f310 Christos Stavrakakis
    elif output_format == "csv":
145 b0e7f310 Christos Stavrakakis
        if headers:
146 b0e7f310 Christos Stavrakakis
            line = ",".join("\"%s\"" % uenc(v) for v in headers)
147 b0e7f310 Christos Stavrakakis
            out.write(line + "\n")
148 b0e7f310 Christos Stavrakakis
            for row in table:
149 b0e7f310 Christos Stavrakakis
                line = ",".join("\"%s\"" % uenc(v) for v in row)
150 b0e7f310 Christos Stavrakakis
                out.write(line + "\n")
151 b0e7f310 Christos Stavrakakis
    elif output_format == "pretty":
152 b0e7f310 Christos Stavrakakis
        # Find out the max width of each column
153 b0e7f310 Christos Stavrakakis
        widths = [max(map(len, col)) for col in zip(*([headers] + table))]
154 b0e7f310 Christos Stavrakakis
155 b0e7f310 Christos Stavrakakis
        t_length = sum(widths) + len(sep) * (len(widths) - 1)
156 b0e7f310 Christos Stavrakakis
        if headers:
157 b0e7f310 Christos Stavrakakis
            # pretty print the headers
158 b0e7f310 Christos Stavrakakis
            line = sep.join(uenc(v.rjust(w)) for v, w in zip(headers, widths))
159 b0e7f310 Christos Stavrakakis
            out.write(line + "\n")
160 b0e7f310 Christos Stavrakakis
            out.write("-" * t_length + "\n")
161 b0e7f310 Christos Stavrakakis
162 b0e7f310 Christos Stavrakakis
        # print the rest table
163 b0e7f310 Christos Stavrakakis
        for row in table:
164 b0e7f310 Christos Stavrakakis
            line = sep.join(uenc(v.rjust(w)) for v, w in zip(row, widths))
165 b0e7f310 Christos Stavrakakis
            out.write(line + "\n")
166 b0e7f310 Christos Stavrakakis
    else:
167 b0e7f310 Christos Stavrakakis
        raise ValueError("Unknown output format '%s'" % output_format)