Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 661c4479

History | View | Annotate | Download (41.1 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 64cd4730 Antony Chazapis
37 0905ccd2 Sofia Papagiannaki
from urllib import quote
38 63ecdd20 Sofia Papagiannaki
from functools import wraps
39 aab4d540 Sofia Papagiannaki
from datetime import datetime, timedelta
40 789bcaf9 Sofia Papagiannaki
from collections import defaultdict
41 64cd4730 Antony Chazapis
42 890b0eaf Sofia Papagiannaki
from django.contrib import messages
43 01ac12d5 Sofia Papagiannaki
from django.contrib.auth.decorators import login_required
44 270dd48d Sofia Papagiannaki
from django.contrib.auth.views import password_change
45 01ac12d5 Sofia Papagiannaki
from django.core.urlresolvers import reverse
46 01ac12d5 Sofia Papagiannaki
from django.db import transaction
47 d1757ca7 Sofia Papagiannaki
from django.db.models import Q
48 01ac12d5 Sofia Papagiannaki
from django.db.utils import IntegrityError
49 01ac12d5 Sofia Papagiannaki
from django.forms.fields import URLField
50 04febd09 Olga Brani
from django.db.models.fields import DateTimeField
51 01ac12d5 Sofia Papagiannaki
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, \
52 789bcaf9 Sofia Papagiannaki
    HttpResponseRedirect, HttpResponseBadRequest, Http404
53 01ac12d5 Sofia Papagiannaki
from django.shortcuts import redirect
54 661c4479 Sofia Papagiannaki
from django.template import RequestContext, loader as template_loader
55 01ac12d5 Sofia Papagiannaki
from django.utils.http import urlencode
56 01ac12d5 Sofia Papagiannaki
from django.utils.translation import ugettext as _
57 aab4d540 Sofia Papagiannaki
from django.views.generic.create_update import (create_object, delete_object,
58 de4ed385 Sofia Papagiannaki
                                                get_model_and_form_class)
59 aab4d540 Sofia Papagiannaki
from django.views.generic.list_detail import object_list, object_detail
60 51c57c9c Sofia Papagiannaki
from django.http import HttpResponseBadRequest
61 d220292f Sofia Papagiannaki
from django.core.paginator import Paginator, InvalidPage
62 661c4479 Sofia Papagiannaki
from django.core.xheaders import populate_xheaders
63 64cd4730 Antony Chazapis
64 5ce3ce4f Sofia Papagiannaki
from astakos.im.models import (
65 5ce3ce4f Sofia Papagiannaki
    AstakosUser, ApprovalTerms, AstakosGroup, Resource,
66 aab4d540 Sofia Papagiannaki
    EmailChange, GroupKind, Membership)
67 4e30244e Sofia Papagiannaki
from astakos.im.activation_backends import get_backend, SimpleBackend
68 1662ac2d Sofia Papagiannaki
from astakos.im.util import get_context, prepare_response, set_cookie, get_query
69 51c57c9c Sofia Papagiannaki
from astakos.im.forms import (LoginForm, InvitationForm, ProfileForm,
70 51c57c9c Sofia Papagiannaki
                              FeedbackForm, SignApprovalTermsForm,
71 51c57c9c Sofia Papagiannaki
                              ExtendedPasswordChangeForm, EmailChangeForm,
72 51c57c9c Sofia Papagiannaki
                              AstakosGroupCreationForm, AstakosGroupSearchForm,
73 789bcaf9 Sofia Papagiannaki
                              AstakosGroupUpdateForm, AddGroupMembersForm,
74 789bcaf9 Sofia Papagiannaki
                              AstakosGroupSortForm)
75 aab4d540 Sofia Papagiannaki
from astakos.im.functions import (send_feedback, SendMailError,
76 51c57c9c Sofia Papagiannaki
                                  invite as invite_func, logout as auth_logout,
77 51c57c9c Sofia Papagiannaki
                                  activate as activate_func,
78 51c57c9c Sofia Papagiannaki
                                  switch_account_to_shibboleth,
79 51c57c9c Sofia Papagiannaki
                                  send_admin_notification,
80 51c57c9c Sofia Papagiannaki
                                  SendNotificationError)
81 5ce3ce4f Sofia Papagiannaki
from astakos.im.settings import (
82 5ce3ce4f Sofia Papagiannaki
    COOKIE_NAME, COOKIE_DOMAIN, SITENAME, LOGOUT_NEXT,
83 d220292f Sofia Papagiannaki
    LOGGING_LEVEL, PAGINATE_BY)
84 6e029beb Sofia Papagiannaki
from astakos.im.tasks import request_billing
85 64cd4730 Antony Chazapis
86 e015e9e6 Sofia Papagiannaki
logger = logging.getLogger(__name__)
87 e015e9e6 Sofia Papagiannaki
88 5ce3ce4f Sofia Papagiannaki
89 789bcaf9 Sofia Papagiannaki
DB_REPLACE_GROUP_SCHEME = """REPLACE(REPLACE("auth_group".name, 'http://', ''),
90 789bcaf9 Sofia Papagiannaki
                                     'https://', '')"""
91 789bcaf9 Sofia Papagiannaki
92 51c57c9c Sofia Papagiannaki
def render_response(template, tab=None, status=200, reset_cookie=False,
93 51c57c9c Sofia Papagiannaki
                    context_instance=None, **kwargs):
94 890b0eaf Sofia Papagiannaki
    """
95 890b0eaf Sofia Papagiannaki
    Calls ``django.template.loader.render_to_string`` with an additional ``tab``
96 890b0eaf Sofia Papagiannaki
    keyword argument and returns an ``django.http.HttpResponse`` with the
97 890b0eaf Sofia Papagiannaki
    specified ``status``.
98 890b0eaf Sofia Papagiannaki
    """
99 64cd4730 Antony Chazapis
    if tab is None:
100 881c856c Sofia Papagiannaki
        tab = template.partition('_')[0].partition('.html')[0]
101 64cd4730 Antony Chazapis
    kwargs.setdefault('tab', tab)
102 661c4479 Sofia Papagiannaki
    html = template_loader.render_to_string(
103 5ce3ce4f Sofia Papagiannaki
        template, kwargs, context_instance=context_instance)
104 c301698f Sofia Papagiannaki
    response = HttpResponse(html, status=status)
105 c301698f Sofia Papagiannaki
    if reset_cookie:
106 c301698f Sofia Papagiannaki
        set_cookie(response, context_instance['request'].user)
107 c301698f Sofia Papagiannaki
    return response
108 64cd4730 Antony Chazapis
109 63ecdd20 Sofia Papagiannaki
110 63ecdd20 Sofia Papagiannaki
def requires_anonymous(func):
111 63ecdd20 Sofia Papagiannaki
    """
112 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is not Anonymous and in that case
113 7482228b Sofia Papagiannaki
    redirects to `logout`.
114 63ecdd20 Sofia Papagiannaki
    """
115 63ecdd20 Sofia Papagiannaki
    @wraps(func)
116 63ecdd20 Sofia Papagiannaki
    def wrapper(request, *args):
117 63ecdd20 Sofia Papagiannaki
        if not request.user.is_anonymous():
118 63ecdd20 Sofia Papagiannaki
            next = urlencode({'next': request.build_absolute_uri()})
119 270dd48d Sofia Papagiannaki
            logout_uri = reverse(logout) + '?' + next
120 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(logout_uri)
121 63ecdd20 Sofia Papagiannaki
        return func(request, *args)
122 63ecdd20 Sofia Papagiannaki
    return wrapper
123 63ecdd20 Sofia Papagiannaki
124 5ce3ce4f Sofia Papagiannaki
125 270dd48d Sofia Papagiannaki
def signed_terms_required(func):
126 270dd48d Sofia Papagiannaki
    """
127 270dd48d Sofia Papagiannaki
    Decorator checkes whether the request.user is Anonymous and in that case
128 270dd48d Sofia Papagiannaki
    redirects to `logout`.
129 270dd48d Sofia Papagiannaki
    """
130 270dd48d Sofia Papagiannaki
    @wraps(func)
131 270dd48d Sofia Papagiannaki
    def wrapper(request, *args, **kwargs):
132 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
133 270dd48d Sofia Papagiannaki
            params = urlencode({'next': request.build_absolute_uri(),
134 5ce3ce4f Sofia Papagiannaki
                                'show_form': ''})
135 270dd48d Sofia Papagiannaki
            terms_uri = reverse('latest_terms') + '?' + params
136 270dd48d Sofia Papagiannaki
            return HttpResponseRedirect(terms_uri)
137 270dd48d Sofia Papagiannaki
        return func(request, *args, **kwargs)
138 270dd48d Sofia Papagiannaki
    return wrapper
139 270dd48d Sofia Papagiannaki
140 5ce3ce4f Sofia Papagiannaki
141 270dd48d Sofia Papagiannaki
@signed_terms_required
142 aab4d540 Sofia Papagiannaki
def index(request, login_template_name='im/login.html', extra_context=None):
143 890b0eaf Sofia Papagiannaki
    """
144 dcf55476 Sofia Papagiannaki
    If there is logged on user renders the profile page otherwise renders login page.
145 176023aa Kostas Papadimitriou

146 890b0eaf Sofia Papagiannaki
    **Arguments**
147 176023aa Kostas Papadimitriou

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

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

156 890b0eaf Sofia Papagiannaki
    ``extra_context``
157 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
158 176023aa Kostas Papadimitriou

159 890b0eaf Sofia Papagiannaki
    **Template:**
160 176023aa Kostas Papadimitriou

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

163 890b0eaf Sofia Papagiannaki
    """
164 dcf55476 Sofia Papagiannaki
    template_name = login_template_name
165 dcf55476 Sofia Papagiannaki
    if request.user.is_authenticated():
166 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('edit_profile'))
167 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
168 5ce3ce4f Sofia Papagiannaki
                           login_form=LoginForm(request=request),
