Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (10.3 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 45a4e443 Kostas Papadimitriou
                   context_processors=None, form_class=None, msg=None,
90 45a4e443 Kostas Papadimitriou
                   summary_template_name=None):
91 70e11eaa Sofia Papagiannaki
    """
92 70e11eaa Sofia Papagiannaki
    Based of django.views.generic.create_update.create_object which displays a
93 70e11eaa Sofia Papagiannaki
    summary page before creating the object.
94 70e11eaa Sofia Papagiannaki
    """
95 70e11eaa Sofia Papagiannaki
96 8fb8d0cf Giorgos Korfiatis
    if extra_context is None:
97 8fb8d0cf Giorgos Korfiatis
        extra_context = {}
98 70e11eaa Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
99 70e11eaa Sofia Papagiannaki
        return redirect_to_login(request.path)
100 9024ed2e Giorgos Korfiatis
101 9024ed2e Giorgos Korfiatis
    model, form_class = get_model_and_form_class(model, form_class)
102 9024ed2e Giorgos Korfiatis
    extra_context['edit'] = 0
103 9024ed2e Giorgos Korfiatis
    if request.method == 'POST':
104 9024ed2e Giorgos Korfiatis
        form = form_class(request.POST, request.FILES)
105 9024ed2e Giorgos Korfiatis
        if form.is_valid():
106 9024ed2e Giorgos Korfiatis
            verify = request.GET.get('verify')
107 9024ed2e Giorgos Korfiatis
            edit = request.GET.get('edit')
108 9024ed2e Giorgos Korfiatis
            if verify == '1':
109 9024ed2e Giorgos Korfiatis
                extra_context['show_form'] = False
110 9024ed2e Giorgos Korfiatis
                extra_context['form_data'] = form.cleaned_data
111 45a4e443 Kostas Papadimitriou
                template_name = summary_template_name
112 9024ed2e Giorgos Korfiatis
            elif edit == '1':
113 9024ed2e Giorgos Korfiatis
                extra_context['show_form'] = True
114 9024ed2e Giorgos Korfiatis
            else:
115 9024ed2e Giorgos Korfiatis
                new_object = form.save()
116 9024ed2e Giorgos Korfiatis
                if not msg:
117 9024ed2e Giorgos Korfiatis
                    msg = _(
118 9024ed2e Giorgos Korfiatis
                        "The %(verbose_name)s was created successfully.")
119 9024ed2e Giorgos Korfiatis
                msg = msg % model._meta.__dict__
120 9024ed2e Giorgos Korfiatis
                messages.success(request, msg, fail_silently=True)
121 9024ed2e Giorgos Korfiatis
                return redirect(post_save_redirect, new_object)
122 70e11eaa Sofia Papagiannaki
    else:
123 9024ed2e Giorgos Korfiatis
        form = form_class()
124 9024ed2e Giorgos Korfiatis
125 9024ed2e Giorgos Korfiatis
    # Create the template, context, response
126 9024ed2e Giorgos Korfiatis
    if not template_name:
127 9024ed2e Giorgos Korfiatis
        template_name = "%s/%s_form.html" % \
128 9024ed2e Giorgos Korfiatis
            (model._meta.app_label, model._meta.object_name.lower())
129 9024ed2e Giorgos Korfiatis
    t = template_loader.get_template(template_name)
130 9024ed2e Giorgos Korfiatis
    c = RequestContext(request, {
131 9024ed2e Giorgos Korfiatis
        'form': form
132 9024ed2e Giorgos Korfiatis
    }, context_processors)
133 9024ed2e Giorgos Korfiatis
    apply_extra_context(extra_context, c)
134 9024ed2e Giorgos Korfiatis
    return HttpResponse(t.render(c))
135 9024ed2e Giorgos Korfiatis
136 9024ed2e Giorgos Korfiatis
137 70e11eaa Sofia Papagiannaki
def _update_object(request, model=None, object_id=None, slug=None,
138 8fb8d0cf Giorgos Korfiatis
                   slug_field='slug', template_name=None,
139 8fb8d0cf Giorgos Korfiatis
                   template_loader=template_loader, extra_context=None,
140 8fb8d0cf Giorgos Korfiatis
                   post_save_redirect=None, login_required=False,
141 8fb8d0cf Giorgos Korfiatis
                   context_processors=None, template_object_name='object',
142 45a4e443 Kostas Papadimitriou
                   form_class=None, msg=None, summary_template_name=None):
143 70e11eaa Sofia Papagiannaki
    """
144 70e11eaa Sofia Papagiannaki
    Based of django.views.generic.create_update.update_object which displays a
145 70e11eaa Sofia Papagiannaki
    summary page before updating the object.
146 70e11eaa Sofia Papagiannaki
    """
147 70e11eaa Sofia Papagiannaki
148 8fb8d0cf Giorgos Korfiatis
    if extra_context is None:
149 8fb8d0cf Giorgos Korfiatis
        extra_context = {}
