Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views / util.py @ a1ed6730

History | View | Annotate | Download (11.1 kB)

1 9fb7a900 Giorgos Korfiatis
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2 70e11eaa Sofia Papagiannaki
#
3 70e11eaa Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 70e11eaa Sofia Papagiannaki
# without modification, are permitted provided that the following
5 70e11eaa Sofia Papagiannaki
# conditions are met:
6 70e11eaa Sofia Papagiannaki
#
7 70e11eaa Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 70e11eaa Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 70e11eaa Sofia Papagiannaki
#      disclaimer.
10 70e11eaa Sofia Papagiannaki
#
11 70e11eaa Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 70e11eaa Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 70e11eaa Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 70e11eaa Sofia Papagiannaki
#      provided with the distribution.
15 70e11eaa Sofia Papagiannaki
#
16 70e11eaa Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 70e11eaa Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 70e11eaa Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 70e11eaa Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 70e11eaa Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 70e11eaa Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 70e11eaa Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 70e11eaa Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 70e11eaa Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 70e11eaa Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 70e11eaa Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 70e11eaa Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 70e11eaa Sofia Papagiannaki
#
29 70e11eaa Sofia Papagiannaki
# The views and conclusions contained in the software and
30 70e11eaa Sofia Papagiannaki
# documentation are those of the authors and should not be
31 70e11eaa Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 70e11eaa Sofia Papagiannaki
# or implied, of GRNET S.A.
33 70e11eaa Sofia Papagiannaki
34 70e11eaa Sofia Papagiannaki
from django.contrib import messages
35 70e11eaa Sofia Papagiannaki
from django.contrib.auth.views import redirect_to_login
36 70e11eaa Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
37 70e11eaa Sofia Papagiannaki
from django.core.xheaders import populate_xheaders
38 70e11eaa Sofia Papagiannaki
from django.http import HttpResponse
39 70e11eaa Sofia Papagiannaki
from django.shortcuts import redirect
40 70e11eaa Sofia Papagiannaki
from django.template import RequestContext, loader as template_loader
41 70e11eaa Sofia Papagiannaki
from django.utils.translation import ugettext as _
42 70e11eaa Sofia Papagiannaki
from django.views.generic.create_update import apply_extra_context, \
43 70e11eaa Sofia Papagiannaki
    get_model_and_form_class, lookup_object
44 70e11eaa Sofia Papagiannaki
45 70e11eaa Sofia Papagiannaki
from synnefo.lib.ordereddict import OrderedDict
46 70e11eaa Sofia Papagiannaki
47 70e11eaa Sofia Papagiannaki
from snf_django.lib.db.transaction import commit_on_success_strict
48 70e11eaa Sofia Papagiannaki
49 70e11eaa Sofia Papagiannaki
from astakos.im import presentation
50 70e11eaa Sofia Papagiannaki
from astakos.im.util import model_to_dict
51 70e11eaa Sofia Papagiannaki
from astakos.im.models import Resource
52 9fb7a900 Giorgos Korfiatis
import astakos.im.messages as astakos_messages
53 9fb7a900 Giorgos Korfiatis
import logging
54 9fb7a900 Giorgos Korfiatis
55 9fb7a900 Giorgos Korfiatis
logger = logging.getLogger(__name__)
56 9fb7a900 Giorgos Korfiatis
57 9fb7a900 Giorgos Korfiatis
58 9fb7a900 Giorgos Korfiatis
class ExceptionHandler(object):
59 9fb7a900 Giorgos Korfiatis
    def __init__(self, request):
60 9fb7a900 Giorgos Korfiatis
        self.request = request
61 9fb7a900 Giorgos Korfiatis
62 9fb7a900 Giorgos Korfiatis
    def __enter__(self):
63 9fb7a900 Giorgos Korfiatis
        pass
64 9fb7a900 Giorgos Korfiatis
65 9fb7a900 Giorgos Korfiatis
    def __exit__(self, exc_type, value, traceback):
66 9fb7a900 Giorgos Korfiatis
        if value is not None:  # exception
67 9fb7a900 Giorgos Korfiatis
            logger.exception(value)
68 9fb7a900 Giorgos Korfiatis
            m = _(astakos_messages.GENERIC_ERROR)