169 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
170 5ce3ce4f Sofia Papagiannaki
171 64cd4730 Antony Chazapis
172 890b0eaf Sofia Papagiannaki
@login_required
173 270dd48d Sofia Papagiannaki
@signed_terms_required
174 890b0eaf Sofia Papagiannaki
@transaction.commit_manually
175 aab4d540 Sofia Papagiannaki
def invite(request, template_name='im/invitations.html', extra_context=None):
176 890b0eaf Sofia Papagiannaki
    """
177 890b0eaf Sofia Papagiannaki
    Allows a user to invite somebody else.
178 176023aa Kostas Papadimitriou

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

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

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

188 890b0eaf Sofia Papagiannaki
    **Arguments**
189 176023aa Kostas Papadimitriou

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

194 890b0eaf Sofia Papagiannaki
    ``extra_context``
195 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
196 176023aa Kostas Papadimitriou

197 890b0eaf Sofia Papagiannaki
    **Template:**
198 176023aa Kostas Papadimitriou

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

201 890b0eaf Sofia Papagiannaki
    **Settings:**
202 176023aa Kostas Papadimitriou

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

205 890b0eaf Sofia Papagiannaki
    * LOGIN_URL: login uri
206 2cbaacd5 Sofia Papagiannaki
    * ASTAKOS_DEFAULT_CONTACT_EMAIL: service support email
207 890b0eaf Sofia Papagiannaki
    """
208 64cd4730 Antony Chazapis
    status = None
209 64cd4730 Antony Chazapis
    message = None
210 8f5a3a06 Sofia Papagiannaki
    form = InvitationForm()
211 5ce3ce4f Sofia Papagiannaki
212 18ffbee1 Sofia Papagiannaki
    inviter = request.user
213 64cd4730 Antony Chazapis
    if request.method == 'POST':
214 8f5a3a06 Sofia Papagiannaki
        form = InvitationForm(request.POST)
215 64cd4730 Antony Chazapis
        if inviter.invitations > 0:
216 8f5a3a06 Sofia Papagiannaki
            if form.is_valid():
217 8f5a3a06 Sofia Papagiannaki
                try:
218 8f5a3a06 Sofia Papagiannaki
                    invitation = form.save()
219 8f5a3a06 Sofia Papagiannaki
                    invite_func(invitation, inviter)
220 8f5a3a06 Sofia Papagiannaki
                    message = _('Invitation sent to %s' % invitation.username)
221 24406ae3 Sofia Papagiannaki
                    messages.success(request, message)
222 8f5a3a06 Sofia Papagiannaki
                except SendMailError, e:
223 8f5a3a06 Sofia Papagiannaki
                    message = e.message
224 24406ae3 Sofia Papagiannaki
                    messages.error(request, message)
225 8f5a3a06 Sofia Papagiannaki
                    transaction.rollback()
226 18ffbee1 Sofia Papagiannaki
                except BaseException, e:
227 18ffbee1 Sofia Papagiannaki
                    message = _('Something went wrong.')
228 24406ae3 Sofia Papagiannaki
                    messages.error(request, message)
229 18ffbee1 Sofia Papagiannaki
                    logger.exception(e)
230 18ffbee1 Sofia Papagiannaki
                    transaction.rollback()
231 18ffbee1 Sofia Papagiannaki
                else:
232 18ffbee1 Sofia Papagiannaki
                    transaction.commit()
233 64cd4730 Antony Chazapis
        else:
234 64cd4730 Antony Chazapis
            message = _('No invitations left')
235 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
236 176023aa Kostas Papadimitriou
237 a196eb7e Sofia Papagiannaki
    sent = [{'email': inv.username,
238 d6ae71a2 root
             'realname': inv.realname,
239 d6ae71a2 root
             'is_consumed': inv.is_consumed}
240 5ce3ce4f Sofia Papagiannaki
            for inv in request.user.invitations_sent.all()]
241 77e2ad52 root
    kwargs = {'inviter': inviter,
242 5ce3ce4f Sofia Papagiannaki
              'sent': sent}
243 0905ccd2 Sofia Papagiannaki
    context = get_context(request, extra_context, **kwargs)
244 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
245 5ce3ce4f Sofia Papagiannaki
                           invitation_form=form,
246 5ce3ce4f Sofia Papagiannaki
                           context_instance=context)
247 5ce3ce4f Sofia Papagiannaki
248 64cd4730 Antony Chazapis
249 890b0eaf Sofia Papagiannaki
@login_required
250 270dd48d Sofia Papagiannaki
@signed_terms_required
251 aab4d540 Sofia Papagiannaki
def edit_profile(request, template_name='im/profile.html', extra_context=None):
252 890b0eaf Sofia Papagiannaki
    """
253 890b0eaf Sofia Papagiannaki
    Allows a user to edit his/her profile.
254 176023aa Kostas Papadimitriou

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

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

261 890b0eaf Sofia Papagiannaki
    **Arguments**
262 176023aa Kostas Papadimitriou

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

267 890b0eaf Sofia Papagiannaki
    ``extra_context``
268 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
269 176023aa Kostas Papadimitriou

270 890b0eaf Sofia Papagiannaki
    **Template:**
271 176023aa Kostas Papadimitriou

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

274 92defad4 Sofia Papagiannaki
    **Settings:**
275 176023aa Kostas Papadimitriou

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

278 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
279 890b0eaf Sofia Papagiannaki
    """
280 aab4d540 Sofia Papagiannaki
    extra_context = extra_context or {}
281 15efc749 Sofia Papagiannaki
    form = ProfileForm(instance=request.user)
282 15efc749 Sofia Papagiannaki
    extra_context['next'] = request.GET.get('next')
283 c301698f Sofia Papagiannaki
    reset_cookie = False
284 64cd4730 Antony Chazapis
    if request.method == 'POST':
285 15efc749 Sofia Papagiannaki
        form = ProfileForm(request.POST, instance=request.user)
286 890b0eaf Sofia Papagiannaki
        if form.is_valid():
287 64cd4730 Antony Chazapis
            try:
288 c301698f Sofia Papagiannaki
                prev_token = request.user.auth_token
289 c301698f Sofia Papagiannaki
                user = form.save()
290 c301698f Sofia Papagiannaki
                reset_cookie = user.auth_token != prev_token
291 c301698f Sofia Papagiannaki
                form = ProfileForm(instance=user)
292 1a3675a0 Sofia Papagiannaki
                next = request.POST.get('next')
293 1a3675a0 Sofia Papagiannaki
                if next:
294 1a3675a0 Sofia Papagiannaki
                    return redirect(next)
295 890b0eaf Sofia Papagiannaki
                msg = _('Profile has been updated successfully')
296 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
297 890b0eaf Sofia Papagiannaki
            except ValueError, ve:
298 24406ae3 Sofia Papagiannaki
                messages.success(request, ve)
299 23447441 Sofia Papagiannaki
    elif request.method == "GET":
300 fff4343a Sofia Papagiannaki
        if not request.user.is_verified:
301 fff4343a Sofia Papagiannaki
            request.user.is_verified = True
302 fff4343a Sofia Papagiannaki
            request.user.save()
303 0905ccd2 Sofia Papagiannaki
    return render_response(template_name,
304 5ce3ce4f Sofia Papagiannaki
                           reset_cookie=reset_cookie,
305 5ce3ce4f Sofia Papagiannaki
                           profile_form=form,
306 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request,
307 5ce3ce4f Sofia Papagiannaki
                                                        extra_context))
308 5ce3ce4f Sofia Papagiannaki
309 64cd4730 Antony Chazapis
310 10ed0073 Sofia Papagiannaki
@transaction.commit_manually
311 aab4d540 Sofia Papagiannaki
def signup(request, template_name='im/signup.html', on_success='im/signup_complete.html', extra_context=None, backend=None):
312 890b0eaf Sofia Papagiannaki
    """
313 890b0eaf Sofia Papagiannaki
    Allows a user to create a local account.
314 176023aa Kostas Papadimitriou

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

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

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

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

328 890b0eaf Sofia Papagiannaki
    **Arguments**
329 5ce3ce4f Sofia Papagiannaki

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

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

338 890b0eaf Sofia Papagiannaki
    ``extra_context``
339 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
340 176023aa Kostas Papadimitriou

341 890b0eaf Sofia Papagiannaki
    **Template:**
342 5ce3ce4f Sofia Papagiannaki

343 8f5a3a06 Sofia Papagiannaki
    im/signup.html or ``template_name`` keyword argument.
344 5ce3ce4f Sofia Papagiannaki
    im/signup_complete.html or ``on_success`` keyword argument.
345 890b0eaf Sofia Papagiannaki
    """
346 0d02a287 Sofia Papagiannaki
    if request.user.is_authenticated():
347 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('edit_profile'))
348 5ce3ce4f Sofia Papagiannaki
349 0a569195 Sofia Papagiannaki
    provider = get_query(request).get('provider', 'local')
350 890b0eaf Sofia Papagiannaki
    try:
351 18ffbee1 Sofia Papagiannaki
        if not backend:
352 18ffbee1 Sofia Papagiannaki
            backend = get_backend(request)
353 8f5a3a06 Sofia Papagiannaki
        form = backend.get_signup_form(provider)
354 0a569195 Sofia Papagiannaki
    except Exception, e:
355 4e30244e Sofia Papagiannaki
        form = SimpleBackend(request).get_signup_form(provider)
356 24406ae3 Sofia Papagiannaki
        messages.error(request, e)
357 8f5a3a06 Sofia Papagiannaki
    if request.method == 'POST':
358 8f5a3a06 Sofia Papagiannaki
        if form.is_valid():
359 18ffbee1 Sofia Papagiannaki
            user = form.save(commit=False)
360 8f5a3a06 Sofia Papagiannaki
            try:
361 8f5a3a06 Sofia Papagiannaki
                result = backend.handle_activation(user)
362 8f5a3a06 Sofia Papagiannaki
                status = messages.SUCCESS
363 18ffbee1 Sofia Papagiannaki
                message = result.message
364 18ffbee1 Sofia Papagiannaki
                user.save()
365 ca828a10 Sofia Papagiannaki
                if 'additional_email' in form.cleaned_data:
366 ca828a10 Sofia Papagiannaki
                    additional_email = form.cleaned_data['additional_email']
367 ca828a10 Sofia Papagiannaki
                    if additional_email != user.email:
368 ca828a10 Sofia Papagiannaki
                        user.additionalmail_set.create(email=additional_email)
369 5ce3ce4f Sofia Papagiannaki
                        msg = 'Additional email: %s saved for user %s.' % (
370 5ce3ce4f Sofia Papagiannaki
                            additional_email, user.email)
371 aab4d540 Sofia Papagiannaki
                        logger.log(LOGGING_LEVEL, msg)
372 8f5a3a06 Sofia Papagiannaki
                if user and user.is_active:
373 8f5a3a06 Sofia Papagiannaki
                    next = request.POST.get('next', '')
374 48121481 root
                    transaction.commit()
375 8f5a3a06 Sofia Papagiannaki
                    return prepare_response(request, user, next=next)
376 8f5a3a06 Sofia Papagiannaki
                messages.add_message(request, status, message)
377 48121481 root
                transaction.commit()
378 8f5a3a06 Sofia Papagiannaki
                return render_response(on_success,
379 8f5a3a06 Sofia Papagiannaki
                                       context_instance=get_context(request, extra_context))
380 18ffbee1 Sofia Papagiannaki
            except SendMailError, e:
381 18ffbee1 Sofia Papagiannaki
                message = e.message
382 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
383 10ed0073 Sofia Papagiannaki
                transaction.rollback()
384 18ffbee1 Sofia Papagiannaki
            except BaseException, e:
385 18ffbee1 Sofia Papagiannaki
                message = _('Something went wrong.')
386 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
387 0a569195 Sofia Papagiannaki
                logger.exception(e)
388 10ed0073 Sofia Papagiannaki
                transaction.rollback()
389 8f5a3a06 Sofia Papagiannaki
    return render_response(template_name,
390 5ce3ce4f Sofia Papagiannaki
                           signup_form=form,
391 5ce3ce4f Sofia Papagiannaki
                           provider=provider,
392 890b0eaf Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
393 64cd4730 Antony Chazapis
394 5ce3ce4f Sofia Papagiannaki
395 890b0eaf Sofia Papagiannaki
@login_required
396 270dd48d Sofia Papagiannaki
@signed_terms_required
397 aab4d540 Sofia Papagiannaki
def feedback(request, template_name='im/feedback.html', email_template_name='im/feedback_mail.txt', extra_context=None):
398 890b0eaf Sofia Papagiannaki
    """
399 890b0eaf Sofia Papagiannaki
    Allows a user to send feedback.
400 176023aa Kostas Papadimitriou

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

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

406 890b0eaf Sofia Papagiannaki
    **Arguments**
407 176023aa Kostas Papadimitriou

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

412 890b0eaf Sofia Papagiannaki
    ``extra_context``
413 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
414 176023aa Kostas Papadimitriou

415 890b0eaf Sofia Papagiannaki
    **Template:**
416 176023aa Kostas Papadimitriou

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

419 890b0eaf Sofia Papagiannaki
    **Settings:**
420 176023aa Kostas Papadimitriou

421 92defad4 Sofia Papagiannaki
    * LOGIN_URL: login uri
422 2cbaacd5 Sofia Papagiannaki
    * ASTAKOS_DEFAULT_CONTACT_EMAIL: List of feedback recipients
423 890b0eaf Sofia Papagiannaki
    """
424 64cd4730 Antony Chazapis
    if request.method == 'GET':
425 890b0eaf Sofia Papagiannaki
        form = FeedbackForm()
426 890b0eaf Sofia Papagiannaki
    if request.method == 'POST':
427 890b0eaf Sofia Papagiannaki
        if not request.user:
428 890b0eaf Sofia Papagiannaki
            return HttpResponse('Unauthorized', status=401)
429 176023aa Kostas Papadimitriou
430 890b0eaf Sofia Papagiannaki
        form = FeedbackForm(request.POST)
431 890b0eaf Sofia Papagiannaki
        if form.is_valid():
432 e9083112 Sofia Papagiannaki
            msg = form.cleaned_data['feedback_msg']
433 8f5a3a06 Sofia Papagiannaki
            data = form.cleaned_data['feedback_data']
434 538ccdd5 Sofia Papagiannaki
            try:
435 8f5a3a06 Sofia Papagiannaki
                send_feedback(msg, data, request.user, email_template_name)
436 8f5a3a06 Sofia Papagiannaki
            except SendMailError, e:
437 24406ae3 Sofia Papagiannaki
                messages.error(request, message)
438 8f5a3a06 Sofia Papagiannaki
            else:
439 538ccdd5 Sofia Papagiannaki
                message = _('Feedback successfully sent')
440 aab4d540 Sofia Papagiannaki
                messages.success(request, message)
441 890b0eaf Sofia Papagiannaki
    return render_response(template_name,
442 5ce3ce4f Sofia Papagiannaki
                           feedback_form=form,
443 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request, extra_context))
444 5ce3ce4f Sofia Papagiannaki
445 15efc749 Sofia Papagiannaki
446 8e45d6fd Sofia Papagiannaki
@signed_terms_required
447 aab4d540 Sofia Papagiannaki
def logout(request, template='registration/logged_out.html', extra_context=None):
448 63ecdd20 Sofia Papagiannaki
    """
449 7482228b Sofia Papagiannaki
    Wraps `django.contrib.auth.logout` and delete the cookie.
450 63ecdd20 Sofia Papagiannaki
    """
451 7482228b Sofia Papagiannaki
    response = HttpResponse()
452 8e45d6fd Sofia Papagiannaki
    if request.user.is_authenticated():
453 8e45d6fd Sofia Papagiannaki
        email = request.user.email
454 8e45d6fd Sofia Papagiannaki
        auth_logout(request)
455 8e45d6fd Sofia Papagiannaki
        response.delete_cookie(COOKIE_NAME, path='/', domain=COOKIE_DOMAIN)
456 8e45d6fd Sofia Papagiannaki
        msg = 'Cookie deleted for %s' % email
457 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
458 63ecdd20 Sofia Papagiannaki
    next = request.GET.get('next')
459 63ecdd20 Sofia Papagiannaki
    if next:
460 63ecdd20 Sofia Papagiannaki
        response['Location'] = next
461 63ecdd20 Sofia Papagiannaki
        response.status_code = 302
462 63ecdd20 Sofia Papagiannaki
        return response
463 0d02a287 Sofia Papagiannaki
    elif LOGOUT_NEXT:
464 0d02a287 Sofia Papagiannaki
        response['Location'] = LOGOUT_NEXT
465 0d02a287 Sofia Papagiannaki
        response.status_code = 301
466 0d02a287 Sofia Papagiannaki
        return response
467 24406ae3 Sofia Papagiannaki
    messages.success(request, _('You have successfully logged out.'))
468 49df775e Sofia Papagiannaki
    context = get_context(request, extra_context)
469 aab4d540 Sofia Papagiannaki
    response.write(loader.render_to_string(template, context_instance=context))
470 49df775e Sofia Papagiannaki
    return response
471 2126d85d Sofia Papagiannaki
472 5ce3ce4f Sofia Papagiannaki
473 683cf244 Sofia Papagiannaki
@transaction.commit_manually
474 3e295388 Sofia Papagiannaki
def activate(request, greeting_email_template_name='im/welcome_email.txt', helpdesk_email_template_name='im/helpdesk_notification.txt'):
475 2126d85d Sofia Papagiannaki
    """
476 683cf244 Sofia Papagiannaki
    Activates the user identified by the ``auth`` request parameter, sends a welcome email
477 683cf244 Sofia Papagiannaki
    and renews the user token.
478 176023aa Kostas Papadimitriou

479 683cf244 Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the user state will be updated
480 683cf244 Sofia Papagiannaki
    only if the email will be send successfully.
481 2126d85d Sofia Papagiannaki
    """
482 2126d85d Sofia Papagiannaki
    token = request.GET.get('auth')
483 2126d85d Sofia Papagiannaki
    next = request.GET.get('next')
484 2126d85d Sofia Papagiannaki
    try:
485 2126d85d Sofia Papagiannaki
        user = AstakosUser.objects.get(auth_token=token)
486 2126d85d Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
487 683cf244 Sofia Papagiannaki
        return HttpResponseBadRequest(_('No such user'))
488 5ce3ce4f Sofia Papagiannaki
489 d1757ca7 Sofia Papagiannaki
    if user.is_active:
490 23b9b72f Sofia Papagiannaki
        message = _('Account already active.')
491 24406ae3 Sofia Papagiannaki
        messages.error(request, message)
492 23b9b72f Sofia Papagiannaki
        return index(request)