150 70e11eaa Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
151 70e11eaa Sofia Papagiannaki
        return redirect_to_login(request.path)
152 70e11eaa Sofia Papagiannaki
153 9024ed2e Giorgos Korfiatis
    model, form_class = get_model_and_form_class(model, form_class)
154 9024ed2e Giorgos Korfiatis
    obj = lookup_object(model, object_id, slug, slug_field)
155 9024ed2e Giorgos Korfiatis
156 9024ed2e Giorgos Korfiatis
    if request.method == 'POST':
157 9024ed2e Giorgos Korfiatis
        form = form_class(request.POST, request.FILES, instance=obj)
158 9024ed2e Giorgos Korfiatis
        if form.is_valid():
159 9024ed2e Giorgos Korfiatis
            verify = request.GET.get('verify')
160 9024ed2e Giorgos Korfiatis
            edit = request.GET.get('edit')
161 9024ed2e Giorgos Korfiatis
            if verify == '1':
162 9024ed2e Giorgos Korfiatis
                extra_context['show_form'] = False
163 9024ed2e Giorgos Korfiatis
                extra_context['form_data'] = form.cleaned_data
164 45a4e443 Kostas Papadimitriou
                template_name = summary_template_name
165 9024ed2e Giorgos Korfiatis
            elif edit == '1':
166 9024ed2e Giorgos Korfiatis
                extra_context['show_form'] = True
167 9024ed2e Giorgos Korfiatis
            else:
168 9024ed2e Giorgos Korfiatis
                obj = form.save()
169 9024ed2e Giorgos Korfiatis
                if not msg:
170 9024ed2e Giorgos Korfiatis
                    msg = _(
171 9024ed2e Giorgos Korfiatis
                        "The %(verbose_name)s was created successfully.")
172 9024ed2e Giorgos Korfiatis
                msg = msg % model._meta.__dict__
173 9024ed2e Giorgos Korfiatis
                messages.success(request, msg, fail_silently=True)
174 9024ed2e Giorgos Korfiatis
                return redirect(post_save_redirect, obj)
175 70e11eaa Sofia Papagiannaki
    else:
176 9024ed2e Giorgos Korfiatis
        form = form_class(instance=obj)
177 9024ed2e Giorgos Korfiatis
178 9024ed2e Giorgos Korfiatis
    if not template_name:
179 9024ed2e Giorgos Korfiatis
        template_name = "%s/%s_form.html" % \
180 9024ed2e Giorgos Korfiatis
            (model._meta.app_label, model._meta.object_name.lower())
181 9024ed2e Giorgos Korfiatis
    t = template_loader.get_template(template_name)
182 9024ed2e Giorgos Korfiatis
    c = RequestContext(request, {
183 9024ed2e Giorgos Korfiatis
        'form': form,
184 9024ed2e Giorgos Korfiatis
        template_object_name: obj,
185 9024ed2e Giorgos Korfiatis
    }, context_processors)
186 9024ed2e Giorgos Korfiatis
    apply_extra_context(extra_context, c)
187 9024ed2e Giorgos Korfiatis
    response = HttpResponse(t.render(c))
188 9024ed2e Giorgos Korfiatis
    populate_xheaders(request, response, model,
189 9024ed2e Giorgos Korfiatis
                      getattr(obj, obj._meta.pk.attname))
190 9024ed2e Giorgos Korfiatis
    return response
191 70e11eaa Sofia Papagiannaki
192 8fb8d0cf Giorgos Korfiatis
193 2dc27ac1 Giorgos Korfiatis
def _resources_catalog():
194 70e11eaa Sofia Papagiannaki
    """
195 70e11eaa Sofia Papagiannaki
    `resource_catalog` contains a list of tuples. Each tuple contains the group
196 70e11eaa Sofia Papagiannaki
    key the resource is assigned to and resources list of dicts that contain
197 70e11eaa Sofia Papagiannaki
    resource information.
198 70e11eaa Sofia Papagiannaki
    `resource_groups` contains information about the groups
199 70e11eaa Sofia Papagiannaki
    """
200 70e11eaa Sofia Papagiannaki
    # presentation data
201 70e11eaa Sofia Papagiannaki
    resources_meta = presentation.RESOURCES
202 70e11eaa Sofia Papagiannaki
    resource_groups = resources_meta.get('groups', {})
203 70e11eaa Sofia Papagiannaki
    resource_catalog = ()
204 70e11eaa Sofia Papagiannaki
    resource_keys = []
205 70e11eaa Sofia Papagiannaki
206 70e11eaa Sofia Papagiannaki
    # resources in database
207 70e11eaa Sofia Papagiannaki
    resource_details = map(lambda obj: model_to_dict(obj, exclude=[]),
208 70e11eaa Sofia Papagiannaki
                           Resource.objects.all())
209 70e11eaa Sofia Papagiannaki
    # initialize resource_catalog to contain all group/resource information
