Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 480ce06b

History | View | Annotate | Download (46.4 kB)

1 aba1e498 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 176023aa Kostas Papadimitriou
#
3 64cd4730 Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 64cd4730 Antony Chazapis
# without modification, are permitted provided that the following
5 64cd4730 Antony Chazapis
# conditions are met:
6 176023aa Kostas Papadimitriou
#
7 64cd4730 Antony Chazapis
#   1. Redistributions of source code must retain the above
8 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
9 64cd4730 Antony Chazapis
#      disclaimer.
10 176023aa Kostas Papadimitriou
#
11 64cd4730 Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 64cd4730 Antony Chazapis
#      copyright notice, this list of conditions and the following
13 64cd4730 Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 64cd4730 Antony Chazapis
#      provided with the distribution.
15 176023aa Kostas Papadimitriou
#
16 64cd4730 Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 64cd4730 Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 64cd4730 Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 64cd4730 Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 64cd4730 Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 64cd4730 Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 64cd4730 Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 64cd4730 Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 64cd4730 Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 64cd4730 Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 64cd4730 Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 64cd4730 Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 176023aa Kostas Papadimitriou
#
29 64cd4730 Antony Chazapis
# The views and conclusions contained in the software and
30 64cd4730 Antony Chazapis
# documentation are those of the authors and should not be
31 64cd4730 Antony Chazapis
# interpreted as representing official policies, either expressed
32 64cd4730 Antony Chazapis
# or implied, of GRNET S.A.
33 64cd4730 Antony Chazapis
34 64cd4730 Antony Chazapis
import logging
35 6e029beb Sofia Papagiannaki
import calendar
36 9a06d96f Olga Brani
import inflect
37 9a06d96f Olga Brani
38 9a06d96f Olga Brani
engine = inflect.engine()
39 64cd4730 Antony Chazapis
40 0905ccd2 Sofia Papagiannaki
from urllib import quote
41 63ecdd20 Sofia Papagiannaki
from functools import wraps
42 c0b26605 Sofia Papagiannaki
from datetime import datetime
43 64cd4730 Antony Chazapis
44 a5cef8d0 Kostas Papadimitriou
from django_tables2 import RequestConfig
45 a5cef8d0 Kostas Papadimitriou
46 c630fee6 Kostas Papadimitriou
from django.shortcuts import get_object_or_404
47 890b0eaf Sofia Papagiannaki
from django.contrib import messages
48 01ac12d5 Sofia Papagiannaki
from django.contrib.auth.decorators import login_required
49 01ac12d5 Sofia Papagiannaki
from django.core.urlresolvers import reverse
50 01ac12d5 Sofia Papagiannaki
from django.db import transaction
51 01ac12d5 Sofia Papagiannaki
from django.db.utils import IntegrityError
52 73fbaec4 Sofia Papagiannaki
from django.http import (
53 73fbaec4 Sofia Papagiannaki
    HttpResponse, HttpResponseBadRequest,
54 73fbaec4 Sofia Papagiannaki
    HttpResponseForbidden, HttpResponseRedirect,
55 73fbaec4 Sofia Papagiannaki
    HttpResponseBadRequest, Http404)
56 01ac12d5 Sofia Papagiannaki
from django.shortcuts import redirect
57 661c4479 Sofia Papagiannaki
from django.template import RequestContext, loader as template_loader
58 01ac12d5 Sofia Papagiannaki
from django.utils.http import urlencode
59 01ac12d5 Sofia Papagiannaki
from django.utils.translation import ugettext as _
60 e1a80257 Sofia Papagiannaki
from django.views.generic.create_update import (
61 4e748491 Sofia Papagiannaki
    apply_extra_context, lookup_object, delete_object, get_model_and_form_class)
62 f3342849 Sofia Papagiannaki
from django.views.generic.list_detail import object_list, object_detail
63 661c4479 Sofia Papagiannaki
from django.core.xheaders import populate_xheaders
64 792c2f3b Olga Brani
from django.core.exceptions import ValidationError, PermissionDenied
65 c0b26605 Sofia Papagiannaki
from django.template.loader import render_to_string
66 9a06d96f Olga Brani
from django.views.decorators.http import require_http_methods
67 29b0ec5a Sofia Papagiannaki
from django.db.models import Q
68 bfe23b13 Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
69 96b44c04 Sofia Papagiannaki
from django.utils import simplejson as json
70 c0b26605 Sofia Papagiannaki
71 c630fee6 Kostas Papadimitriou
import astakos.im.messages as astakos_messages
72 c630fee6 Kostas Papadimitriou
73 29b0ec5a Sofia Papagiannaki
from astakos.im.activation_backends import get_backend, SimpleBackend
74 5550bcfb Kostas Papadimitriou
from astakos.im import tables
75 e1a80257 Sofia Papagiannaki
from astakos.im.models import (
76 73fbaec4 Sofia Papagiannaki
    AstakosUser, ApprovalTerms,
77 fcc1e93f Sofia Papagiannaki
    EmailChange, RESOURCE_SEPARATOR,
78 fcc1e93f Sofia Papagiannaki
    AstakosUserAuthProvider, PendingThirdPartyUser,
79 73fbaec4 Sofia Papagiannaki
    ProjectApplication, ProjectMembership, Project)
80 73fbaec4 Sofia Papagiannaki
from astakos.im.util import (
81 73fbaec4 Sofia Papagiannaki
    get_context, prepare_response, get_query, restrict_next)
82 e1a80257 Sofia Papagiannaki
from astakos.im.forms import (
83 e1a80257 Sofia Papagiannaki
    LoginForm, InvitationForm, ProfileForm,
84 e1a80257 Sofia Papagiannaki
    FeedbackForm, SignApprovalTermsForm,
85 e1a80257 Sofia Papagiannaki
    EmailChangeForm,
86 bfe23b13 Sofia Papagiannaki
    ProjectApplicationForm, ProjectSortForm,
87 73fbaec4 Sofia Papagiannaki
    AddProjectMembersForm, ProjectSearchForm,
88 73fbaec4 Sofia Papagiannaki
    ProjectMembersSortForm)
89 f3342849 Sofia Papagiannaki
from astakos.im.functions import (
90 f3342849 Sofia Papagiannaki
    send_feedback, SendMailError,
91 f3342849 Sofia Papagiannaki
    logout as auth_logout,
92 f3342849 Sofia Papagiannaki
    activate as activate_func,
93 73fbaec4 Sofia Papagiannaki
    invite,
94 f3342849 Sofia Papagiannaki
    send_activation as send_activation_func,
95 73fbaec4 Sofia Papagiannaki
    SendNotificationError,
96 73fbaec4 Sofia Papagiannaki
    accept_membership, reject_membership, remove_membership,
97 7dd3047d Sofia Papagiannaki
    leave_project, join_project, enroll_member)
98 f3342849 Sofia Papagiannaki
from astakos.im.settings import (
99 f3342849 Sofia Papagiannaki
    COOKIE_DOMAIN, LOGOUT_NEXT,
100 f3342849 Sofia Papagiannaki
    LOGGING_LEVEL, PAGINATE_BY,
101 a9c7ff8a Sofia Papagiannaki
    RESOURCES_PRESENTATION_DATA, PAGINATE_BY_ALL,
102 a9c7ff8a Sofia Papagiannaki
    MODERATION_ENABLED)
103 96b44c04 Sofia Papagiannaki
from astakos.im.api import get_services
104 48421603 Kostas Papadimitriou
from astakos.im import settings as astakos_settings
105 820b18e0 Sofia Papagiannaki
from astakos.im.api.callpoint import AstakosCallpoint
106 792c2f3b Olga Brani
from astakos.im import auth_providers
107 ae497612 Olga Brani
108 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
109 e015e9e6 Sofia Papagiannaki
110 820b18e0 Sofia Papagiannaki
callpoint = AstakosCallpoint()
111 9a06d96f Olga Brani
112 b2ffa772 Sofia Papagiannaki
def render_response(template, tab=None, status=200, context_instance=None, **kwargs):
113 890b0eaf Sofia Papagiannaki
    """
114 890b0eaf Sofia Papagiannaki
    Calls ``django.template.loader.render_to_string`` with an additional ``tab``
115 890b0eaf Sofia Papagiannaki
    keyword argument and returns an ``django.http.HttpResponse`` with the
116 890b0eaf Sofia Papagiannaki
    specified ``status``.
117 890b0eaf Sofia Papagiannaki
    """
118 64cd4730 Antony Chazapis
    if tab is None:
119 881c856c Sofia Papagiannaki
        tab = template.partition('_')[0].partition('.html')[0]
120 64cd4730 Antony Chazapis
    kwargs.setdefault('tab', tab)
121 661c4479 Sofia Papagiannaki
    html = template_loader.render_to_string(
122 5ce3ce4f Sofia Papagiannaki
        template, kwargs, context_instance=context_instance)
123 c301698f Sofia Papagiannaki
    response = HttpResponse(html, status=status)
124 c301698f Sofia Papagiannaki
    return response
125 64cd4730 Antony Chazapis
126 792c2f3b Olga Brani
def requires_auth_provider(provider_id, **perms):
127 792c2f3b Olga Brani
    """
128 792c2f3b Olga Brani
    """
129 792c2f3b Olga Brani
    def decorator(func, *args, **kwargs):
130 792c2f3b Olga Brani
        @wraps(func)
131 792c2f3b Olga Brani
        def wrapper(request, *args, **kwargs):
132 792c2f3b Olga Brani
            provider = auth_providers.get_provider(provider_id)
133 792c2f3b Olga Brani
134 792c2f3b Olga Brani
            if not provider or not provider.is_active():
135 792c2f3b Olga Brani
                raise PermissionDenied
136 792c2f3b Olga Brani
137 792c2f3b Olga Brani
            if provider:
138 792c2f3b Olga Brani
                for pkey, value in perms.iteritems():
139 792c2f3b Olga Brani
                    attr = 'is_available_for_%s' % pkey.lower()
140 792c2f3b Olga Brani
                    if getattr(provider, attr)() != value:
141 279d6e51 Olga Brani
                        #TODO: add session message
142 c630fee6 Kostas Papadimitriou
                        return HttpResponseRedirect(reverse('login'))
143 792c2f3b Olga Brani
            return func(request, *args)
144 792c2f3b Olga Brani
        return wrapper
145 792c2f3b Olga Brani
    return decorator
146 792c2f3b Olga Brani
147 63ecdd20 Sofia Papagiannaki
148 63ecdd20 Sofia Papagiannaki
def requires_anonymous(func):
149 63ecdd20 Sofia Papagiannaki
    """
150 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is not Anonymous and in that case
151 7482228b Sofia Papagiannaki
    redirects to `logout`.
152 63ecdd20 Sofia Papagiannaki
    """
153 63ecdd20 Sofia Papagiannaki
    @wraps(func)
154 63ecdd20 Sofia Papagiannaki
    def wrapper(request, *args):
155 63ecdd20 Sofia Papagiannaki
        if not request.user.is_anonymous():
156 63ecdd20 Sofia Papagiannaki
            next = urlencode({'next': request.build_absolute_uri()})
157 270dd48d Sofia Papagiannaki
            logout_uri = reverse(logout) + '?' + next
158 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(logout_uri)
159 63ecdd20 Sofia Papagiannaki
        return func(request, *args)
160 63ecdd20 Sofia Papagiannaki
    return wrapper
161 63ecdd20 Sofia Papagiannaki
162 5ce3ce4f Sofia Papagiannaki
163 270dd48d Sofia Papagiannaki
def signed_terms_required(func):
164 270dd48d Sofia Papagiannaki
    """
165 badcb2a9 Kostas Papadimitriou
    Decorator checks whether the request.user is Anonymous and in that case
166 270dd48d Sofia Papagiannaki
    redirects to `logout`.
167 270dd48d Sofia Papagiannaki
    """
168 270dd48d Sofia Papagiannaki
    @wraps(func)
169 270dd48d Sofia Papagiannaki
    def wrapper(request, *args, **kwargs):