493 5ce3ce4f Sofia Papagiannaki
494 0a569195 Sofia Papagiannaki
    try:
495 3abf6c78 Sofia Papagiannaki
        local_user = AstakosUser.objects.get(
496 5ce3ce4f Sofia Papagiannaki
            ~Q(id=user.id),
497 3abf6c78 Sofia Papagiannaki
            email=user.email,
498 3abf6c78 Sofia Papagiannaki
            is_active=True
499 3abf6c78 Sofia Papagiannaki
        )
500 0a569195 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
501 27e26a41 Sofia Papagiannaki
        try:
502 3abf6c78 Sofia Papagiannaki
            activate_func(
503 3abf6c78 Sofia Papagiannaki
                user,
504 3abf6c78 Sofia Papagiannaki
                greeting_email_template_name,
505 3abf6c78 Sofia Papagiannaki
                helpdesk_email_template_name,
506 3abf6c78 Sofia Papagiannaki
                verify_email=True
507 3abf6c78 Sofia Papagiannaki
            )
508 23b9b72f Sofia Papagiannaki
            response = prepare_response(request, user, next, renew=True)
509 23b9b72f Sofia Papagiannaki
            transaction.commit()
510 23b9b72f Sofia Papagiannaki
            return response
511 23b9b72f Sofia Papagiannaki
        except SendMailError, e:
512 23b9b72f Sofia Papagiannaki
            message = e.message
513 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
514 23b9b72f Sofia Papagiannaki
            transaction.rollback()
515 23b9b72f Sofia Papagiannaki
            return index(request)
516 23b9b72f Sofia Papagiannaki
        except BaseException, e:
517 23b9b72f Sofia Papagiannaki
            message = _('Something went wrong.')
518 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
519 23b9b72f Sofia Papagiannaki
            logger.exception(e)
520 23b9b72f Sofia Papagiannaki
            transaction.rollback()
521 23b9b72f Sofia Papagiannaki
            return index(request)
522 0a569195 Sofia Papagiannaki
    else:
523 23b9b72f Sofia Papagiannaki
        try:
524 3abf6c78 Sofia Papagiannaki
            user = switch_account_to_shibboleth(
525 3abf6c78 Sofia Papagiannaki
                user,
526 3abf6c78 Sofia Papagiannaki
                local_user,
527 3abf6c78 Sofia Papagiannaki
                greeting_email_template_name
528 3abf6c78 Sofia Papagiannaki
            )
529 23b9b72f Sofia Papagiannaki
            response = prepare_response(request, user, next, renew=True)
530 23b9b72f Sofia Papagiannaki
            transaction.commit()
531 23b9b72f Sofia Papagiannaki
            return response
532 23b9b72f Sofia Papagiannaki
        except SendMailError, e:
533 23b9b72f Sofia Papagiannaki
            message = e.message
534 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
535 23b9b72f Sofia Papagiannaki
            transaction.rollback()
536 23b9b72f Sofia Papagiannaki
            return index(request)
537 23b9b72f Sofia Papagiannaki
        except BaseException, e:
538 23b9b72f Sofia Papagiannaki
            message = _('Something went wrong.')
539 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
540 23b9b72f Sofia Papagiannaki
            logger.exception(e)
541 23b9b72f Sofia Papagiannaki
            transaction.rollback()
542 23b9b72f Sofia Papagiannaki
            return index(request)
543 270dd48d Sofia Papagiannaki
544 5ce3ce4f Sofia Papagiannaki
545 aab4d540 Sofia Papagiannaki
def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context=None):
546 270dd48d Sofia Papagiannaki
    term = None
547 270dd48d Sofia Papagiannaki
    terms = None
548 270dd48d Sofia Papagiannaki
    if not term_id:
549 270dd48d Sofia Papagiannaki
        try:
550 270dd48d Sofia Papagiannaki
            term = ApprovalTerms.objects.order_by('-id')[0]
551 270dd48d Sofia Papagiannaki
        except IndexError:
552 270dd48d Sofia Papagiannaki
            pass
553 270dd48d Sofia Papagiannaki
    else:
554 270dd48d Sofia Papagiannaki
        try:
555 aab4d540 Sofia Papagiannaki
            term = ApprovalTerms.objects.get(id=term_id)
556 aab4d540 Sofia Papagiannaki
        except ApprovalTerms.DoesNotExist, e:
557 270dd48d Sofia Papagiannaki
            pass
558 176023aa Kostas Papadimitriou
559 270dd48d Sofia Papagiannaki
    if not term:
560 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('index'))
561 270dd48d Sofia Papagiannaki
    f = open(term.location, 'r')
562 270dd48d Sofia Papagiannaki
    terms = f.read()
563 176023aa Kostas Papadimitriou
564 270dd48d Sofia Papagiannaki
    if request.method == 'POST':
565 270dd48d Sofia Papagiannaki
        next = request.POST.get('next')
566 270dd48d Sofia Papagiannaki
        if not next:
567 6ff7a7ca Sofia Papagiannaki
            next = reverse('index')
568 270dd48d Sofia Papagiannaki
        form = SignApprovalTermsForm(request.POST, instance=request.user)
569 270dd48d Sofia Papagiannaki
        if not form.is_valid():
570 270dd48d Sofia Papagiannaki
            return render_response(template_name,
571 5ce3ce4f Sofia Papagiannaki
                                   terms=terms,
572 5ce3ce4f Sofia Papagiannaki
                                   approval_terms_form=form,
573 5ce3ce4f Sofia Papagiannaki
                                   context_instance=get_context(request, extra_context))
574 270dd48d Sofia Papagiannaki
        user = form.save()
575 270dd48d Sofia Papagiannaki
        return HttpResponseRedirect(next)
576 270dd48d Sofia Papagiannaki
    else:
577 586967c0 Sofia Papagiannaki
        form = None
578 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
579 586967c0 Sofia Papagiannaki
            form = SignApprovalTermsForm(instance=request.user)
580 270dd48d Sofia Papagiannaki
        return render_response(template_name,
581 5ce3ce4f Sofia Papagiannaki
                               terms=terms,
582 5ce3ce4f Sofia Papagiannaki
                               approval_terms_form=form,
583 5ce3ce4f Sofia Papagiannaki
                               context_instance=get_context(request, extra_context))
584 5ce3ce4f Sofia Papagiannaki
585 270dd48d Sofia Papagiannaki
586 270dd48d Sofia Papagiannaki
@signed_terms_required
587 270dd48d Sofia Papagiannaki
def change_password(request):
588 1039bab1 Sofia Papagiannaki
    return password_change(request,
589 5ce3ce4f Sofia Papagiannaki
                           post_change_redirect=reverse('edit_profile'),
590 5ce3ce4f Sofia Papagiannaki
                           password_change_form=ExtendedPasswordChangeForm)
591 5ce3ce4f Sofia Papagiannaki
592 49790d9d Sofia Papagiannaki
593 8e45d6fd Sofia Papagiannaki
@signed_terms_required
594 8e45d6fd Sofia Papagiannaki
@login_required
595 49790d9d Sofia Papagiannaki
@transaction.commit_manually
596 49790d9d Sofia Papagiannaki
def change_email(request, activation_key=None,
597 49790d9d Sofia Papagiannaki
                 email_template_name='registration/email_change_email.txt',
598 49790d9d Sofia Papagiannaki
                 form_template_name='registration/email_change_form.html',
599 49790d9d Sofia Papagiannaki
                 confirm_template_name='registration/email_change_done.html',
600 aab4d540 Sofia Papagiannaki
                 extra_context=None):
601 49790d9d Sofia Papagiannaki
    if activation_key:
602 49790d9d Sofia Papagiannaki
        try:
603 49790d9d Sofia Papagiannaki
            user = EmailChange.objects.change_email(activation_key)
604 49790d9d Sofia Papagiannaki
            if request.user.is_authenticated() and request.user == user:
605 49790d9d Sofia Papagiannaki
                msg = _('Email changed successfully.')
606 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
607 49790d9d Sofia Papagiannaki
                auth_logout(request)
608 49790d9d Sofia Papagiannaki
                response = prepare_response(request, user)
609 49790d9d Sofia Papagiannaki
                transaction.commit()
610 49790d9d Sofia Papagiannaki
                return response
611 49790d9d Sofia Papagiannaki
        except ValueError, e:
612 24406ae3 Sofia Papagiannaki
            messages.error(request, e)
613 49790d9d Sofia Papagiannaki
        return render_response(confirm_template_name,
614 5ce3ce4f Sofia Papagiannaki
                               modified_user=user if 'user' in locals(
615 5ce3ce4f Sofia Papagiannaki
                               ) else None,
616 5ce3ce4f Sofia Papagiannaki
                               context_instance=get_context(request,
617 5ce3ce4f Sofia Papagiannaki
                                                            extra_context))
618 5ce3ce4f Sofia Papagiannaki
619 49790d9d Sofia Papagiannaki
    if not request.user.is_authenticated():
620 49790d9d Sofia Papagiannaki
        path = quote(request.get_full_path())
621 6ff7a7ca Sofia Papagiannaki
        url = request.build_absolute_uri(reverse('index'))
622 49790d9d Sofia Papagiannaki
        return HttpResponseRedirect(url + '?next=' + path)
623 49790d9d Sofia Papagiannaki
    form = EmailChangeForm(request.POST or None)
624 49790d9d Sofia Papagiannaki
    if request.method == 'POST' and form.is_valid():
625 49790d9d Sofia Papagiannaki
        try:
626 49790d9d Sofia Papagiannaki
            ec = form.save(email_template_name, request)
627 49790d9d Sofia Papagiannaki
        except SendMailError, e:
628 49790d9d Sofia Papagiannaki
            msg = e
629 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
630 49790d9d Sofia Papagiannaki
            transaction.rollback()
631 49790d9d Sofia Papagiannaki
        except IntegrityError, e:
632 49790d9d Sofia Papagiannaki
            msg = _('There is already a pending change email request.')
633 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
634 49790d9d Sofia Papagiannaki
        else:
635 49790d9d Sofia Papagiannaki
            msg = _('Change email request has been registered succefully.\
636 49790d9d Sofia Papagiannaki
                    You are going to receive a verification email in the new address.')
637 24406ae3 Sofia Papagiannaki
            messages.success(request, msg)
638 49790d9d Sofia Papagiannaki
            transaction.commit()
639 49790d9d Sofia Papagiannaki
    return render_response(form_template_name,
640 5ce3ce4f Sofia Papagiannaki
                           form=form,
641 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request,
642 5ce3ce4f Sofia Papagiannaki
                                                        extra_context))
643 5ce3ce4f Sofia Papagiannaki
644 8e45d6fd Sofia Papagiannaki
645 8e45d6fd Sofia Papagiannaki
@signed_terms_required
646 01ac12d5 Sofia Papagiannaki
@login_required
647 0f4fa26d Sofia Papagiannaki
def group_add(request, kind_name='default'):
648 0f4fa26d Sofia Papagiannaki
    try:
649 5ce3ce4f Sofia Papagiannaki
        kind = GroupKind.objects.get(name=kind_name)
650 0f4fa26d Sofia Papagiannaki
    except:
651 0f4fa26d Sofia Papagiannaki
        return HttpResponseBadRequest(_('No such group kind'))
652 5ce3ce4f Sofia Papagiannaki
653 5ce3ce4f Sofia Papagiannaki
    template_loader = loader
654 5ce3ce4f Sofia Papagiannaki
    post_save_redirect = '/im/group/%(id)s/'
655 5ce3ce4f Sofia Papagiannaki
    context_processors = None
656 0f4fa26d Sofia Papagiannaki
    model, form_class = get_model_and_form_class(
657 0f4fa26d Sofia Papagiannaki
        model=None,
658 0f4fa26d Sofia Papagiannaki
        form_class=AstakosGroupCreationForm
659 0f4fa26d Sofia Papagiannaki
    )
660 5ce3ce4f Sofia Papagiannaki
    resources = dict(
661 5ce3ce4f Sofia Papagiannaki
        (str(r.id), r) for r in Resource.objects.select_related().all())
662 3abf6c78 Sofia Papagiannaki
    policies = []
663 0f4fa26d Sofia Papagiannaki
    if request.method == 'POST':
664 0f4fa26d Sofia Papagiannaki
        form = form_class(request.POST, request.FILES, resources=resources)
665 0f4fa26d Sofia Papagiannaki
        if form.is_valid():
666 0f4fa26d Sofia Papagiannaki
            new_object = form.save()
667 5ce3ce4f Sofia Papagiannaki
668 3abf6c78 Sofia Papagiannaki
            # save owner
669 0f4fa26d Sofia Papagiannaki
            new_object.owners = [request.user]
670 5ce3ce4f Sofia Papagiannaki
671 3abf6c78 Sofia Papagiannaki
            # save quota policies
672 670de92a Sofia Papagiannaki
            for (rid, uplimit) in form.resources():
673 0f4fa26d Sofia Papagiannaki
                try:
674 0f4fa26d Sofia Papagiannaki
                    r = resources[rid]
675 0f4fa26d Sofia Papagiannaki
                except KeyError, e:
676 0f4fa26d Sofia Papagiannaki
                    logger.exception(e)
677 3abf6c78 Sofia Papagiannaki
                    # TODO Should I stay or should I go???
678 0f4fa26d Sofia Papagiannaki
                    continue
679 0f4fa26d Sofia Papagiannaki
                else:
680 0f4fa26d Sofia Papagiannaki
                    new_object.astakosgroupquota_set.create(
681 5ce3ce4f Sofia Papagiannaki
                        resource=r,
682 670de92a Sofia Papagiannaki
                        uplimit=uplimit
683 0f4fa26d Sofia Papagiannaki
                    )
684 670de92a Sofia Papagiannaki
                policies.append('%s %d' % (r, uplimit))
685 0f4fa26d Sofia Papagiannaki
            msg = _("The %(verbose_name)s was created successfully.") %\
686 5ce3ce4f Sofia Papagiannaki
                {"verbose_name": model._meta.verbose_name}
687 0f4fa26d Sofia Papagiannaki
            messages.success(request, msg, fail_silently=True)
688 5ce3ce4f Sofia Papagiannaki
689 3abf6c78 Sofia Papagiannaki
            # send notification
690 3abf6c78 Sofia Papagiannaki
            try:
691 3abf6c78 Sofia Papagiannaki
                send_admin_notification(
692 3abf6c78 Sofia Papagiannaki
                    template_name='im/group_creation_notification.txt',
693 3abf6c78 Sofia Papagiannaki
                    dictionary={
694 5ce3ce4f Sofia Papagiannaki
                        'group': new_object,
695 5ce3ce4f Sofia Papagiannaki
                        'owner': request.user,
696 5ce3ce4f Sofia Papagiannaki
                        'policies': policies,
697 3abf6c78 Sofia Papagiannaki
                    },
698 3abf6c78 Sofia Papagiannaki
                    subject='%s alpha2 testing group creation notification' % SITENAME
699 3abf6c78 Sofia Papagiannaki
                )
700 3abf6c78 Sofia Papagiannaki
            except SendNotificationError, e:
701 3abf6c78 Sofia Papagiannaki
                messages.error(request, e, fail_silently=True)
702 aab4d540 Sofia Papagiannaki
            return HttpResponseRedirect(post_save_redirect % new_object.__dict__)
703 0f4fa26d Sofia Papagiannaki
    else:
704 0f4fa26d Sofia Papagiannaki
        now = datetime.now()
705 0f4fa26d Sofia Papagiannaki
        data = {
706 5ce3ce4f Sofia Papagiannaki
            'kind': kind
707 0f4fa26d Sofia Papagiannaki
        }
708 0f4fa26d Sofia Papagiannaki
        form = form_class(data, resources=resources)
709 0f4fa26d Sofia Papagiannaki
710 0f4fa26d Sofia Papagiannaki
    # Create the template, context, response
711 0f4fa26d Sofia Papagiannaki
    template_name = "%s/%s_form.html" % (
712 0f4fa26d Sofia Papagiannaki
        model._meta.app_label,
713 0f4fa26d Sofia Papagiannaki
        model._meta.object_name.lower()
714 0f4fa26d Sofia Papagiannaki
    )
715 0f4fa26d Sofia Papagiannaki
    t = template_loader.get_template(template_name)
716 0f4fa26d Sofia Papagiannaki
    c = RequestContext(request, {
717 c8977d75 Olga Brani
        'form': form,
718 c8977d75 Olga Brani
        'kind': kind,
719 0f4fa26d Sofia Papagiannaki
    }, context_processors)
720 0f4fa26d Sofia Papagiannaki
    return HttpResponse(t.render(c))
721 8e45d6fd Sofia Papagiannaki
722 5ce3ce4f Sofia Papagiannaki
723 8e45d6fd Sofia Papagiannaki
@signed_terms_required
724 8e45d6fd Sofia Papagiannaki
@login_required
725 ade90760 Sofia Papagiannaki
def group_list(request):
726 789bcaf9 Sofia Papagiannaki
    none = request.user.astakos_groups.none()
727 789bcaf9 Sofia Papagiannaki
    q = AstakosGroup.objects.raw("""
728 789bcaf9 Sofia Papagiannaki
        SELECT auth_group.id,
729 789bcaf9 Sofia Papagiannaki
        %s AS groupname,
730 789bcaf9 Sofia Papagiannaki
        im_groupkind.name AS kindname,
731 789bcaf9 Sofia Papagiannaki
        im_astakosgroup.*,
732 789bcaf9 Sofia Papagiannaki
        owner.email AS groupowner,
733 789bcaf9 Sofia Papagiannaki
        (SELECT COUNT(*) FROM im_membership
734 789bcaf9 Sofia Papagiannaki
            WHERE group_id = im_astakosgroup.group_ptr_id
735 789bcaf9 Sofia Papagiannaki
            AND date_joined IS NOT NULL) AS approved_members_num,
736 04febd09 Olga Brani
        (SELECT CASE WHEN(
737 04febd09 Olga Brani
                    SELECT date_joined FROM im_membership
738 04febd09 Olga Brani
                    WHERE group_id = im_astakosgroup.group_ptr_id
739 04febd09 Olga Brani
                    AND person_id = %s) IS NULL
740 04febd09 Olga Brani
                    THEN 'Pending' ELSE 'Registered' END) AS membership_status
741 789bcaf9 Sofia Papagiannaki
        FROM im_astakosgroup
742 789bcaf9 Sofia Papagiannaki
        INNER JOIN im_membership ON (
743 789bcaf9 Sofia Papagiannaki
            im_astakosgroup.group_ptr_id = im_membership.group_id)
744 789bcaf9 Sofia Papagiannaki
        INNER JOIN auth_group ON(im_astakosgroup.group_ptr_id = auth_group.id)
745 789bcaf9 Sofia Papagiannaki
        INNER JOIN im_groupkind ON (im_astakosgroup.kind_id = im_groupkind.id)
746 789bcaf9 Sofia Papagiannaki
        LEFT JOIN im_astakosuser_owner ON (
747 789bcaf9 Sofia Papagiannaki
            im_astakosuser_owner.astakosgroup_id = im_astakosgroup.group_ptr_id)
748 789bcaf9 Sofia Papagiannaki
        LEFT JOIN auth_user as owner ON (
749 789bcaf9 Sofia Papagiannaki
            im_astakosuser_owner.astakosuser_id = owner.id)
750 789bcaf9 Sofia Papagiannaki
        WHERE im_membership.person_id = %s
751 789bcaf9 Sofia Papagiannaki
        """ % (DB_REPLACE_GROUP_SCHEME, request.user.id, request.user.id))