69 9fb7a900 Giorgos Korfiatis
            messages.error(self.request, m)
70 9fb7a900 Giorgos Korfiatis
            return True  # suppress exception
71 9fb7a900 Giorgos Korfiatis
72 70e11eaa Sofia Papagiannaki
73 70e11eaa Sofia Papagiannaki
def render_response(template, tab=None, status=200, context_instance=None, **kwargs):
74 70e11eaa Sofia Papagiannaki
    """
75 70e11eaa Sofia Papagiannaki
    Calls ``django.template.loader.render_to_string`` with an additional ``tab``
76 70e11eaa Sofia Papagiannaki
    keyword argument and returns an ``django.http.HttpResponse`` with the
77 70e11eaa Sofia Papagiannaki
    specified ``status``.
78 70e11eaa Sofia Papagiannaki
    """
79 70e11eaa Sofia Papagiannaki
    if tab is None:
80 70e11eaa Sofia Papagiannaki
        tab = template.partition('_')[0].partition('.html')[0]
81 70e11eaa Sofia Papagiannaki
    kwargs.setdefault('tab', tab)
82 70e11eaa Sofia Papagiannaki
    html = template_loader.render_to_string(
83 70e11eaa Sofia Papagiannaki
        template, kwargs, context_instance=context_instance)
84 70e11eaa Sofia Papagiannaki
    response = HttpResponse(html, status=status)
85 70e11eaa Sofia Papagiannaki
    return response
86 70e11eaa Sofia Papagiannaki
87 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
88 70e11eaa Sofia Papagiannaki
def _create_object(request, model=None, template_name=None,
89 70e11eaa Sofia Papagiannaki
        template_loader=template_loader, extra_context=None, post_save_redirect=None,
90 70e11eaa Sofia Papagiannaki
        login_required=False, context_processors=None, form_class=None,
91 70e11eaa Sofia Papagiannaki
        msg=None):
92 70e11eaa Sofia Papagiannaki
    """
93 70e11eaa Sofia Papagiannaki
    Based of django.views.generic.create_update.create_object which displays a
94 70e11eaa Sofia Papagiannaki
    summary page before creating the object.
95 70e11eaa Sofia Papagiannaki
    """
96 70e11eaa Sofia Papagiannaki
    response = None
97 70e11eaa Sofia Papagiannaki
98 70e11eaa Sofia Papagiannaki
    if extra_context is None: extra_context = {}
99 70e11eaa Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
100 70e11eaa Sofia Papagiannaki
        return redirect_to_login(request.path)
101 70e11eaa Sofia Papagiannaki
    try:
102 70e11eaa Sofia Papagiannaki
103 70e11eaa Sofia Papagiannaki
        model, form_class = get_model_and_form_class(model, form_class)
104 70e11eaa Sofia Papagiannaki
        extra_context['edit'] = 0
105 70e11eaa Sofia Papagiannaki
        if request.method == 'POST':
106 70e11eaa Sofia Papagiannaki
            form = form_class(request.POST, request.FILES)
107 70e11eaa Sofia Papagiannaki
            if form.is_valid():
108 70e11eaa Sofia Papagiannaki
                verify = request.GET.get('verify')
109 70e11eaa Sofia Papagiannaki
                edit = request.GET.get('edit')
110 70e11eaa Sofia Papagiannaki
                if verify == '1':
111 70e11eaa Sofia Papagiannaki
                    extra_context['show_form'] = False
112 70e11eaa Sofia Papagiannaki
                    extra_context['form_data'] = form.cleaned_data
113 70e11eaa Sofia Papagiannaki
                elif edit == '1':
114 70e11eaa Sofia Papagiannaki
                    extra_context['show_form'] = True
115 70e11eaa Sofia Papagiannaki
                else:
116 70e11eaa Sofia Papagiannaki
                    new_object = form.save()
117 70e11eaa Sofia Papagiannaki
                    if not msg:
118 70e11eaa Sofia Papagiannaki
                        msg = _("The %(verbose_name)s was created successfully.")
119 70e11eaa Sofia Papagiannaki
                    msg = msg % model._meta.__dict__
120 70e11eaa Sofia Papagiannaki
                    messages.success(request, msg, fail_silently=True)