170 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
171 270dd48d Sofia Papagiannaki
            params = urlencode({'next': request.build_absolute_uri(),
172 5ce3ce4f Sofia Papagiannaki
                                'show_form': ''})
173 270dd48d Sofia Papagiannaki
            terms_uri = reverse('latest_terms') + '?' + params
174 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(terms_uri)
175 270dd48d Sofia Papagiannaki
        return func(request, *args, **kwargs)
176 270dd48d Sofia Papagiannaki
    return wrapper
177 270dd48d Sofia Papagiannaki
178 5ce3ce4f Sofia Papagiannaki
179 badcb2a9 Kostas Papadimitriou
def required_auth_methods_assigned(only_warn=False):
180 badcb2a9 Kostas Papadimitriou
    """
181 badcb2a9 Kostas Papadimitriou
    Decorator that checks whether the request.user has all required auth providers
182 badcb2a9 Kostas Papadimitriou
    assigned.
183 badcb2a9 Kostas Papadimitriou
    """
184 badcb2a9 Kostas Papadimitriou
    required_providers = auth_providers.REQUIRED_PROVIDERS.keys()
185 badcb2a9 Kostas Papadimitriou
186 badcb2a9 Kostas Papadimitriou
    def decorator(func):
187 badcb2a9 Kostas Papadimitriou
        if not required_providers:
188 badcb2a9 Kostas Papadimitriou
            return func
189 badcb2a9 Kostas Papadimitriou
190 badcb2a9 Kostas Papadimitriou
        @wraps(func)
191 badcb2a9 Kostas Papadimitriou
        def wrapper(request, *args, **kwargs):
192 badcb2a9 Kostas Papadimitriou
            if request.user.is_authenticated():
193 badcb2a9 Kostas Papadimitriou
                for required in required_providers:
194 badcb2a9 Kostas Papadimitriou
                    if not request.user.has_auth_provider(required):
195 badcb2a9 Kostas Papadimitriou
                        provider = auth_providers.get_provider(required)
196 badcb2a9 Kostas Papadimitriou
                        if only_warn:
197 badcb2a9 Kostas Papadimitriou
                            messages.error(request,
198 badcb2a9 Kostas Papadimitriou
                                           _(astakos_messages.AUTH_PROVIDER_REQUIRED  % {
199 badcb2a9 Kostas Papadimitriou
                                               'provider': provider.get_title_display}))
200 badcb2a9 Kostas Papadimitriou
                        else:
201 badcb2a9 Kostas Papadimitriou
                            return HttpResponseRedirect(reverse('edit_profile'))
202 badcb2a9 Kostas Papadimitriou
            return func(request, *args, **kwargs)
203 badcb2a9 Kostas Papadimitriou
        return wrapper
204 badcb2a9 Kostas Papadimitriou
    return decorator
205 badcb2a9 Kostas Papadimitriou
206 badcb2a9 Kostas Papadimitriou
207 badcb2a9 Kostas Papadimitriou
def valid_astakos_user_required(func):
208 badcb2a9 Kostas Papadimitriou
    return signed_terms_required(required_auth_methods_assigned()(login_required(func)))
209 badcb2a9 Kostas Papadimitriou
210 badcb2a9 Kostas Papadimitriou
211 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
212 270dd48d Sofia Papagiannaki
@signed_terms_required
213 1f3b4b39 Sofia Papagiannaki
def index(request, login_template_name='im/login.html', profile_template_name='im/profile.html', extra_context=None):
214 890b0eaf Sofia Papagiannaki
    """
215 dcf55476 Sofia Papagiannaki
    If there is logged on user renders the profile page otherwise renders login page.
216 176023aa Kostas Papadimitriou

217 890b0eaf Sofia Papagiannaki
    **Arguments**
218 176023aa Kostas Papadimitriou

219 dcf55476 Sofia Papagiannaki
    ``login_template_name``
220 dcf55476 Sofia Papagiannaki
        A custom login template to use. This is optional; if not specified,
221 1e685275 Sofia Papagiannaki
        this will default to ``im/login.html``.
222 176023aa Kostas Papadimitriou

223 dcf55476 Sofia Papagiannaki
    ``profile_template_name``
224 dcf55476 Sofia Papagiannaki
        A custom profile template to use. This is optional; if not specified,
225 1e685275 Sofia Papagiannaki
        this will default to ``im/profile.html``.
226 176023aa Kostas Papadimitriou

227 890b0eaf Sofia Papagiannaki
    ``extra_context``
228 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
229 176023aa Kostas Papadimitriou

230 890b0eaf Sofia Papagiannaki
    **Template:**
231 176023aa Kostas Papadimitriou

232 1e685275 Sofia Papagiannaki
    im/profile.html or im/login.html or ``template_name`` keyword argument.
233 176023aa Kostas Papadimitriou

234 890b0eaf Sofia Papagiannaki
    """
235 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
236 dcf55476 Sofia Papagiannaki
    template_name = login_template_name
237 dcf55476 Sofia Papagiannaki
    if request.user.is_authenticated():
238 f534fb96 Sofia Papagiannaki
        return HttpResponseRedirect(reverse('astakos.im.views.edit_profile'))
239 792c2f3b Olga Brani
240 f7cf5257 Kostas Papadimitriou
    third_party_token = request.GET.get('key', False)
241 f7cf5257 Kostas Papadimitriou
    if third_party_token:
242 f7cf5257 Kostas Papadimitriou
        messages.info(request, astakos_messages.AUTH_PROVIDER_LOGIN_TO_ADD)
243 f7cf5257 Kostas Papadimitriou
244 ef20ea07 Sofia Papagiannaki
    return render_response(
245 ef20ea07 Sofia Papagiannaki
        template_name,
246 ef20ea07 Sofia Papagiannaki
        login_form = LoginForm(request=request),
247 ef20ea07 Sofia Papagiannaki
        context_instance = get_context(request, extra_context)
248 ef20ea07 Sofia Papagiannaki
    )
249 5ce3ce4f Sofia Papagiannaki
250 64cd4730 Antony Chazapis
251 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
252 badcb2a9 Kostas Papadimitriou
@valid_astakos_user_required
253 890b0eaf Sofia Papagiannaki
@transaction.commit_manually
254 aab4d540 Sofia Papagiannaki
def invite(request, template_name='im/invitations.html', extra_context=None):
255 890b0eaf Sofia Papagiannaki
    """
256 890b0eaf Sofia Papagiannaki
    Allows a user to invite somebody else.
257 176023aa Kostas Papadimitriou

258 890b0eaf Sofia Papagiannaki
    In case of GET request renders a form for providing the invitee information.
259 890b0eaf Sofia Papagiannaki
    In case of POST checks whether the user has not run out of invitations and then
260 890b0eaf Sofia Papagiannaki
    sends an invitation email to singup to the service.
261 176023aa Kostas Papadimitriou

262 890b0eaf Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the number of the
263 890b0eaf Sofia Papagiannaki
    user invitations is going to be updated only if the email has been successfully sent.
264 176023aa Kostas Papadimitriou

265 2cbaacd5 Sofia Papagiannaki
    If the user isn't logged in, redirects to settings.LOGIN_URL.
266 176023aa Kostas Papadimitriou

267 890b0eaf Sofia Papagiannaki
    **Arguments**
268 176023aa Kostas Papadimitriou

269 890b0eaf Sofia Papagiannaki
    ``template_name``
270 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
271 1e685275 Sofia Papagiannaki
        this will default to ``im/invitations.html``.
272 176023aa Kostas Papadimitriou

273 890b0eaf Sofia Papagiannaki
    ``extra_context``
274 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
275 176023aa Kostas Papadimitriou

276 890b0eaf Sofia Papagiannaki
    **Template:**
277 176023aa Kostas Papadimitriou

278 1e685275 Sofia Papagiannaki
    im/invitations.html or ``template_name`` keyword argument.
279 176023aa Kostas Papadimitriou

280 890b0eaf Sofia Papagiannaki
    **Settings:**
281 176023aa Kostas Papadimitriou

282 890b0eaf Sofia Papagiannaki
    The view expectes the following settings are defined:
283 176023aa Kostas Papadimitriou

284 890b0eaf Sofia Papagiannaki
    * LOGIN_URL: login uri
285 890b0eaf Sofia Papagiannaki
    """
286 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
287 64cd4730 Antony Chazapis
    status = None
288 64cd4730 Antony Chazapis
    message = None
289 8f5a3a06 Sofia Papagiannaki
    form = InvitationForm()
290 5ce3ce4f Sofia Papagiannaki
291 18ffbee1 Sofia Papagiannaki
    inviter = request.user
292 64cd4730 Antony Chazapis
    if request.method == 'POST':
293 8f5a3a06 Sofia Papagiannaki
        form = InvitationForm(request.POST)
294 64cd4730 Antony Chazapis
        if inviter.invitations > 0:
295 8f5a3a06 Sofia Papagiannaki
            if form.is_valid():
296 8f5a3a06 Sofia Papagiannaki
                try:
297 9a06d96f Olga Brani
                    email = form.cleaned_data.get('username')
298 9a06d96f Olga Brani
                    realname = form.cleaned_data.get('realname')
299 73fbaec4 Sofia Papagiannaki
                    invite(inviter, email, realname)
300 ae497612 Olga Brani
                    message = _(astakos_messages.INVITATION_SENT) % locals()
301 24406ae3 Sofia Papagiannaki
                    messages.success(request, message)
302 8f5a3a06 Sofia Papagiannaki
                except SendMailError, e:
303 8f5a3a06 Sofia Papagiannaki
                    message = e.message
304 24406ae3 Sofia Papagiannaki
                    messages.error(request, message)
305 8f5a3a06 Sofia Papagiannaki
                    transaction.rollback()
306 18ffbee1 Sofia Papagiannaki
                except BaseException, e:
307 ae497612 Olga Brani
                    message = _(astakos_messages.GENERIC_ERROR)
308 24406ae3 Sofia Papagiannaki
                    messages.error(request, message)
309 18ffbee1 Sofia Papagiannaki
                    logger.exception(e)
310 18ffbee1 Sofia Papagiannaki
                    transaction.rollback()
311 18ffbee1 Sofia Papagiannaki
                else:
312 18ffbee1 Sofia Papagiannaki
                    transaction.commit()
313 64cd4730 Antony Chazapis
        else:
314 ae497612 Olga Brani
            message = _(astakos_messages.MAX_INVITATION_NUMBER_REACHED)
315 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
316 176023aa Kostas Papadimitriou
317 a196eb7e Sofia Papagiannaki
    sent = [{'email': inv.username,
318 d6ae71a2 root
             'realname': inv.realname,
319 d6ae71a2 root
             'is_consumed': inv.is_consumed}
320 5ce3ce4f Sofia Papagiannaki
            for inv in request.user.invitations_sent.all()]
321 77e2ad52 root
    kwargs = {'inviter': inviter,
322 5ce3ce4f Sofia Papagiannaki
              'sent': sent}
323 0905ccd2 Sofia Papagiannaki
    context = get_context(request, extra_context, **kwargs)
324 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
325 5ce3ce4f Sofia Papagiannaki
                           invitation_form=form,
326 5ce3ce4f Sofia Papagiannaki
                           context_instance=context)