752 789bcaf9 Sofia Papagiannaki
    d = defaultdict(list)
753 789bcaf9 Sofia Papagiannaki
    for g in q:
754 789bcaf9 Sofia Papagiannaki
        if request.user.email == g.groupowner:
755 789bcaf9 Sofia Papagiannaki
            d['own'].append(g)
756 789bcaf9 Sofia Papagiannaki
        else:
757 789bcaf9 Sofia Papagiannaki
            d['other'].append(g)
758 fc9ce5b3 Olga Brani
    
759 789bcaf9 Sofia Papagiannaki
    for k, l in d.iteritems():
760 d220292f Sofia Papagiannaki
        page = request.GET.get('%s_page' % k, 1)
761 789bcaf9 Sofia Papagiannaki
        sorting = globals()['%s_sorting' % k] = request.GET.get('%s_sorting' % k)
762 789bcaf9 Sofia Papagiannaki
        if sorting:
763 789bcaf9 Sofia Papagiannaki
            sort_form = AstakosGroupSortForm({'sort_by': sorting})
764 789bcaf9 Sofia Papagiannaki
            if sort_form.is_valid():
765 04febd09 Olga Brani
                sort_field = q._model_fields.get(sorting)
766 04febd09 Olga Brani
                default = datetime.utcfromtimestamp(0) if isinstance(sort_field, DateTimeField) else ''
767 04febd09 Olga Brani
                l.sort(key=lambda i: getattr(i, sorting) if getattr(i, sorting) else default )
768 789bcaf9 Sofia Papagiannaki
                globals()['%s_sorting' % k] = sorting
769 789bcaf9 Sofia Papagiannaki
        paginator = Paginator(l, PAGINATE_BY)
770 789bcaf9 Sofia Papagiannaki
        
771 d220292f Sofia Papagiannaki
        try:
772 d220292f Sofia Papagiannaki
            page_number = int(page)
773 d220292f Sofia Papagiannaki
        except ValueError:
774 d220292f Sofia Papagiannaki
            if page == 'last':
775 d220292f Sofia Papagiannaki
                page_number = paginator.num_pages
776 d220292f Sofia Papagiannaki
            else:
777 d220292f Sofia Papagiannaki
                # Page is not 'last', nor can it be converted to an int.
778 d220292f Sofia Papagiannaki
                raise Http404
779 d220292f Sofia Papagiannaki
        try:
780 789bcaf9 Sofia Papagiannaki
            page_obj = globals()['%s_page_obj' % k] = paginator.page(page_number)
781 d220292f Sofia Papagiannaki
        except InvalidPage:
782 d220292f Sofia Papagiannaki
            raise Http404
783 789bcaf9 Sofia Papagiannaki
    return object_list(request, queryset=none,
784 d220292f Sofia Papagiannaki
                       extra_context={'is_search':False,
785 789bcaf9 Sofia Papagiannaki
                                      'mine': own_page_obj,
786 789bcaf9 Sofia Papagiannaki
                                      'other': other_page_obj,
787 fc9ce5b3 Olga Brani
                                      'own_sorting': own_sorting,
788 789bcaf9 Sofia Papagiannaki
                                      'other_sorting': other_sorting
789 789bcaf9 Sofia Papagiannaki
                                      })
790 5ce3ce4f Sofia Papagiannaki
791 8e45d6fd Sofia Papagiannaki
792 8e45d6fd Sofia Papagiannaki
@signed_terms_required
793 8e45d6fd Sofia Papagiannaki
@login_required
794 8e45d6fd Sofia Papagiannaki
def group_detail(request, group_id):
795 661c4479 Sofia Papagiannaki
    q = AstakosGroup.objects.filter(pk=group_id)
796 661c4479 Sofia Papagiannaki
    q = q.extra(select={
797 661c4479 Sofia Papagiannaki
        'is_member': """SELECT CASE WHEN EXISTS(
798 661c4479 Sofia Papagiannaki
                            SELECT id FROM im_membership
799 661c4479 Sofia Papagiannaki
                            WHERE group_id = im_astakosgroup.group_ptr_id
800 661c4479 Sofia Papagiannaki
                            AND person_id = %s)
801 661c4479 Sofia Papagiannaki
                        THEN 1 ELSE 0 END""" % request.user.id,
802 661c4479 Sofia Papagiannaki
        'is_owner': """SELECT CASE WHEN EXISTS(
803 661c4479 Sofia Papagiannaki
                            SELECT id FROM im_astakosuser_owner
804 661c4479 Sofia Papagiannaki
                            WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
805 661c4479 Sofia Papagiannaki
                            AND astakosuser_id = %s)
806 661c4479 Sofia Papagiannaki
                        THEN 1 ELSE 0 END""" % request.user.id,
807 661c4479 Sofia Papagiannaki
        'kindname': """SELECT name FROM im_groupkind
808 661c4479 Sofia Papagiannaki
                       WHERE id = im_astakosgroup.kind_id"""})
809 661c4479 Sofia Papagiannaki
    
810 661c4479 Sofia Papagiannaki
    model = q.model
811 661c4479 Sofia Papagiannaki
    context_processors = None
812 661c4479 Sofia Papagiannaki
    mimetype = None
813 8e45d6fd Sofia Papagiannaki
    try:
814 661c4479 Sofia Papagiannaki
        obj = q.get()
815 661c4479 Sofia Papagiannaki
    except ObjectDoesNotExist:
816 661c4479 Sofia Papagiannaki
        raise Http404("No %s found matching the query" % (model._meta.verbose_name))
817 04febd09 Olga Brani
    
818 661c4479 Sofia Papagiannaki
    update_form = AstakosGroupUpdateForm(instance=obj)
819 661c4479 Sofia Papagiannaki
    addmembers_form = AddGroupMembersForm()
820 661c4479 Sofia Papagiannaki
    if request.method == 'POST':
821 661c4479 Sofia Papagiannaki
        update_data = {}
822 661c4479 Sofia Papagiannaki
        addmembers_data = {}
823 661c4479 Sofia Papagiannaki
        for k,v in request.POST.iteritems():
824 661c4479 Sofia Papagiannaki
            if k in update_form.fields:
825 661c4479 Sofia Papagiannaki
                update_data[k] = v
826 661c4479 Sofia Papagiannaki
            if k in addmembers_form.fields:
827 661c4479 Sofia Papagiannaki
                addmembers_data[k] = v
828 661c4479 Sofia Papagiannaki
        update_data = update_data or None
829 661c4479 Sofia Papagiannaki
        addmembers_data = addmembers_data or None
830 661c4479 Sofia Papagiannaki
        update_form = AstakosGroupUpdateForm(update_data, instance=obj)
831 661c4479 Sofia Papagiannaki
        addmembers_form = AddGroupMembersForm(addmembers_data)
832 661c4479 Sofia Papagiannaki
        if update_form.is_valid():
833 661c4479 Sofia Papagiannaki
            update_form.save()
834 661c4479 Sofia Papagiannaki
        if addmembers_form.is_valid():
835 661c4479 Sofia Papagiannaki
            map(obj.approve_member, addmembers_form.valid_users)
836 661c4479 Sofia Papagiannaki
            addmembers_form = AddGroupMembersForm()
837 04febd09 Olga Brani
    
838 661c4479 Sofia Papagiannaki
    template_name = "%s/%s_detail.html" % (model._meta.app_label, model._meta.object_name.lower())
839 661c4479 Sofia Papagiannaki
    t = template_loader.get_template(template_name)
840 661c4479 Sofia Papagiannaki
    c = RequestContext(request, {
841 661c4479 Sofia Papagiannaki
        'object': obj,
842 661c4479 Sofia Papagiannaki
    }, context_processors)
843 661c4479 Sofia Papagiannaki
    extra_context = {'update_form': update_form,
844 661c4479 Sofia Papagiannaki
                     'addmembers_form': addmembers_form,
845 661c4479 Sofia Papagiannaki
                     'page': request.GET.get('page', 1),
846 661c4479 Sofia Papagiannaki
                     'sorting': request.GET.get('sorting')}
847 661c4479 Sofia Papagiannaki
    for key, value in extra_context.items():
848 661c4479 Sofia Papagiannaki
        if callable(value):
849 661c4479 Sofia Papagiannaki
            c[key] = value()
850 04febd09 Olga Brani
        else:
851 661c4479 Sofia Papagiannaki
            c[key] = value
852 661c4479 Sofia Papagiannaki
    response = HttpResponse(t.render(c), mimetype=mimetype)
853 661c4479 Sofia Papagiannaki
    populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.name))
854 661c4479 Sofia Papagiannaki
    return response
855 8e45d6fd Sofia Papagiannaki
856 5ce3ce4f Sofia Papagiannaki
857 01ac12d5 Sofia Papagiannaki
@signed_terms_required
858 01ac12d5 Sofia Papagiannaki
@login_required
859 95a51cdc Sofia Papagiannaki
def group_search(request, extra_context=None, **kwargs):
860 d220292f Sofia Papagiannaki
    q = request.GET.get('q')
861 04febd09 Olga Brani
    sorting = request.GET.get('sorting')
