Projet

Général

Profil

0001-add-date-and-time-filters-for-resource-logs-14671.patch

Anonyme, 17 avril 2018 15:54

Télécharger (8,73 ko)

Voir les différences:

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(-)
passerelle/base/forms.py
1
from datetime import datetime, time
2

  
1 3
from django import forms
2 4

  
3 5
from .models import ApiUser, AccessRight
......
17 19
            'resource_type': forms.HiddenInput(),
18 20
            'resource_pk': forms.HiddenInput(),
19 21
        }
22

  
23

  
24
class CustomDateInput(forms.DateInput):
25
    input_type = 'date'
26

  
27

  
28
class CustomTimeInput(forms.TimeInput):
29
    input_type = 'time'
30

  
31

  
32
class LogFilterForm(forms.Form):
33
    date__gte = forms.DateField(required=False, widget=CustomDateInput)
34
    time__gte = forms.TimeField(required=False, widget=CustomTimeInput, initial=time(0, 0))
35
    date__lte = forms.DateField(required=False, widget=CustomDateInput)
36
    time__lte = forms.TimeField(required=False, widget=CustomTimeInput, initial=time(0, 0))
37
    order_by = forms.ChoiceField(required=False,
38
        choices=(('timestamp', 'timestamp'), ('-timestamp', '-timestamp')),
39
        initial=('-timestamp', '-timestamp'))
40
    page = forms.IntegerField(required=False, initial=1, min_value=1)
41
    page_size = forms.IntegerField(required=False, initial=10, min_value=1, max_value=1000)
42

  
43
    def prepare_query(self):
44
        '''Transform input to datetime lte and gte dictionnary
45
        '''
46
        query_filter = {}
47
        if self.cleaned_data.get('date__gte'):
48
            time__gte = self.cleaned_data['time__gte'] or time(0,0)
49
            query_filter.update({
50
                'timestamp__gte': datetime.combine(self.cleaned_data.get('date__gte'), time__gte)})
51
        if self.cleaned_data.get('date__lte'):
52
            time__lte = self.cleaned_data['time__lte'] or time(0,0)
53
            query_filter.update({
54
                'timestamp__lte': datetime.combine(self.cleaned_data.get('date__lte'), time__lte)})
55
        return query_filter, {
56
            'page': self.cleaned_data['page'],
57
            'page_size': self.cleaned_data['page_size'],
58
            'order_by': self.cleaned_data['order_by']
59
        }
passerelle/base/templatetags/passerelle.py
1 1
from __future__ import absolute_import
2
import urllib
2 3

  
3 4
from django import template
5
from django.core.urlresolvers import reverse
4 6
from django.contrib.contenttypes.models import ContentType
5 7
from django.contrib.auth import get_permission_codename
6 8
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
9
from django.utils.dateparse import parse_datetime
10
from django.db.models import Q
7 11

  
8 12
from passerelle.utils import get_trusted_services
9 13
from ..models import AccessRight, ResourceLog
14
from ..forms import LogFilterForm
10 15

  
11 16
register = template.Library()
12 17

  
......
22 27
    context['trusted_services'] = get_trusted_services()
23 28
    return context
24 29

  
30
def get_resource_log_query(request):
31
    query_params = {
32
        'page': 1,
33
        'page_size': 10,
34
        'order_by': '-timestamp'
35
    }
36
    query_filter = {}
37
    get = request.GET.dict()
38
    # Add search parameters from request.GET
39
    for param in ['page', 'order_by', 'page_size']:
40
        try:
41
            query_params[param] = get.pop(param)
42
        except KeyError:
43
            continue
44
    # Add query filters from request.GET
45
    for key, value in get.items():
46
        if key.startswith('timestamp'):
47
            datetime_obj = parse_datetime(value)
48
            if datetime_obj:
49
                query_filter[key] = datetime_obj
50

  
51
    return query_filter, query_params
52

  
53

  
54
def post_resource_log_query(logfilterform):
55
    '''Add search parameters from From'''
56
    query_params = {}
57
    query_filter = {}
58
    if logfilterform.is_valid():
59
        query_filter, query_params = logfilterform.prepare_query()
60
    return query_filter, query_params
