1
0
clubhaus-schornbach/clubhaus/homepage/views.py

102 lines
3.7 KiB
Python

import django.utils.timezone
from django.core.cache import cache
from django.http import HttpRequest, HttpResponseRedirect
from django.shortcuts import render
from django.urls import reverse
import clubhaus.settings as django_settings
from .exceptions import RateLimitHit, ProxyUsageDetected
from .models import Tobacco, ClubhausEvent, EventDate, EventDateVote, VotingUser, Setting
def bad_request(request, exception, template_name="homepage/400.html"):
return render(request, template_name, context={"exception": exception}, status=400)
def index(request: HttpRequest) -> django.http.HttpResponse:
settings = Setting.objects.filter(active=True).first()
return render(request, 'homepage/index.html', {'settings': settings})
def impressum(request: HttpRequest) -> django.http.HttpResponse:
return render(request, 'homepage/impressum.html')
def cookies(request: HttpRequest) -> django.http.HttpResponse:
return render(request, 'homepage/cookies.html')
def tobacco(request: HttpRequest) -> django.http.HttpResponse:
context = {'tobaccos': Tobacco.objects.all().order_by('-in_stock', "category__name", "name")}
return render(request, 'homepage/tobacco.html', context)
def events(request: HttpRequest) -> django.http.HttpResponse:
next_events = ClubhausEvent.objects.filter(active=True).order_by('-id')
if len(next_events) == 1:
next_event = next_events[0]
dates = EventDate.objects.filter(event=next_event).order_by("date")
votes = EventDateVote.objects.filter(date__event=next_event).order_by("voter_id", "date")
unique_voters = list(set(map(lambda v: v.voter, votes)))
vote_map = {}
for voter in unique_voters:
vote_map[voter] = {date.date.isoformat(): None for date in dates}
for vote in votes:
voter = vote.voter
v_date = vote.date.date.isoformat()
if voter in vote_map and v_date in vote_map[voter]:
vote_map[voter][v_date] = vote.available
return render(request, 'homepage/events.html', {'next_event': next_event, "dates": dates, 'votes': vote_map})
else:
return render(request, 'homepage/coming-soon.html')
def voting(request: HttpRequest) -> django.http.HttpResponse:
request.session.clear_expired()
# Proxy use is forbidden
if proxy := request.META.get("HTTP_X_FORWARDED_FOR"):
raise ProxyUsageDetected(proxy)
if request.method != "POST":
return HttpResponseRedirect(reverse("events"))
# Check rate limit
ip = request.META["HTTP_X_REAL_IP"]
cache_key = f"voting_block_{ip}"
rate_cache: django.core.cache.BaseCache = cache
if ip not in rate_cache:
rate_cache.add(cache_key, 0, django_settings.IP_RATE_LIMIT_TIME)
rate_cache.incr(cache_key)
if rate_cache.get(cache_key) > django_settings.IP_RATE_LIMIT_COUNT:
raise RateLimitHit(ip)
# check params
if not request.POST["name"]:
return HttpResponseRedirect(reverse("events"))
name = request.POST["name"]
modify_key = request.POST["modifyKey"] or ""
request.session["name"] = name
request.session["modifyKey"] = modify_key
# handle delete
if request.POST["deleteClicked"] == "1":
VotingUser.objects.filter(name=name, modify_key=modify_key).delete()
return HttpResponseRedirect(reverse("events"))
# handle normal voting
user, _ = VotingUser.objects.get_or_create(name=name, modify_key=modify_key)
event_dates = EventDate.objects.filter(event__active=True).order_by("date")
for date in event_dates:
available = date.date.isoformat() in request.POST
EventDateVote.objects.update_or_create(voter=user, date=date, defaults={"available": available})
return HttpResponseRedirect(reverse("events"))