121 70e11eaa Sofia Papagiannaki
                    response = redirect(post_save_redirect, new_object)
122 70e11eaa Sofia Papagiannaki
        else:
123 70e11eaa Sofia Papagiannaki
            form = form_class()
124 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
125 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
126 70e11eaa Sofia Papagiannaki
        return None
127 70e11eaa Sofia Papagiannaki
    else:
128 70e11eaa Sofia Papagiannaki
        if response == None:
129 70e11eaa Sofia Papagiannaki
            # Create the template, context, response
130 70e11eaa Sofia Papagiannaki
            if not template_name:
131 70e11eaa Sofia Papagiannaki
                template_name = "%s/%s_form.html" %\
132 70e11eaa Sofia Papagiannaki
                     (model._meta.app_label, model._meta.object_name.lower())
133 70e11eaa Sofia Papagiannaki
            t = template_loader.get_template(template_name)
134 70e11eaa Sofia Papagiannaki
            c = RequestContext(request, {
135 70e11eaa Sofia Papagiannaki
                'form': form
136 70e11eaa Sofia Papagiannaki
            }, context_processors)
137 70e11eaa Sofia Papagiannaki
            apply_extra_context(extra_context, c)
138 70e11eaa Sofia Papagiannaki
            response = HttpResponse(t.render(c))
139 70e11eaa Sofia Papagiannaki
        return response
140 70e11eaa Sofia Papagiannaki
141 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
142 70e11eaa Sofia Papagiannaki
def _update_object(request, model=None, object_id=None, slug=None,
143 70e11eaa Sofia Papagiannaki
        slug_field='slug', template_name=None, template_loader=template_loader,
144 70e11eaa Sofia Papagiannaki
        extra_context=None, post_save_redirect=None, login_required=False,
145 70e11eaa Sofia Papagiannaki
        context_processors=None, template_object_name='object',
146 70e11eaa Sofia Papagiannaki
        form_class=None, msg=None):
147 70e11eaa Sofia Papagiannaki
    """
148 70e11eaa Sofia Papagiannaki
    Based of django.views.generic.create_update.update_object which displays a
149 70e11eaa Sofia Papagiannaki
    summary page before updating the object.
150 70e11eaa Sofia Papagiannaki
    """
151 70e11eaa Sofia Papagiannaki
    response = None
152 70e11eaa Sofia Papagiannaki
153 70e11eaa Sofia Papagiannaki
    if extra_context is None: extra_context = {}
154 70e11eaa Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
155 70e11eaa Sofia Papagiannaki
        return redirect_to_login(request.path)
156 70e11eaa Sofia Papagiannaki
157 70e11eaa Sofia Papagiannaki
    try:
158 70e11eaa Sofia Papagiannaki
        model, form_class = get_model_and_form_class(model, form_class)
159 70e11eaa Sofia Papagiannaki
        obj = lookup_object(model, object_id, slug, slug_field)
160 70e11eaa Sofia Papagiannaki
161 70e11eaa Sofia Papagiannaki
        if request.method == 'POST':
162 70e11eaa Sofia Papagiannaki
            form = form_class(request.POST, request.FILES, instance=obj)
163 70e11eaa Sofia Papagiannaki
            if form.is_valid():
164 70e11eaa Sofia Papagiannaki
                verify = request.GET.get('verify')
165 70e11eaa Sofia Papagiannaki
                edit = request.GET.get('edit')
166 70e11eaa Sofia Papagiannaki
                if verify == '1':
167 70e11eaa Sofia Papagiannaki
                    extra_context['show_form'] = False
168 70e11eaa Sofia Papagiannaki
                    extra_context['form_data'] = form.cleaned_data
169 70e11eaa Sofia Papagiannaki
                elif edit == '1':
170 70e11eaa Sofia Papagiannaki
                    extra_context['show_form'] = True
171 70e11eaa Sofia Papagiannaki
                else:
172 70e11eaa Sofia Papagiannaki
                    obj = form.save()
173 70e11eaa Sofia Papagiannaki
                    if not msg:
174 70e11eaa Sofia Papagiannaki
                        msg = _("The %(verbose_name)s was created successfully.")
175 70e11eaa Sofia Papagiannaki
                    msg = msg % model._meta.__dict__