327 5ce3ce4f Sofia Papagiannaki
328 64cd4730 Antony Chazapis
329 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
330 badcb2a9 Kostas Papadimitriou
@required_auth_methods_assigned(only_warn=True)
331 890b0eaf Sofia Papagiannaki
@login_required
332 270dd48d Sofia Papagiannaki
@signed_terms_required
333 aab4d540 Sofia Papagiannaki
def edit_profile(request, template_name='im/profile.html', extra_context=None):
334 890b0eaf Sofia Papagiannaki
    """
335 890b0eaf Sofia Papagiannaki
    Allows a user to edit his/her profile.
336 176023aa Kostas Papadimitriou

337 890b0eaf Sofia Papagiannaki
    In case of GET request renders a form for displaying the user information.
338 ce86cd44 Sofia Papagiannaki
    In case of POST updates the user informantion and redirects to ``next``
339 ce86cd44 Sofia Papagiannaki
    url parameter if exists.
340 176023aa Kostas Papadimitriou

341 2cbaacd5 Sofia Papagiannaki
    If the user isn't logged in, redirects to settings.LOGIN_URL.
342 176023aa Kostas Papadimitriou

343 890b0eaf Sofia Papagiannaki
    **Arguments**
344 176023aa Kostas Papadimitriou

345 890b0eaf Sofia Papagiannaki
    ``template_name``
346 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
347 1e685275 Sofia Papagiannaki
        this will default to ``im/profile.html``.
348 176023aa Kostas Papadimitriou

349 890b0eaf Sofia Papagiannaki
    ``extra_context``
350 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
351 176023aa Kostas Papadimitriou

352 890b0eaf Sofia Papagiannaki
    **Template:**
353 176023aa Kostas Papadimitriou

354 1e685275 Sofia Papagiannaki
    im/profile.html or ``template_name`` keyword argument.
355 176023aa Kostas Papadimitriou

356 92defad4 Sofia Papagiannaki
    **Settings:**
357 176023aa Kostas Papadimitriou

358 92defad4 Sofia Papagiannaki
    The view expectes the following settings are defined:
359 176023aa Kostas Papadimitriou

360 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
361 890b0eaf Sofia Papagiannaki
    """
362 aab4d540 Sofia Papagiannaki
    extra_context = extra_context or {}
363 bf0c6de5 Sofia Papagiannaki
    form = ProfileForm(
364 bf0c6de5 Sofia Papagiannaki
        instance=request.user,
365 bf0c6de5 Sofia Papagiannaki
        session_key=request.session.session_key
366 bf0c6de5 Sofia Papagiannaki
    )
367 15efc749 Sofia Papagiannaki
    extra_context['next'] = request.GET.get('next')
368 64cd4730 Antony Chazapis
    if request.method == 'POST':
369 bf0c6de5 Sofia Papagiannaki
        form = ProfileForm(
370 bf0c6de5 Sofia Papagiannaki
            request.POST,
371 bf0c6de5 Sofia Papagiannaki
            instance=request.user,
372 bf0c6de5 Sofia Papagiannaki
            session_key=request.session.session_key
373 bf0c6de5 Sofia Papagiannaki
        )
374 890b0eaf Sofia Papagiannaki
        if form.is_valid():
375 64cd4730 Antony Chazapis
            try:
376 c301698f Sofia Papagiannaki
                prev_token = request.user.auth_token
377 c301698f Sofia Papagiannaki
                user = form.save()
378 bf0c6de5 Sofia Papagiannaki
                form = ProfileForm(
379 bf0c6de5 Sofia Papagiannaki
                    instance=user,
380 bf0c6de5 Sofia Papagiannaki
                    session_key=request.session.session_key
381 bf0c6de5 Sofia Papagiannaki
                )
382 217994f8 Sofia Papagiannaki
                next = restrict_next(
383 217994f8 Sofia Papagiannaki
                    request.POST.get('next'),
384 217994f8 Sofia Papagiannaki
                    domain=COOKIE_DOMAIN
385 217994f8 Sofia Papagiannaki
                )
386 1a3675a0 Sofia Papagiannaki
                if next:
387 1a3675a0 Sofia Papagiannaki
                    return redirect(next)
388 ae497612 Olga Brani
                msg = _(astakos_messages.PROFILE_UPDATED)
389 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
390 890b0eaf Sofia Papagiannaki
            except ValueError, ve:
391 24406ae3 Sofia Papagiannaki
                messages.success(request, ve)
392 23447441 Sofia Papagiannaki
    elif request.method == "GET":
393 792c2f3b Olga Brani
        request.user.is_verified = True
394 792c2f3b Olga Brani
        request.user.save()
395 792c2f3b Olga Brani
396 792c2f3b Olga Brani
    # existing providers
397 792c2f3b Olga Brani
    user_providers = request.user.get_active_auth_providers()
398 792c2f3b Olga Brani
399 792c2f3b Olga Brani
    # providers that user can add
400 792c2f3b Olga Brani
    user_available_providers = request.user.get_available_auth_providers()
401 792c2f3b Olga Brani
402 96b44c04 Sofia Papagiannaki
    try:
403 96b44c04 Sofia Papagiannaki
        resp = get_services(request)
404 96b44c04 Sofia Papagiannaki
    except Exception, e:
405 96b44c04 Sofia Papagiannaki
        services = ()
406 96b44c04 Sofia Papagiannaki
    else:
407 96b44c04 Sofia Papagiannaki
        services = json.loads(resp.content)
408 96b44c04 Sofia Papagiannaki
    extra_context['services'] = services
409 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
410 8f5a3a06 Sofia Papagiannaki
                           profile_form = form,
411 792c2f3b Olga Brani
                           user_providers = user_providers,
412 792c2f3b Olga Brani
                           user_available_providers = user_available_providers,
413 0905ccd2 Sofia Papagiannaki
                           context_instance = get_context(request,
414 c301698f Sofia Papagiannaki
                                                          extra_context))
415 5ce3ce4f Sofia Papagiannaki
416 64cd4730 Antony Chazapis
417 10ed0073 Sofia Papagiannaki
@transaction.commit_manually
418 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
419 279d6e51 Olga Brani
def signup(request, template_name='im/signup.html', on_success='im/signup_complete.html', extra_context=None, backend=None):
420 890b0eaf Sofia Papagiannaki
    """
421 890b0eaf Sofia Papagiannaki
    Allows a user to create a local account.
422 176023aa Kostas Papadimitriou

423 b669d9c0 Sofia Papagiannaki
    In case of GET request renders a form for entering the user information.
424 890b0eaf Sofia Papagiannaki
    In case of POST handles the signup.
425 176023aa Kostas Papadimitriou

426 890b0eaf Sofia Papagiannaki
    The user activation will be delegated to the backend specified by the ``backend`` keyword argument
427 8f5a3a06 Sofia Papagiannaki
    if present, otherwise to the ``astakos.im.activation_backends.InvitationBackend``
428 8f5a3a06 Sofia Papagiannaki
    if settings.ASTAKOS_INVITATIONS_ENABLED is True or ``astakos.im.activation_backends.SimpleBackend`` if not
429 8f5a3a06 Sofia Papagiannaki
    (see activation_backends);
430 5ce3ce4f Sofia Papagiannaki

431 b669d9c0 Sofia Papagiannaki
    Upon successful user creation, if ``next`` url parameter is present the user is redirected there
432 890b0eaf Sofia Papagiannaki
    otherwise renders the same page with a success message.
433 5ce3ce4f Sofia Papagiannaki

434 8f5a3a06 Sofia Papagiannaki
    On unsuccessful creation, renders ``template_name`` with an error message.
435 5ce3ce4f Sofia Papagiannaki

436 890b0eaf Sofia Papagiannaki
    **Arguments**
437 5ce3ce4f Sofia Papagiannaki

438 8f5a3a06 Sofia Papagiannaki
    ``template_name``
439 8f5a3a06 Sofia Papagiannaki
        A custom template to render. This is optional;
440 1e685275 Sofia Papagiannaki
        if not specified, this will default to ``im/signup.html``.
441 176023aa Kostas Papadimitriou

442 f7e8a159 Sofia Papagiannaki
    ``on_success``
443 f7e8a159 Sofia Papagiannaki
        A custom template to render in case of success. This is optional;
444 1e685275 Sofia Papagiannaki
        if not specified, this will default to ``im/signup_complete.html``.
445 176023aa Kostas Papadimitriou

446 890b0eaf Sofia Papagiannaki
    ``extra_context``
447 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
448 176023aa Kostas Papadimitriou

449 890b0eaf Sofia Papagiannaki
    **Template:**
450 5ce3ce4f Sofia Papagiannaki

451 8f5a3a06 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
452 5ce3ce4f Sofia Papagiannaki
    im/signup_complete.html or ``on_success`` keyword argument.
453 890b0eaf Sofia Papagiannaki
    """
454 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
455 0d02a287 Sofia Papagiannaki
    if request.user.is_authenticated():
456 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('edit_profile'))
457 5ce3ce4f Sofia Papagiannaki
458 0a569195 Sofia Papagiannaki
    provider = get_query(request).get('provider', 'local')
459 279d6e51 Olga Brani
    if not auth_providers.get_provider(provider).is_available_for_create():
460 279d6e51 Olga Brani
        raise PermissionDenied
461 279d6e51 Olga Brani
462 6c8a3f7c Sofia Papagiannaki
    id = get_query(request).get('id')
463 6c8a3f7c Sofia Papagiannaki
    try:
464 6c8a3f7c Sofia Papagiannaki
        instance = AstakosUser.objects.get(id=id) if id else None
465 6c8a3f7c Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
466 6c8a3f7c Sofia Papagiannaki
        instance = None
467 6c8a3f7c Sofia Papagiannaki
468 8ab484ea Kostas Papadimitriou
    third_party_token = request.REQUEST.get('third_party_token', None)
469 c630fee6 Kostas Papadimitriou
    if third_party_token:
470 c630fee6 Kostas Papadimitriou
        pending = get_object_or_404(PendingThirdPartyUser,
471 c630fee6 Kostas Papadimitriou
                                    token=third_party_token)
472 c630fee6 Kostas Papadimitriou
        provider = pending.provider
473 c630fee6 Kostas Papadimitriou
        instance = pending.get_user_instance()
474 8ab484ea Kostas Papadimitriou
475 890b0eaf Sofia Papagiannaki
    try:
476 18ffbee1 Sofia Papagiannaki
        if not backend:
477 18ffbee1 Sofia Papagiannaki
            backend = get_backend(request)
478 6c8a3f7c Sofia Papagiannaki
        form = backend.get_signup_form(provider, instance)
479 0a569195 Sofia Papagiannaki
    except Exception, e:
480 4e30244e Sofia Papagiannaki
        form = SimpleBackend(request).get_signup_form(provider)
481 24406ae3 Sofia Papagiannaki
        messages.error(request, e)
482 8f5a3a06 Sofia Papagiannaki
    if request.method == 'POST':
483 8f5a3a06 Sofia Papagiannaki
        if form.is_valid():
484 18ffbee1 Sofia Papagiannaki
            user = form.save(commit=False)
485 8f5a3a06 Sofia Papagiannaki
            try:
486 8f5a3a06 Sofia Papagiannaki
                result = backend.handle_activation(user)
487 8f5a3a06 Sofia Papagiannaki
                status = messages.SUCCESS
488 18ffbee1 Sofia Papagiannaki
                message = result.message
489 792c2f3b Olga Brani
490 792c2f3b Olga Brani
                form.store_user(user, request)
491 792c2f3b Olga Brani
492 ca828a10 Sofia Papagiannaki
                if 'additional_email' in form.cleaned_data:
493 ca828a10 Sofia Papagiannaki
                    additional_email = form.cleaned_data['additional_email']
494 ca828a10 Sofia Papagiannaki
                    if additional_email != user.email:
495 ca828a10 Sofia Papagiannaki
                        user.additionalmail_set.create(email=additional_email)
496 5ce3ce4f Sofia Papagiannaki
                        msg = 'Additional email: %s saved for user %s.' % (
497 6c8a3f7c Sofia Papagiannaki
                            additional_email,
498 6c8a3f7c Sofia Papagiannaki
                            user.email
499 6c8a3f7c Sofia Papagiannaki
                        )
500 b669d9c0 Sofia Papagiannaki
                        logger._log(LOGGING_LEVEL, msg, [])
501 8f5a3a06 Sofia Papagiannaki
                if user and user.is_active:
502 8f5a3a06 Sofia Papagiannaki
                    next = request.POST.get('next', '')
503 40a0cd8b Sofia Papagiannaki
                    response = prepare_response(request, user, next=next)
