Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / management / commands / _common.py @ 44f510e1

History | View | Annotate | Download (8.7 kB)

1
# Copyright 2012, 2013 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from datetime import datetime
35
import uuid
36

    
37
from django.core.validators import validate_email
38
from django.utils.timesince import timesince, timeuntil
39
from django.contrib.auth.models import Permission
40
from django.contrib.contenttypes.models import ContentType
41
from django.core.exceptions import FieldError
42
from django.core.management import CommandError
43

    
44
from synnefo.util import units
45
from synnefo.lib.ordereddict import OrderedDict
46
from astakos.im.models import AstakosUser
47
from astakos.im.resources import get_resources
48

    
49
DEFAULT_CONTENT_TYPE = None
50

    
51

    
52
def get_user(email_or_id, **kwargs):
53
    try:
54
        if email_or_id.isdigit():
55
            return AstakosUser.objects.get(id=int(email_or_id))
56
        else:
57
            return AstakosUser.objects.get(email__iexact=email_or_id, **kwargs)
58
    except AstakosUser.DoesNotExist, AstakosUser.MultipleObjectsReturned:
59
        return None
60

    
61

    
62
def format_bool(b):
63
    return 'YES' if b else 'NO'
64

    
65

    
66
def format_date(d):
67
    if not d:
68
        return ''
69

    
70
    if d < datetime.now():
71
        return timesince(d) + ' ago'
72
    else:
73
        return 'in ' + timeuntil(d)
74

    
75

    
76
def format_dict(d, level=1, ident=22):
77
    iteritems = d.iteritems()
78
    if not isinstance(d, OrderedDict):
79
        iteritems = sorted(iteritems)
80

    
81
    l = ['%s: %s\n' % (k.rjust(level*ident), format(v, level+1))
82
         for k, v in iteritems]
83
    l.insert(0, '\n')
84
    return ''.join(l)
85

    
86

    
87
def format_set(s):
88
    return list(s)
89

    
90

    
91
def format(obj, level=1, ident=22):
92
    if isinstance(obj, bool):
93
        return format_bool(obj)
94
    elif isinstance(obj, datetime):
95
        return format_date(obj)
96
    elif isinstance(obj, dict):
97
        return format_dict(obj, level, ident)
98
    elif isinstance(obj, set):
99
        return format_set(obj)
100
    else:
101
        return obj
102

    
103

    
104
def get_astakosuser_content_type():
105
    try:
106
        return ContentType.objects.get(app_label='im',
107
                                       model='astakosuser')
108
    except:
109
        return DEFAULT_CONTENT_TYPE
110

    
111

    
112
def add_user_permission(user, pname):
113
    content_type = get_astakosuser_content_type()
114
    if user.has_perm(pname):
115
        return 0, None
116
    p, created = Permission.objects.get_or_create(codename=pname,
117
                                                  name=pname.capitalize(),
118
                                                  content_type=content_type)
119
    user.user_permissions.add(p)
120
    return 1, created
121

    
122

    
123
def add_group_permission(group, pname):
124
    content_type = get_astakosuser_content_type()
125
    if pname in [p.codename for p in group.permissions.all()]:
126
        return 0, None
127
    content_type = ContentType.objects.get(app_label='im',
128
                                           model='astakosuser')
129
    p, created = Permission.objects.get_or_create(codename=pname,
130
                                                  name=pname.capitalize(),
131
                                                  content_type=content_type)
132
    group.permissions.add(p)
133
    return 1, created
134

    
135

    
136
def remove_user_permission(user, pname):
137
    content_type = get_astakosuser_content_type()
138
    if user.has_perm(pname):
139
        return 0
140
    try:
141
        p = Permission.objects.get(codename=pname,
142
                                   content_type=content_type)
143
        user.user_permissions.remove(p)
144
        return 1
145
    except Permission.DoesNotExist:
146
        return -1
147

    
148

    
149
def remove_group_permission(group, pname):
150
    content_type = get_astakosuser_content_type()
151
    if pname not in [p.codename for p in group.permissions.all()]:
152
        return 0
153
    try:
154
        p = Permission.objects.get(codename=pname,
155
                                   content_type=content_type)
156
        group.permissions.remove(p)
157
        return 1
158
    except Permission.DoesNotExist:
159
        return -1
160

    
161

    
162
def shortened(s, limit, suffix=True):
163
    length = len(s)
164
    if length <= limit:
165
        return s
166
    else:
167
        display = limit - 2
168
        if suffix:
169
            return '..' + s[-display:]
170
        else:
171
            return s[:display] + '..'
172

    
173

    
174
# Copied from snf-cyclades-app/synnefo/management/common.py
175
# It could be moved to snf-common
176
def filter_results(objects, filter_by):
177
    filter_list = filter_by.split(",")
178
    filter_dict = {}
179
    exclude_dict = {}
180

    
181
    def map_field_type(query):
182
        def fix_bool(val):
183
            if val.lower() in ("yes", "true", "t"):
184
                return True
185
            if val.lower() in ("no", "false", "f"):
186
                return False
187
            return val
188

    
189
        if "!=" in query:
190
            key, val = query.split("!=")
191
            exclude_dict[key] = fix_bool(val)
192
            return
193
        OP_MAP = {
194
            ">=": "__gte",
195
            "=>": "__gte",
196
            ">":  "__gt",
197
            "<=": "__lte",
198
            "=<": "__lte",
199
            "<":  "__lt",
200
            "=":  "",
201
        }
202
        for op, new_op in OP_MAP.items():
203
            if op in query:
204
                key, val = query.split(op)
205
                filter_dict[key + new_op] = fix_bool(val)
206
                return
207

    
208
    map(lambda x: map_field_type(x), filter_list)
209

    
210
    try:
211
        objects = objects.filter(**filter_dict)
212
        return objects.exclude(**exclude_dict)
213
    except FieldError as e:
214
        raise CommandError(e)
215
    except Exception as e:
216
        raise CommandError("Can not filter results: %s" % e)
217

    
218

    
219
def is_uuid(s):
220
    if s is None:
221
        return False
222
    try:
223
        uuid.UUID(s)
224
    except ValueError:
225
        return False
226
    else:
227
        return True
228

    
229

    
230
def is_email(s):
231
    if s is None:
232
        return False
233
    try:
234
        validate_email(s)
235
    except:
236
        return False
237
    else:
238
        return True
239

    
240

    
241
style_options = ', '.join(units.STYLES)
242

    
243

    
244
def check_style(style):
245
    if style not in units.STYLES:
246
        m = "Invalid unit style. Valid ones are %s." % style_options
247
        raise CommandError(m)
248

    
249

    
250
class ResourceDict(object):
251
    _object = None
252

    
253
    @classmethod
254
    def get(cls):
255
        if cls._object is None:
256
            cls._object = get_resources()
257
        return cls._object
258

    
259

    
260
def show_resource_value(number, resource, style):
261
    resource_dict = ResourceDict.get()
262
    unit = resource_dict[resource]['unit']
263
    return units.show(number, unit, style)
264

    
265

    
266
def show_quotas(qh_quotas, astakos_initial, info=None, style=None):
267
    labels = ('source', 'resource', 'base quota', 'total quota', 'usage')
268
    if info is not None:
269
        labels = ('uuid', 'email') + labels
270

    
271
    print_data = []
272
    for holder, holder_quotas in qh_quotas.iteritems():
273
        h_initial = astakos_initial.get(holder)
274
        if info is not None:
275
            email = info.get(holder, "")
276

    
277
        for source, source_quotas in holder_quotas.iteritems():
278
            s_initial = h_initial.get(source) if h_initial else None
279
            for resource, values in source_quotas.iteritems():
280
                initial = s_initial.get(resource) if s_initial else None
281
                initial = show_resource_value(initial, resource, style)
282
                limit = show_resource_value(values['limit'], resource, style)
283
                usage = show_resource_value(values['usage'], resource, style)
284
                fields = (source, resource, initial, limit, usage)
285
                if info is not None:
286
                    fields = (holder, email) + fields
287

    
288
                print_data.append(fields)
289
    return print_data, labels