61

  
25 62

  
26 63
@register.inclusion_tag('passerelle/includes/resource-logs-table.html', takes_context=True)
27 64
def resource_logs_table(context, resource):
65
    '''Logs table with customizable pagination and timestamp filters
66
    '''
28 67
    request = context.get('request')
29
    page = request.GET.get('page', 1)
30

  
31 68
    connector = resource.get_connector_slug()
32
    context['connector'] = connector
33
    context['slug'] = resource.slug
34
    qs = ResourceLog.objects.filter(appname=connector, slug=resource.slug).order_by('-timestamp')
69
    # defaults params
70
    query_params = {
71
        'page': 1,
72
        'page_size': 10,
73
        'order_by': '-timestamp'
74
    }
75
    query_filter = {}
76
    # Add search parameters from request query
77
    if request.method == 'GET':
78
        query_filter, query_params = get_resource_log_query(request)
79
        # GET params initialize the Form data
80
        date__gte, time__gte, date__lte, time__lte = False, False, False, False
81
        if query_filter.get('timestamp__gte'):
82
            date__gte = query_filter['timestamp__gte'].date().isoformat()
83
            time__gte = query_filter['timestamp__gte'].time()
84
        if query_filter.get('timestamp__lte'):
85
            date__lte = query_filter['timestamp__lte'].date()
86
            time__lte = query_filter['timestamp__lte'].time().isoformat()
87

  
88
        logfilterform = LogFilterForm(data=dict({
89
            'date__gte': date__gte or None,
90
            'time__gte': time__gte or None,
91
            'date__lte': date__lte or None,
92
            'time__lte': time__lte or None
93
        }, **query_params))
94
    else:
95
        logfilterform = LogFilterForm(data=request.POST)
96
        query_filter, query_params = post_resource_log_query(logfilterform)
97

  
98
    if len(query_filter.keys()):
99
        qs = ResourceLog.objects.filter(Q(**query_filter))
100
        qs = qs.filter(appname=connector, slug=resource.slug)
101
    else:
102
        qs = ResourceLog.objects.filter(appname=connector, slug=resource.slug)
35 103

  
36
    paginator = Paginator(qs, 10)
104
    qs = qs.order_by(query_params['order_by'])
105
    paginator = Paginator(qs, int(query_params['page_size']))
37 106
    try:
38
        logrecords = paginator.page(page)
107
        logrecords = paginator.page(query_params['page'])
39 108
    except PageNotAnInteger:
40 109
        logrecords = paginator.page(1)
41 110
    except (EmptyPage,):
42 111
        logrecords = paginator.page(paginator.num_pages)
43 112

  
44
    context['logrecords'] = logrecords
113
    context.update({
114
        'logfilterform': logfilterform,
115
        'query_filter': query_filter,
116
        'query_params': query_params,
117
        'logrecords': logrecords,
118
        'permalink': reverse('view-connector', args=(connector, resource.slug)) + '?' + urllib.urlencode(dict(query_filter, **query_params))
119
    })
45 120
    return context
46 121

  
47 122

  
passerelle/templates/passerelle/includes/resource-logs-table.html
2 2
{% load tz %}
3 3

  
4 4
{% block content %}
5
<form action="." method="POST" id="logfilter" style="padding:1em; border: 1px solid gray;">
6
  {% csrf_token %}
7
  {{ logfilterform }}
8
  <input type="submit" id="_submit" style="height: 3.3rem;">
9
</form>
5 10
{% if logrecords %}
6 11
<table class="main">
7 12
    <thead>
......
19 24
    {% endfor %}
20 25
    </tbody>
21 26
</table>
22

  
23
{% with page_obj=logrecords %}
24
  {% include "gadjo/pagination.html" with anchor="#logs" %}
25
{% endwith %}
26

  
27 27
{% else %}
28 28
<p>{% trans 'No records found' %}</p>
29 29
{% endif %}
30
<a href="{{ permalink }}">{% trans "Link to the results" %}</a>
30 31
{% endblock %}
passerelle/views.py
137 137
        template_names.append('passerelle/manage/service_view.html')
138 138
        return template_names
139 139

  
140
    def post(self, request, *args, **kwargs):
141
        return self.get(request, *args, **kwargs)
142

  
140 143

  
141 144
class GenericCreateConnectorView(GenericConnectorMixin, CreateView):
142 145
    template_name = 'passerelle/manage/service_form.html'
143
-