Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 6bdf0aa3

History | View | Annotate | Download (42 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 01ac12d5 Sofia Papagiannaki
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, \
51 789bcaf9 Sofia Papagiannaki
    HttpResponseRedirect, HttpResponseBadRequest, Http404
52 01ac12d5 Sofia Papagiannaki
from django.shortcuts import redirect
53 661c4479 Sofia Papagiannaki
from django.template import RequestContext, loader as template_loader
54 01ac12d5 Sofia Papagiannaki
from django.utils.http import urlencode
55 01ac12d5 Sofia Papagiannaki
from django.utils.translation import ugettext as _
56 aab4d540 Sofia Papagiannaki
from django.views.generic.create_update import (create_object, delete_object,
57 de4ed385 Sofia Papagiannaki
                                                get_model_and_form_class)
58 aab4d540 Sofia Papagiannaki
from django.views.generic.list_detail import object_list, object_detail
59 51c57c9c Sofia Papagiannaki
from django.http import HttpResponseBadRequest
60 661c4479 Sofia Papagiannaki
from django.core.xheaders import populate_xheaders
61 64cd4730 Antony Chazapis
62 5ce3ce4f Sofia Papagiannaki
from astakos.im.models import (
63 5ce3ce4f Sofia Papagiannaki
    AstakosUser, ApprovalTerms, AstakosGroup, Resource,
64 aab4d540 Sofia Papagiannaki
    EmailChange, GroupKind, Membership)
65 4e30244e Sofia Papagiannaki
from astakos.im.activation_backends import get_backend, SimpleBackend
66 1662ac2d Sofia Papagiannaki
from astakos.im.util import get_context, prepare_response, set_cookie, get_query
67 51c57c9c Sofia Papagiannaki
from astakos.im.forms import (LoginForm, InvitationForm, ProfileForm,
68 51c57c9c Sofia Papagiannaki
                              FeedbackForm, SignApprovalTermsForm,
69 51c57c9c Sofia Papagiannaki
                              ExtendedPasswordChangeForm, EmailChangeForm,
70 51c57c9c Sofia Papagiannaki
                              AstakosGroupCreationForm, AstakosGroupSearchForm,
71 54213d7a Sofia Papagiannaki
                              AstakosGroupUpdateForm, AddGroupMembersForm,
72 3bb604eb Sofia Papagiannaki
                              AstakosGroupSortForm, MembersSortForm,
73 3bb604eb Sofia Papagiannaki
                              TimelineForm)
74 aab4d540 Sofia Papagiannaki
from astakos.im.functions import (send_feedback, SendMailError,
75 51c57c9c Sofia Papagiannaki
                                  invite as invite_func, logout as auth_logout,
76 51c57c9c Sofia Papagiannaki
                                  activate as activate_func,
77 51c57c9c Sofia Papagiannaki
                                  switch_account_to_shibboleth,
78 51c57c9c Sofia Papagiannaki
                                  send_admin_notification,
79 51c57c9c Sofia Papagiannaki
                                  SendNotificationError)
80 2925e285 root
from astakos.im.endpoints.quotaholder import timeline_charge
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 c3f6cdf1 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 c3f6cdf1 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 572194d0 Sofia Papagiannaki
    response.write(template_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 3bb604eb Sofia Papagiannaki
def activate(request, greeting_email_template_name='im/welcome_email.txt',
475 3bb604eb Sofia Papagiannaki
             helpdesk_email_template_name='im/helpdesk_notification.txt'):
476 2126d85d Sofia Papagiannaki
    """
477 683cf244 Sofia Papagiannaki
    Activates the user identified by the ``auth`` request parameter, sends a welcome email
478 683cf244 Sofia Papagiannaki
    and renews the user token.
479 176023aa Kostas Papadimitriou

480 683cf244 Sofia Papagiannaki
    The view uses commit_manually decorator in order to ensure the user state will be updated
481 683cf244 Sofia Papagiannaki
    only if the email will be send successfully.
482 2126d85d Sofia Papagiannaki
    """
483 2126d85d Sofia Papagiannaki
    token = request.GET.get('auth')
484 2126d85d Sofia Papagiannaki
    next = request.GET.get('next')
485 2126d85d Sofia Papagiannaki
    try:
486 2126d85d Sofia Papagiannaki
        user = AstakosUser.objects.get(auth_token=token)
487 2126d85d Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
488 683cf244 Sofia Papagiannaki
        return HttpResponseBadRequest(_('No such user'))
489 5ce3ce4f Sofia Papagiannaki
490 d1757ca7 Sofia Papagiannaki
    if user.is_active:
491 23b9b72f Sofia Papagiannaki
        message = _('Account already active.')
492 24406ae3 Sofia Papagiannaki
        messages.error(request, message)
493 23b9b72f Sofia Papagiannaki
        return index(request)
494 5ce3ce4f Sofia Papagiannaki
495 0a569195 Sofia Papagiannaki
    try:
496 3abf6c78 Sofia Papagiannaki
        local_user = AstakosUser.objects.get(
497 5ce3ce4f Sofia Papagiannaki
            ~Q(id=user.id),
498 3abf6c78 Sofia Papagiannaki
            email=user.email,
499 3abf6c78 Sofia Papagiannaki
            is_active=True
500 3abf6c78 Sofia Papagiannaki
        )
501 0a569195 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
502 27e26a41 Sofia Papagiannaki
        try:
503 3abf6c78 Sofia Papagiannaki
            activate_func(
504 3abf6c78 Sofia Papagiannaki
                user,
505 3abf6c78 Sofia Papagiannaki
                greeting_email_template_name,
506 3abf6c78 Sofia Papagiannaki
                helpdesk_email_template_name,
507 3abf6c78 Sofia Papagiannaki
                verify_email=True
508 3abf6c78 Sofia Papagiannaki
            )
509 23b9b72f Sofia Papagiannaki
            response = prepare_response(request, user, next, renew=True)
510 23b9b72f Sofia Papagiannaki
            transaction.commit()
511 23b9b72f Sofia Papagiannaki
            return response
512 23b9b72f Sofia Papagiannaki
        except SendMailError, e:
513 23b9b72f Sofia Papagiannaki
            message = e.message
514 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
515 23b9b72f Sofia Papagiannaki
            transaction.rollback()
516 23b9b72f Sofia Papagiannaki
            return index(request)
517 23b9b72f Sofia Papagiannaki
        except BaseException, e:
518 23b9b72f Sofia Papagiannaki
            message = _('Something went wrong.')
519 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
520 23b9b72f Sofia Papagiannaki
            logger.exception(e)
521 23b9b72f Sofia Papagiannaki
            transaction.rollback()
522 23b9b72f Sofia Papagiannaki
            return index(request)
523 0a569195 Sofia Papagiannaki
    else:
524 23b9b72f Sofia Papagiannaki
        try:
525 3abf6c78 Sofia Papagiannaki
            user = switch_account_to_shibboleth(
526 3abf6c78 Sofia Papagiannaki
                user,
527 3abf6c78 Sofia Papagiannaki
                local_user,
528 3abf6c78 Sofia Papagiannaki
                greeting_email_template_name
529 3abf6c78 Sofia Papagiannaki
            )
530 23b9b72f Sofia Papagiannaki
            response = prepare_response(request, user, next, renew=True)
531 23b9b72f Sofia Papagiannaki
            transaction.commit()
532 23b9b72f Sofia Papagiannaki
            return response
533 23b9b72f Sofia Papagiannaki
        except SendMailError, e:
534 23b9b72f Sofia Papagiannaki
            message = e.message
535 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
536 23b9b72f Sofia Papagiannaki
            transaction.rollback()
537 23b9b72f Sofia Papagiannaki
            return index(request)
538 23b9b72f Sofia Papagiannaki
        except BaseException, e:
539 23b9b72f Sofia Papagiannaki
            message = _('Something went wrong.')
540 24406ae3 Sofia Papagiannaki
            messages.error(request, message)
541 23b9b72f Sofia Papagiannaki
            logger.exception(e)
542 23b9b72f Sofia Papagiannaki
            transaction.rollback()
543 23b9b72f Sofia Papagiannaki
            return index(request)
544 270dd48d Sofia Papagiannaki
545 5ce3ce4f Sofia Papagiannaki
546 aab4d540 Sofia Papagiannaki
def approval_terms(request, term_id=None, template_name='im/approval_terms.html', extra_context=None):
547 270dd48d Sofia Papagiannaki
    term = None
548 270dd48d Sofia Papagiannaki
    terms = None
549 270dd48d Sofia Papagiannaki
    if not term_id:
550 270dd48d Sofia Papagiannaki
        try:
551 270dd48d Sofia Papagiannaki
            term = ApprovalTerms.objects.order_by('-id')[0]
552 270dd48d Sofia Papagiannaki
        except IndexError:
553 270dd48d Sofia Papagiannaki
            pass
554 270dd48d Sofia Papagiannaki
    else:
555 270dd48d Sofia Papagiannaki
        try:
556 aab4d540 Sofia Papagiannaki
            term = ApprovalTerms.objects.get(id=term_id)
557 aab4d540 Sofia Papagiannaki
        except ApprovalTerms.DoesNotExist, e:
558 270dd48d Sofia Papagiannaki
            pass
559 176023aa Kostas Papadimitriou
560 270dd48d Sofia Papagiannaki
    if not term:
561 6ff7a7ca Sofia Papagiannaki
        return HttpResponseRedirect(reverse('index'))
562 270dd48d Sofia Papagiannaki
    f = open(term.location, 'r')
563 270dd48d Sofia Papagiannaki
    terms = f.read()
564 176023aa Kostas Papadimitriou
565 270dd48d Sofia Papagiannaki
    if request.method == 'POST':
566 270dd48d Sofia Papagiannaki
        next = request.POST.get('next')
567 270dd48d Sofia Papagiannaki
        if not next:
568 6ff7a7ca Sofia Papagiannaki
            next = reverse('index')
569 270dd48d Sofia Papagiannaki
        form = SignApprovalTermsForm(request.POST, instance=request.user)
570 270dd48d Sofia Papagiannaki
        if not form.is_valid():
571 270dd48d Sofia Papagiannaki
            return render_response(template_name,
572 5ce3ce4f Sofia Papagiannaki
                                   terms=terms,
573 5ce3ce4f Sofia Papagiannaki
                                   approval_terms_form=form,
574 5ce3ce4f Sofia Papagiannaki
                                   context_instance=get_context(request, extra_context))
575 270dd48d Sofia Papagiannaki
        user = form.save()
576 270dd48d Sofia Papagiannaki
        return HttpResponseRedirect(next)
577 270dd48d Sofia Papagiannaki
    else:
578 586967c0 Sofia Papagiannaki
        form = None
579 fcf90160 Sofia Papagiannaki
        if request.user.is_authenticated() and not request.user.signed_terms:
580 586967c0 Sofia Papagiannaki
            form = SignApprovalTermsForm(instance=request.user)
581 270dd48d Sofia Papagiannaki
        return render_response(template_name,
582 5ce3ce4f Sofia Papagiannaki
                               terms=terms,
583 5ce3ce4f Sofia Papagiannaki
                               approval_terms_form=form,
584 5ce3ce4f Sofia Papagiannaki
                               context_instance=get_context(request, extra_context))
585 5ce3ce4f Sofia Papagiannaki
586 270dd48d Sofia Papagiannaki
587 270dd48d Sofia Papagiannaki
@signed_terms_required
588 270dd48d Sofia Papagiannaki
def change_password(request):
589 1039bab1 Sofia Papagiannaki
    return password_change(request,
590 5ce3ce4f Sofia Papagiannaki
                           post_change_redirect=reverse('edit_profile'),
591 5ce3ce4f Sofia Papagiannaki
                           password_change_form=ExtendedPasswordChangeForm)
592 5ce3ce4f Sofia Papagiannaki
593 49790d9d Sofia Papagiannaki
594 8e45d6fd Sofia Papagiannaki
@signed_terms_required
595 8e45d6fd Sofia Papagiannaki
@login_required
596 49790d9d Sofia Papagiannaki
@transaction.commit_manually
597 49790d9d Sofia Papagiannaki
def change_email(request, activation_key=None,
598 49790d9d Sofia Papagiannaki
                 email_template_name='registration/email_change_email.txt',
599 49790d9d Sofia Papagiannaki
                 form_template_name='registration/email_change_form.html',
600 49790d9d Sofia Papagiannaki
                 confirm_template_name='registration/email_change_done.html',
601 aab4d540 Sofia Papagiannaki
                 extra_context=None):
602 49790d9d Sofia Papagiannaki
    if activation_key:
603 49790d9d Sofia Papagiannaki
        try:
604 49790d9d Sofia Papagiannaki
            user = EmailChange.objects.change_email(activation_key)
605 49790d9d Sofia Papagiannaki
            if request.user.is_authenticated() and request.user == user:
606 49790d9d Sofia Papagiannaki
                msg = _('Email changed successfully.')
607 24406ae3 Sofia Papagiannaki
                messages.success(request, msg)
608 49790d9d Sofia Papagiannaki
                auth_logout(request)
609 49790d9d Sofia Papagiannaki
                response = prepare_response(request, user)
610 49790d9d Sofia Papagiannaki
                transaction.commit()
611 49790d9d Sofia Papagiannaki
                return response
612 49790d9d Sofia Papagiannaki
        except ValueError, e:
613 24406ae3 Sofia Papagiannaki
            messages.error(request, e)
614 49790d9d Sofia Papagiannaki
        return render_response(confirm_template_name,
615 5ce3ce4f Sofia Papagiannaki
                               modified_user=user if 'user' in locals(
616 5ce3ce4f Sofia Papagiannaki
                               ) else None,
617 5ce3ce4f Sofia Papagiannaki
                               context_instance=get_context(request,
618 5ce3ce4f Sofia Papagiannaki
                                                            extra_context))
619 5ce3ce4f Sofia Papagiannaki
620 49790d9d Sofia Papagiannaki
    if not request.user.is_authenticated():
621 49790d9d Sofia Papagiannaki
        path = quote(request.get_full_path())
622 6ff7a7ca Sofia Papagiannaki
        url = request.build_absolute_uri(reverse('index'))
623 49790d9d Sofia Papagiannaki
        return HttpResponseRedirect(url + '?next=' + path)
624 49790d9d Sofia Papagiannaki
    form = EmailChangeForm(request.POST or None)
625 49790d9d Sofia Papagiannaki
    if request.method == 'POST' and form.is_valid():
626 49790d9d Sofia Papagiannaki
        try:
627 49790d9d Sofia Papagiannaki
            ec = form.save(email_template_name, request)
628 49790d9d Sofia Papagiannaki
        except SendMailError, e:
629 49790d9d Sofia Papagiannaki
            msg = e
630 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
631 49790d9d Sofia Papagiannaki
            transaction.rollback()
632 49790d9d Sofia Papagiannaki
        except IntegrityError, e:
633 49790d9d Sofia Papagiannaki
            msg = _('There is already a pending change email request.')
634 24406ae3 Sofia Papagiannaki
            messages.error(request, msg)
635 49790d9d Sofia Papagiannaki
        else:
636 49790d9d Sofia Papagiannaki
            msg = _('Change email request has been registered succefully.\
637 49790d9d Sofia Papagiannaki
                    You are going to receive a verification email in the new address.')
638 24406ae3 Sofia Papagiannaki
            messages.success(request, msg)
639 49790d9d Sofia Papagiannaki
            transaction.commit()
640 49790d9d Sofia Papagiannaki
    return render_response(form_template_name,
641 5ce3ce4f Sofia Papagiannaki
                           form=form,
642 5ce3ce4f Sofia Papagiannaki
                           context_instance=get_context(request,
643 5ce3ce4f Sofia Papagiannaki
                                                        extra_context))
644 5ce3ce4f Sofia Papagiannaki
645 8e45d6fd Sofia Papagiannaki
646 8e45d6fd Sofia Papagiannaki
@signed_terms_required
647 01ac12d5 Sofia Papagiannaki
@login_required
648 0f4fa26d Sofia Papagiannaki
def group_add(request, kind_name='default'):
649 0f4fa26d Sofia Papagiannaki
    try:
650 5ce3ce4f Sofia Papagiannaki
        kind = GroupKind.objects.get(name=kind_name)
651 0f4fa26d Sofia Papagiannaki
    except:
652 0f4fa26d Sofia Papagiannaki
        return HttpResponseBadRequest(_('No such group kind'))
653 5ce3ce4f Sofia Papagiannaki
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 0f225db4 Sofia Papagiannaki
                    THEN 0 ELSE 1 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 801be7a3 Sofia Papagiannaki
    
759 801be7a3 Sofia Papagiannaki
    # validate sorting
760 801be7a3 Sofia Papagiannaki
    fields = ('own', 'other')
761 801be7a3 Sofia Papagiannaki
    for f in fields:
762 801be7a3 Sofia Papagiannaki
        v = globals()['%s_sorting' % f] = request.GET.get('%s_sorting' % f)
763 801be7a3 Sofia Papagiannaki
        if v:
764 801be7a3 Sofia Papagiannaki
            form = AstakosGroupSortForm({'sort_by': v})
765 801be7a3 Sofia Papagiannaki
            if not form.is_valid():
766 801be7a3 Sofia Papagiannaki
                globals()['%s_sorting' % f] = form.cleaned_data.get('sort_by')
767 789bcaf9 Sofia Papagiannaki
    return object_list(request, queryset=none,
768 d220292f Sofia Papagiannaki
                       extra_context={'is_search':False,
769 77aaed51 Sofia Papagiannaki
                                      'mine': d['own'],
770 77aaed51 Sofia Papagiannaki
                                      'other': d['other'],
771 fc9ce5b3 Olga Brani
                                      'own_sorting': own_sorting,
772 801be7a3 Sofia Papagiannaki
                                      'other_sorting': other_sorting,
773 77aaed51 Sofia Papagiannaki
                                      'own_page': request.GET.get('own_page', 1),
774 801be7a3 Sofia Papagiannaki
                                      'other_page': request.GET.get('other_page', 1)
775 789bcaf9 Sofia Papagiannaki
                                      })
776 5ce3ce4f Sofia Papagiannaki
777 8e45d6fd Sofia Papagiannaki
778 8e45d6fd Sofia Papagiannaki
@signed_terms_required
779 8e45d6fd Sofia Papagiannaki
@login_required
780 8e45d6fd Sofia Papagiannaki
def group_detail(request, group_id):
781 032ade79 Sofia Papagiannaki
    q = AstakosGroup.objects.select_related().filter(pk=group_id)
782 661c4479 Sofia Papagiannaki
    q = q.extra(select={
783 661c4479 Sofia Papagiannaki
        'is_member': """SELECT CASE WHEN EXISTS(
784 661c4479 Sofia Papagiannaki
                            SELECT id FROM im_membership
785 661c4479 Sofia Papagiannaki
                            WHERE group_id = im_astakosgroup.group_ptr_id
786 661c4479 Sofia Papagiannaki
                            AND person_id = %s)
787 661c4479 Sofia Papagiannaki
                        THEN 1 ELSE 0 END""" % request.user.id,
788 661c4479 Sofia Papagiannaki
        'is_owner': """SELECT CASE WHEN EXISTS(
789 032ade79 Sofia Papagiannaki
                        SELECT id FROM im_astakosuser_owner
790 032ade79 Sofia Papagiannaki
                        WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
791 032ade79 Sofia Papagiannaki
                        AND astakosuser_id = %s)
792 661c4479 Sofia Papagiannaki
                        THEN 1 ELSE 0 END""" % request.user.id,
793 661c4479 Sofia Papagiannaki
        'kindname': """SELECT name FROM im_groupkind
794 661c4479 Sofia Papagiannaki
                       WHERE id = im_astakosgroup.kind_id"""})
795 661c4479 Sofia Papagiannaki
    
796 661c4479 Sofia Papagiannaki
    model = q.model
797 661c4479 Sofia Papagiannaki
    context_processors = None
798 661c4479 Sofia Papagiannaki
    mimetype = None
799 8e45d6fd Sofia Papagiannaki
    try:
800 661c4479 Sofia Papagiannaki
        obj = q.get()
801 8e45d6fd Sofia Papagiannaki
    except AstakosGroup.DoesNotExist:
802 032ade79 Sofia Papagiannaki
        raise Http404("No %s found matching the query" % (
803 032ade79 Sofia Papagiannaki
            model._meta.verbose_name))
804 04febd09 Olga Brani
    
805 661c4479 Sofia Papagiannaki
    update_form = AstakosGroupUpdateForm(instance=obj)
806 661c4479 Sofia Papagiannaki
    addmembers_form = AddGroupMembersForm()
807 661c4479 Sofia Papagiannaki
    if request.method == 'POST':
808 661c4479 Sofia Papagiannaki
        update_data = {}
809 661c4479 Sofia Papagiannaki
        addmembers_data = {}
810 661c4479 Sofia Papagiannaki
        for k,v in request.POST.iteritems():
811 661c4479 Sofia Papagiannaki
            if k in update_form.fields:
812 661c4479 Sofia Papagiannaki
                update_data[k] = v
813 661c4479 Sofia Papagiannaki
            if k in addmembers_form.fields:
814 661c4479 Sofia Papagiannaki
                addmembers_data[k] = v
815 661c4479 Sofia Papagiannaki
        update_data = update_data or None
816 661c4479 Sofia Papagiannaki
        addmembers_data = addmembers_data or None
817 661c4479 Sofia Papagiannaki
        update_form = AstakosGroupUpdateForm(update_data, instance=obj)
818 661c4479 Sofia Papagiannaki
        addmembers_form = AddGroupMembersForm(addmembers_data)
819 661c4479 Sofia Papagiannaki
        if update_form.is_valid():
820 661c4479 Sofia Papagiannaki
            update_form.save()
821 661c4479 Sofia Papagiannaki
        if addmembers_form.is_valid():
822 661c4479 Sofia Papagiannaki
            map(obj.approve_member, addmembers_form.valid_users)
823 661c4479 Sofia Papagiannaki
            addmembers_form = AddGroupMembersForm()
824 04febd09 Olga Brani
    
825 661c4479 Sofia Papagiannaki
    template_name = "%s/%s_detail.html" % (model._meta.app_label, model._meta.object_name.lower())
826 661c4479 Sofia Papagiannaki
    t = template_loader.get_template(template_name)
827 661c4479 Sofia Papagiannaki
    c = RequestContext(request, {
828 661c4479 Sofia Papagiannaki
        'object': obj,
829 661c4479 Sofia Papagiannaki
    }, context_processors)
830 801be7a3 Sofia Papagiannaki
    
831 801be7a3 Sofia Papagiannaki
    # validate sorting
832 801be7a3 Sofia Papagiannaki
    sorting= request.GET.get('sorting')
833 801be7a3 Sofia Papagiannaki
    if sorting:
834 801be7a3 Sofia Papagiannaki
        form = MembersSortForm({'sort_by': sorting})
835 801be7a3 Sofia Papagiannaki
        if form.is_valid():
836 801be7a3 Sofia Papagiannaki
            sorting = form.cleaned_data.get('sort_by')
837 801be7a3 Sofia Papagiannaki
         
838 661c4479 Sofia Papagiannaki
    extra_context = {'update_form': update_form,
839 661c4479 Sofia Papagiannaki
                     'addmembers_form': addmembers_form,
840 661c4479 Sofia Papagiannaki
                     'page': request.GET.get('page', 1),
841 801be7a3 Sofia Papagiannaki
                     'sorting': sorting}
842 661c4479 Sofia Papagiannaki
    for key, value in extra_context.items():
843 661c4479 Sofia Papagiannaki
        if callable(value):
844 661c4479 Sofia Papagiannaki
            c[key] = value()
845 04febd09 Olga Brani
        else:
846 661c4479 Sofia Papagiannaki
            c[key] = value
847 661c4479 Sofia Papagiannaki
    response = HttpResponse(t.render(c), mimetype=mimetype)
848 661c4479 Sofia Papagiannaki
    populate_xheaders(request, response, model, getattr(obj, obj._meta.pk.name))
849 661c4479 Sofia Papagiannaki
    return response
850 5ce3ce4f Sofia Papagiannaki
851 8e45d6fd Sofia Papagiannaki
852 5c1ad9e3 Sofia Papagiannaki
@signed_terms_required
853 5c1ad9e3 Sofia Papagiannaki
@login_required
854 95a51cdc Sofia Papagiannaki
def group_search(request, extra_context=None, **kwargs):
855 d220292f Sofia Papagiannaki
    q = request.GET.get('q')
856 04febd09 Olga Brani
    sorting = request.GET.get('sorting')
857 01ac12d5 Sofia Papagiannaki
    if request.method == 'GET':
858 d220292f Sofia Papagiannaki
        form = AstakosGroupSearchForm({'q': q} if q else None)
859 01ac12d5 Sofia Papagiannaki
    else:
860 01ac12d5 Sofia Papagiannaki
        form = AstakosGroupSearchForm(get_query(request))
861 01ac12d5 Sofia Papagiannaki
        if form.is_valid():
862 01ac12d5 Sofia Papagiannaki
            q = form.cleaned_data['q'].strip()
863 d220292f Sofia Papagiannaki
    if q:
864 789bcaf9 Sofia Papagiannaki
        queryset = AstakosGroup.objects.select_related()
865 789bcaf9 Sofia Papagiannaki
        queryset = queryset.filter(name__contains=q)
866 789bcaf9 Sofia Papagiannaki
        queryset = queryset.filter(approval_date__isnull=False)
867 789bcaf9 Sofia Papagiannaki
        queryset = queryset.extra(select={
868 789bcaf9 Sofia Papagiannaki
                'groupname': DB_REPLACE_GROUP_SCHEME,
869 789bcaf9 Sofia Papagiannaki
                'kindname': "im_groupkind.name",
870 789bcaf9 Sofia Papagiannaki
                'approved_members_num': """
871 789bcaf9 Sofia Papagiannaki
                    SELECT COUNT(*) FROM im_membership
872 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
873 789bcaf9 Sofia Papagiannaki
                    AND date_joined IS NOT NULL""",
874 789bcaf9 Sofia Papagiannaki
                'membership_approval_date': """
875 789bcaf9 Sofia Papagiannaki
                    SELECT date_joined FROM im_membership
876 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
877 789bcaf9 Sofia Papagiannaki
                    AND person_id = %s""" % request.user.id,
878 789bcaf9 Sofia Papagiannaki
                'is_member': """
879 789bcaf9 Sofia Papagiannaki
                    SELECT CASE WHEN EXISTS(
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)
883 701118f4 Sofia Papagiannaki
                    THEN 1 ELSE 0 END""" % request.user.id,
884 701118f4 Sofia Papagiannaki
                'is_owner': """
885 701118f4 Sofia Papagiannaki
                    SELECT CASE WHEN EXISTS(
886 701118f4 Sofia Papagiannaki
                    SELECT id FROM im_astakosuser_owner
887 701118f4 Sofia Papagiannaki
                    WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
888 701118f4 Sofia Papagiannaki
                    AND astakosuser_id = %s)
889 789bcaf9 Sofia Papagiannaki
                    THEN 1 ELSE 0 END""" % request.user.id})
890 04febd09 Olga Brani
        if sorting:
891 04febd09 Olga Brani
            # TODO check sorting value
892 04febd09 Olga Brani
            queryset = queryset.order_by(sorting)
893 d220292f Sofia Papagiannaki
    else:
894 d220292f Sofia Papagiannaki
        queryset = AstakosGroup.objects.none()
895 d220292f Sofia Papagiannaki
    return object_list(
896 d220292f Sofia Papagiannaki
        request,
897 d220292f Sofia Papagiannaki
        queryset,
898 d220292f Sofia Papagiannaki
        paginate_by=PAGINATE_BY,
899 d220292f Sofia Papagiannaki
        page=request.GET.get('page') or 1,
900 d220292f Sofia Papagiannaki
        template_name='im/astakosgroup_list.html',
901 d220292f Sofia Papagiannaki
        extra_context=dict(form=form,
902 d220292f Sofia Papagiannaki
                           is_search=True,
903 04febd09 Olga Brani
                           q=q,
904 04febd09 Olga Brani
                           sorting=sorting))
905 5ce3ce4f Sofia Papagiannaki
906 df67421c Sofia Papagiannaki
@signed_terms_required
907 df67421c Sofia Papagiannaki
@login_required
908 df67421c Sofia Papagiannaki
def group_all(request, extra_context=None, **kwargs):
909 789bcaf9 Sofia Papagiannaki
    q = AstakosGroup.objects.select_related()
910 789bcaf9 Sofia Papagiannaki
    q = q.filter(approval_date__isnull=False)
911 789bcaf9 Sofia Papagiannaki
    q = q.extra(select={
912 789bcaf9 Sofia Papagiannaki
                'groupname': DB_REPLACE_GROUP_SCHEME,
913 789bcaf9 Sofia Papagiannaki
                'kindname': "im_groupkind.name",
914 789bcaf9 Sofia Papagiannaki
                'approved_members_num': """
915 789bcaf9 Sofia Papagiannaki
                    SELECT COUNT(*) FROM im_membership
916 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
917 789bcaf9 Sofia Papagiannaki
                    AND date_joined IS NOT NULL""",
918 789bcaf9 Sofia Papagiannaki
                'membership_approval_date': """
919 789bcaf9 Sofia Papagiannaki
                    SELECT date_joined FROM im_membership
920 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
921 789bcaf9 Sofia Papagiannaki
                    AND person_id = %s""" % request.user.id,
922 789bcaf9 Sofia Papagiannaki
                'is_member': """
923 789bcaf9 Sofia Papagiannaki
                    SELECT CASE WHEN EXISTS(
924 789bcaf9 Sofia Papagiannaki
                    SELECT date_joined FROM im_membership
925 789bcaf9 Sofia Papagiannaki
                    WHERE group_id = im_astakosgroup.group_ptr_id
926 789bcaf9 Sofia Papagiannaki
                    AND person_id = %s)
927 789bcaf9 Sofia Papagiannaki
                    THEN 1 ELSE 0 END""" % request.user.id})
928 04febd09 Olga Brani
    sorting = request.GET.get('sorting')
929 04febd09 Olga Brani
    if sorting:
930 04febd09 Olga Brani
        # TODO check sorting value
931 04febd09 Olga Brani
        q = q.order_by(sorting)
932 df67421c Sofia Papagiannaki
    return object_list(
933 df67421c Sofia Papagiannaki
                request,
934 789bcaf9 Sofia Papagiannaki
                q,
935 d220292f Sofia Papagiannaki
                paginate_by=PAGINATE_BY,
936 d220292f Sofia Papagiannaki
                page=request.GET.get('page') or 1,
937 df67421c Sofia Papagiannaki
                template_name='im/astakosgroup_list.html',
938 df67421c Sofia Papagiannaki
                extra_context=dict(form=AstakosGroupSearchForm(),
939 04febd09 Olga Brani
                                   is_search=True,
940 04febd09 Olga Brani
                                   sorting=sorting))
941 df67421c Sofia Papagiannaki
942 01ac12d5 Sofia Papagiannaki
943 01ac12d5 Sofia Papagiannaki
@signed_terms_required
944 01ac12d5 Sofia Papagiannaki
@login_required
945 01ac12d5 Sofia Papagiannaki
def group_join(request, group_id):
946 95a51cdc Sofia Papagiannaki
    m = Membership(group_id=group_id,
947 5ce3ce4f Sofia Papagiannaki
                   person=request.user,
948 789bcaf9 Sofia Papagiannaki
                   date_requested=datetime.now())
949 95a51cdc Sofia Papagiannaki
    try:
950 95a51cdc Sofia Papagiannaki
        m.save()
951 0f4fa26d Sofia Papagiannaki
        post_save_redirect = reverse(
952 0f4fa26d Sofia Papagiannaki
            'group_detail',
953 789bcaf9 Sofia Papagiannaki
            kwargs=dict(group_id=group_id))
954 95a51cdc Sofia Papagiannaki
        return HttpResponseRedirect(post_save_redirect)
955 95a51cdc Sofia Papagiannaki
    except IntegrityError, e:
956 95a51cdc Sofia Papagiannaki
        logger.exception(e)
957 95a51cdc Sofia Papagiannaki
        msg = _('Failed to join group.')
958 95a51cdc Sofia Papagiannaki
        messages.error(request, msg)
959 95a51cdc Sofia Papagiannaki
        return group_search(request)
960 01ac12d5 Sofia Papagiannaki
961 5ce3ce4f Sofia Papagiannaki
962 01ac12d5 Sofia Papagiannaki
@signed_terms_required
963 01ac12d5 Sofia Papagiannaki
@login_required
964 01ac12d5 Sofia Papagiannaki
def group_leave(request, group_id):
965 01ac12d5 Sofia Papagiannaki
    try:
966 0f4fa26d Sofia Papagiannaki
        m = Membership.objects.select_related().get(
967 0f4fa26d Sofia Papagiannaki
            group__id=group_id,
968 032ade79 Sofia Papagiannaki
            person=request.user)
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 032ade79 Sofia Papagiannaki
            kwargs=dict(group_id=group_id)))
981 01ac12d5 Sofia Papagiannaki
982 5ce3ce4f Sofia Papagiannaki
983 1eaeb5b6 Sofia Papagiannaki
def handle_membership(func):
984 1eaeb5b6 Sofia Papagiannaki
    @wraps(func)
985 1eaeb5b6 Sofia Papagiannaki
    def wrapper(request, group_id, user_id):
986 1eaeb5b6 Sofia Papagiannaki
        try:
987 1eaeb5b6 Sofia Papagiannaki
            m = Membership.objects.select_related().get(
988 1eaeb5b6 Sofia Papagiannaki
                group__id=group_id,
989 032ade79 Sofia Papagiannaki
                person__id=user_id)
990 1eaeb5b6 Sofia Papagiannaki
        except Membership.DoesNotExist:
991 1eaeb5b6 Sofia Papagiannaki
            return HttpResponseBadRequest(_('Invalid membership.'))
992 1eaeb5b6 Sofia Papagiannaki
        else:
993 1eaeb5b6 Sofia Papagiannaki
            if request.user not in m.group.owner.all():
994 1eaeb5b6 Sofia Papagiannaki
                return HttpResponseForbidden(_('User is not a group owner.'))
995 1eaeb5b6 Sofia Papagiannaki
            func(request, m)
996 56b1281c Sofia Papagiannaki
            return group_detail(request, group_id)
997 1eaeb5b6 Sofia Papagiannaki
    return wrapper
998 01ac12d5 Sofia Papagiannaki
999 5ce3ce4f Sofia Papagiannaki
1000 01ac12d5 Sofia Papagiannaki
@signed_terms_required
1001 01ac12d5 Sofia Papagiannaki
@login_required
1002 1eaeb5b6 Sofia Papagiannaki
@handle_membership
1003 01ac12d5 Sofia Papagiannaki
def approve_member(request, membership):
1004 01ac12d5 Sofia Papagiannaki
    try:
1005 01ac12d5 Sofia Papagiannaki
        membership.approve()
1006 01ac12d5 Sofia Papagiannaki
        realname = membership.person.realname
1007 01ac12d5 Sofia Papagiannaki
        msg = _('%s has been successfully joined the group.' % realname)
1008 01ac12d5 Sofia Papagiannaki
        messages.success(request, msg)
1009 01ac12d5 Sofia Papagiannaki
    except BaseException, e:
1010 01ac12d5 Sofia Papagiannaki
        logger.exception(e)
1011 56b1281c Sofia Papagiannaki
        realname = membership.person.realname
1012 01ac12d5 Sofia Papagiannaki
        msg = _('Something went wrong during %s\'s approval.' % realname)
1013 01ac12d5 Sofia Papagiannaki
        messages.error(request, msg)
1014 5ce3ce4f Sofia Papagiannaki
1015 5ce3ce4f Sofia Papagiannaki
1016 01ac12d5 Sofia Papagiannaki
@signed_terms_required
1017 01ac12d5 Sofia Papagiannaki
@login_required
1018 1eaeb5b6 Sofia Papagiannaki
@handle_membership
1019 01ac12d5 Sofia Papagiannaki
def disapprove_member(request, membership):
1020 01ac12d5 Sofia Papagiannaki
    try:
1021 01ac12d5 Sofia Papagiannaki
        membership.disapprove()
1022 01ac12d5 Sofia Papagiannaki
        realname = membership.person.realname
1023 01ac12d5 Sofia Papagiannaki
        msg = _('%s has been successfully removed from the group.' % realname)
1024 01ac12d5 Sofia Papagiannaki
        messages.success(request, msg)
1025 01ac12d5 Sofia Papagiannaki
    except BaseException, e:
1026 01ac12d5 Sofia Papagiannaki
        logger.exception(e)
1027 01ac12d5 Sofia Papagiannaki
        msg = _('Something went wrong during %s\'s disapproval.' % realname)
1028 01ac12d5 Sofia Papagiannaki
        messages.error(request, msg)
1029 ffb1e7a8 Sofia Papagiannaki
1030 5ce3ce4f Sofia Papagiannaki
1031 ffb1e7a8 Sofia Papagiannaki
@signed_terms_required
1032 ffb1e7a8 Sofia Papagiannaki
@login_required
1033 ffb1e7a8 Sofia Papagiannaki
def resource_list(request):
1034 0f4fa26d Sofia Papagiannaki
    return render_response(
1035 0f4fa26d Sofia Papagiannaki
        template='im/astakosuserquota_list.html',
1036 dfdc64d2 Sofia Papagiannaki
        context_instance=get_context(request))
1037 5ce3ce4f Sofia Papagiannaki
1038 5ce3ce4f Sofia Papagiannaki
1039 4b7d68f0 Olga Brani
def group_create_list(request):
1040 4b7d68f0 Olga Brani
    return render_response(
1041 4b7d68f0 Olga Brani
        template='im/astakosgroup_create_list.html',
1042 032ade79 Sofia Papagiannaki
        context_instance=get_context(request),)
1043 6e029beb Sofia Papagiannaki
1044 5ce3ce4f Sofia Papagiannaki
1045 6e029beb Sofia Papagiannaki
@signed_terms_required
1046 6e029beb Sofia Papagiannaki
@login_required
1047 6e029beb Sofia Papagiannaki
def billing(request):
1048 5056da3d Olga Brani
    
1049 6e029beb Sofia Papagiannaki
    today = datetime.today()
1050 5056da3d Olga Brani
    month_last_day= calendar.monthrange(today.year, today.month)[1]
1051 5056da3d Olga Brani
    
1052 5056da3d Olga Brani
    start = request.POST.get('datefrom', None)
1053 5056da3d Olga Brani
    if start:
1054 5056da3d Olga Brani
        today = datetime.fromtimestamp(int(start))
1055 5056da3d Olga Brani
        month_last_day= calendar.monthrange(today.year, today.month)[1]
1056 5056da3d Olga Brani
    
1057 6e029beb Sofia Papagiannaki
    start = datetime(today.year, today.month, 1).strftime("%s")
1058 6e029beb Sofia Papagiannaki
    end = datetime(today.year, today.month, month_last_day).strftime("%s")
1059 4de59eac Olga Brani
    r = request_billing.apply(args=('pgerakios@grnet.gr',
1060 5ce3ce4f Sofia Papagiannaki
                                    int(start) * 1000,
1061 5056da3d Olga Brani
                                    int(end) * 1000))
1062 5056da3d Olga Brani
    data = {}
1063 5056da3d Olga Brani
    
1064 6e029beb Sofia Papagiannaki
    try:
1065 6e029beb Sofia Papagiannaki
        status, data = r.result
1066 0f225db4 Sofia Papagiannaki
        data=_clear_billing_data(data)
1067 6e029beb Sofia Papagiannaki
        if status != 200:
1068 6e029beb Sofia Papagiannaki
            messages.error(request, _('Service response status: %d' % status))
1069 6e029beb Sofia Papagiannaki
    except:
1070 6e029beb Sofia Papagiannaki
        messages.error(request, r.result)
1071 5056da3d Olga Brani
    
1072 5056da3d Olga Brani
    print type(start)
1073 5056da3d Olga Brani
    
1074 6e029beb Sofia Papagiannaki
    return render_response(
1075 6e029beb Sofia Papagiannaki
        template='im/billing.html',
1076 6e029beb Sofia Papagiannaki
        context_instance=get_context(request),
1077 5056da3d Olga Brani
        data=data,
1078 5056da3d Olga Brani
        zerodate=datetime(month=1,year=1970, day=1),
1079 5056da3d Olga Brani
        today=today,
1080 5056da3d Olga Brani
        start=int(start),
1081 5056da3d Olga Brani
        month_last_day=month_last_day)  
1082 5056da3d Olga Brani
    
1083 0f225db4 Sofia Papagiannaki
def _clear_billing_data(data):
1084 5056da3d Olga Brani
    
1085 5056da3d Olga Brani
    # remove addcredits entries
1086 5056da3d Olga Brani
    def isnotcredit(e):
1087 5056da3d Olga Brani
        return e['serviceName'] != "addcredits"
1088 5056da3d Olga Brani
    
1089 5056da3d Olga Brani
    
1090 5056da3d Olga Brani
    
1091 5056da3d Olga Brani
    # separate services    
1092 5056da3d Olga Brani
    def servicefilter(service_name):
1093 5056da3d Olga Brani
        service = service_name
1094 5056da3d Olga Brani
        def fltr(e):
1095 5056da3d Olga Brani
            return e['serviceName'] == service
1096 5056da3d Olga Brani
        return fltr
1097 5056da3d Olga Brani
        
1098 5056da3d Olga Brani
    
1099 5056da3d Olga Brani
    data['bill_nocredits'] = filter(isnotcredit, data['bill'])
1100 5056da3d Olga Brani
    data['bill_vmtime'] = filter(servicefilter('vmtime'), data['bill'])
1101 5056da3d Olga Brani
    data['bill_diskspace'] = filter(servicefilter('diskspace'), data['bill'])
1102 4de59eac Olga Brani
    data['bill_addcredits'] = filter(servicefilter('addcredits'), data['bill'])
1103 5056da3d Olga Brani
        
1104 c3a00daf Olga Brani
    return data    
1105 54213d7a Sofia Papagiannaki
1106 3bcad004 Sofia Papagiannaki
@signed_terms_required
1107 3bcad004 Sofia Papagiannaki
@login_required
1108 54213d7a Sofia Papagiannaki
def timeline(request):
1109 88305cf0 root
#    data = {'entity':request.user.email}
1110 2925e285 root
    timeline_body = ()
1111 2925e285 root
    timeline_header = ()
1112 88305cf0 root
#    form = TimelineForm(data)
1113 88305cf0 root
    form = TimelineForm()
1114 54213d7a Sofia Papagiannaki
    if request.method == 'POST':
1115 54213d7a Sofia Papagiannaki
        data = request.POST
1116 2925e285 root
        form = TimelineForm(data)
1117 2925e285 root
        if form.is_valid():
1118 2925e285 root
            data = form.cleaned_data
1119 2925e285 root
            timeline_header = ('entity', 'resource',
1120 2925e285 root
                               'event name', 'event date',
1121 2925e285 root
                               'incremental cost', 'total cost')
1122 2925e285 root
            timeline_body = timeline_charge(
1123 2925e285 root
                                    data['entity'],     data['resource'],
1124 2925e285 root
                                    data['start_date'], data['end_date'],
1125 2925e285 root
                                    data['details'],    data['operation'])
1126 2925e285 root
        
1127 54213d7a Sofia Papagiannaki
    return render_response(template='im/timeline.html',
1128 54213d7a Sofia Papagiannaki
                           context_instance=get_context(request),
1129 54213d7a Sofia Papagiannaki
                           form=form,
1130 c3f6cdf1 root
                           timeline_header=timeline_header,
1131 c3f6cdf1 root
                           timeline_body=timeline_body)
1132 28c06e75 root
    return data