Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (10.4 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.xheaders import populate_xheaders
37 70e11eaa Sofia Papagiannaki
from django.http import HttpResponse
38 70e11eaa Sofia Papagiannaki
from django.shortcuts import redirect
39 70e11eaa Sofia Papagiannaki
from django.template import RequestContext, loader as template_loader
40 70e11eaa Sofia Papagiannaki
from django.utils.translation import ugettext as _
41 70e11eaa Sofia Papagiannaki
from django.views.generic.create_update import apply_extra_context, \
42 70e11eaa Sofia Papagiannaki
    get_model_and_form_class, lookup_object
43 70e11eaa Sofia Papagiannaki
44 70e11eaa Sofia Papagiannaki
from synnefo.lib.ordereddict import OrderedDict
45 70e11eaa Sofia Papagiannaki
46 70e11eaa Sofia Papagiannaki
from astakos.im import presentation
47 70e11eaa Sofia Papagiannaki
from astakos.im.util import model_to_dict
48 70e11eaa Sofia Papagiannaki
from astakos.im.models import Resource
49 9fb7a900 Giorgos Korfiatis
import astakos.im.messages as astakos_messages
50 9fb7a900 Giorgos Korfiatis
import logging
51 9fb7a900 Giorgos Korfiatis
52 9fb7a900 Giorgos Korfiatis
logger = logging.getLogger(__name__)
53 9fb7a900 Giorgos Korfiatis
54 9fb7a900 Giorgos Korfiatis
55 9fb7a900 Giorgos Korfiatis
class ExceptionHandler(object):
56 9fb7a900 Giorgos Korfiatis
    def __init__(self, request):
57 9fb7a900 Giorgos Korfiatis
        self.request = request
58 9fb7a900 Giorgos Korfiatis
59 9fb7a900 Giorgos Korfiatis
    def __enter__(self):
60 9fb7a900 Giorgos Korfiatis
        pass
61 9fb7a900 Giorgos Korfiatis
62 9fb7a900 Giorgos Korfiatis
    def __exit__(self, exc_type, value, traceback):
63 9fb7a900 Giorgos Korfiatis
        if value is not None:  # exception
64 9fb7a900 Giorgos Korfiatis
            logger.exception(value)
65 9fb7a900 Giorgos Korfiatis
            m = _(astakos_messages.GENERIC_ERROR)
66 9fb7a900 Giorgos Korfiatis
            messages.error(self.request, m)
67 9fb7a900 Giorgos Korfiatis
            return True  # suppress exception
68 9fb7a900 Giorgos Korfiatis
69 70e11eaa Sofia Papagiannaki
70 8fb8d0cf Giorgos Korfiatis
def render_response(template, tab=None, status=200, context_instance=None,
71 8fb8d0cf Giorgos Korfiatis
                    **kwargs):
72 70e11eaa Sofia Papagiannaki
    """
73 8fb8d0cf Giorgos Korfiatis
    Calls ``django.template.loader.render_to_string`` with an additional
74 8fb8d0cf Giorgos Korfiatis
    ``tab`` keyword argument and returns an ``django.http.HttpResponse``
75 8fb8d0cf Giorgos Korfiatis
    with the specified ``status``.
76 70e11eaa Sofia Papagiannaki
    """
77 70e11eaa Sofia Papagiannaki
    if tab is None:
78 70e11eaa Sofia Papagiannaki
        tab = template.partition('_')[0].partition('.html')[0]
79 70e11eaa Sofia Papagiannaki
    kwargs.setdefault('tab', tab)
80 70e11eaa Sofia Papagiannaki
    html = template_loader.render_to_string(
81 70e11eaa Sofia Papagiannaki
        template, kwargs, context_instance=context_instance)
82 70e11eaa Sofia Papagiannaki
    response = HttpResponse(html, status=status)
83 70e11eaa Sofia Papagiannaki
    return response
84 70e11eaa Sofia Papagiannaki
85 8fb8d0cf Giorgos Korfiatis
86 70e11eaa Sofia Papagiannaki
def _create_object(request, model=None, template_name=None,
87 8fb8d0cf Giorgos Korfiatis
                   template_loader=template_loader, extra_context=None,
88 8fb8d0cf Giorgos Korfiatis
                   post_save_redirect=None, login_required=False,
89 8fb8d0cf Giorgos Korfiatis
                   context_processors=None, form_class=None, msg=None):
90 70e11eaa Sofia Papagiannaki
    """
91 70e11eaa Sofia Papagiannaki
    Based of django.views.generic.create_update.create_object which displays a
92 70e11eaa Sofia Papagiannaki
    summary page before creating the object.
93 70e11eaa Sofia Papagiannaki
    """
94 70e11eaa Sofia Papagiannaki
95 8fb8d0cf Giorgos Korfiatis
    if extra_context is None:
96 8fb8d0cf Giorgos Korfiatis
        extra_context = {}
97 70e11eaa Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
98 70e11eaa Sofia Papagiannaki
        return redirect_to_login(request.path)
99 9024ed2e Giorgos Korfiatis
100 9024ed2e Giorgos Korfiatis
    model, form_class = get_model_and_form_class(model, form_class)
101 9024ed2e Giorgos Korfiatis
    extra_context['edit'] = 0
102 9024ed2e Giorgos Korfiatis
    if request.method == 'POST':
103 9024ed2e Giorgos Korfiatis
        form = form_class(request.POST, request.FILES)
104 9024ed2e Giorgos Korfiatis
        if form.is_valid():
105 9024ed2e Giorgos Korfiatis
            verify = request.GET.get('verify')
106 9024ed2e Giorgos Korfiatis
            edit = request.GET.get('edit')
107 9024ed2e Giorgos Korfiatis
            if verify == '1':
108 9024ed2e Giorgos Korfiatis
                extra_context['show_form'] = False
109 9024ed2e Giorgos Korfiatis
                extra_context['form_data'] = form.cleaned_data
110 9024ed2e Giorgos Korfiatis
            elif edit == '1':
111 9024ed2e Giorgos Korfiatis
                extra_context['show_form'] = True
112 9024ed2e Giorgos Korfiatis
            else:
113 9024ed2e Giorgos Korfiatis
                new_object = form.save()
114 9024ed2e Giorgos Korfiatis
                if not msg:
115 9024ed2e Giorgos Korfiatis
                    msg = _(
116 9024ed2e Giorgos Korfiatis
                        "The %(verbose_name)s was created successfully.")
117 9024ed2e Giorgos Korfiatis
                msg = msg % model._meta.__dict__
118 9024ed2e Giorgos Korfiatis
                messages.success(request, msg, fail_silently=True)
119 9024ed2e Giorgos Korfiatis
                return redirect(post_save_redirect, new_object)
120 70e11eaa Sofia Papagiannaki
    else:
121 9024ed2e Giorgos Korfiatis
        form = form_class()
122 9024ed2e Giorgos Korfiatis
123 9024ed2e Giorgos Korfiatis
    # Create the template, context, response
124 9024ed2e Giorgos Korfiatis
    if not template_name:
125 9024ed2e Giorgos Korfiatis
        template_name = "%s/%s_form.html" % \
126 9024ed2e Giorgos Korfiatis
            (model._meta.app_label, model._meta.object_name.lower())
127 9024ed2e Giorgos Korfiatis
    t = template_loader.get_template(template_name)
128 9024ed2e Giorgos Korfiatis
    c = RequestContext(request, {
129 9024ed2e Giorgos Korfiatis
        'form': form
130 9024ed2e Giorgos Korfiatis
    }, context_processors)
131 9024ed2e Giorgos Korfiatis
    apply_extra_context(extra_context, c)
132 9024ed2e Giorgos Korfiatis
    return HttpResponse(t.render(c))
133 9024ed2e Giorgos Korfiatis
134 9024ed2e Giorgos Korfiatis
135 70e11eaa Sofia Papagiannaki
def _update_object(request, model=None, object_id=None, slug=None,
136 8fb8d0cf Giorgos Korfiatis
                   slug_field='slug', template_name=None,
137 8fb8d0cf Giorgos Korfiatis
                   template_loader=template_loader, extra_context=None,
138 8fb8d0cf Giorgos Korfiatis
                   post_save_redirect=None, login_required=False,
139 8fb8d0cf Giorgos Korfiatis
                   context_processors=None, template_object_name='object',
140 8fb8d0cf Giorgos Korfiatis
                   form_class=None, msg=None):
141 70e11eaa Sofia Papagiannaki
    """
142 70e11eaa Sofia Papagiannaki
    Based of django.views.generic.create_update.update_object which displays a
143 70e11eaa Sofia Papagiannaki
    summary page before updating the object.
144 70e11eaa Sofia Papagiannaki
    """
145 70e11eaa Sofia Papagiannaki
146 8fb8d0cf Giorgos Korfiatis
    if extra_context is None:
147 8fb8d0cf Giorgos Korfiatis
        extra_context = {}
148 70e11eaa Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
149 70e11eaa Sofia Papagiannaki
        return redirect_to_login(request.path)
150 70e11eaa Sofia Papagiannaki
151 9024ed2e Giorgos Korfiatis
    model, form_class = get_model_and_form_class(model, form_class)
152 9024ed2e Giorgos Korfiatis
    obj = lookup_object(model, object_id, slug, slug_field)
153 9024ed2e Giorgos Korfiatis
154 9024ed2e Giorgos Korfiatis
    if request.method == 'POST':
155 9024ed2e Giorgos Korfiatis
        form = form_class(request.POST, request.FILES, instance=obj)
156 9024ed2e Giorgos Korfiatis
        if form.is_valid():
157 9024ed2e Giorgos Korfiatis
            verify = request.GET.get('verify')
158 9024ed2e Giorgos Korfiatis
            edit = request.GET.get('edit')
159 9024ed2e Giorgos Korfiatis
            if verify == '1':
160 9024ed2e Giorgos Korfiatis
                extra_context['show_form'] = False
161 9024ed2e Giorgos Korfiatis
                extra_context['form_data'] = form.cleaned_data
162 9024ed2e Giorgos Korfiatis
            elif edit == '1':
163 9024ed2e Giorgos Korfiatis
                extra_context['show_form'] = True
164 9024ed2e Giorgos Korfiatis
            else:
165 9024ed2e Giorgos Korfiatis
                obj = form.save()
166 9024ed2e Giorgos Korfiatis
                if not msg:
167 9024ed2e Giorgos Korfiatis
                    msg = _(
168 9024ed2e Giorgos Korfiatis
                        "The %(verbose_name)s was created successfully.")
169 9024ed2e Giorgos Korfiatis
                msg = msg % model._meta.__dict__
170 9024ed2e Giorgos Korfiatis
                messages.success(request, msg, fail_silently=True)
171 9024ed2e Giorgos Korfiatis
                return redirect(post_save_redirect, obj)
172 70e11eaa Sofia Papagiannaki
    else:
173 9024ed2e Giorgos Korfiatis
        form = form_class(instance=obj)
174 9024ed2e Giorgos Korfiatis
175 9024ed2e Giorgos Korfiatis
    if not template_name:
176 9024ed2e Giorgos Korfiatis
        template_name = "%s/%s_form.html" % \
177 9024ed2e Giorgos Korfiatis
            (model._meta.app_label, model._meta.object_name.lower())
178 9024ed2e Giorgos Korfiatis
    t = template_loader.get_template(template_name)
179 9024ed2e Giorgos Korfiatis
    c = RequestContext(request, {
180 9024ed2e Giorgos Korfiatis
        'form': form,
181 9024ed2e Giorgos Korfiatis
        template_object_name: obj,
182 9024ed2e Giorgos Korfiatis
    }, context_processors)
183 9024ed2e Giorgos Korfiatis
    apply_extra_context(extra_context, c)
184 9024ed2e Giorgos Korfiatis
    response = HttpResponse(t.render(c))
185 9024ed2e Giorgos Korfiatis
    populate_xheaders(request, response, model,
186 9024ed2e Giorgos Korfiatis
                      getattr(obj, obj._meta.pk.attname))
187 9024ed2e Giorgos Korfiatis
    return response
188 70e11eaa Sofia Papagiannaki
189 8fb8d0cf Giorgos Korfiatis
190 70e11eaa Sofia Papagiannaki
def _resources_catalog(for_project=False, for_usage=False):
191 70e11eaa Sofia Papagiannaki
    """
192 70e11eaa Sofia Papagiannaki
    `resource_catalog` contains a list of tuples. Each tuple contains the group
193 70e11eaa Sofia Papagiannaki
    key the resource is assigned to and resources list of dicts that contain
194 70e11eaa Sofia Papagiannaki
    resource information.
195 70e11eaa Sofia Papagiannaki
    `resource_groups` contains information about the groups
196 70e11eaa Sofia Papagiannaki
    """
197 70e11eaa Sofia Papagiannaki
    # presentation data
198 70e11eaa Sofia Papagiannaki
    resources_meta = presentation.RESOURCES
199 70e11eaa Sofia Papagiannaki
    resource_groups = resources_meta.get('groups', {})
200 70e11eaa Sofia Papagiannaki
    resource_catalog = ()
201 70e11eaa Sofia Papagiannaki
    resource_keys = []
202 70e11eaa Sofia Papagiannaki
203 70e11eaa Sofia Papagiannaki
    # resources in database
204 70e11eaa Sofia Papagiannaki
    resource_details = map(lambda obj: model_to_dict(obj, exclude=[]),
205 70e11eaa Sofia Papagiannaki
                           Resource.objects.all())
206 70e11eaa Sofia Papagiannaki
    # initialize resource_catalog to contain all group/resource information
207 70e11eaa Sofia Papagiannaki
    for r in resource_details:
208 70e11eaa Sofia Papagiannaki
        if not r.get('group') in resource_groups:
209 70e11eaa Sofia Papagiannaki
            resource_groups[r.get('group')] = {'icon': 'unknown'}
210 70e11eaa Sofia Papagiannaki
211 70e11eaa Sofia Papagiannaki
    resource_keys = [r.get('str_repr') for r in resource_details]
212 70e11eaa Sofia Papagiannaki
    resource_catalog = [[g, filter(lambda r: r.get('group', '') == g,
213 70e11eaa Sofia Papagiannaki
                                   resource_details)] for g in resource_groups]
214 70e11eaa Sofia Papagiannaki
215 70e11eaa Sofia Papagiannaki
    # order groups, also include unknown groups
216 70e11eaa Sofia Papagiannaki
    groups_order = resources_meta.get('groups_order')
217 70e11eaa Sofia Papagiannaki
    for g in resource_groups.keys():
218 70e11eaa Sofia Papagiannaki
        if not g in groups_order:
219 70e11eaa Sofia Papagiannaki
            groups_order.append(g)
220 70e11eaa Sofia Papagiannaki
221 70e11eaa Sofia Papagiannaki
    # order resources, also include unknown resources
222 70e11eaa Sofia Papagiannaki
    resources_order = resources_meta.get('resources_order')
223 70e11eaa Sofia Papagiannaki
    for r in resource_keys:
224 70e11eaa Sofia Papagiannaki
        if not r in resources_order:
225 70e11eaa Sofia Papagiannaki
            resources_order.append(r)
226 70e11eaa Sofia Papagiannaki
227 70e11eaa Sofia Papagiannaki
    # sort catalog groups
228 70e11eaa Sofia Papagiannaki
    resource_catalog = sorted(resource_catalog,
229 70e11eaa Sofia Papagiannaki
                              key=lambda g: groups_order.index(g[0]))
230 70e11eaa Sofia Papagiannaki
231 70e11eaa Sofia Papagiannaki
    # sort groups
232 70e11eaa Sofia Papagiannaki
    def groupindex(g):
233 70e11eaa Sofia Papagiannaki
        return groups_order.index(g[0])
234 70e11eaa Sofia Papagiannaki
    resource_groups_list = sorted([(k, v) for k, v in resource_groups.items()],
235 70e11eaa Sofia Papagiannaki
                                  key=groupindex)
236 70e11eaa Sofia Papagiannaki
    resource_groups = OrderedDict(resource_groups_list)
237 70e11eaa Sofia Papagiannaki
238 70e11eaa Sofia Papagiannaki
    # sort resources
239 70e11eaa Sofia Papagiannaki
    def resourceindex(r):
240 70e11eaa Sofia Papagiannaki
        return resources_order.index(r['str_repr'])
241 70e11eaa Sofia Papagiannaki
242 70e11eaa Sofia Papagiannaki
    for index, group in enumerate(resource_catalog):
243 70e11eaa Sofia Papagiannaki
        resource_catalog[index][1] = sorted(resource_catalog[index][1],
244 70e11eaa Sofia Papagiannaki
                                            key=resourceindex)
245 70e11eaa Sofia Papagiannaki
        if len(resource_catalog[index][1]) == 0:
246 70e11eaa Sofia Papagiannaki
            resource_catalog.pop(index)
247 70e11eaa Sofia Papagiannaki
            for gindex, g in enumerate(resource_groups):
248 70e11eaa Sofia Papagiannaki
                if g[0] == group[0]:
249 70e11eaa Sofia Papagiannaki
                    resource_groups.pop(gindex)
250 70e11eaa Sofia Papagiannaki
251 70e11eaa Sofia Papagiannaki
    # filter out resources which user cannot request in a project application
252 70e11eaa Sofia Papagiannaki
    exclude = resources_meta.get('exclude_from_usage', [])
253 70e11eaa Sofia Papagiannaki
    for group_index, group_resources in enumerate(list(resource_catalog)):
254 70e11eaa Sofia Papagiannaki
        group, resources = group_resources
255 70e11eaa Sofia Papagiannaki
        for index, resource in list(enumerate(resources)):
256 70e11eaa Sofia Papagiannaki
            if for_project and not resource.get('allow_in_projects'):
257 70e11eaa Sofia Papagiannaki
                resources.remove(resource)
258 70e11eaa Sofia Papagiannaki
            if resource.get('str_repr') in exclude and for_usage:
259 70e11eaa Sofia Papagiannaki
                resources.remove(resource)
260 70e11eaa Sofia Papagiannaki
261 70e11eaa Sofia Papagiannaki
    # cleanup empty groups
262 70e11eaa Sofia Papagiannaki
    for group_index, group_resources in enumerate(list(resource_catalog)):
263 70e11eaa Sofia Papagiannaki
        group, resources = group_resources
264 70e11eaa Sofia Papagiannaki
        if len(resources) == 0:
265 70e11eaa Sofia Papagiannaki
            resource_catalog.pop(group_index)
266 70e11eaa Sofia Papagiannaki
            resource_groups.pop(group)
267 70e11eaa Sofia Papagiannaki
268 70e11eaa Sofia Papagiannaki
    return resource_catalog, resource_groups