504 c3f6cdf1 root
                    transaction.commit()
505 40a0cd8b Sofia Papagiannaki
                    return response
506 8f5a3a06 Sofia Papagiannaki
                messages.add_message(request, status, message)
507 792c2f3b Olga Brani
                transaction.commit()
508 279d6e51 Olga Brani
                return render_response(
509 279d6e51 Olga Brani
                    on_success,
510 279d6e51 Olga Brani
                    context_instance=get_context(
511 279d6e51 Olga Brani
                        request,
512 279d6e51 Olga Brani
                        extra_context
513 279d6e51 Olga Brani
                    )
514 279d6e51 Olga Brani
                )
515 18ffbee1 Sofia Papagiannaki
            except SendMailError, e:
516 c44955a6 Sofia Papagiannaki
                logger.exception(e)
517 18ffbee1 Sofia Papagiannaki
                status = messages.ERROR
518 18ffbee1 Sofia Papagiannaki
                message = e.message
519 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
520 10ed0073 Sofia Papagiannaki
                transaction.rollback()
521 18ffbee1 Sofia Papagiannaki
            except BaseException, e:
522 678b2236 Sofia Papagiannaki
                logger.exception(e)
523 ae497612 Olga Brani
                message = _(astakos_messages.GENERIC_ERROR)
524 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
525 0a569195 Sofia Papagiannaki
                logger.exception(e)
526 10ed0073 Sofia Papagiannaki
                transaction.rollback()
527 8f5a3a06 Sofia Papagiannaki
    return render_response(template_name,
528 5ce3ce4f Sofia Papagiannaki
                           signup_form=form,
529 8ab484ea Kostas Papadimitriou
                           third_party_token=third_party_token,
530 5ce3ce4f Sofia Papagiannaki
                           provider=provider,
531 890b0eaf Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
532 64cd4730 Antony Chazapis
533 5ce3ce4f Sofia Papagiannaki
534 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
535 badcb2a9 Kostas Papadimitriou
@required_auth_methods_assigned(only_warn=True)
536 890b0eaf Sofia Papagiannaki
@login_required
537 270dd48d Sofia Papagiannaki
@signed_terms_required
538 aab4d540 Sofia Papagiannaki
def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context=None):
539 890b0eaf Sofia Papagiannaki
    """
540 890b0eaf Sofia Papagiannaki
    Allows a user to send feedback.
541 176023aa Kostas Papadimitriou

542 890b0eaf Sofia Papagiannaki
    In case of GET request renders a form for providing the feedback information.
543 890b0eaf Sofia Papagiannaki
    In case of POST sends an email to support team.
544 176023aa Kostas Papadimitriou

545 2cbaacd5 Sofia Papagiannaki
    If the user isn't logged in, redirects to settings.LOGIN_URL.
546 176023aa Kostas Papadimitriou

547 890b0eaf Sofia Papagiannaki
    **Arguments**
548 176023aa Kostas Papadimitriou

549 890b0eaf Sofia Papagiannaki
    ``template_name``
550 890b0eaf Sofia Papagiannaki
        A custom template to use. This is optional; if not specified,
551 1e685275 Sofia Papagiannaki
        this will default to ``im/feedback.html``.
552 176023aa Kostas Papadimitriou

553 890b0eaf Sofia Papagiannaki
    ``extra_context``
554 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
555 176023aa Kostas Papadimitriou

556 890b0eaf Sofia Papagiannaki
    **Template:**
557 176023aa Kostas Papadimitriou

558 1e685275 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
559 176023aa Kostas Papadimitriou

560 890b0eaf Sofia Papagiannaki
    **Settings:**
561 176023aa Kostas Papadimitriou

562 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
563 890b0eaf Sofia Papagiannaki
    """
564 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
565 64cd4730 Antony Chazapis
    if request.method == 'GET':
566 890b0eaf Sofia Papagiannaki
        form = FeedbackForm()
567 890b0eaf Sofia Papagiannaki
    if request.method == 'POST':
568 890b0eaf Sofia Papagiannaki
        if not request.user:
569 890b0eaf Sofia Papagiannaki
            return HttpResponse('Unauthorized', status=401)
570 176023aa Kostas Papadimitriou
571 890b0eaf Sofia Papagiannaki
        form = FeedbackForm(request.POST)
572 890b0eaf Sofia Papagiannaki
        if form.is_valid():
573 e9083112 Sofia Papagiannaki
            msg = form.cleaned_data['feedback_msg']
574 8f5a3a06 Sofia Papagiannaki
            data = form.cleaned_data['feedback_data']
575 538ccdd5 Sofia Papagiannaki
            try:
576 8f5a3a06 Sofia Papagiannaki
                send_feedback(msg, data, request.user, email_template_name)
577 8f5a3a06 Sofia Papagiannaki
            except SendMailError, e:
578 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
579 8f5a3a06 Sofia Papagiannaki
            else:
580 ae497612 Olga Brani
                message = _(astakos_messages.FEEDBACK_SENT)
581 aab4d540 Sofia Papagiannaki
                messages.success(request, message)
582 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
583 5ce3ce4f Sofia Papagiannaki
                           feedback_form=form,
584 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
585 5ce3ce4f Sofia Papagiannaki
586 15efc749 Sofia Papagiannaki
587 217994f8 Sofia Papagiannaki
@require_http_methods(["GET"])
588 8e45d6fd Sofia Papagiannaki
@signed_terms_required
589 aab4d540 Sofia Papagiannaki
def logout(request, template='registration/logged_out.html', extra_context=None):
590 63ecdd20 Sofia Papagiannaki
    """
591 b2ffa772 Sofia Papagiannaki
    Wraps `django.contrib.auth.logout`.
592 63ecdd20 Sofia Papagiannaki
    """
593 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
594 7482228b Sofia Papagiannaki
    response = HttpResponse()
595 8e45d6fd Sofia Papagiannaki
    if request.user.is_authenticated():
596 8e45d6fd Sofia Papagiannaki
        email = request.user.email
597 8e45d6fd Sofia Papagiannaki
        auth_logout(request)
598 c630fee6 Kostas Papadimitriou
    else:
599 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
600 c630fee6 Kostas Papadimitriou
        response.status_code = 301
601 c630fee6 Kostas Papadimitriou
        return response
602 c630fee6 Kostas Papadimitriou
603 217994f8 Sofia Papagiannaki
    next = restrict_next(
604 217994f8 Sofia Papagiannaki
        request.GET.get('next'),
605 217994f8 Sofia Papagiannaki
        domain=COOKIE_DOMAIN
606 217994f8 Sofia Papagiannaki
    )
607 c630fee6 Kostas Papadimitriou
608 63ecdd20 Sofia Papagiannaki
    if next:
609 63ecdd20 Sofia Papagiannaki
        response['Location'] = next
610 63ecdd20 Sofia Papagiannaki
        response.status_code = 302
611 0d02a287 Sofia Papagiannaki
    elif LOGOUT_NEXT:
612 0d02a287 Sofia Papagiannaki
        response['Location'] = LOGOUT_NEXT
613 0d02a287 Sofia Papagiannaki
        response.status_code = 301
614 b2ffa772 Sofia Papagiannaki
    else:
615 c0b26605 Sofia Papagiannaki
        messages.add_message(request, messages.SUCCESS, _(astakos_messages.LOGOUT_SUCCESS))
616 c630fee6 Kostas Papadimitriou
        response['Location'] = reverse('index')
617 c630fee6 Kostas Papadimitriou
        response.status_code = 301
618 49df775e Sofia Papagiannaki
    return response
619 2126d85d Sofia Papagiannaki
620 5ce3ce4f Sofia Papagiannaki
621 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
622 683cf244 Sofia Papagiannaki
@transaction.commit_manually
623 3bb604eb Sofia Papagiannaki
def activate(request, greeting_email_template_name='im/welcome_email.txt',
624 3bb604eb Sofia Papagiannaki
             helpdesk_email_template_name='im/helpdesk_notification.txt'):
625 2126d85d Sofia Papagiannaki
    """
626 683cf244 Sofia Papagiannaki
    Activates the user identified by the ``auth`` request parameter, sends a welcome email
627 683cf244 Sofia Papagiannaki
    and renews the user token.
628 176023aa Kostas Papadimitriou

629 683cf244 Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the user state will be updated
630 683cf244 Sofia Papagiannaki
    only if the email will be send successfully.
631 2126d85d Sofia Papagiannaki
    """
632 2126d85d Sofia Papagiannaki
    token = request.GET.get('auth')
633 2126d85d Sofia Papagiannaki
    next = request.GET.get('next')
634 2126d85d Sofia Papagiannaki
    try:
635 2126d85d Sofia Papagiannaki
        user = AstakosUser.objects.get(auth_token=token)
636 2126d85d Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
637 279d6e51 Olga Brani
        return HttpResponseBadRequest(_(astakos_messages.ACCOUNT_UNKNOWN))
638 5ce3ce4f Sofia Papagiannaki
639 d1757ca7 Sofia Papagiannaki
    if user.is_active:
640 ae497612 Olga Brani
        message = _(astakos_messages.ACCOUNT_ALREADY_ACTIVE)
641 24406ae3 Sofia Papagiannaki
        messages.error(request, message)
642 279d6e51 Olga Brani
        return index(request)
643 5ce3ce4f Sofia Papagiannaki
644 0a569195 Sofia Papagiannaki
    try:
645 279d6e51 Olga Brani
        activate_func(user, greeting_email_template_name, helpdesk_email_template_name, verify_email=True)
646 ef20ea07 Sofia Papagiannaki
        response = prepare_response(request, user, next, renew=True)
647 ef20ea07 Sofia Papagiannaki
        transaction.commit()
648 279d6e51 Olga Brani
        return response
649 ef20ea07 Sofia Papagiannaki
    except SendMailError, e:
650 ef20ea07 Sofia Papagiannaki
        message = e.message
651 ef20ea07 Sofia Papagiannaki
        messages.add_message(request, messages.ERROR, message)
652 ef20ea07 Sofia Papagiannaki
        transaction.rollback()
653 279d6e51 Olga Brani
        return index(request)
654 ef20ea07 Sofia Papagiannaki
    except BaseException, e:
655 ef20ea07 Sofia Papagiannaki
        status = messages.ERROR
656 c0b26605 Sofia Papagiannaki
        message = _(astakos_messages.GENERIC_ERROR)
657 ef20ea07 Sofia Papagiannaki
        messages.add_message(request, messages.ERROR, message)
658 ef20ea07 Sofia Papagiannaki
        logger.exception(e)
659 ef20ea07 Sofia Papagiannaki
        transaction.rollback()
660 279d6e51 Olga Brani
        return index(request)
661 270dd48d Sofia Papagiannaki
662 5ce3ce4f Sofia Papagiannaki
663 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
664 aab4d540 Sofia Papagiannaki
def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context=None):
665 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
666 270dd48d Sofia Papagiannaki
    term = None
667 270dd48d Sofia Papagiannaki
    terms = None
668 270dd48d Sofia Papagiannaki
    if not term_id:
669 270dd48d Sofia Papagiannaki
        try:
670 270dd48d Sofia Papagiannaki
            term = ApprovalTerms.objects.order_by('-id')[0]
671 270dd48d Sofia Papagiannaki
        except IndexError:
672 270dd48d Sofia Papagiannaki
            pass
673 270dd48d Sofia Papagiannaki
    else:
674 270dd48d Sofia Papagiannaki
        try:
675 aab4d540 Sofia Papagiannaki
            term = ApprovalTerms.objects.get(id=term_id)
676 aab4d540 Sofia Papagiannaki
        except ApprovalTerms.DoesNotExist, e:
677 270dd48d Sofia Papagiannaki
            pass
678 176023aa Kostas Papadimitriou
679 270dd48d Sofia Papagiannaki
    if not term:
680 ae497612 Olga Brani
        messages.error(request, _(astakos_messages.NO_APPROVAL_TERMS))