176 70e11eaa Sofia Papagiannaki
                    messages.success(request, msg, fail_silently=True)
177 70e11eaa Sofia Papagiannaki
                    response = redirect(post_save_redirect, obj)
178 70e11eaa Sofia Papagiannaki
        else:
179 70e11eaa Sofia Papagiannaki
            form = form_class(instance=obj)
180 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
181 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
182 70e11eaa Sofia Papagiannaki
        return None
183 70e11eaa Sofia Papagiannaki
    else:
184 70e11eaa Sofia Papagiannaki
        if response == None:
185 70e11eaa Sofia Papagiannaki
            if not template_name:
186 70e11eaa Sofia Papagiannaki
                template_name = "%s/%s_form.html" %\
187 70e11eaa Sofia Papagiannaki
                    (model._meta.app_label, model._meta.object_name.lower())
188 70e11eaa Sofia Papagiannaki
            t = template_loader.get_template(template_name)
189 70e11eaa Sofia Papagiannaki
            c = RequestContext(request, {
190 70e11eaa Sofia Papagiannaki
                'form': form,
191 70e11eaa Sofia Papagiannaki
                template_object_name: obj,
192 70e11eaa Sofia Papagiannaki
            }, context_processors)
193 70e11eaa Sofia Papagiannaki
            apply_extra_context(extra_context, c)
194 70e11eaa Sofia Papagiannaki
            response = HttpResponse(t.render(c))
195 70e11eaa Sofia Papagiannaki
            populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.attname))
196 70e11eaa Sofia Papagiannaki
        return response
197 70e11eaa Sofia Papagiannaki
198 70e11eaa Sofia Papagiannaki
def _resources_catalog(for_project=False, for_usage=False):
199 70e11eaa Sofia Papagiannaki
    """
200 70e11eaa Sofia Papagiannaki
    `resource_catalog` contains a list of tuples. Each tuple contains the group
201 70e11eaa Sofia Papagiannaki
    key the resource is assigned to and resources list of dicts that contain
202 70e11eaa Sofia Papagiannaki
    resource information.
203 70e11eaa Sofia Papagiannaki
    `resource_groups` contains information about the groups
204 70e11eaa Sofia Papagiannaki
    """
205 70e11eaa Sofia Papagiannaki
    # presentation data
206 70e11eaa Sofia Papagiannaki
    resources_meta = presentation.RESOURCES
207 70e11eaa Sofia Papagiannaki
    resource_groups = resources_meta.get('groups', {})
208 70e11eaa Sofia Papagiannaki
    resource_catalog = ()
209 70e11eaa Sofia Papagiannaki
    resource_keys = []
210 70e11eaa Sofia Papagiannaki
211 70e11eaa Sofia Papagiannaki
    # resources in database
212 70e11eaa Sofia Papagiannaki
    resource_details = map(lambda obj: model_to_dict(obj, exclude=[]),
213 70e11eaa Sofia Papagiannaki
                           Resource.objects.all())
214 70e11eaa Sofia Papagiannaki
    # initialize resource_catalog to contain all group/resource information
215 70e11eaa Sofia Papagiannaki
    for r in resource_details:
216 70e11eaa Sofia Papagiannaki
        if not r.get('group') in resource_groups:
217 70e11eaa Sofia Papagiannaki
            resource_groups[r.get('group')] = {'icon': 'unknown'}
218 70e11eaa Sofia Papagiannaki
219 70e11eaa Sofia Papagiannaki
    resource_keys = [r.get('str_repr') for r in resource_details]
220 70e11eaa Sofia Papagiannaki
    resource_catalog = [[g, filter(lambda r: r.get('group', '') == g,
221 70e11eaa Sofia Papagiannaki
                                   resource_details)] for g in resource_groups]
222 70e11eaa Sofia Papagiannaki
223 70e11eaa Sofia Papagiannaki
    # order groups, also include unknown groups
224 70e11eaa Sofia Papagiannaki
    groups_order = resources_meta.get('groups_order')
225 70e11eaa Sofia Papagiannaki
    for g in resource_groups.keys():
226 70e11eaa Sofia Papagiannaki
        if not g in groups_order:
227 70e11eaa Sofia Papagiannaki
            groups_order.append(g)
