198 lines
6.3 KiB
Python
198 lines
6.3 KiB
Python
from django.contrib.admin.views.decorators import staff_member_required
|
|
from django.shortcuts import redirect, render, 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 LogSource, LogEntry
|
|
from .forms import SearchForm
|
|
from utils import is_link_legit
|
|
import datetime
|
|
|
|
|
|
def chat_view(request):
|
|
ctx = {
|
|
"debug": settings.DEBUG,
|
|
"bosh_url": settings.KHAGANAT_XMPP_BOSH_URL,
|
|
"jid": settings.KHAGANAT_XMPP_JID,
|
|
"rooms": settings.KHAGANAT_XMPP_ROOMS,
|
|
"websocket_url": settings.KHAGANAT_XMPP_WEBSOCKET_URL,
|
|
}
|
|
return render(request, "chat/chat_conversejs.html", ctx)
|
|
|
|
|
|
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(login_url="login")
|
|
def switch_log_source(request, pk):
|
|
return _switch_hidden(request, LogSource, pk)
|
|
|
|
|
|
@staff_member_required(login_url="login")
|
|
def switch_log_entry(request, pk):
|
|
return _switch_hidden(request, LogEntry, pk)
|
|
|
|
|
|
def log_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 LogEntriesView(generic.ListView):
|
|
template_name = "chat/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 = LogEntry.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 LogSource.objects.get(slug=self.kwargs["source"])
|
|
|
|
def get_sources(self):
|
|
"""Return available sources."""
|
|
now, start_date, end_date = _get_dates()
|
|
qs = LogEntry.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 LogEntry.objects.none()
|
|
src = self.get_source()
|
|
if src is None:
|
|
return LogEntry.objects.none()
|
|
if src.hidden and not is_staff:
|
|
return LogEntry.objects.none()
|
|
qs = (
|
|
LogEntry.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")
|