Merge branch 'dev' of https://code.grnet.gr/git/astakos into dev
[astakos] / snf-astakos-app / astakos / im / views.py
index fabcc62..c5cd73e 100644 (file)
@@ -47,7 +47,6 @@ from django.db import transaction
 from django.db.models import Q
 from django.db.utils import IntegrityError
 from django.forms.fields import URLField
-from django.db.models.fields import DateTimeField
 from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, \
     HttpResponseRedirect, HttpResponseBadRequest, Http404
 from django.shortcuts import redirect
@@ -58,7 +57,6 @@ from django.views.generic.create_update import (create_object, delete_object,
                                                 get_model_and_form_class)
 from django.views.generic.list_detail import object_list, object_detail
 from django.http import HttpResponseBadRequest
-from django.core.paginator import Paginator, InvalidPage
 from django.core.xheaders import populate_xheaders
 
 from astakos.im.models import (
@@ -71,13 +69,15 @@ from astakos.im.forms import (LoginForm, InvitationForm, ProfileForm,
                               ExtendedPasswordChangeForm, EmailChangeForm,
                               AstakosGroupCreationForm, AstakosGroupSearchForm,
                               AstakosGroupUpdateForm, AddGroupMembersForm,
-                              AstakosGroupSortForm)
+                              AstakosGroupSortForm, MembersSortForm,
+                              TimelineForm)
 from astakos.im.functions import (send_feedback, SendMailError,
                                   invite as invite_func, logout as auth_logout,
                                   activate as activate_func,
                                   switch_account_to_shibboleth,
                                   send_admin_notification,
                                   SendNotificationError)
+from astakos.im.endpoints.quotaholder import timeline_charge
 from astakos.im.settings import (
     COOKIE_NAME, COOKIE_DOMAIN, SITENAME, LOGOUT_NEXT,
     LOGGING_LEVEL, PAGINATE_BY)
