Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views.py @ 5cb31e51

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

141 890b0eaf Sofia Papagiannaki
    **Arguments**
142 176023aa Kostas Papadimitriou

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

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

151 890b0eaf Sofia Papagiannaki
    ``extra_context``
152 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
153 176023aa Kostas Papadimitriou

154 890b0eaf Sofia Papagiannaki
    **Template:**
155 176023aa Kostas Papadimitriou

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

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

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

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

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

183 890b0eaf Sofia Papagiannaki
    **Arguments**
184 176023aa Kostas Papadimitriou

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

189 890b0eaf Sofia Papagiannaki
    ``extra_context``
190 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
191 176023aa Kostas Papadimitriou

192 890b0eaf Sofia Papagiannaki
    **Template:**
193 176023aa Kostas Papadimitriou

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

196 890b0eaf Sofia Papagiannaki
    **Settings:**
197 176023aa Kostas Papadimitriou

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

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

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

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

256 890b0eaf Sofia Papagiannaki
    **Arguments**
257 176023aa Kostas Papadimitriou

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

262 890b0eaf Sofia Papagiannaki
    ``extra_context``
263 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
264 176023aa Kostas Papadimitriou

265 890b0eaf Sofia Papagiannaki
    **Template:**
266 176023aa Kostas Papadimitriou

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

269 92defad4 Sofia Papagiannaki
    **Settings:**
270 176023aa Kostas Papadimitriou

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

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

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

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

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

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

323 890b0eaf Sofia Papagiannaki
    **Arguments**
324 5ce3ce4f Sofia Papagiannaki

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

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

333 890b0eaf Sofia Papagiannaki
    ``extra_context``
334 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
335 176023aa Kostas Papadimitriou

336 890b0eaf Sofia Papagiannaki
    **Template:**
337 5ce3ce4f Sofia Papagiannaki

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

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

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

401 890b0eaf Sofia Papagiannaki
    **Arguments**
402 176023aa Kostas Papadimitriou

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

407 890b0eaf Sofia Papagiannaki
    ``extra_context``
408 890b0eaf Sofia Papagiannaki
        An dictionary of variables to add to the template context.
409 176023aa Kostas Papadimitriou

410 890b0eaf Sofia Papagiannaki
    **Template:**
411 176023aa Kostas Papadimitriou

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

414 890b0eaf Sofia Papagiannaki
    **Settings:**
415 176023aa Kostas Papadimitriou

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

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