194 lines
5.9 KiB
Python
194 lines
5.9 KiB
Python
from django.contrib.admin.views.decorators import staff_member_required
|
|
from django.shortcuts import redirect, get_object_or_404
|
|
from django.db.models.functions import TruncDate
|
|
from django.db.models import Count
|
|
from django.views import generic
|
|
from django.conf import settings
|
|
from django.urls import reverse
|
|
from django.http import Http404
|
|
from nsfw import views as nsfw
|
|
from .models import Source, Entry
|
|
from .forms import SearchForm
|
|
from utils import is_link_legit
|
|
import datetime
|
|
|
|
|
|
def _get_dates():
|
|
now = datetime.date.today()
|
|
start_date = now - datetime.timedelta(
|
|
days=settings.KHAGANAT_LOGS_MAX_DAYS
|
|
)
|
|
end_date = now - datetime.timedelta(
|
|
days=settings.KHAGANAT_LOGS_MIN_DAYS - 1
|
|
)
|
|
return (now, start_date, end_date)
|
|
|
|
|
|
def _switch_hidden(request, obj, pk):
|
|
e = get_object_or_404(obj, pk=pk)
|
|
e.hidden = not e.hidden
|
|
e.save()
|
|
|
|
next_page = request.GET.get('next', '/')
|
|
if not is_link_legit(next_page):
|
|
next_page = reverse('log_index')
|
|
return redirect(next_page)
|
|
|
|
|
|
@staff_member_required
|
|
def switch_source(request, pk):
|
|
return _switch_hidden(request, Source, pk)
|
|
|
|
|
|
@staff_member_required
|
|
def switch_entry(request, pk):
|
|
return _switch_hidden(request, Entry, pk)
|
|
|
|
|
|
def search_view(request):
|
|
if request.method == 'POST':
|
|
form = SearchForm(request.POST)
|
|
if form.is_valid():
|
|
date = form.cleaned_data['date']
|
|
return redirect(reverse('log_day', kwargs={
|
|
'source': form.cleaned_data['source'],
|
|
'year': date.year,
|
|
'month': date.month,
|
|
'day': date.day,
|
|
}))
|
|
raise Http404('No search parameters.')
|
|
|
|
|
|
class EntriesView(generic.ListView):
|
|
template_name = 'logs/entries.html'
|
|
context_object_name = 'entries'
|
|
filter_nsfw = False
|
|
|
|
def is_nsfw(self):
|
|
for e in self.get_queryset():
|
|
for tag in settings.KHAGANAT_NSFW_TAGS:
|
|
if tag.lower() in e.content.lower():
|
|
return True
|
|
return False
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
if self.is_nsfw():
|
|
if not nsfw.is_nsfw_allowed(request):
|
|
self.filter_nsfw = True
|
|
else:
|
|
nsfw.alert(request, request.get_full_path())
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
def get_date(self):
|
|
"""Return the date object corresponding to the URL parameters
|
|
or None if missing.
|
|
"""
|
|
has_date = all([
|
|
self.kwargs.get('year') is not None,
|
|
self.kwargs.get('month') is not None,
|
|
self.kwargs.get('day') is not None,
|
|
])
|
|
if not has_date:
|
|
return None
|
|
return datetime.date(
|
|
self.kwargs['year'],
|
|
self.kwargs['month'],
|
|
self.kwargs['day']
|
|
)
|
|
|
|
def get_dates(self, source):
|
|
"""Return a list if available dates for the current source."""
|
|
_, start_date, end_date = _get_dates()
|
|
if source is None:
|
|
return []
|
|
|
|
nb_max = settings.KHAGANAT_LOGS_MAX_DAYS
|
|
nb_max -= settings.KHAGANAT_LOGS_MIN_DAYS
|
|
lst = Entry.objects.filter(
|
|
source=source,
|
|
)
|
|
if not self.request.user.is_staff:
|
|
lst = lst.filter(
|
|
hidden=False,
|
|
created__range=(start_date, end_date)
|
|
)
|
|
lst = lst.annotate(
|
|
date=TruncDate('created')
|
|
).values('date').annotate(
|
|
nb=Count('date')
|
|
).order_by('-date')[:nb_max]
|
|
return [o['date'] for o in lst]
|
|
|
|
def get_source(self):
|
|
"""Return the current source."""
|
|
if self.kwargs.get('source') is None:
|
|
return None
|
|
return Source.objects.get(slug=self.kwargs['source'])
|
|
|
|
def get_sources(self):
|
|
"""Return available sources."""
|
|
now, start_date, end_date = _get_dates()
|
|
qs = Entry.objects.all()
|
|
|
|
if not self.request.user.is_staff:
|
|
qs = qs.filter(
|
|
hidden=False,
|
|
source__hidden=False,
|
|
created__range=(start_date, end_date)
|
|
)
|
|
qs = qs.values(
|
|
'source', 'source__name', 'source__slug',
|
|
'source__id', 'source__hidden'
|
|
).annotate(
|
|
nb=Count('id')
|
|
)
|
|
|
|
out = []
|
|
for src in qs:
|
|
dts = self.get_dates(src['source'])
|
|
src['first_date'] = dts[0] if dts else None
|
|
out.append(src)
|
|
|
|
return out
|
|
|
|
def get_context_data(self, **kwargs):
|
|
context = super().get_context_data(**kwargs)
|
|
context['form'] = SearchForm()
|
|
context['sources'] = self.get_sources()
|
|
context['current_source'] = self.get_source()
|
|
context['dates'] = self.get_dates(context['current_source'])
|
|
context['current_date'] = self.get_date()
|
|
context['filter_nsfw'] = self.filter_nsfw
|
|
context['current_url'] = self.request.get_full_path()
|
|
return context
|
|
|
|
def get_queryset(self):
|
|
"""Return the entries to be displayed."""
|
|
dt = self.get_date()
|
|
if dt is None:
|
|
return []
|
|
|
|
is_staff = self.request.user.is_staff
|
|
now = datetime.date.today()
|
|
out_of_bounds = any((
|
|
(now - dt).days > settings.KHAGANAT_LOGS_MAX_DAYS,
|
|
(now - dt).days < settings.KHAGANAT_LOGS_MIN_DAYS,
|
|
))
|
|
if out_of_bounds and not is_staff:
|
|
return Entry.objects.none()
|
|
src = self.get_source()
|
|
if src is None:
|
|
return Entry.objects.none()
|
|
if src.hidden and not is_staff:
|
|
return Entry.objects.none()
|
|
qs = Entry.objects.filter(
|
|
source=src,
|
|
created__year=dt.year
|
|
).filter(
|
|
created__month=dt.month,
|
|
).filter(
|
|
created__day=dt.day
|
|
)
|
|
if not is_staff:
|
|
qs = qs.filter(hidden=False)
|
|
return qs.order_by('created')
|