@@ -371,10 +371,10 @@ def signup(request, template_name='im/signup.html', on_success='im/signup_comple
                         logger.log(LOGGING_LEVEL, msg)
                 if user and user.is_active:
                     next = request.POST.get('next', '')
-                   transaction.commit()
+                    transaction.commit()
                     return prepare_response(request, user, next=next)
                 messages.add_message(request, status, message)
-               transaction.commit()
+                transaction.commit()
                 return render_response(on_success,
                                        context_instance=get_context(request, extra_context))
             except SendMailError, e:
@@ -466,12 +466,13 @@ def logout(request, template='registration/logged_out.html', extra_context=None)
         return response
     messages.success(request, _('You have successfully logged out.'))
     context = get_context(request, extra_context)
-    response.write(loader.render_to_string(template, context_instance=context))
+    response.write(template_loader.render_to_string(template, context_instance=context))
     return response
 
 
 @transaction.commit_manually
-def activate(request, greeting_email_template_name='im/welcome_email.txt', helpdesk_email_template_name='im/helpdesk_notification.txt'):
+def activate(request, greeting_email_template_name='im/welcome_email.txt',
+             helpdesk_email_template_name='im/helpdesk_notification.txt'):
     """
     Activates the user identified by the ``auth`` request parameter, sends a welcome email
     and renews the user token.
@@ -650,7 +651,6 @@ def group_add(request, kind_name='default'):
     except:
         return HttpResponseBadRequest(_('No such group kind'))
 
-    template_loader = loader
     post_save_redirect = '/im/group/%(id)s/'
     context_processors = None
     model, form_class = get_model_and_form_class(
@@ -756,43 +756,29 @@ def group_list(request):
         else:
             d['other'].append(g)
     
-    for k, l in d.iteritems():
-        page = request.GET.get('%s_page' % k, 1)
-        sorting = globals()['%s_sorting' % k] = request.GET.get('%s_sorting' % k)
-        if sorting:
-            sort_form = AstakosGroupSortForm({'sort_by': sorting})
-            if sort_form.is_valid():
-                sort_field = q._model_fields.get(sorting)
-                default = _get_default(sort_field)
-                l.sort(key=lambda i: getattr(i, sorting) if getattr(i, sorting) else default)
-                globals()['%s_sorting' % k] = sorting
-        paginator = Paginator(l, PAGINATE_BY)
-        
-        try:
-            page_number = int(page)
-        except ValueError:
-            if page == 'last':
-                page_number = paginator.num_pages
-            else:
-                # Page is not 'last', nor can it be converted to an int.
-                raise Http404
-        try:
-            page_obj = globals()['%s_page_obj' % k] = paginator.page(page_number)
-        except InvalidPage:
-            raise Http404
+    # validate sorting
+    fields = ('own', 'other')
+    for f in fields:
+        v = globals()['%s_sorting' % f] = request.GET.get('%s_sorting' % f)
+        if v:
+            form = AstakosGroupSortForm({'sort_by': v})
+            if not form.is_valid():
+                globals()['%s_sorting' % f] = form.cleaned_data.get('sort_by')
     return object_list(request, queryset=none,
                        extra_context={'is_search':False,
-                                      'mine': own_page_obj,
-                                      'other': other_page_obj,
+                                      'mine': d['own'],
+                                      'other': d['other'],
                                       'own_sorting': own_sorting,
-                                      'other_sorting': other_sorting
+                                      'other_sorting': other_sorting,
+                                      'own_page': request.GET.get('own_page', 1),
+                                      'other_page': request.GET.get('other_page', 1)
                                       })
 
 
 @signed_terms_required
 @login_required
 def group_detail(request, group_id):
-    q = AstakosGroup.objects.filter(pk=group_id)
+    q = AstakosGroup.objects.select_related().filter(pk=group_id)
     q = q.extra(select={
         'is_member': """SELECT CASE WHEN EXISTS(
                             SELECT id FROM im_membership
@@ -800,9 +786,9 @@ def group_detail(request, group_id):
                             AND person_id = %s)
                         THEN 1 ELSE 0 END""" % request.user.id,
         'is_owner': """SELECT CASE WHEN EXISTS(
-                            SELECT id FROM im_astakosuser_owner
-                            WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
-                            AND astakosuser_id = %s)
+                        SELECT id FROM im_astakosuser_owner
+                        WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
+                        AND astakosuser_id = %s)
                         THEN 1 ELSE 0 END""" % request.user.id,
         'kindname': """SELECT name FROM im_groupkind
                        WHERE id = im_astakosgroup.kind_id"""})
@@ -812,8 +798,9 @@ def group_detail(request, group_id):
     mimetype = None
     try:
         obj = q.get()
-    except ObjectDoesNotExist:
-        raise Http404("No %s found matching the query" % (model._meta.verbose_name))
+    except AstakosGroup.DoesNotExist:
+        raise Http404("No %s found matching the query" % (
+            model._meta.verbose_name))
     
     update_form = AstakosGroupUpdateForm(instance=obj)
     addmembers_form = AddGroupMembersForm()
@@ -840,10 +827,18 @@ def group_detail(request, group_id):
     c = RequestContext(request, {
         'object': obj,
     }, context_processors)
+    
+    # validate sorting
+    sorting= request.GET.get('sorting')
+    if sorting:
+        form = MembersSortForm({'sort_by': sorting})
+        if form.is_valid():
+            sorting = form.cleaned_data.get('sort_by')
+         
     extra_context = {'update_form': update_form,
                      'addmembers_form': addmembers_form,
                      'page': request.GET.get('page', 1),
-                     'sorting': request.GET.get('sorting')}
+                     'sorting': sorting}
     for key, value in extra_context.items():
         if callable(value):
             c[key] = value()
@@ -885,6 +880,12 @@ def group_search(request, extra_context=None, **kwargs):
                     SELECT date_joined FROM im_membership
                     WHERE group_id = im_astakosgroup.group_ptr_id
                     AND person_id = %s)
+                    THEN 1 ELSE 0 END""" % request.user.id,
+                'is_owner': """
+                    SELECT CASE WHEN EXISTS(
+                    SELECT id FROM im_astakosuser_owner
+                    WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
+                    AND astakosuser_id = %s)
                     THEN 1 ELSE 0 END""" % request.user.id})
         if sorting:
             # TODO check sorting value
