journal/views: consolidate api and html views

This commit is contained in:
Christophe Siraut 2020-09-22 11:38:18 +02:00
parent b84931938b
commit 8e5bee568a
6 changed files with 39 additions and 48 deletions

View File

@ -11,24 +11,26 @@ class EntryManager(models.Manager):
def dump(self, timestamp=None, host=None, lines=100, **kwargs):
qs = Entry.objects.all()
if host:
qs = qs.filter(host=host)
qs = qs.filter(host__in=host)
qs = qs.filter(**self.parse_options(**kwargs))
if lines:
qs = qs.order_by('-timestamp')[:int(lines)][::-1]
return qs
def parse_options(self, mode='exact', **kwargs):
def parse_options(self, **kwargs):
# todo mode='contains' require jsonb KeyTextTransform and probably annotations
options = {}
for k, v in kwargs.items():
options['data__' + k.upper() + '__%s' % mode] = v
if k.upper() == 'csrfmiddlewaretoken':
continue
options['data__' + k.upper() + '__in'] = v
return options
def hosts(self):
value = cache.get('hosts')
if value is None:
value = self.model.objects.all().values_list('host', flat=True).distinct()
cache.set('hosts', value, 6000 * random.random())
cache.set('hosts', value, 600 * random.random())
return value
def units(self):

View File

@ -1,18 +1,18 @@
{% extends "base.html" %}
{% block content %}
<h1>Logtracker</h1>
<p><a href="{% url 'home' %}">Logtracker</a></p>
<br/>
<h2>Journal entries</h2>
<b>Journal entries</b>
<ul>
<li>Recent log entries : <a href="{% url 'journal' %}?host=&lines=100">html</a> / <a href="{% url 'journal-api' %}?host=&lines=100">json</a></li>
<li><a href="{% url 'journal' %}?lines=100">Recent log entries</a> (<a href="{% url 'journal-api' %}?lines=100">api</a>)</li>
</ul>
<h2>Emails</h2>
<b>Emails</b>
<ul>
<li><a href="{% url 'mail-api' %}?host=&sender=&lines=100">Recent email entries (json)</a></li>
<li><a href="{% url 'senders' %}">Recent email senders list</a></li>
<li><a href="{% url 'senders' %}">Recent email senders list</a> (<a href="{% url 'mail-api' %}?host=&sender=&lines=100">api</a>)</li>
<li>Search email by address:
<form action="." style="display:inline;" method="post">{% csrf_token %}
<input type="text" name="address">

View File

@ -1,30 +1,13 @@
{% extends "base.html" %}
{% block content %}
<h1>Logtracker</h1>
<p><a href="{% url 'home' %}">Logtracker</a> - journal entries</p>
<div style='position:absolute;right:0;'>
<form action='.' style='display:inline;'>
<select name="host" onchange="this.form.submit()">
<option>Hosts</option>
{% for h in hosts %}
<option value="{{ h }}">{{ h }}</option>
{% endfor %}
</select>
<form action="." style="display:inline;">
{{ form.as_table }}
<input type="submit" value="Filter" />
</form>
<form action='.' style='display:inline;'>
<select name="_SYSTEMD_UNIT" onchange="this.form.submit()">
<option>Units</option>
{% for u in units %}
<option value="{{ u }}">{{ u }}</option>
{% endfor %}
</select>
</form>
</div>
<h2>Journal entries</h2>
<table>
<thead>
<tr>

View File

@ -1,25 +1,28 @@
import datetime
from functools import wraps
from django import forms
from django.contrib.auth.mixins import LoginRequiredMixin
from django.conf import settings
from django.core import serializers
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView
from django.views.generic.list import ListView
from django.views.generic.base import View, TemplateView
from django.views.generic.edit import FormView
from logtracker.journal.models import Entry
from logtracker.journal.journalstream import get_journal_entries
class APIEntriesList(LoginRequiredMixin, ListView):
class APIEntriesList(LoginRequiredMixin, View):
def get_queryset(self):
lines = self.request.GET.get('lines', 100)
host = self.request.GET.get('host', '')
return Entry.objects.dump(host=host, lines=lines)
host = self.request.GET.getlist('host')
options = {k: v for k, v in self.request.GET.lists() if k not in ('lines', 'host', 'timestamp')}
return Entry.objects.dump(host=host, lines=lines, **options)
def get(self, request, *args, **kwargs):
queryset = self.get_queryset()
@ -27,21 +30,25 @@ class APIEntriesList(LoginRequiredMixin, ListView):
return HttpResponse(response, content_type='application/json')
class EntriesList(LoginRequiredMixin, ListView):
template_name = 'journal/entry_list.html'
class EntriesForm(forms.Form):
host = forms.MultipleChoiceField(required=False, choices=[(e, e) for e in Entry.objects.hosts()])
_systemd_unit = forms.MultipleChoiceField(required=False, choices=((u, u) for u in Entry.objects.units()))
priority = forms.MultipleChoiceField(required=False, choices=[(i, i) for i in range(1, 7)])
def get_queryset(self):
lines = self.request.GET.get('lines', 100)
host = self.request.GET.get('host')
options = {k: v for k, v in self.request.GET.items() if k not in ('lines', 'host', 'timestamp')}
return Entry.objects.dump(host=host, lines=lines, **options)
@method_decorator(csrf_exempt, name='dispatch')
class EntriesList(LoginRequiredMixin, FormView):
template_name = 'journal/entry_list.html'
form_class = EntriesForm
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data['hosts'] = Entry.objects.hosts
data['units'] = Entry.objects.units
data['object_list'] = APIEntriesList.get_queryset(self)
return data
def get_initial(self):
return {k: v for k, v in self.request.GET.lists()}
class HomeView(LoginRequiredMixin, TemplateView):
template_name = 'home.html'

View File

@ -1,9 +1,8 @@
{% extends "base.html" %}
{% block content %}
<h1>Mailtracker</h1>
<p><a href="{% url 'home' %}">Logtracker</a> - recent senders</p>
<h2>Recent senders</h2>
<table>
<thead>
<tr>

View File

@ -7,7 +7,7 @@ from logtracker.mail.views import EmailsList, SendersList, MailHome
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', HomeView.as_view()),
url(r'^$', HomeView.as_view(), name='home'),
url(r'^journal/$', EntriesList.as_view(), name='journal'),
url(r'^api/journal/$', APIEntriesList.as_view(), name='journal-api'),
url(r'^api/mail/$', EmailsList.as_view(), name='mail-api'),