Files
fet2020/fet2020/posts/views.py
2023-11-20 21:26:14 +00:00

322 lines
8.8 KiB
Python

import logging
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import Http404, HttpResponse
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils import timezone
from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView
from authentications.decorators import authenticated_user
from documents.etherpadlib import add_ep_cookie
from fet2020.utils import add_log_action
from members.models import Member
from .forms import (
EventUpdateForm,
FetMeetingCreateForm,
FetMeetingUpdateForm,
NewsUpdateForm,
PostSearchForm,
)
from .models import Event, FetMeeting, FileUpload, Post
from .utils import render_to_pdf
logger = logging.getLogger(__name__)
def index(request):
posts = None
public_only = not request.user.is_authenticated
if request.method == "POST":
form = PostSearchForm(request.POST)
if form.is_valid():
posts = Post.objects.date_filtered_list(
public_only,
form.cleaned_data["year"],
form.cleaned_data["month"],
form.cleaned_data["fet_meeting_only"],
)
else:
last_year = Post.objects.get_queryset().first()
if last_year:
last_post_year = last_year.date.year
now_year = timezone.now().year
# if the last post is a year old or more, then set year to it
if last_post_year < now_year:
year = last_post_year
else:
year = now_year
else:
year = None
data = {
"year": year,
}
form = PostSearchForm(data)
posts = Post.objects.date_filtered_list(public_only, data["year"])
context = {
"formset": form,
"posts": posts,
}
return render(request, "posts/index.html", context)
def calendar(request):
"""
ICS-calendar for outlook, google calender,...
"""
# publish all events with status 'PUBLIC' and 'ONLY_INTERN' independent of authenticated user
events = Event.all_events.published_all(True)
context = {
"events": events,
}
return render(
request, "posts/fet_calendar.ics", context, content_type="text/calendar"
)
def tags(request, tag=""):
public_only = not request.user.is_authenticated
posts = Post.objects.published(public_only).filter(tags__name=tag)
context = {
"posts": posts,
"tag": tag,
}
return render(request, "posts/tag.html", context)
class PostDetailView(DetailView):
model = Post
def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs)
# check if etherpad server works
if self.object.agenda_link or self.object.protocol_link:
try:
response = add_ep_cookie(request, response)
except Exception as e:
logger.info("Etherpad Server doesn't work. Error: %s", e)
return response
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# files
files = FileUpload.objects.filter(post=self.object)
# author
author = None
author_image = None
post_author = Member.all_members.filter(username=self.object.author).first()
if post_author:
author = post_author
author_image = post_author.avatar_url
related_posts = self.object.tags.similar_objects()
# list of non 'is_hidden' posts for related_posts
for obj in related_posts:
if not obj.published:
related_posts.remove(obj)
context = {
"post": self.object,
"files": files,
"author": author,
"author_image": author_image,
"next": self.post_next(),
"prev": self.post_prev(),
"related_posts": related_posts[:4],
}
return context
def get_queryset(self):
self.public_only = not self.request.user.is_authenticated
return Post.objects.published(self.public_only)
def get_template_names(self):
template_name = "posts/news/detail.html"
if self.object.post_type == "E":
template_name = "posts/event/detail.html"
elif self.object.post_type == "F":
template_name = "posts/fetmeeting/detail.html"
return template_name
def post_prev(self):
"""
Helper function for getting previous post
"""
posts = Post.objects.date_sorted_list(self.public_only).filter(
post_type=self.object.post_type
)
qs = posts.filter(date__lt=self.object.date)
if not qs:
qs = posts[:1]
return qs.first().slug
def post_next(self):
"""
Helper function for getting next post
"""
posts = (
Post.objects.date_sorted_list(self.public_only)
.filter(post_type=self.object.post_type)
.reverse()
)
qs = posts.filter(date__gt=self.object.date)
if not qs:
qs = posts[:1]
return qs.first().slug
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
def form_valid(self, form):
model = "news"
if self.object.post_type == "E":
model = "event"
elif self.object.post_type == "F":
model = "fetmeeting"
add_log_action(self.request, form, "posts", model, False)
return super().form_valid(form)
def get_form_class(self):
form_class = NewsUpdateForm
if self.object.post_type == "E":
form_class = EventUpdateForm
elif self.object.post_type == "F":
form_class = FetMeetingUpdateForm
return form_class
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
try:
q = kwargs["data"]
_mutable = q._mutable
q._mutable = True
event_start_0 = q.pop("event_start_0")[0]
event_start_1 = q.pop("event_start_1")[0]
q.update({"event_start": f"{event_start_0} {event_start_1}"})
event_end_0 = q.pop("event_end_0")[0]
event_end_1 = q.pop("event_end_1")[0]
q.update({"event_end": f"{event_end_0} {event_end_1}"})
q._mutable = _mutable
except Exception:
pass
return kwargs
def get_template_names(self):
template_name = "posts/news/update.html"
if self.object.post_type == "E":
template_name = "posts/event/update.html"
elif self.object.post_type == "F":
template_name = "posts/fetmeeting/update.html"
return template_name
class FetMeetingCreateView(LoginRequiredMixin, CreateView):
model = FetMeeting
template_name = "posts/fetmeeting/create.html"
form_class = FetMeetingCreateForm
def form_valid(self, form):
form.instance.author = self.request.user
add_log_action(self.request, form, "posts", "fetmeeting", True)
obj = form.save(commit=False)
obj.tags.set(["fachschaft"])
obj.save()
return super().form_valid(form)
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
try:
q = kwargs["data"]
_mutable = q._mutable
q._mutable = True
event_start_0 = q.pop("event_start_0")[0]
event_start_1 = q.pop("event_start_1")[0]
q.update({"event_start": f"{event_start_0} {event_start_1}"})
event_end_0 = q.pop("event_end_0")[0]
event_end_1 = q.pop("event_end_1")[0]
q.update({"event_end": f"{event_end_0} {event_end_1}"})
q._mutable = _mutable
except Exception:
pass
return kwargs
def show_pdf_agenda(request, id):
post = Post.objects.published(True).get(slug=id)
html = post.agenda_html
return show_pdf(request, html, post.slug + "-agenda")
@authenticated_user
def show_pdf_protocol(request, id):
post = Post.objects.published(True).get(slug=id)
html = post.protocol_html
return show_pdf(request, html, post.slug + "-protokoll")
def show_pdf(request, html, filename):
rendered = render_to_string(
settings.BASE_DIR + "/templates/posts/pdf/template.html"
)
# get body-content from pdf template
rendered = rendered.split("<html>")[1]
rendered = rendered.split("<body>")[0]
# set body-content in html
idx = html.index("<body>")
html = html[:idx] + rendered + html[idx:]
pdf = render_to_pdf(html)
if not pdf:
raise Http404("can't create pdf file")
response = HttpResponse(pdf, content_type="application/pdf")
content = "inline; filename=%s" % filename
response["Content-Disposition"] = content
return response