862 01ac12d5 Sofia Papagiannaki
    if request.method == 'GET':
863 d220292f Sofia Papagiannaki
        form = AstakosGroupSearchForm({'q': q} if q else None)
864 01ac12d5 Sofia Papagiannaki
    else:
865 01ac12d5 Sofia Papagiannaki
        form = AstakosGroupSearchForm(get_query(request))
866 01ac12d5 Sofia Papagiannaki
        if form.is_valid():
867 01ac12d5 Sofia Papagiannaki
            q = form.cleaned_data['q'].strip()
868 d220292f Sofia Papagiannaki
    if q:
869 789bcaf9 Sofia Papagiannaki
        queryset = AstakosGroup.objects.select_related()
870 789bcaf9 Sofia Papagiannaki
        queryset = queryset.filter(name__contains=q)
871 789bcaf9 Sofia Papagiannaki
        queryset = queryset.filter(approval_date__isnull=False)
872 789bcaf9 Sofia Papagiannaki
        queryset = queryset.extra(select={
873 789bcaf9 Sofia Papagiannaki
                'groupname': DB_REPLACE_GROUP_SCHEME,
874 789bcaf9 Sofia Papagiannaki
                'kindname': "im_groupkind.name",
875 789bcaf9 Sofia Papagiannaki
                'approved_members_num': """
876 789bcaf9 Sofia Papagiannaki
                    SELECT COUNT(*) FROM im_membership
877 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
878 789bcaf9 Sofia Papagiannaki
                    AND date_joined IS NOT NULL""",
879 789bcaf9 Sofia Papagiannaki
                'membership_approval_date': """
880 789bcaf9 Sofia Papagiannaki
                    SELECT date_joined FROM im_membership
881 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
882 789bcaf9 Sofia Papagiannaki
                    AND person_id = %s""" % request.user.id,
883 789bcaf9 Sofia Papagiannaki
                'is_member': """
884 789bcaf9 Sofia Papagiannaki
                    SELECT CASE WHEN EXISTS(
885 789bcaf9 Sofia Papagiannaki
                    SELECT date_joined FROM im_membership
886 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
887 789bcaf9 Sofia Papagiannaki
                    AND person_id = %s)
888 789bcaf9 Sofia Papagiannaki
                    THEN 1 ELSE 0 END""" % request.user.id})
889 04febd09 Olga Brani
        if sorting:
890 04febd09 Olga Brani
            # TODO check sorting value
891 04febd09 Olga Brani
            queryset = queryset.order_by(sorting)
892 d220292f Sofia Papagiannaki
    else:
893 d220292f Sofia Papagiannaki
        queryset = AstakosGroup.objects.none()
894 d220292f Sofia Papagiannaki
    return object_list(
895 d220292f Sofia Papagiannaki
        request,
896 d220292f Sofia Papagiannaki
        queryset,
897 d220292f Sofia Papagiannaki
        paginate_by=PAGINATE_BY,
898 d220292f Sofia Papagiannaki
        page=request.GET.get('page') or 1,
899 d220292f Sofia Papagiannaki
        template_name='im/astakosgroup_list.html',
900 d220292f Sofia Papagiannaki
        extra_context=dict(form=form,
901 d220292f Sofia Papagiannaki
                           is_search=True,
902 04febd09 Olga Brani
                           q=q,
903 04febd09 Olga Brani
                           sorting=sorting))
904 5ce3ce4f Sofia Papagiannaki
905 df67421c Sofia Papagiannaki
@signed_terms_required
906 df67421c Sofia Papagiannaki
@login_required
907 df67421c Sofia Papagiannaki
def group_all(request, extra_context=None, **kwargs):
908 789bcaf9 Sofia Papagiannaki
    q = AstakosGroup.objects.select_related()
909 789bcaf9 Sofia Papagiannaki
    q = q.filter(approval_date__isnull=False)
910 789bcaf9 Sofia Papagiannaki
    q = q.extra(select={
911 789bcaf9 Sofia Papagiannaki
                'groupname': DB_REPLACE_GROUP_SCHEME,
912 789bcaf9 Sofia Papagiannaki
                'kindname': "im_groupkind.name",
913 789bcaf9 Sofia Papagiannaki
                'approved_members_num': """
914 789bcaf9 Sofia Papagiannaki
                    SELECT COUNT(*) FROM im_membership
915 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
916 789bcaf9 Sofia Papagiannaki
                    AND date_joined IS NOT NULL""",
917 789bcaf9 Sofia Papagiannaki
                'membership_approval_date': """
918 789bcaf9 Sofia Papagiannaki
                    SELECT date_joined FROM im_membership
919 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
920 789bcaf9 Sofia Papagiannaki
                    AND person_id = %s""" % request.user.id,
921 789bcaf9 Sofia Papagiannaki
                'is_member': """
922 789bcaf9 Sofia Papagiannaki
                    SELECT CASE WHEN EXISTS(
923 789bcaf9 Sofia Papagiannaki
                    SELECT date_joined FROM im_membership
924 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
925 789bcaf9 Sofia Papagiannaki
                    AND person_id = %s)
926 789bcaf9 Sofia Papagiannaki
                    THEN 1 ELSE 0 END""" % request.user.id})
927 04febd09 Olga Brani
    sorting = request.GET.get('sorting')
928 04febd09 Olga Brani
    if sorting:
929 04febd09 Olga Brani
        # TODO check sorting value
930 04febd09 Olga Brani
        q = q.order_by(sorting)
931 df67421c Sofia Papagiannaki
    return object_list(
932 df67421c Sofia Papagiannaki
                request,
933 789bcaf9 Sofia Papagiannaki
                q,
934 d220292f Sofia Papagiannaki
                paginate_by=PAGINATE_BY,
935 d220292f Sofia Papagiannaki
                page=request.GET.get('page') or 1,
936 df67421c Sofia Papagiannaki
                template_name='im/astakosgroup_list.html',
937 df67421c Sofia Papagiannaki
                extra_context=dict(form=AstakosGroupSearchForm(),
938 04febd09 Olga Brani
                                   is_search=True,
939 04febd09 Olga Brani
                                   sorting=sorting))
940 df67421c Sofia Papagiannaki
941 01ac12d5 Sofia Papagiannaki
942 01ac12d5 Sofia Papagiannaki
@signed_terms_required
943 01ac12d5 Sofia Papagiannaki
@login_required
944 01ac12d5 Sofia Papagiannaki
def group_join(request, group_id):
945 95a51cdc Sofia Papagiannaki
    m = Membership(group_id=group_id,
946 5ce3ce4f Sofia Papagiannaki
                   person=request.user,
947 789bcaf9 Sofia Papagiannaki
                   date_requested=datetime.now())
948 95a51cdc Sofia Papagiannaki
    try:
949 95a51cdc Sofia Papagiannaki
        m.save()
950 0f4fa26d Sofia Papagiannaki
        post_save_redirect = reverse(
951 0f4fa26d Sofia Papagiannaki
            'group_detail',
952 789bcaf9 Sofia Papagiannaki
            kwargs=dict(group_id=group_id))
953 95a51cdc Sofia Papagiannaki
        return HttpResponseRedirect(post_save_redirect)
954 95a51cdc Sofia Papagiannaki
    except IntegrityError, e:
955 95a51cdc Sofia Papagiannaki
        logger.exception(e)
956 95a51cdc Sofia Papagiannaki
        msg = _('Failed to join group.')
957 95a51cdc Sofia Papagiannaki
        messages.error(request, msg)
958 95a51cdc Sofia Papagiannaki
        return group_search(request)
959 01ac12d5 Sofia Papagiannaki
960 5ce3ce4f Sofia Papagiannaki
961 01ac12d5 Sofia Papagiannaki
@signed_terms_required
962 01ac12d5 Sofia Papagiannaki
@login_required
963 01ac12d5 Sofia Papagiannaki
def group_leave(request, group_id):
964 01ac12d5 Sofia Papagiannaki
    try:
965 0f4fa26d Sofia Papagiannaki
        m = Membership.objects.select_related().get(
966 0f4fa26d Sofia Papagiannaki
            group__id=group_id,
967 0f4fa26d Sofia Papagiannaki
            person=request.user
968 0f4fa26d Sofia Papagiannaki
        )
969 01ac12d5 Sofia Papagiannaki
    except Membership.DoesNotExist:
970 01ac12d5 Sofia Papagiannaki
        return HttpResponseBadRequest(_('Invalid membership.'))
971 01ac12d5 Sofia Papagiannaki
    if request.user in m.group.owner.all():
972 01ac12d5 Sofia Papagiannaki
        return HttpResponseForbidden(_('Owner can not leave the group.'))
973 0f4fa26d Sofia Papagiannaki
    return delete_object(
974 0f4fa26d Sofia Papagiannaki
        request,
975 0f4fa26d Sofia Papagiannaki
        model=Membership,
976 5ce3ce4f Sofia Papagiannaki
        object_id=m.id,
977 0f4fa26d Sofia Papagiannaki
        template_name='im/astakosgroup_list.html',
978 5ce3ce4f Sofia Papagiannaki
        post_delete_redirect=reverse(
979 0f4fa26d Sofia Papagiannaki
            'group_detail',
980 0f4fa26d Sofia Papagiannaki
            kwargs=dict(group_id=group_id)
981 0f4fa26d Sofia Papagiannaki
        )
982 0f4fa26d Sofia Papagiannaki
    )
983 01ac12d5 Sofia Papagiannaki
984 5ce3ce4f Sofia Papagiannaki
985 1eaeb5b6 Sofia Papagiannaki
def handle_membership(func):
986 1eaeb5b6 Sofia Papagiannaki
    @wraps(func)
