khaganat-web/chat/views.py

199 lines
6.3 KiB
Python
Raw Permalink Normal View History

from django.contrib.admin.views.decorators import staff_member_required
2019-07-23 13:16:03 +00:00
from django.shortcuts import redirect, render, get_object_or_404
2018-01-27 17:58:36 +00:00
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
2019-07-23 13:16:03 +00:00
from .models import LogSource, LogEntry
from .forms import SearchForm
from utils import is_link_legit
2018-01-27 17:58:36 +00:00
import datetime
2018-01-27 22:12:09 +00:00
2019-07-23 13:16:03 +00:00
def chat_view(request):
ctx = {
2019-07-24 17:07:41 +00:00
"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,
2019-07-23 13:16:03 +00:00
}
2019-07-24 17:07:41 +00:00
return render(request, "chat/chat_conversejs.html", ctx)
2019-07-23 13:16:03 +00:00
def _get_dates():
now = datetime.date.today()
2019-07-24 17:07:41 +00:00
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()
2019-07-24 17:07:41 +00:00
next_page = request.GET.get("next", "/")
if not is_link_legit(next_page):
2019-07-24 17:07:41 +00:00
next_page = reverse("log_index")
return redirect(next_page)
@staff_member_required(login_url="login")
2019-07-23 13:16:03 +00:00
def switch_log_source(request, pk):
return _switch_hidden(request, LogSource, pk)
@staff_member_required(login_url="login")
2019-07-23 13:16:03 +00:00
def switch_log_entry(request, pk):
return _switch_hidden(request, LogEntry, pk)
2019-07-23 13:16:03 +00:00
def log_search_view(request):
2019-07-24 17:07:41 +00:00
if request.method == "POST":
form = SearchForm(request.POST)
if form.is_valid():
2019-07-24 17:07:41 +00:00
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.")
2019-07-23 13:16:03 +00:00
class LogEntriesView(generic.ListView):
2019-07-24 17:07:41 +00:00
template_name = "chat/entries.html"
context_object_name = "entries"
filter_nsfw = False
2018-01-27 17:58:36 +00:00
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.
"""
2019-07-24 17:07:41 +00:00
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(
2019-07-24 17:07:41 +00:00
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 []
2018-11-08 19:11:14 +00:00
nb_max = settings.KHAGANAT_LOGS_MAX_DAYS
nb_max -= settings.KHAGANAT_LOGS_MIN_DAYS
2019-07-24 17:07:41 +00:00
lst = LogEntry.objects.filter(source=source)
if not self.request.user.is_staff:
2019-07-24 17:07:41 +00:00
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."""
2019-07-24 17:07:41 +00:00
if self.kwargs.get("source") is None:
return None
2019-07-24 17:07:41 +00:00
return LogSource.objects.get(slug=self.kwargs["source"])
def get_sources(self):
"""Return available sources."""
now, start_date, end_date = _get_dates()
2019-07-23 13:16:03 +00:00
qs = LogEntry.objects.all()
if not self.request.user.is_staff:
qs = qs.filter(
hidden=False,
source__hidden=False,
2019-07-24 17:07:41 +00:00
created__range=(start_date, end_date),
)
qs = qs.values(
2019-07-24 17:07:41 +00:00
"source", "source__name", "source__slug", "source__id", "source__hidden"
).annotate(nb=Count("id"))
2018-01-27 22:12:09 +00:00
out = []
2018-01-27 22:12:09 +00:00
for src in qs:
2019-07-24 17:07:41 +00:00
dts = self.get_dates(src["source"])
src["first_date"] = dts[0] if dts else None
2018-01-27 17:58:36 +00:00
out.append(src)
2018-01-27 22:12:09 +00:00
2018-01-27 17:58:36 +00:00
return out
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
2019-07-24 17:07:41 +00:00
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()
2018-01-27 17:58:36 +00:00
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
2018-01-27 17:58:36 +00:00
now = datetime.date.today()
2019-07-24 17:07:41 +00:00
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:
2019-07-23 13:16:03 +00:00
return LogEntry.objects.none()
src = self.get_source()
if src is None:
2019-07-23 13:16:03 +00:00
return LogEntry.objects.none()
if src.hidden and not is_staff:
2019-07-23 13:16:03 +00:00
return LogEntry.objects.none()
2019-07-24 17:07:41 +00:00
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)
2019-07-24 17:07:41 +00:00
return qs.order_by("created")