From 7ec02f085aaebbc3c917ceb6140cc777282590c1 Mon Sep 17 00:00:00 2001 From: Elias Showk Date: Fri, 13 Apr 2018 19:30:16 +0200 Subject: [PATCH 4/4] add a new page for resource paginated logs (#14671) --- passerelle/base/models.py | 21 +++++- passerelle/base/templatetags/passerelle.py | 12 --- .../includes/resource-logs-table.html | 30 -------- .../passerelle/manage/service_log.html | 47 ++++++++++++ .../passerelle/manage/service_view.html | 7 +- passerelle/urls.py | 2 +- passerelle/views.py | 74 +++++++------------ 7 files changed, 93 insertions(+), 100 deletions(-) delete mode 100644 passerelle/templates/passerelle/includes/resource-logs-table.html create mode 100644 passerelle/templates/passerelle/manage/service_log.html diff --git a/passerelle/base/models.py b/passerelle/base/models.py index 5509e93..d631d8e 100644 --- a/passerelle/base/models.py +++ b/passerelle/base/models.py @@ -190,6 +190,11 @@ class BaseResource(models.Model): return reverse('delete-connector', kwargs={'connector': self.get_connector_slug(), 'slug': self.slug}) + def get_log_url(self): + return reverse('view-connector-log', + kwargs={'connector': self.get_connector_slug(), 'slug': self.slug}) + + def get_description_fields(self): fields = [] for field in self._meta.fields: @@ -430,13 +435,24 @@ class AccessRight(models.Model): class ResourceLogManager(models.Manager): - def get_paginated_logs(self, appname, slug, page, order_by=None, page_size=None): + def get_paginated_logs(self, appname, slug, page, lookup_dict=None, lookup_or=None, order_by=None, page_size=None): if order_by is None: order_by = '-timestamp' if page_size is None: page_size = 10 - qs = self.filter(appname=appname, slug=slug).order_by(order_by) + if lookup_dict: + q_list = [Q(key=value) for key, value in lookup_dict.items()] + lookups = q_list.pop() + for q_item in q_list: + if lookup_or is None: + lookups &= q_item + else: + lookups |= q_item + qs = self.filter(lookups, appname=appname, slug=slug) + else: + qs = self.filter(appname=appname, slug=slug) + qs.order_by(order_by) paginator = Paginator(qs, page_size) try: logrecords = paginator.page(page) @@ -471,6 +487,7 @@ class ResourceLog(models.Model): def __unicode__(self): return '%s %s %s %s' % (self.timestamp, self.levelno, self.appname, self.slug) + STATUS_CHOICES = ( ('unknown', _('Unknown')), ('up', _('Up')), diff --git a/passerelle/base/templatetags/passerelle.py b/passerelle/base/templatetags/passerelle.py index 039c4c9..424a72c 100644 --- a/passerelle/base/templatetags/passerelle.py +++ b/passerelle/base/templatetags/passerelle.py @@ -22,18 +22,6 @@ def access_rights_table(context, resource, permission): return context -@register.inclusion_tag('passerelle/includes/resource-logs-table.html', takes_context=True) -def resource_logs_table(context, resource): - request = context.get('request') - page = request.GET.get('page', 1) - - connector = resource.get_connector_slug() - context['connector'] = connector - context['slug'] = resource.slug - context['logrecords'] = ResourceLog.objects.get_paginated_logs(connector, resource.slug, page) - return context - - @register.filter def can_edit(obj, user): return user.has_perm(get_permission_codename('change', obj._meta), obj=obj) diff --git a/passerelle/templates/passerelle/includes/resource-logs-table.html b/passerelle/templates/passerelle/includes/resource-logs-table.html deleted file mode 100644 index b618174..0000000 --- a/passerelle/templates/passerelle/includes/resource-logs-table.html +++ /dev/null @@ -1,30 +0,0 @@ -{% load i18n passerelle %} -{% load tz %} - -{% block content %} -{% if logrecords %} - - - - - - - - {% for record in logrecords %} - - - - - - {% endfor %} - -
{% trans 'Timestamp' %}{% trans 'Source IP' %}{% trans 'Message' %}
{{ record.timestamp|localtime }}{{ record.sourceip|default:"-" }}{{ record.message}}
- -{% with page_obj=logrecords %} - {% include "gadjo/pagination.html" with anchor="#logs" %} -{% endwith %} - -{% else %} -

{% trans 'No records found' %}

-{% endif %} -{% endblock %} diff --git a/passerelle/templates/passerelle/manage/service_log.html b/passerelle/templates/passerelle/manage/service_log.html new file mode 100644 index 0000000..02b26d9 --- /dev/null +++ b/passerelle/templates/passerelle/manage/service_log.html @@ -0,0 +1,47 @@ +{% extends "passerelle/manage/service_view.html" %} +{% load i18n passerelle %} +{% load tz %} + +{% block breadcrumb %} +{{ block.super }} +{{ object.get_verbose_name }} +{% endblock %} + +{% block content %} +{% if perms.base.view_resourcelog %} +
+

{% trans "Logs" %}

+
+ {% block logs %} + + {% if logrecords %} + + + + + + + + {% for record in logrecords %} + + + + + + {% endfor %} + +
{% trans 'Timestamp' %}{% trans 'Source IP' %}{% trans 'Message' %}
{{ record.timestamp|localtime }}{{ record.sourceip|default:"-" }}{{ record.message}}
+ + {% with page_obj=logrecords %} + {% include "gadjo/pagination.html" with anchor="#logs" %} + {% endwith %} + + {% else %} +

{% trans 'No records found' %}

+ {% endif %} + + {% endblock %} +
+
+{% endif %} +{% endblock %} diff --git a/passerelle/templates/passerelle/manage/service_view.html b/passerelle/templates/passerelle/manage/service_view.html index e88c05f..8d78b40 100644 --- a/passerelle/templates/passerelle/manage/service_view.html +++ b/passerelle/templates/passerelle/manage/service_view.html @@ -87,12 +87,7 @@ {% if perms.base.view_resourcelog %}
-

{% trans "Logs" %}

-
- {% block logs %} - {% resource_logs_table resource=object %} - {% endblock %} -
+

{% trans "Logs" %}

{% endif %} diff --git a/passerelle/urls.py b/passerelle/urls.py index a60bdd9..c08d1bb 100644 --- a/passerelle/urls.py +++ b/passerelle/urls.py @@ -79,7 +79,7 @@ urlpatterns += [ urlpatterns += [ url(r'^(?P[\w,-]+)/(?P[\w,-]+)/$', GenericConnectorView.as_view(), name='view-connector'), - url(r'^(?P[\w,-]+)/(?P[\w,-]+)/logs.json$', + url(r'^(?P[\w,-]+)/(?P[\w,-]+)/logs$', GenericConnectorLogView.as_view(), name='view-connector-log'), url(r'^(?P[\w,-]+)/(?P[\w,-]+)/(?P[\w,-]+)(?:/(?P.*))?$', GenericEndpointView.as_view(), name='generic-endpoint') diff --git a/passerelle/views.py b/passerelle/views.py index c58f6ce..b86c2a7 100644 --- a/passerelle/views.py +++ b/passerelle/views.py @@ -8,7 +8,7 @@ from django.conf.urls import url from django.core.exceptions import PermissionDenied from django.contrib.auth import logout as auth_logout from django.contrib.auth import views as auth_views -from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseRedirect, Http404 +from django.http import HttpResponse, HttpResponseRedirect, Http404 from django.views.decorators.csrf import csrf_exempt from django.views.generic import (RedirectView, View, TemplateView, CreateView, DeleteView, UpdateView, DetailView) @@ -16,23 +16,19 @@ from django.views.generic.detail import SingleObjectMixin from django.conf import settings from django.shortcuts import resolve_url from django.core.urlresolvers import reverse -from django.core.paginator import EmptyPage, PageNotAnInteger from django.utils.translation import ugettext_lazy as _ from django.utils.encoding import force_text -from django.utils.timezone import make_aware from django.forms.models import modelform_factory from django.forms.widgets import ClearableFileInput +from .base.models import BaseResource, ResourceLog +from .utils import to_json, is_authorized +from .forms import GenericConnectorForm if 'mellon' in settings.INSTALLED_APPS: from mellon.utils import get_idps else: get_idps = lambda: [] -from passerelle.base.models import BaseResource, ResourceLog - -from .utils import to_json, response_for_json, is_authorized -from .forms import GenericConnectorForm - def get_all_apps(): return [x for x in apps.get_models() if issubclass(x, BaseResource) and \ @@ -141,47 +137,27 @@ class GenericConnectorView(GenericConnectorMixin, DetailView): template_names.append('passerelle/manage/service_view.html') return template_names -class GenericConnectorLogView(GenericConnectorMixin, View): - - content_type = 'application/json' - epoch = make_aware(datetime(1970,1,1)) - - def totimestamp(self, datetime_obj): - td = datetime_obj - self.epoch - # return td.total_seconds() - return int((td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**3) - - def resource_logs_table(self, request, *args, **kwargs): - if 'slug' not in kwargs: - raise HttpResponseBadRequest('URL must specify a slug value') - if 'connector' not in kwargs: - raise HttpResponseBadRequest('URL must specify a connector value') - page = request.GET.get('page', 1) - return ResourceLog.objects.get_paginated_logs(kwargs['connector'], kwargs['slug'], page) - - def get(self, request, *args, **kwargs): - page_obj = self.resource_logs_table(request, *args, **kwargs) - # no previous or next is representezd a None value - try: - previous_page_number = page_obj.previous_page_number() - except (EmptyPage,): - previous_page_number = None - try: - next_page_number = page_obj.next_page_number() - except (EmptyPage,): - next_page_number = None - return response_for_json(request, dict([ - ('count', page_obj.paginator.count), - ('page_range', list(page_obj.paginator.page_range)), - ('number', page_obj.number), - ('next_page_number', next_page_number), - ('previous_page_number', previous_page_number), - ('logs', [dict([('message', log.message), - ('timestamp', self.totimestamp(log.timestamp)), - ('level', log.level), - ('extra', log.extra), - ('sourceip', log.sourceip)]) for log in page_obj]) - ])) +class GenericConnectorLogView(GenericConnectorMixin, DetailView): + + template_name = 'passerelle/manage/service_log.html' + + def query_resource_log_paginator(self, connector, slug, **kwargs): + page = kwargs.get('page', 1) + return ResourceLog.objects.get_paginated_logs(connector, slug, page, + lookup_dict=kwargs.get('lookups'), lookup_or=kwargs.get('lookup_or'), + order_by=kwargs.get('order_by'), page_size=kwargs.get('page_size')) + + def get_context_data(self, object, **kwargs): + # request = context.get('request') + connector = object.get_connector_slug() + page_obj = self.query_resource_log_paginator(connector, object.slug, **kwargs) + return { + 'view': self, + 'object': object, + 'connector': connector, + 'slug': object.slug, + 'logrecords': page_obj + } class GenericCreateConnectorView(GenericConnectorMixin, CreateView): -- 2.17.0