681 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('index'))
682 270dd48d Sofia Papagiannaki
    f = open(term.location, 'r')
683 270dd48d Sofia Papagiannaki
    terms = f.read()
684 176023aa Kostas Papadimitriou
685 270dd48d Sofia Papagiannaki
    if request.method == 'POST':
686 217994f8 Sofia Papagiannaki
        next = restrict_next(
687 217994f8 Sofia Papagiannaki
            request.POST.get('next'),
688 217994f8 Sofia Papagiannaki
            domain=COOKIE_DOMAIN
689 217994f8 Sofia Papagiannaki
        )
690 270dd48d Sofia Papagiannaki
        if not next:
691 6ff7a7ca Sofia Papagiannaki
            next = reverse('index')
692 270dd48d Sofia Papagiannaki
        form = SignApprovalTermsForm(request.POST, instance=request.user)
693 270dd48d Sofia Papagiannaki
        if not form.is_valid():
694 270dd48d Sofia Papagiannaki
            return render_response(template_name,
695 5ce3ce4f Sofia Papagiannaki
                                   terms=terms,
696 5ce3ce4f Sofia Papagiannaki
                                   approval_terms_form=form,
697 5ce3ce4f Sofia Papagiannaki
                                   context_instance=get_context(request, extra_context))
698 270dd48d Sofia Papagiannaki
        user = form.save()
699 270dd48d Sofia Papagiannaki
        return HttpResponseRedirect(next)
700 270dd48d Sofia Papagiannaki
    else:
701 586967c0 Sofia Papagiannaki
        form = None
702 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
703 586967c0 Sofia Papagiannaki
            form = SignApprovalTermsForm(instance=request.user)
704 270dd48d Sofia Papagiannaki
        return render_response(template_name,
705 5ce3ce4f Sofia Papagiannaki
                               terms=terms,
706 5ce3ce4f Sofia Papagiannaki
                               approval_terms_form=form,
707 5ce3ce4f Sofia Papagiannaki
                               context_instance=get_context(request, extra_context))
708 5ce3ce4f Sofia Papagiannaki
709 270dd48d Sofia Papagiannaki
710 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
711 badcb2a9 Kostas Papadimitriou
@valid_astakos_user_required
712 49790d9d Sofia Papagiannaki
@transaction.commit_manually
713 49790d9d Sofia Papagiannaki
def change_email(request, activation_key=None,
714 49790d9d Sofia Papagiannaki
                 email_template_name='registration/email_change_email.txt',
715 49790d9d Sofia Papagiannaki
                 form_template_name='registration/email_change_form.html',
716 49790d9d Sofia Papagiannaki
                 confirm_template_name='registration/email_change_done.html',
717 aab4d540 Sofia Papagiannaki
                 extra_context=None):
718 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
719 53e0b8fe Kostas Papadimitriou
720 53e0b8fe Kostas Papadimitriou
721 49790d9d Sofia Papagiannaki
    if activation_key:
722 49790d9d Sofia Papagiannaki
        try:
723 49790d9d Sofia Papagiannaki
            user = EmailChange.objects.change_email(activation_key)
724 49790d9d Sofia Papagiannaki
            if request.user.is_authenticated() and request.user == user:
725 ae497612 Olga Brani
                msg = _(astakos_messages.EMAIL_CHANGED)
726 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
727 49790d9d Sofia Papagiannaki
                auth_logout(request)
728 49790d9d Sofia Papagiannaki
                response = prepare_response(request, user)
729 49790d9d Sofia Papagiannaki
                transaction.commit()
730 53e0b8fe Kostas Papadimitriou
                return HttpResponseRedirect(reverse('edit_profile'))
731 49790d9d Sofia Papagiannaki
        except ValueError, e:
732 24406ae3 Sofia Papagiannaki
            messages.error(request, e)
733 53e0b8fe Kostas Papadimitriou
            transaction.rollback()
734 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('index'))
735 53e0b8fe Kostas Papadimitriou
736 49790d9d Sofia Papagiannaki
        return render_response(confirm_template_name,
737 53e0b8fe Kostas Papadimitriou
                               modified_user=user if 'user' in locals() \
738 53e0b8fe Kostas Papadimitriou
                               else None, context_instance=get_context(request,
739 5ce3ce4f Sofia Papagiannaki
                                                            extra_context))
740 5ce3ce4f Sofia Papagiannaki
741 49790d9d Sofia Papagiannaki
    if not request.user.is_authenticated():
742 49790d9d Sofia Papagiannaki
        path = quote(request.get_full_path())
743 6ff7a7ca Sofia Papagiannaki
        url = request.build_absolute_uri(reverse('index'))
744 49790d9d Sofia Papagiannaki
        return HttpResponseRedirect(url + '?next=' + path)
745 53e0b8fe Kostas Papadimitriou
746 53e0b8fe Kostas Papadimitriou
    # clean up expired email changes
747 53e0b8fe Kostas Papadimitriou
    if request.user.email_change_is_pending():
748 53e0b8fe Kostas Papadimitriou
        change = request.user.emailchanges.get()
749 53e0b8fe Kostas Papadimitriou
        if change.activation_key_expired():
750 53e0b8fe Kostas Papadimitriou
            change.delete()
751 53e0b8fe Kostas Papadimitriou
            transaction.commit()
752 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('email_change'))
753 53e0b8fe Kostas Papadimitriou
754 49790d9d Sofia Papagiannaki
    form = EmailChangeForm(request.POST or None)
755 49790d9d Sofia Papagiannaki
    if request.method == 'POST' and form.is_valid():
756 49790d9d Sofia Papagiannaki
        try:
757 53e0b8fe Kostas Papadimitriou
            # delete pending email changes
758 53e0b8fe Kostas Papadimitriou
            request.user.emailchanges.all().delete()
759 49790d9d Sofia Papagiannaki
            ec = form.save(email_template_name, request)
760 49790d9d Sofia Papagiannaki
        except SendMailError, e:
761 49790d9d Sofia Papagiannaki
            msg = e
762 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
763 49790d9d Sofia Papagiannaki
            transaction.rollback()
764 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('edit_profile'))
765 49790d9d Sofia Papagiannaki
        else:
766 ae497612 Olga Brani
            msg = _(astakos_messages.EMAIL_CHANGE_REGISTERED)
767 24406ae3 Sofia Papagiannaki
            messages.success(request, msg)
768 49790d9d Sofia Papagiannaki
            transaction.commit()
769 53e0b8fe Kostas Papadimitriou
            return HttpResponseRedirect(reverse('edit_profile'))
770 53e0b8fe Kostas Papadimitriou
771 53e0b8fe Kostas Papadimitriou
    if request.user.email_change_is_pending():
772 53e0b8fe Kostas Papadimitriou
        messages.warning(request, astakos_messages.PENDING_EMAIL_CHANGE_REQUEST)
773 53e0b8fe Kostas Papadimitriou
774 c0b26605 Sofia Papagiannaki
    return render_response(
775 c0b26605 Sofia Papagiannaki
        form_template_name,
776 c0b26605 Sofia Papagiannaki
        form=form,
777 c0b26605 Sofia Papagiannaki
        context_instance=get_context(request, extra_context)
778 c0b26605 Sofia Papagiannaki
    )
779 1f3b4b39 Sofia Papagiannaki
780 1f3b4b39 Sofia Papagiannaki
781 1f3b4b39 Sofia Papagiannaki
def send_activation(request, user_id, template_name='im/login.html', extra_context=None):
782 792c2f3b Olga Brani
783 badcb2a9 Kostas Papadimitriou
    if request.user.is_authenticated():
784 badcb2a9 Kostas Papadimitriou
        messages.error(request, _(astakos_messages.ALREADY_LOGGED_IN))
785 badcb2a9 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
786 badcb2a9 Kostas Papadimitriou
787 48421603 Kostas Papadimitriou
    if astakos_settings.MODERATION_ENABLED:
788 792c2f3b Olga Brani
        raise PermissionDenied
789 792c2f3b Olga Brani
790 1f3b4b39 Sofia Papagiannaki
    extra_context = extra_context or {}
791 1f3b4b39 Sofia Papagiannaki
    try:
792 1f3b4b39 Sofia Papagiannaki
        u = AstakosUser.objects.get(id=user_id)
793 1f3b4b39 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
794 c0b26605 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.ACCOUNT_UNKNOWN))
795 1f3b4b39 Sofia Papagiannaki
    else:
796 1f3b4b39 Sofia Papagiannaki
        try:
797 1f3b4b39 Sofia Papagiannaki
            send_activation_func(u)
798 c0b26605 Sofia Papagiannaki
            msg = _(astakos_messages.ACTIVATION_SENT)
799 1f3b4b39 Sofia Papagiannaki
            messages.success(request, msg)
800 1f3b4b39 Sofia Papagiannaki
        except SendMailError, e:
801 1f3b4b39 Sofia Papagiannaki
            messages.error(request, e)
802 1f3b4b39 Sofia Papagiannaki
    return render_response(
803 1f3b4b39 Sofia Papagiannaki
        template_name,
804 c0b26605 Sofia Papagiannaki
        login_form = LoginForm(request=request),
805 1f3b4b39 Sofia Papagiannaki
        context_instance = get_context(
806 1f3b4b39 Sofia Papagiannaki
            request,
807 1f3b4b39 Sofia Papagiannaki
            extra_context
808 1f3b4b39 Sofia Papagiannaki
        )
809 1f3b4b39 Sofia Papagiannaki
    )
810 5ce3ce4f Sofia Papagiannaki
811 73fbaec4 Sofia Papagiannaki
812 73fbaec4 Sofia Papagiannaki
@require_http_methods(["GET"])
813 badcb2a9 Kostas Papadimitriou
@valid_astakos_user_required
814 666c7490 Sofia Papagiannaki
def resource_usage(request):
815 e9ef5009 Kostas Papadimitriou
816 e9ef5009 Kostas Papadimitriou
    def with_class(entry):
817 e9ef5009 Kostas Papadimitriou
         entry['load_class'] = 'red'
818 e9ef5009 Kostas Papadimitriou
         max_value = float(entry['maxValue'])
819 e9ef5009 Kostas Papadimitriou
         curr_value = float(entry['currValue'])
820 e9ef5009 Kostas Papadimitriou
         entry['ratio_limited']= 0
821 e9ef5009 Kostas Papadimitriou
         if max_value > 0 :
822 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = (curr_value / max_value) * 100
823 e9ef5009 Kostas Papadimitriou
         else:
824 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = 0
825 e9ef5009 Kostas Papadimitriou
         if entry['ratio'] < 66:
826 e9ef5009 Kostas Papadimitriou
             entry['load_class'] = 'yellow'
827 e9ef5009 Kostas Papadimitriou
         if entry['ratio'] < 33:
828 e9ef5009 Kostas Papadimitriou
             entry['load_class'] = 'green'
829 e9ef5009 Kostas Papadimitriou
         if entry['ratio']<0:
830 e9ef5009 Kostas Papadimitriou
             entry['ratio'] = 0
831 e9ef5009 Kostas Papadimitriou
         if entry['ratio']>100:
832 e9ef5009 Kostas Papadimitriou
             entry['ratio_limited'] = 100
833 e9ef5009 Kostas Papadimitriou
         else:
834 e9ef5009 Kostas Papadimitriou
             entry['ratio_limited'] = entry['ratio']
835 e9ef5009 Kostas Papadimitriou
         return entry
836 e9ef5009 Kostas Papadimitriou
837 e9ef5009 Kostas Papadimitriou
    def pluralize(entry):
838 e9ef5009 Kostas Papadimitriou
        entry['plural'] = engine.plural(entry.get('name'))
839 e9ef5009 Kostas Papadimitriou
        return entry
840 e9ef5009 Kostas Papadimitriou
841 a9c7ff8a Sofia Papagiannaki
    resource_usage = None
842 666c7490 Sofia Papagiannaki
    result = callpoint.get_user_usage(request.user.id)
