From 6ab48bfd60402649d1415e3f54502f27432cb986 Mon Sep 17 00:00:00 2001 From: Elias Showk Date: Tue, 17 Apr 2018 11:07:43 +0200 Subject: [PATCH] add date and time filters for resource logs (#14671) --- passerelle/base/forms.py | 40 ++++++++ passerelle/base/templatetags/passerelle.py | 91 +++++++++++++++++-- .../includes/resource-logs-table.html | 11 ++- passerelle/views.py | 3 + 4 files changed, 132 insertions(+), 13 deletions(-) diff --git a/passerelle/base/forms.py b/passerelle/base/forms.py index 6621a90..590a09f 100644 --- a/passerelle/base/forms.py +++ b/passerelle/base/forms.py @@ -1,3 +1,5 @@ +from datetime import datetime, time + from django import forms from .models import ApiUser, AccessRight @@ -17,3 +19,41 @@ class AccessRightForm(forms.ModelForm): 'resource_type': forms.HiddenInput(), 'resource_pk': forms.HiddenInput(), } + + +class CustomDateInput(forms.DateInput): + input_type = 'date' + + +class CustomTimeInput(forms.TimeInput): + input_type = 'time' + + +class LogFilterForm(forms.Form): + date__gte = forms.DateField(required=False, widget=CustomDateInput) + time__gte = forms.TimeField(required=False, widget=CustomTimeInput, initial=time(0, 0)) + date__lte = forms.DateField(required=False, widget=CustomDateInput) + time__lte = forms.TimeField(required=False, widget=CustomTimeInput, initial=time(0, 0)) + order_by = forms.ChoiceField(required=False, + choices=(('timestamp', 'timestamp'), ('-timestamp', '-timestamp')), + initial=('-timestamp', '-timestamp')) + page = forms.IntegerField(required=False, initial=1, min_value=1) + page_size = forms.IntegerField(required=False, initial=10, min_value=1, max_value=1000) + + def prepare_query(self): + '''Transform input to datetime lte and gte dictionnary + ''' + query_filter = {} + if self.cleaned_data.get('date__gte'): + time__gte = self.cleaned_data['time__gte'] or time(0,0) + query_filter.update({ + 'timestamp__gte': datetime.combine(self.cleaned_data.get('date__gte'), time__gte)}) + if self.cleaned_data.get('date__lte'): + time__lte = self.cleaned_data['time__lte'] or time(0,0) + query_filter.update({ + 'timestamp__lte': datetime.combine(self.cleaned_data.get('date__lte'), time__lte)}) + return query_filter, { + 'page': self.cleaned_data['page'], + 'page_size': self.cleaned_data['page_size'], + 'order_by': self.cleaned_data['order_by'] + } diff --git a/passerelle/base/templatetags/passerelle.py b/passerelle/base/templatetags/passerelle.py index 2e51b37..08b341d 100644 --- a/passerelle/base/templatetags/passerelle.py +++ b/passerelle/base/templatetags/passerelle.py @@ -1,12 +1,17 @@ from __future__ import absolute_import +import urllib from django import template +from django.core.urlresolvers import reverse from django.contrib.contenttypes.models import ContentType from django.contrib.auth import get_permission_codename from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger +from django.utils.dateparse import parse_datetime +from django.db.models import Q from passerelle.utils import get_trusted_services from ..models import AccessRight, ResourceLog +from ..forms import LogFilterForm register = template.Library() @@ -22,26 +27,96 @@ def access_rights_table(context, resource, permission): context['trusted_services'] = get_trusted_services() return context +def get_resource_log_query(request): + query_params = { + 'page': 1, + 'page_size': 10, + 'order_by': '-timestamp' + } + query_filter = {} + get = request.GET.dict() + # Add search parameters from request.GET + for param in ['page', 'order_by', 'page_size']: + try: + query_params[param] = get.pop(param) + except KeyError: + continue + # Add query filters from request.GET + for key, value in get.items(): + if key.startswith('timestamp'): + datetime_obj = parse_datetime(value) + if datetime_obj: + query_filter[key] = datetime_obj + + return query_filter, query_params + + +def post_resource_log_query(logfilterform): + '''Add search parameters from From''' + query_params = {} + query_filter = {} + if logfilterform.is_valid(): + query_filter, query_params = logfilterform.prepare_query() + return query_filter, query_params + @register.inclusion_tag('passerelle/includes/resource-logs-table.html', takes_context=True) def resource_logs_table(context, resource): + '''Logs table with customizable pagination and timestamp filters + ''' request = context.get('request') - page = request.GET.get('page', 1) - connector = resource.get_connector_slug() - context['connector'] = connector - context['slug'] = resource.slug - qs = ResourceLog.objects.filter(appname=connector, slug=resource.slug).order_by('-timestamp') + # defaults params + query_params = { + 'page': 1, + 'page_size': 10, + 'order_by': '-timestamp' + } + query_filter = {} + # Add search parameters from request query + if request.method == 'GET': + query_filter, query_params = get_resource_log_query(request) + # GET params initialize the Form data + date__gte, time__gte, date__lte, time__lte = False, False, False, False + if query_filter.get('timestamp__gte'): + date__gte = query_filter['timestamp__gte'].date().isoformat() + time__gte = query_filter['timestamp__gte'].time() + if query_filter.get('timestamp__lte'): + date__lte = query_filter['timestamp__lte'].date() + time__lte = query_filter['timestamp__lte'].time().isoformat() + + logfilterform = LogFilterForm(data=dict({ + 'date__gte': date__gte or None, + 'time__gte': time__gte or None, + 'date__lte': date__lte or None, + 'time__lte': time__lte or None + }, **query_params)) + else: + logfilterform = LogFilterForm(data=request.POST) + query_filter, query_params = post_resource_log_query(logfilterform) + + if len(query_filter.keys()): + qs = ResourceLog.objects.filter(Q(**query_filter)) + qs = qs.filter(appname=connector, slug=resource.slug) + else: + qs = ResourceLog.objects.filter(appname=connector, slug=resource.slug) - paginator = Paginator(qs, 10) + qs = qs.order_by(query_params['order_by']) + paginator = Paginator(qs, int(query_params['page_size'])) try: - logrecords = paginator.page(page) + logrecords = paginator.page(query_params['page']) except PageNotAnInteger: logrecords = paginator.page(1) except (EmptyPage,): logrecords = paginator.page(paginator.num_pages) - context['logrecords'] = logrecords + context.update({ + 'logfilterform': logfilterform, + 'query_filter': query_filter, + 'query_params': query_params, + 'logrecords': logrecords, + 'permalink': reverse('view-connector', args=(connector, resource.slug)) + '?' + urllib.urlencode(dict(query_filter, **query_params)) + }) return context diff --git a/passerelle/templates/passerelle/includes/resource-logs-table.html b/passerelle/templates/passerelle/includes/resource-logs-table.html index b618174..23ef4f8 100644 --- a/passerelle/templates/passerelle/includes/resource-logs-table.html +++ b/passerelle/templates/passerelle/includes/resource-logs-table.html @@ -2,6 +2,11 @@ {% load tz %} {% block content %} +
+ {% csrf_token %} + {{ logfilterform }} + +
{% if logrecords %} @@ -19,12 +24,8 @@ {% endfor %}
- -{% with page_obj=logrecords %} - {% include "gadjo/pagination.html" with anchor="#logs" %} -{% endwith %} - {% else %}

{% trans 'No records found' %}

{% endif %} +{% trans "Link to the results" %} {% endblock %} diff --git a/passerelle/views.py b/passerelle/views.py index dcadcce..4cfe7a6 100644 --- a/passerelle/views.py +++ b/passerelle/views.py @@ -137,6 +137,9 @@ class GenericConnectorView(GenericConnectorMixin, DetailView): template_names.append('passerelle/manage/service_view.html') return template_names + def post(self, request, *args, **kwargs): + return self.get(request, *args, **kwargs) + class GenericCreateConnectorView(GenericConnectorMixin, CreateView): template_name = 'passerelle/manage/service_form.html' -- 2.17.0