@@ -964,8 +965,7 @@ def group_leave(request, group_id):
     try:
         m = Membership.objects.select_related().get(
             group__id=group_id,
-            person=request.user
-        )
+            person=request.user)
     except Membership.DoesNotExist:
         return HttpResponseBadRequest(_('Invalid membership.'))
     if request.user in m.group.owner.all():
@@ -977,9 +977,7 @@ def group_leave(request, group_id):
         template_name='im/astakosgroup_list.html',
         post_delete_redirect=reverse(
             'group_detail',
-            kwargs=dict(group_id=group_id)
-        )
-    )
+            kwargs=dict(group_id=group_id)))
 
 
 def handle_membership(func):
@@ -988,20 +986,14 @@ def handle_membership(func):
         try:
             m = Membership.objects.select_related().get(
                 group__id=group_id,
-                person__id=user_id
-            )
+                person__id=user_id)
         except Membership.DoesNotExist:
             return HttpResponseBadRequest(_('Invalid membership.'))
         else:
             if request.user not in m.group.owner.all():
                 return HttpResponseForbidden(_('User is not a group owner.'))
             func(request, m)
-            return render_response(
-                template='im/astakosgroup_detail.html',
-                context_instance=get_context(request),
-                object=m.group,
-                quota=m.group.quota
-            )
+            return group_detail(request, group_id)
     return wrapper
 
 
@@ -1016,6 +1008,7 @@ def approve_member(request, membership):
         messages.success(request, msg)
     except BaseException, e:
         logger.exception(e)
+        realname = membership.person.realname
         msg = _('Something went wrong during %s\'s approval.' % realname)
         messages.error(request, msg)
 
@@ -1040,16 +1033,13 @@ def disapprove_member(request, membership):
 def resource_list(request):
     return render_response(
         template='im/astakosuserquota_list.html',
-        context_instance=get_context(request),
-        quota=request.user.quota
-    )
+        context_instance=get_context(request))
 
 
 def group_create_list(request):
     return render_response(
         template='im/astakosgroup_create_list.html',
-        context_instance=get_context(request),
-    )
+        context_instance=get_context(request),)
 
 
 @signed_terms_required
@@ -1111,12 +1101,32 @@ def _clear_billing_data(data):
     data['bill_diskspace'] = filter(servicefilter('diskspace'), data['bill'])
     data['bill_addcredits'] = filter(servicefilter('addcredits'), data['bill'])
         
-    return data
-
+    return data    
 
-def _get_default(field):
-    if isinstance(field, DateTimeField):
-        return datetime.utcfromtimestamp(0)
-    elif isinstance(field, int):
-        return 0
-    return ''
\ No newline at end of file
+@signed_terms_required
+@login_required
+def timeline(request):
+#    data = {'entity':request.user.email}
+    timeline_body = ()
+    timeline_header = ()
+#    form = TimelineForm(data)
+    form = TimelineForm()
+    if request.method == 'POST':
+        data = request.POST
+        form = TimelineForm(data)
+        if form.is_valid():
+            data = form.cleaned_data
+            timeline_header = ('entity', 'resource',
+                               'event name', 'event date',
+                               'incremental cost', 'total cost')
+            timeline_body = timeline_charge(
+                                    data['entity'],     data['resource'],
+                                    data['start_date'], data['end_date'],
+                                    data['details'],    data['operation'])
+        
+    return render_response(template='im/timeline.html',
+                           context_instance=get_context(request),
+                           form=form,
+                           timeline_header=timeline_header,
+                           timeline_body=timeline_body)
+    return data