843 820b18e0 Sofia Papagiannaki
    if result.is_success:
844 a9c7ff8a Sofia Papagiannaki
        resource_usage = result.data
845 e9ef5009 Kostas Papadimitriou
        backenddata = map(with_class, result.data)
846 e2497bc5 Sofia Papagiannaki
        backenddata = map(pluralize , backenddata)
847 9a06d96f Olga Brani
    else:
848 820b18e0 Sofia Papagiannaki
        messages.error(request, result.reason)
849 37f8b1a6 Olga Brani
        backenddata = []
850 666c7490 Sofia Papagiannaki
    return render_response('im/resource_usage.html',
851 3cbd5e47 Olga Brani
                           context_instance=get_context(request),
852 e9ef5009 Kostas Papadimitriou
                           resource_usage=backenddata,
853 3cbd5e47 Olga Brani
                           result=result)
854 9a06d96f Olga Brani
855 f432088a Kostas Papadimitriou
# TODO: action only on POST and user should confirm the removal
856 d2633501 Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
857 d2633501 Kostas Papadimitriou
@login_required
858 d2633501 Kostas Papadimitriou
@signed_terms_required
859 d2633501 Kostas Papadimitriou
def remove_auth_provider(request, pk):
860 f432088a Kostas Papadimitriou
    try:
861 f432088a Kostas Papadimitriou
        provider = request.user.auth_providers.get(pk=pk)
862 f432088a Kostas Papadimitriou
    except AstakosUserAuthProvider.DoesNotExist:
863 f432088a Kostas Papadimitriou
        raise Http404
864 f432088a Kostas Papadimitriou
865 d2633501 Kostas Papadimitriou
    if provider.can_remove():
866 d2633501 Kostas Papadimitriou
        provider.delete()
867 d2633501 Kostas Papadimitriou
        return HttpResponseRedirect(reverse('edit_profile'))
868 d2633501 Kostas Papadimitriou
    else:
869 f432088a Kostas Papadimitriou
        raise PermissionDenied
870 5ebebb20 Olga Brani
871 792c2f3b Olga Brani
872 5ebebb20 Olga Brani
def how_it_works(request):
873 5ebebb20 Olga Brani
    return render_response(
874 ccab6eb5 Sofia Papagiannaki
        'im/how_it_works.html',
875 ccab6eb5 Sofia Papagiannaki
        context_instance=get_context(request))
876 e1a80257 Sofia Papagiannaki
877 bfe23b13 Sofia Papagiannaki
@transaction.commit_manually
878 172ce682 Sofia Papagiannaki
def _create_object(request, model=None, template_name=None,
879 172ce682 Sofia Papagiannaki
        template_loader=template_loader, extra_context=None, post_save_redirect=None,
880 6556e514 Sofia Papagiannaki
        login_required=False, context_processors=None, form_class=None,
881 6556e514 Sofia Papagiannaki
        msg=None):
882 172ce682 Sofia Papagiannaki
    """
883 4e748491 Sofia Papagiannaki
    Based of django.views.generic.create_update.create_object which displays a
884 172ce682 Sofia Papagiannaki
    summary page before creating the object.
885 172ce682 Sofia Papagiannaki
    """
886 bfe23b13 Sofia Papagiannaki
    rollback = False
887 172ce682 Sofia Papagiannaki
    response = None
888 4e748491 Sofia Papagiannaki
889 4e748491 Sofia Papagiannaki
    if extra_context is None: extra_context = {}
890 4e748491 Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
891 4e748491 Sofia Papagiannaki
        return redirect_to_login(request.path)
892 ccab6eb5 Sofia Papagiannaki
    try:
893 f7cf5257 Kostas Papadimitriou
894 172ce682 Sofia Papagiannaki
        model, form_class = get_model_and_form_class(model, form_class)
895 172ce682 Sofia Papagiannaki
        extra_context['edit'] = 0
896 172ce682 Sofia Papagiannaki
        if request.method == 'POST':
897 172ce682 Sofia Papagiannaki
            form = form_class(request.POST, request.FILES)
898 172ce682 Sofia Papagiannaki
            if form.is_valid():
899 172ce682 Sofia Papagiannaki
                verify = request.GET.get('verify')
900 172ce682 Sofia Papagiannaki
                edit = request.GET.get('edit')
901 172ce682 Sofia Papagiannaki
                if verify == '1':
902 172ce682 Sofia Papagiannaki
                    extra_context['show_form'] = False
903 172ce682 Sofia Papagiannaki
                    extra_context['form_data'] = form.cleaned_data
904 172ce682 Sofia Papagiannaki
                elif edit == '1':
905 172ce682 Sofia Papagiannaki
                    extra_context['show_form'] = True
906 172ce682 Sofia Papagiannaki
                else:
907 172ce682 Sofia Papagiannaki
                    new_object = form.save()
908 6556e514 Sofia Papagiannaki
                    if not msg:
909 6556e514 Sofia Papagiannaki
                        msg = _("The %(verbose_name)s was created successfully.")
910 6556e514 Sofia Papagiannaki
                    msg = msg % model._meta.__dict__
911 172ce682 Sofia Papagiannaki
                    messages.success(request, msg, fail_silently=True)
912 172ce682 Sofia Papagiannaki
                    response = redirect(post_save_redirect, new_object)
913 172ce682 Sofia Papagiannaki
        else:
914 172ce682 Sofia Papagiannaki
            form = form_class()
915 b8f05f8d Sofia Papagiannaki
    except BaseException, e:
916 b8f05f8d Sofia Papagiannaki
        logger.exception(e)
917 b8f05f8d Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
918 bfe23b13 Sofia Papagiannaki
        rollback = True
919 bfe23b13 Sofia Papagiannaki
    finally:
920 bfe23b13 Sofia Papagiannaki
        if rollback:
921 bfe23b13 Sofia Papagiannaki
            transaction.rollback()
922 bfe23b13 Sofia Papagiannaki
        else:
923 bfe23b13 Sofia Papagiannaki
            transaction.commit()
924 4e748491 Sofia Papagiannaki
925 172ce682 Sofia Papagiannaki
        if response == None:
926 172ce682 Sofia Papagiannaki
            # Create the template, context, response
927 172ce682 Sofia Papagiannaki
            if not template_name:
928 172ce682 Sofia Papagiannaki
                template_name = "%s/%s_form.html" %\
929 172ce682 Sofia Papagiannaki
                     (model._meta.app_label, model._meta.object_name.lower())
930 172ce682 Sofia Papagiannaki
            t = template_loader.get_template(template_name)
931 172ce682 Sofia Papagiannaki
            c = RequestContext(request, {
932 172ce682 Sofia Papagiannaki
                'form': form
933 172ce682 Sofia Papagiannaki
            }, context_processors)
934 172ce682 Sofia Papagiannaki
            apply_extra_context(extra_context, c)
935 172ce682 Sofia Papagiannaki
            response = HttpResponse(t.render(c))
936 172ce682 Sofia Papagiannaki
        return response
937 172ce682 Sofia Papagiannaki
938 4e748491 Sofia Papagiannaki
@transaction.commit_manually
939 4e748491 Sofia Papagiannaki
def _update_object(request, model=None, object_id=None, slug=None,
940 4e748491 Sofia Papagiannaki
        slug_field='slug', template_name=None, template_loader=template_loader,
941 4e748491 Sofia Papagiannaki
        extra_context=None, post_save_redirect=None, login_required=False,
942 4e748491 Sofia Papagiannaki
        context_processors=None, template_object_name='object',
943 6556e514 Sofia Papagiannaki
        form_class=None, msg=None):
944 4e748491 Sofia Papagiannaki
    """
945 4e748491 Sofia Papagiannaki
    Based of django.views.generic.create_update.update_object which displays a
946 4e748491 Sofia Papagiannaki
    summary page before updating the object.
947 4e748491 Sofia Papagiannaki
    """
948 4e748491 Sofia Papagiannaki
    rollback = False
949 4e748491 Sofia Papagiannaki
    response = None
950 4e748491 Sofia Papagiannaki
951 4e748491 Sofia Papagiannaki
    if extra_context is None: extra_context = {}
952 4e748491 Sofia Papagiannaki
    if login_required and not request.user.is_authenticated():
953 4e748491 Sofia Papagiannaki
        return redirect_to_login(request.path)
954 f7cf5257 Kostas Papadimitriou
955 4e748491 Sofia Papagiannaki
    try:
956 4e748491 Sofia Papagiannaki
        model, form_class = get_model_and_form_class(model, form_class)
957 4e748491 Sofia Papagiannaki
        obj = lookup_object(model, object_id, slug, slug_field)
958 f7cf5257 Kostas Papadimitriou
959 4e748491 Sofia Papagiannaki
        if request.method == 'POST':
960 4e748491 Sofia Papagiannaki
            form = form_class(request.POST, request.FILES, instance=obj)
961 4e748491 Sofia Papagiannaki
            if form.is_valid():
962 4e748491 Sofia Papagiannaki
                verify = request.GET.get('verify')
963 4e748491 Sofia Papagiannaki
                edit = request.GET.get('edit')
964 4e748491 Sofia Papagiannaki
                if verify == '1':
965 4e748491 Sofia Papagiannaki
                    extra_context['show_form'] = False
966 4e748491 Sofia Papagiannaki
                    extra_context['form_data'] = form.cleaned_data
967 4e748491 Sofia Papagiannaki
                elif edit == '1':
968 4e748491 Sofia Papagiannaki
                    extra_context['show_form'] = True
969 f7cf5257 Kostas Papadimitriou
                else:
970 4e748491 Sofia Papagiannaki
                    obj = form.save()
971 6556e514 Sofia Papagiannaki
                    if not msg:
972 6556e514 Sofia Papagiannaki
                        msg = _("The %(verbose_name)s was created successfully.")
973 6556e514 Sofia Papagiannaki
                    msg = msg % model._meta.__dict__
974 6556e514 Sofia Papagiannaki
                    messages.success(request, msg, fail_silently=True)
975 4e748491 Sofia Papagiannaki
                    response = redirect(post_save_redirect, obj)
976 4e748491 Sofia Papagiannaki
        else:
977 4e748491 Sofia Papagiannaki
            form = form_class(instance=obj)
978 4e748491 Sofia Papagiannaki
    except BaseException, e:
979 4e748491 Sofia Papagiannaki
        logger.exception(e)
980 4e748491 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
981 4e748491 Sofia Papagiannaki
        rollback = True
982 4e748491 Sofia Papagiannaki
    finally:
983 4e748491 Sofia Papagiannaki
        if rollback:
984 4e748491 Sofia Papagiannaki
            transaction.rollback()
985 4e748491 Sofia Papagiannaki
        else:
986 4e748491 Sofia Papagiannaki
            transaction.commit()
987 4e748491 Sofia Papagiannaki
        if response == None:
988 4e748491 Sofia Papagiannaki
            if not template_name:
989 4e748491 Sofia Papagiannaki
                template_name = "%s/%s_form.html" %\
990 4e748491 Sofia Papagiannaki
                    (model._meta.app_label, model._meta.object_name.lower())
991 4e748491 Sofia Papagiannaki
            t = template_loader.get_template(template_name)
992 4e748491 Sofia Papagiannaki
            c = RequestContext(request, {
993 4e748491 Sofia Papagiannaki
                'form': form,
994 4e748491 Sofia Papagiannaki
                template_object_name: obj,
995 4e748491 Sofia Papagiannaki
            }, context_processors)
996 4e748491 Sofia Papagiannaki
            apply_extra_context(extra_context, c)
997 4e748491 Sofia Papagiannaki
            response = HttpResponse(t.render(c))
998 4e748491 Sofia Papagiannaki
            populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.attname))
999 4e748491 Sofia Papagiannaki
        return response
