Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 401089d8

History | View | Annotate | Download (47 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 1ebea3d3 Kostas Papadimitriou
from astakos.im.api import get_services_dict
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 1ebea3d3 Kostas Papadimitriou
    extra_context['services'] = get_services_dict()
403 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
404 8f5a3a06 Sofia Papagiannaki
                           profile_form = form,
405 792c2f3b Olga Brani
                           user_providers = user_providers,
406 792c2f3b Olga Brani
                           user_available_providers = user_available_providers,
407 0905ccd2 Sofia Papagiannaki
                           context_instance = get_context(request,
408 c301698f Sofia Papagiannaki
                                                          extra_context))
409 5ce3ce4f Sofia Papagiannaki
410 64cd4730 Antony Chazapis
411 10ed0073 Sofia Papagiannaki
@transaction.commit_manually
412 9a06d96f Olga Brani
@require_http_methods(["GET", "POST"])
413 279d6e51 Olga Brani
def signup(request, template_name='im/signup.html', on_success='im/signup_complete.html', extra_context=None, backend=None):
414 890b0eaf Sofia Papagiannaki
    """
415 890b0eaf Sofia Papagiannaki
    Allows a user to create a local account.
416 176023aa Kostas Papadimitriou

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

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

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

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

430 890b0eaf Sofia Papagiannaki
    **Arguments**
431 5ce3ce4f Sofia Papagiannaki

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

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

440 890b0eaf Sofia Papagiannaki
    ``extra_context``
441 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
442 176023aa Kostas Papadimitriou

443 890b0eaf Sofia Papagiannaki
    **Template:**
444 5ce3ce4f Sofia Papagiannaki

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

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

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

541 890b0eaf Sofia Papagiannaki
    **Arguments**
542 176023aa Kostas Papadimitriou

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

547 890b0eaf Sofia Papagiannaki
    ``extra_context``
548 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
549 176023aa Kostas Papadimitriou

550 890b0eaf Sofia Papagiannaki
    **Template:**
551 176023aa Kostas Papadimitriou

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

554 890b0eaf Sofia Papagiannaki
    **Settings:**
555 176023aa Kostas Papadimitriou

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

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