210 70e11eaa Sofia Papagiannaki
    for r in resource_details:
211 70e11eaa Sofia Papagiannaki
        if not r.get('group') in resource_groups:
212 70e11eaa Sofia Papagiannaki
            resource_groups[r.get('group')] = {'icon': 'unknown'}
213 70e11eaa Sofia Papagiannaki
214 70e11eaa Sofia Papagiannaki
    resource_keys = [r.get('str_repr') for r in resource_details]
215 70e11eaa Sofia Papagiannaki
    resource_catalog = [[g, filter(lambda r: r.get('group', '') == g,
216 70e11eaa Sofia Papagiannaki
                                   resource_details)] for g in resource_groups]
217 70e11eaa Sofia Papagiannaki
218 70e11eaa Sofia Papagiannaki
    # order groups, also include unknown groups
219 70e11eaa Sofia Papagiannaki
    groups_order = resources_meta.get('groups_order')
220 70e11eaa Sofia Papagiannaki
    for g in resource_groups.keys():
221 70e11eaa Sofia Papagiannaki
        if not g in groups_order:
222 70e11eaa Sofia Papagiannaki
            groups_order.append(g)
223 70e11eaa Sofia Papagiannaki
224 70e11eaa Sofia Papagiannaki
    # order resources, also include unknown resources
225 70e11eaa Sofia Papagiannaki
    resources_order = resources_meta.get('resources_order')
226 70e11eaa Sofia Papagiannaki
    for r in resource_keys:
227 70e11eaa Sofia Papagiannaki
        if not r in resources_order:
228 70e11eaa Sofia Papagiannaki
            resources_order.append(r)
229 70e11eaa Sofia Papagiannaki
230 70e11eaa Sofia Papagiannaki
    # sort catalog groups
231 70e11eaa Sofia Papagiannaki
    resource_catalog = sorted(resource_catalog,
232 70e11eaa Sofia Papagiannaki
                              key=lambda g: groups_order.index(g[0]))
233 70e11eaa Sofia Papagiannaki
234 70e11eaa Sofia Papagiannaki
    # sort groups
235 70e11eaa Sofia Papagiannaki
    def groupindex(g):
236 70e11eaa Sofia Papagiannaki
        return groups_order.index(g[0])
237 70e11eaa Sofia Papagiannaki
    resource_groups_list = sorted([(k, v) for k, v in resource_groups.items()],
238 70e11eaa Sofia Papagiannaki
                                  key=groupindex)
239 70e11eaa Sofia Papagiannaki
    resource_groups = OrderedDict(resource_groups_list)
240 70e11eaa Sofia Papagiannaki
241 70e11eaa Sofia Papagiannaki
    # sort resources
242 70e11eaa Sofia Papagiannaki
    def resourceindex(r):
243 70e11eaa Sofia Papagiannaki
        return resources_order.index(r['str_repr'])
244 70e11eaa Sofia Papagiannaki
245 70e11eaa Sofia Papagiannaki
    for index, group in enumerate(resource_catalog):
246 70e11eaa Sofia Papagiannaki
        resource_catalog[index][1] = sorted(resource_catalog[index][1],
247 70e11eaa Sofia Papagiannaki
                                            key=resourceindex)
248 70e11eaa Sofia Papagiannaki
        if len(resource_catalog[index][1]) == 0:
249 70e11eaa Sofia Papagiannaki
            resource_catalog.pop(index)
250 70e11eaa Sofia Papagiannaki
            for gindex, g in enumerate(resource_groups):
251 70e11eaa Sofia Papagiannaki
                if g[0] == group[0]:
252 70e11eaa Sofia Papagiannaki
                    resource_groups.pop(gindex)
253 70e11eaa Sofia Papagiannaki
254 70e11eaa Sofia Papagiannaki
    # filter out resources which user cannot request in a project application
255 2dc27ac1 Giorgos Korfiatis
    for group, resources in list(resource_catalog):
256 2dc27ac1 Giorgos Korfiatis
        for resource in resources:
257 2dc27ac1 Giorgos Korfiatis
            if not resource.get('ui_visible'):
258 70e11eaa Sofia Papagiannaki
                resources.remove(resource)
259 70e11eaa Sofia Papagiannaki
260 70e11eaa Sofia Papagiannaki
    # cleanup empty groups
261 4f21f4a6 Giorgos Korfiatis
    resource_catalog_new = []
262 4f21f4a6 Giorgos Korfiatis
    for group, resources in list(resource_catalog):
263 70e11eaa Sofia Papagiannaki
        if len(resources) == 0:
264 70e11eaa Sofia Papagiannaki
            resource_groups.pop(group)
265 4f21f4a6 Giorgos Korfiatis
        else:
266 4f21f4a6 Giorgos Korfiatis
            resource_catalog_new.append((group, resources))
267 4f21f4a6 Giorgos Korfiatis
    return resource_catalog_new, resource_groups