1000 4e748491 Sofia Papagiannaki
1001 172ce682 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1002 172ce682 Sofia Papagiannaki
@signed_terms_required
1003 172ce682 Sofia Papagiannaki
@login_required
1004 172ce682 Sofia Papagiannaki
def project_add(request):
1005 6556e514 Sofia Papagiannaki
    resource_groups = RESOURCES_PRESENTATION_DATA.get('groups', {})
1006 6556e514 Sofia Papagiannaki
    resource_catalog = ()
1007 172ce682 Sofia Papagiannaki
    result = callpoint.list_resources()
1008 6556e514 Sofia Papagiannaki
    details_fields = [
1009 6556e514 Sofia Papagiannaki
        "name", "homepage", "description","start_date","end_date", "comments"]
1010 6556e514 Sofia Papagiannaki
    membership_fields =[
1011 6556e514 Sofia Papagiannaki
        "member_join_policy", "member_leave_policy", "limit_on_members_number"]
1012 172ce682 Sofia Papagiannaki
    if not result.is_success:
1013 172ce682 Sofia Papagiannaki
        messages.error(
1014 172ce682 Sofia Papagiannaki
            request,
1015 172ce682 Sofia Papagiannaki
            'Unable to retrieve system resources: %s' % result.reason
1016 172ce682 Sofia Papagiannaki
    )
1017 172ce682 Sofia Papagiannaki
    else:
1018 6556e514 Sofia Papagiannaki
        resource_catalog = [
1019 6556e514 Sofia Papagiannaki
            (g, filter(lambda r: r.get('group', '') == g, result.data)) \
1020 6556e514 Sofia Papagiannaki
                for g in resource_groups]
1021 6556e514 Sofia Papagiannaki
    extra_context = {
1022 6556e514 Sofia Papagiannaki
        'resource_catalog':resource_catalog,
1023 6556e514 Sofia Papagiannaki
        'resource_groups':resource_groups,
1024 6556e514 Sofia Papagiannaki
        'show_form':True,
1025 6556e514 Sofia Papagiannaki
        'details_fields':details_fields,
1026 6556e514 Sofia Papagiannaki
        'membership_fields':membership_fields}