228 70e11eaa Sofia Papagiannaki
229 70e11eaa Sofia Papagiannaki
    # order resources, also include unknown resources
230 70e11eaa Sofia Papagiannaki
    resources_order = resources_meta.get('resources_order')
231 70e11eaa Sofia Papagiannaki
    for r in resource_keys:
232 70e11eaa Sofia Papagiannaki
        if not r in resources_order:
233 70e11eaa Sofia Papagiannaki
            resources_order.append(r)
234 70e11eaa Sofia Papagiannaki
235 70e11eaa Sofia Papagiannaki
    # sort catalog groups
236 70e11eaa Sofia Papagiannaki
    resource_catalog = sorted(resource_catalog,
237 70e11eaa Sofia Papagiannaki
                              key=lambda g: groups_order.index(g[0]))
238 70e11eaa Sofia Papagiannaki
239 70e11eaa Sofia Papagiannaki
    # sort groups
240 70e11eaa Sofia Papagiannaki
    def groupindex(g):
241 70e11eaa Sofia Papagiannaki
        return groups_order.index(g[0])
242 70e11eaa Sofia Papagiannaki
    resource_groups_list = sorted([(k, v) for k, v in resource_groups.items()],
243 70e11eaa Sofia Papagiannaki
                                  key=groupindex)
244 70e11eaa Sofia Papagiannaki
    resource_groups = OrderedDict(resource_groups_list)
245 70e11eaa Sofia Papagiannaki
246 70e11eaa Sofia Papagiannaki
    # sort resources
247 70e11eaa Sofia Papagiannaki
    def resourceindex(r):
248 70e11eaa Sofia Papagiannaki
        return resources_order.index(r['str_repr'])
249 70e11eaa Sofia Papagiannaki
250 70e11eaa Sofia Papagiannaki
    for index, group in enumerate(resource_catalog):
251 70e11eaa Sofia Papagiannaki
        resource_catalog[index][1] = sorted(resource_catalog[index][1],
252 70e11eaa Sofia Papagiannaki
                                            key=resourceindex)
253 70e11eaa Sofia Papagiannaki
        if len(resource_catalog[index][1]) == 0:
254 70e11eaa Sofia Papagiannaki
            resource_catalog.pop(index)
255 70e11eaa Sofia Papagiannaki
            for gindex, g in enumerate(resource_groups):
256 70e11eaa Sofia Papagiannaki
                if g[0] == group[0]:
257 70e11eaa Sofia Papagiannaki
                    resource_groups.pop(gindex)
258 70e11eaa Sofia Papagiannaki
259 70e11eaa Sofia Papagiannaki
    # filter out resources which user cannot request in a project application
260 70e11eaa Sofia Papagiannaki
    exclude = resources_meta.get('exclude_from_usage', [])
261 70e11eaa Sofia Papagiannaki
    for group_index, group_resources in enumerate(list(resource_catalog)):
262 70e11eaa Sofia Papagiannaki
        group, resources = group_resources
263 70e11eaa Sofia Papagiannaki
        for index, resource in list(enumerate(resources)):
264 70e11eaa Sofia Papagiannaki
            if for_project and not resource.get('allow_in_projects'):
265 70e11eaa Sofia Papagiannaki
                resources.remove(resource)
266 70e11eaa Sofia Papagiannaki
            if resource.get('str_repr') in exclude and for_usage:
267 70e11eaa Sofia Papagiannaki
                resources.remove(resource)
268 70e11eaa Sofia Papagiannaki
269 70e11eaa Sofia Papagiannaki
    # cleanup empty groups
270 70e11eaa Sofia Papagiannaki
    for group_index, group_resources in enumerate(list(resource_catalog)):
271 70e11eaa Sofia Papagiannaki
        group, resources = group_resources
272 70e11eaa Sofia Papagiannaki
        if len(resources) == 0:
273 70e11eaa Sofia Papagiannaki
            resource_catalog.pop(group_index)
274 70e11eaa Sofia Papagiannaki
            resource_groups.pop(group)
275 70e11eaa Sofia Papagiannaki
276 70e11eaa Sofia Papagiannaki
277 70e11eaa Sofia Papagiannaki
    return resource_catalog, resource_groups