987 1eaeb5b6 Sofia Papagiannaki
    def wrapper(request, group_id, user_id):
988 1eaeb5b6 Sofia Papagiannaki
        try:
989 1eaeb5b6 Sofia Papagiannaki
            m = Membership.objects.select_related().get(
990 1eaeb5b6 Sofia Papagiannaki
                group__id=group_id,
991 1eaeb5b6 Sofia Papagiannaki
                person__id=user_id
992 1eaeb5b6 Sofia Papagiannaki
            )
993 1eaeb5b6 Sofia Papagiannaki
        except Membership.DoesNotExist:
994 1eaeb5b6 Sofia Papagiannaki
            return HttpResponseBadRequest(_('Invalid membership.'))
995 1eaeb5b6 Sofia Papagiannaki
        else:
996 1eaeb5b6 Sofia Papagiannaki
            if request.user not in m.group.owner.all():
997 1eaeb5b6 Sofia Papagiannaki
                return HttpResponseForbidden(_('User is not a group owner.'))
998 1eaeb5b6 Sofia Papagiannaki
            func(request, m)
999 1eaeb5b6 Sofia Papagiannaki
            return render_response(
1000 1eaeb5b6 Sofia Papagiannaki
                template='im/astakosgroup_detail.html',
1001 1eaeb5b6 Sofia Papagiannaki
                context_instance=get_context(request),
1002 1eaeb5b6 Sofia Papagiannaki
                object=m.group,
1003 1eaeb5b6 Sofia Papagiannaki
                quota=m.group.quota
1004 1eaeb5b6 Sofia Papagiannaki
            )
1005 1eaeb5b6 Sofia Papagiannaki
    return wrapper
1006 01ac12d5 Sofia Papagiannaki
1007 5ce3ce4f Sofia Papagiannaki
1008 01ac12d5 Sofia Papagiannaki
@signed_terms_required
1009 01ac12d5 Sofia Papagiannaki
@login_required
1010 1eaeb5b6 Sofia Papagiannaki
@handle_membership
1011 01ac12d5 Sofia Papagiannaki
def approve_member(request, membership):
1012 01ac12d5 Sofia Papagiannaki
    try:
1013 01ac12d5 Sofia Papagiannaki
        membership.approve()
1014 01ac12d5 Sofia Papagiannaki
        realname = membership.person.realname
1015 01ac12d5 Sofia Papagiannaki
        msg = _('%s has been successfully joined the group.' % realname)
1016 01ac12d5 Sofia Papagiannaki
        messages.success(request, msg)
1017 01ac12d5 Sofia Papagiannaki
    except BaseException, e:
1018 01ac12d5 Sofia Papagiannaki
        logger.exception(e)
1019 01ac12d5 Sofia Papagiannaki
        msg = _('Something went wrong during %s\'s approval.' % realname)
1020 01ac12d5 Sofia Papagiannaki
        messages.error(request, msg)
1021 5ce3ce4f Sofia Papagiannaki
1022 5ce3ce4f Sofia Papagiannaki
1023 01ac12d5 Sofia Papagiannaki
@signed_terms_required
1024 01ac12d5 Sofia Papagiannaki
@login_required
1025 1eaeb5b6 Sofia Papagiannaki
@handle_membership
1026 01ac12d5 Sofia Papagiannaki
def disapprove_member(request, membership):
1027 01ac12d5 Sofia Papagiannaki
    try:
1028 01ac12d5 Sofia Papagiannaki
        membership.disapprove()
1029 01ac12d5 Sofia Papagiannaki
        realname = membership.person.realname
1030 01ac12d5 Sofia Papagiannaki
        msg = _('%s has been successfully removed from the group.' % realname)
1031 01ac12d5 Sofia Papagiannaki
        messages.success(request, msg)
1032 01ac12d5 Sofia Papagiannaki
    except BaseException, e:
1033 01ac12d5 Sofia Papagiannaki
        logger.exception(e)
1034 01ac12d5 Sofia Papagiannaki
        msg = _('Something went wrong during %s\'s disapproval.' % realname)
1035 01ac12d5 Sofia Papagiannaki
        messages.error(request, msg)
1036 ffb1e7a8 Sofia Papagiannaki
1037 5ce3ce4f Sofia Papagiannaki
1038 ffb1e7a8 Sofia Papagiannaki
@signed_terms_required
1039 ffb1e7a8 Sofia Papagiannaki
@login_required
1040 ffb1e7a8 Sofia Papagiannaki
def resource_list(request):
1041 0f4fa26d Sofia Papagiannaki
    return render_response(
1042 0f4fa26d Sofia Papagiannaki
        template='im/astakosuserquota_list.html',
1043 0f4fa26d Sofia Papagiannaki
        context_instance=get_context(request),
1044 0f4fa26d Sofia Papagiannaki
        quota=request.user.quota
1045 4b7d68f0 Olga Brani
    )
1046 5ce3ce4f Sofia Papagiannaki
1047 5ce3ce4f Sofia Papagiannaki
1048 4b7d68f0 Olga Brani
def group_create_list(request):
1049 4b7d68f0 Olga Brani
    return render_response(
1050 4b7d68f0 Olga Brani
        template='im/astakosgroup_create_list.html',
1051 4b7d68f0 Olga Brani
        context_instance=get_context(request),
1052 6e029beb Sofia Papagiannaki
    )
1053 6e029beb Sofia Papagiannaki
1054 5ce3ce4f Sofia Papagiannaki
1055 6e029beb Sofia Papagiannaki
@signed_terms_required
1056 6e029beb Sofia Papagiannaki
@login_required
1057 6e029beb Sofia Papagiannaki
def billing(request):
1058 5056da3d Olga Brani
    
1059 6e029beb Sofia Papagiannaki
    today = datetime.today()
1060 5056da3d Olga Brani
    month_last_day= calendar.monthrange(today.year, today.month)[1]
1061 5056da3d Olga Brani
    
1062 5056da3d Olga Brani
    start = request.POST.get('datefrom', None)
1063 5056da3d Olga Brani
    if start:
1064 5056da3d Olga Brani
        today = datetime.fromtimestamp(int(start))
1065 5056da3d Olga Brani
        month_last_day= calendar.monthrange(today.year, today.month)[1]
1066 5056da3d Olga Brani
    
1067 6e029beb Sofia Papagiannaki
    start = datetime(today.year, today.month, 1).strftime("%s")
1068 6e029beb Sofia Papagiannaki
    end = datetime(today.year, today.month, month_last_day).strftime("%s")
1069 4de59eac Olga Brani
    r = request_billing.apply(args=('pgerakios@grnet.gr',
1070 5ce3ce4f Sofia Papagiannaki
                                    int(start) * 1000,
1071 5056da3d Olga Brani
                                    int(end) * 1000))
1072 5056da3d Olga Brani
    data = {}
1073 5056da3d Olga Brani
    
1074 6e029beb Sofia Papagiannaki
    try:
1075 6e029beb Sofia Papagiannaki
        status, data = r.result
1076 5056da3d Olga Brani
        data=clear_billing_data(data)
1077 6e029beb Sofia Papagiannaki
        if status != 200:
1078 6e029beb Sofia Papagiannaki
            messages.error(request, _('Service response status: %d' % status))
1079 6e029beb Sofia Papagiannaki
    except:
1080 6e029beb Sofia Papagiannaki
        messages.error(request, r.result)
1081 5056da3d Olga Brani
    
1082 5056da3d Olga Brani
    print type(start)
1083 5056da3d Olga Brani
    
1084 6e029beb Sofia Papagiannaki
    return render_response(
1085 6e029beb Sofia Papagiannaki
        template='im/billing.html',
1086 6e029beb Sofia Papagiannaki
        context_instance=get_context(request),
1087 5056da3d Olga Brani
        data=data,
1088 5056da3d Olga Brani
        zerodate=datetime(month=1,year=1970, day=1),
1089 5056da3d Olga Brani
        today=today,
1090 5056da3d Olga Brani
        start=int(start),
1091 5056da3d Olga Brani
        month_last_day=month_last_day)  
1092 5056da3d Olga Brani
    
1093 5056da3d Olga Brani
def clear_billing_data(data):
1094 5056da3d Olga Brani
    
1095 5056da3d Olga Brani
    # remove addcredits entries
1096 5056da3d Olga Brani
    def isnotcredit(e):
1097 5056da3d Olga Brani
        return e['serviceName'] != "addcredits"
1098 5056da3d Olga Brani
    
1099 5056da3d Olga Brani
    
1100 5056da3d Olga Brani
    
1101 5056da3d Olga Brani
    # separate services    
1102 5056da3d Olga Brani
    def servicefilter(service_name):
1103 5056da3d Olga Brani
        service = service_name
1104 5056da3d Olga Brani
        def fltr(e):
1105 5056da3d Olga Brani
            return e['serviceName'] == service
1106 5056da3d Olga Brani
        return fltr
1107 5056da3d Olga Brani
        
1108 5056da3d Olga Brani
    
1109 5056da3d Olga Brani
    data['bill_nocredits'] = filter(isnotcredit, data['bill'])
1110 5056da3d Olga Brani
    data['bill_vmtime'] = filter(servicefilter('vmtime'), data['bill'])
1111 5056da3d Olga Brani
    data['bill_diskspace'] = filter(servicefilter('diskspace'), data['bill'])
1112 4de59eac Olga Brani
    data['bill_addcredits'] = filter(servicefilter('addcredits'), data['bill'])
1113 5056da3d Olga Brani
        
1114 c3a00daf Olga Brani
    return data