1027 6556e514 Sofia Papagiannaki
    return _create_object(
1028 6556e514 Sofia Papagiannaki
        request,
1029 6556e514 Sofia Papagiannaki
        template_name='im/projects/projectapplication_form.html',
1030 6556e514 Sofia Papagiannaki
        extra_context=extra_context,
1031 6556e514 Sofia Papagiannaki
        post_save_redirect=reverse('project_list'),
1032 6556e514 Sofia Papagiannaki
        form_class=ProjectApplicationForm,
1033 6556e514 Sofia Papagiannaki
        msg=_("The %(verbose_name)s has been received and \
1034 6556e514 Sofia Papagiannaki
                 is under consideration."))
1035 ccab6eb5 Sofia Papagiannaki
1036 e1a80257 Sofia Papagiannaki
1037 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET"])
1038 e1a80257 Sofia Papagiannaki
@signed_terms_required
1039 e1a80257 Sofia Papagiannaki
@login_required
1040 f3342849 Sofia Papagiannaki
def project_list(request):
1041 5550bcfb Kostas Papadimitriou
    projects = ProjectApplication.objects.user_projects(request.user).select_related()
1042 2743e261 Kostas Papadimitriou
    table = tables.UserProjectApplicationsTable(projects, user=request.user,
1043 2743e261 Kostas Papadimitriou
                                                prefix="my_projects_")
1044 e6d284ef Olga Brani
    RequestConfig(request, paginate={"per_page": PAGINATE_BY}).configure(table)
1045 f7cf5257 Kostas Papadimitriou
1046 e1a80257 Sofia Papagiannaki
    return object_list(
1047 e1a80257 Sofia Papagiannaki
        request,
1048 5550bcfb Kostas Papadimitriou
        projects,
1049 71a38edf Sofia Papagiannaki
        template_name='im/projects/project_list.html',
1050 71a38edf Sofia Papagiannaki
        extra_context={
1051 71a38edf Sofia Papagiannaki
            'is_search':False,
1052 5550bcfb Kostas Papadimitriou
            'table': table,
1053 71a38edf Sofia Papagiannaki
        }
1054 71a38edf Sofia Papagiannaki
    )
1055 e1a80257 Sofia Papagiannaki
1056 f3342849 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1057 e1a80257 Sofia Papagiannaki
@signed_terms_required
1058 e1a80257 Sofia Papagiannaki
@login_required
1059 73fbaec4 Sofia Papagiannaki
def project_update(request, application_id):
1060 6556e514 Sofia Papagiannaki
    resource_groups = RESOURCES_PRESENTATION_DATA.get('groups', {})
1061 6556e514 Sofia Papagiannaki
    resource_catalog = ()
1062 8327782d Sofia Papagiannaki
    result = callpoint.list_resources()
1063 6556e514 Sofia Papagiannaki
    details_fields = [
1064 6556e514 Sofia Papagiannaki
        "name", "homepage", "description","start_date","end_date", "comments"]
1065 6556e514 Sofia Papagiannaki
    membership_fields =[
1066 6556e514 Sofia Papagiannaki
        "member_join_policy", "member_leave_policy", "limit_on_members_number"] 
1067 8327782d Sofia Papagiannaki
    if not result.is_success:
1068 8327782d Sofia Papagiannaki
        messages.error(
1069 8327782d Sofia Papagiannaki
            request,
1070 8327782d Sofia Papagiannaki
            'Unable to retrieve system resources: %s' % result.reason
1071 8327782d Sofia Papagiannaki
    )
1072 172ce682 Sofia Papagiannaki
    else:
1073 6556e514 Sofia Papagiannaki
        resource_catalog = [
1074 6556e514 Sofia Papagiannaki
            (g, filter(lambda r: r.get('group', '') == g, result.data)) \
1075 6556e514 Sofia Papagiannaki
                for g in resource_groups]
1076 6556e514 Sofia Papagiannaki
    extra_context = {
1077 6556e514 Sofia Papagiannaki
        'resource_catalog':resource_catalog,
1078 6556e514 Sofia Papagiannaki
        'resource_groups':resource_groups,
1079 6556e514 Sofia Papagiannaki
        'show_form':True,
1080 6556e514 Sofia Papagiannaki
        'details_fields':details_fields,
1081 6556e514 Sofia Papagiannaki
        'membership_fields':membership_fields}
1082 4e748491 Sofia Papagiannaki
    return _update_object(
1083 f3342849 Sofia Papagiannaki
        request,
1084 73fbaec4 Sofia Papagiannaki
        object_id=application_id,
1085 8327782d Sofia Papagiannaki
        template_name='im/projects/projectapplication_form.html',
1086 37f8b1a6 Olga Brani
        extra_context=extra_context, post_save_redirect=reverse('project_list'),
1087 6556e514 Sofia Papagiannaki
        form_class=ProjectApplicationForm,
1088 6556e514 Sofia Papagiannaki
        msg = _("The %(verbose_name)s has been received and \
1089 6556e514 Sofia Papagiannaki
                    is under consideration."))
1090 17a2f450 Sofia Papagiannaki
1091 e1a80257 Sofia Papagiannaki
1092 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1093 e1a80257 Sofia Papagiannaki
@signed_terms_required
1094 e1a80257 Sofia Papagiannaki
@login_required
1095 73fbaec4 Sofia Papagiannaki
@transaction.commit_manually
1096 73fbaec4 Sofia Papagiannaki
def project_detail(request, application_id):
1097 bfe23b13 Sofia Papagiannaki
    addmembers_form = AddProjectMembersForm()
1098 ccab6eb5 Sofia Papagiannaki
    if request.method == 'POST':
1099 bfe23b13 Sofia Papagiannaki
        addmembers_form = AddProjectMembersForm(request.POST)
1100 ccab6eb5 Sofia Papagiannaki
        if addmembers_form.is_valid():
1101 ccab6eb5 Sofia Papagiannaki
            try:
1102 73fbaec4 Sofia Papagiannaki
                rollback = False
1103 7dd3047d Sofia Papagiannaki
                application_id = int(application_id)
1104 7dd3047d Sofia Papagiannaki
                map(lambda u: enroll_member(
1105 73fbaec4 Sofia Papagiannaki
                        application_id,
1106 73fbaec4 Sofia Papagiannaki
                        u,
1107 73fbaec4 Sofia Papagiannaki
                        request_user=request.user),
1108 73fbaec4 Sofia Papagiannaki
                    addmembers_form.valid_users)
1109 73fbaec4 Sofia Papagiannaki
            except (IOError, PermissionDenied), e:
1110 73fbaec4 Sofia Papagiannaki
                messages.error(request, e)
1111 bfe23b13 Sofia Papagiannaki
            except BaseException, e:
1112 73fbaec4 Sofia Papagiannaki
                rollback = True
1113 bfe23b13 Sofia Papagiannaki
                messages.error(request, e)
1114 73fbaec4 Sofia Papagiannaki
            finally:
1115 73fbaec4 Sofia Papagiannaki
                if rollback == True:
1116 73fbaec4 Sofia Papagiannaki
                    transaction.rollback()
1117 73fbaec4 Sofia Papagiannaki
                else:
1118 73fbaec4 Sofia Papagiannaki
                    transaction.commit()
1119 bfe23b13 Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm()
1120 f7cf5257 Kostas Papadimitriou
1121 2ddfc92b Giorgos Korfiatis
    rollback = False
1122 2743e261 Kostas Papadimitriou
1123 2743e261 Kostas Papadimitriou
    application = get_object_or_404(ProjectApplication, pk=application_id)
1124 3f297552 Sofia Papagiannaki
    try:
1125 3f297552 Sofia Papagiannaki
        members = application.project.projectmembership_set.select_related()
1126 3f297552 Sofia Papagiannaki
    except Project.DoesNotExist:
1127 3f297552 Sofia Papagiannaki
        members = ProjectMembership.objects.none()
1128 2743e261 Kostas Papadimitriou
    members_table = tables.ProjectApplicationMembersTable(members,
1129 2743e261 Kostas Papadimitriou
                                                          prefix="members_")
1130 e6d284ef Olga Brani
    RequestConfig(request, paginate={"per_page": PAGINATE_BY}).configure(members_table)
1131 2743e261 Kostas Papadimitriou
1132 2ddfc92b Giorgos Korfiatis
    try:
1133 2ddfc92b Giorgos Korfiatis
        return object_detail(
1134 2ddfc92b Giorgos Korfiatis
            request,
1135 2ddfc92b Giorgos Korfiatis
            queryset=ProjectApplication.objects.select_related(),
1136 2ddfc92b Giorgos Korfiatis
            object_id=application_id,
1137 2ddfc92b Giorgos Korfiatis
            template_name='im/projects/project_detail.html',
1138 2ddfc92b Giorgos Korfiatis
            extra_context={
1139 2743e261 Kostas Papadimitriou
                'addmembers_form':addmembers_form,
1140 2743e261 Kostas Papadimitriou
                'members_table': members_table
1141 2743e261 Kostas Papadimitriou
            })
1142 2743e261 Kostas Papadimitriou
    except Exception, e:
1143 2ddfc92b Giorgos Korfiatis
        rollback = True
1144 2ddfc92b Giorgos Korfiatis
    finally:
1145 2ddfc92b Giorgos Korfiatis
        if rollback == True:
1146 2ddfc92b Giorgos Korfiatis
            transaction.rollback()
1147 2ddfc92b Giorgos Korfiatis
        else:
1148 2ddfc92b Giorgos Korfiatis
            transaction.commit()
1149 e1a80257 Sofia Papagiannaki
1150 5550bcfb Kostas Papadimitriou
1151 e1a80257 Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
1152 e1a80257 Sofia Papagiannaki
@signed_terms_required
1153 e1a80257 Sofia Papagiannaki
@login_required
1154 e1a80257 Sofia Papagiannaki
def project_search(request):
1155 5550bcfb Kostas Papadimitriou
    q = request.GET.get('q', '')
1156 a5cef8d0 Kostas Papadimitriou
    form = ProjectSearchForm()
1157 a5cef8d0 Kostas Papadimitriou
    q = q.strip()
1158 48421603 Kostas Papadimitriou
1159 a5cef8d0 Kostas Papadimitriou
    if request.method == "POST":
1160 48421603 Kostas Papadimitriou
        form = ProjectSearchForm(request.POST)
1161 48421603 Kostas Papadimitriou
        if form.is_valid():
1162 48421603 Kostas Papadimitriou
            q = form.cleaned_data['q'].strip()
1163 48421603 Kostas Papadimitriou
        else:
1164 a5cef8d0 Kostas Papadimitriou
            q = None
1165 a5cef8d0 Kostas Papadimitriou
1166 a5cef8d0 Kostas Papadimitriou
    if q is None:
1167 a5cef8d0 Kostas Papadimitriou
        projects = ProjectApplication.objects.none()
1168 a5cef8d0 Kostas Papadimitriou
    else:
1169 a5cef8d0 Kostas Papadimitriou
        projects = ProjectApplication.objects.search_by_name(q)
1170 a5cef8d0 Kostas Papadimitriou
        projects = projects.filter(~Q(project__last_approval_date__isnull=True))
1171 a5cef8d0 Kostas Papadimitriou
1172 2743e261 Kostas Papadimitriou
    table = tables.UserProjectApplicationsTable(projects, user=request.user,
1173 2743e261 Kostas Papadimitriou
                                                prefix="my_projects_")
1174 e6d284ef Olga Brani
    RequestConfig(request, paginate={"per_page": PAGINATE_BY}).configure(table)
1175 48421603 Kostas Papadimitriou
1176 bfe23b13 Sofia Papagiannaki
    return object_list(
1177 bfe23b13 Sofia Papagiannaki
        request,
1178 a5cef8d0 Kostas Papadimitriou
        projects,
1179 6dadd24a Sofia Papagiannaki
        template_name='im/projects/project_list.html',
1180 a5cef8d0 Kostas Papadimitriou
        extra_context={
1181 a5cef8d0 Kostas Papadimitriou
          'form': form,
1182 a5cef8d0 Kostas Papadimitriou
          'is_search': True,
1183 a5cef8d0 Kostas Papadimitriou
          'q': q,
1184 a5cef8d0 Kostas Papadimitriou
          'table': table
1185 a5cef8d0 Kostas Papadimitriou
        })
1186 bfe23b13 Sofia Papagiannaki
1187 73fbaec4 Sofia Papagiannaki
@require_http_methods(["POST"])
1188 e1a80257 Sofia Papagiannaki
@signed_terms_required
1189 e1a80257 Sofia Papagiannaki
@login_required
1190 bfe23b13 Sofia Papagiannaki
@transaction.commit_manually
1191 73fbaec4 Sofia Papagiannaki
def project_join(request, application_id):
1192 974ee6a6 Sofia Papagiannaki
    next = request.GET.get('next')
1193 73fbaec4 Sofia Papagiannaki
    if not next:
1194 ed1999ad Kostas Papadimitriou
        next = reverse('astakos.im.views.project_list')
1195 73fbaec4 Sofia Papagiannaki
1196 bfe23b13 Sofia Papagiannaki
    rollback = False
1197 bfe23b13 Sofia Papagiannaki
    try:
1198 974ee6a6 Sofia Papagiannaki
        application_id = int(application_id)
1199 73fbaec4 Sofia Papagiannaki
        join_project(application_id, request.user)
1200 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1201 bfe23b13 Sofia Papagiannaki
        messages.error(request, e)
1202 b8f05f8d Sofia Papagiannaki
    except BaseException, e:
1203 b8f05f8d Sofia Papagiannaki
        logger.exception(e)
1204 b8f05f8d Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1205 bfe23b13 Sofia Papagiannaki
        rollback = True
1206 bfe23b13 Sofia Papagiannaki
    finally:
1207 bfe23b13 Sofia Papagiannaki
        if rollback:
1208 bfe23b13 Sofia Papagiannaki
            transaction.rollback()
1209 bfe23b13 Sofia Papagiannaki
        else:
1210 bfe23b13 Sofia Papagiannaki
            transaction.commit()
1211 974ee6a6 Sofia Papagiannaki
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1212 73fbaec4 Sofia Papagiannaki
    return redirect(next)
1213 bfe23b13 Sofia Papagiannaki
1214 73fbaec4 Sofia Papagiannaki
@require_http_methods(["POST"])
1215 e1a80257 Sofia Papagiannaki
@signed_terms_required
1216 e1a80257 Sofia Papagiannaki
@login_required
1217 73fbaec4 Sofia Papagiannaki
@transaction.commit_manually
1218 73fbaec4 Sofia Papagiannaki
def project_leave(request, application_id):
1219 974ee6a6 Sofia Papagiannaki
    next = request.GET.get('next')
1220 73fbaec4 Sofia Papagiannaki
    if not next:
1221 ed1999ad Kostas Papadimitriou
        next = reverse('astakos.im.views.project_list')
1222 e1a80257 Sofia Papagiannaki
1223 73fbaec4 Sofia Papagiannaki
    rollback = False
1224 73fbaec4 Sofia Papagiannaki
    try:
1225 974ee6a6 Sofia Papagiannaki
        application_id = int(application_id)
1226 73fbaec4 Sofia Papagiannaki
        leave_project(application_id, request.user)
1227 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1228 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1229 73fbaec4 Sofia Papagiannaki
    except BaseException, e:
1230 73fbaec4 Sofia Papagiannaki
        logger.exception(e)
1231 974ee6a6 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1232 73fbaec4 Sofia Papagiannaki
        rollback = True
1233 73fbaec4 Sofia Papagiannaki
    finally:
1234 73fbaec4 Sofia Papagiannaki
        if rollback:
1235 73fbaec4 Sofia Papagiannaki
            transaction.rollback()
1236 73fbaec4 Sofia Papagiannaki
        else:
1237 73fbaec4 Sofia Papagiannaki
            transaction.commit()
1238 f7cf5257 Kostas Papadimitriou
1239 974ee6a6 Sofia Papagiannaki
    next = restrict_next(next, domain=COOKIE_DOMAIN)
1240 73fbaec4 Sofia Papagiannaki
    return redirect(next)
1241 bfe23b13 Sofia Papagiannaki
1242 bfe23b13 Sofia Papagiannaki
@require_http_methods(["GET"])
1243 e1a80257 Sofia Papagiannaki
@signed_terms_required
1244 e1a80257 Sofia Papagiannaki
@login_required
1245 73fbaec4 Sofia Papagiannaki
@transaction.commit_manually
1246 7dd3047d Sofia Papagiannaki
def project_accept_member(request, application_id, user_id):
1247 73fbaec4 Sofia Papagiannaki
    rollback = False
1248 73fbaec4 Sofia Papagiannaki
    try:
1249 974ee6a6 Sofia Papagiannaki
        application_id = int(application_id)
1250 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1251 73fbaec4 Sofia Papagiannaki
        m = accept_membership(application_id, user_id, request.user)
1252 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1253 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1254 73fbaec4 Sofia Papagiannaki
    except BaseException, e:
1255 73fbaec4 Sofia Papagiannaki
        logger.exception(e)
1256 974ee6a6 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1257 73fbaec4 Sofia Papagiannaki
        rollback = True
1258 73fbaec4 Sofia Papagiannaki
    else:
1259 73fbaec4 Sofia Papagiannaki
        realname = m.person.realname
1260 73fbaec4 Sofia Papagiannaki
        msg = _(astakos_messages.USER_JOINED_PROJECT) % locals()
1261 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1262 73fbaec4 Sofia Papagiannaki
    finally:
1263 73fbaec4 Sofia Papagiannaki
        if rollback:
1264 73fbaec4 Sofia Papagiannaki
            transaction.rollback()
1265 73fbaec4 Sofia Papagiannaki
        else:
1266 73fbaec4 Sofia Papagiannaki
            transaction.commit()
1267 7dd3047d Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(application_id,)))
1268 bfe23b13 Sofia Papagiannaki
1269 bfe23b13 Sofia Papagiannaki
@require_http_methods(["GET"])
1270 bfe23b13 Sofia Papagiannaki
@signed_terms_required
1271 bfe23b13 Sofia Papagiannaki
@login_required
1272 73fbaec4 Sofia Papagiannaki
@transaction.commit_manually
1273 73fbaec4 Sofia Papagiannaki
def project_remove_member(request, application_id, user_id):
1274 73fbaec4 Sofia Papagiannaki
    rollback = False
1275 73fbaec4 Sofia Papagiannaki
    try:
1276 974ee6a6 Sofia Papagiannaki
        application_id = int(application_id)
1277 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1278 73fbaec4 Sofia Papagiannaki
        m = remove_membership(application_id, user_id, request.user)
1279 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1280 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1281 73fbaec4 Sofia Papagiannaki
    except BaseException, e:
1282 73fbaec4 Sofia Papagiannaki
        logger.exception(e)
1283 974ee6a6 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1284 73fbaec4 Sofia Papagiannaki
        rollback = True
1285 73fbaec4 Sofia Papagiannaki
    else:
1286 73fbaec4 Sofia Papagiannaki
        realname = m.person.realname
1287 73fbaec4 Sofia Papagiannaki
        msg = _(astakos_messages.USER_LEFT_PROJECT) % locals()
1288 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1289 73fbaec4 Sofia Papagiannaki
    finally:
1290 73fbaec4 Sofia Papagiannaki
        if rollback:
1291 73fbaec4 Sofia Papagiannaki
            transaction.rollback()
1292 73fbaec4 Sofia Papagiannaki
        else:
1293 73fbaec4 Sofia Papagiannaki
            transaction.commit()
1294 7dd3047d Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(application_id,)))
1295 bfe23b13 Sofia Papagiannaki
1296 bfe23b13 Sofia Papagiannaki
@require_http_methods(["GET"])
1297 e1a80257 Sofia Papagiannaki
@signed_terms_required
1298 e1a80257 Sofia Papagiannaki
@login_required
1299 73fbaec4 Sofia Papagiannaki
@transaction.commit_manually
1300 73fbaec4 Sofia Papagiannaki
def project_reject_member(request, application_id, user_id):
1301 73fbaec4 Sofia Papagiannaki
    rollback = False
1302 73fbaec4 Sofia Papagiannaki
    try:
1303 974ee6a6 Sofia Papagiannaki
        application_id = int(application_id)
1304 974ee6a6 Sofia Papagiannaki
        user_id = int(user_id)
1305 73fbaec4 Sofia Papagiannaki
        m = reject_membership(application_id, user_id, request.user)
1306 73fbaec4 Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
1307 73fbaec4 Sofia Papagiannaki
        messages.error(request, e)
1308 73fbaec4 Sofia Papagiannaki
    except BaseException, e:
1309 73fbaec4 Sofia Papagiannaki
        logger.exception(e)
1310 974ee6a6 Sofia Papagiannaki
        messages.error(request, _(astakos_messages.GENERIC_ERROR))
1311 73fbaec4 Sofia Papagiannaki
        rollback = True
1312 73fbaec4 Sofia Papagiannaki
    else:
1313 73fbaec4 Sofia Papagiannaki
        realname = m.person.realname
1314 73fbaec4 Sofia Papagiannaki
        msg = _(astakos_messages.USER_LEFT_PROJECT) % locals()
1315 73fbaec4 Sofia Papagiannaki
        messages.success(request, msg)
1316 73fbaec4 Sofia Papagiannaki
    finally:
1317 73fbaec4 Sofia Papagiannaki
        if rollback:
1318 73fbaec4 Sofia Papagiannaki
            transaction.rollback()
1319 73fbaec4 Sofia Papagiannaki
        else:
1320 73fbaec4 Sofia Papagiannaki
            transaction.commit()
1321 7dd3047d Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(application_id,)))
1322 c630fee6 Kostas Papadimitriou