Files
fet2020/fet2020/posts/views.py
2022-10-04 16:16:25 +00:00

283 lines
7.6 KiB
Python

import logging
from django.conf import settings
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse, Http404
from django.shortcuts import render
from django.template.loader import render_to_string
from django.utils import timezone
from django.views.generic.edit import UpdateView
from django.views.generic.detail import DetailView
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 PostSearchForm, PostUpdateForm
from .models import Event, 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)
def __get_post_object(id=None, public=True):
post = None
try:
if id.isdigit() or id is int:
post = Post.objects.published(public).get(id=int(id))
elif id != "" and id is not None:
post = Post.objects.published(public).get(slug=id)
except Exception:
logger.info("Wrong id '{}'".format(id))
raise Http404("wrong post id")
return post
def post_next(post=None, public=True):
"""
Helper function for getting next post
"""
posts = None
d = post.slug
if post:
posts = Post.objects.date_sorted_list(public).filter(post_type=post.post_type)
if posts:
for k, v in enumerate(posts):
if post.slug == v.slug:
if (k + 1) < len(posts):
d = posts[k + 1].slug
else:
d = posts[0].slug
break
return d
def post_previous(post=None, public=True):
"""
Helper function for getting previous post
"""
posts = None
d = post.slug
if post:
posts = Post.objects.date_sorted_list(public).filter(post_type=post.post_type)
if posts:
for k, v in enumerate(posts):
if post.slug == v.slug:
if k < 1:
d = posts[len(posts) - 1].slug
else:
d = posts[k - 1].slug
break
return d
class PostUpdateView(LoginRequiredMixin, UpdateView):
model = Post
def form_valid(self, form):
add_log_action(self.request, form, "posts", "post", False)
return super().form_valid(form)
def get_form_class(self):
form_class = PostUpdateForm
if self.object.post_type == "E":
form_class = PostUpdateForm
elif self.object.post_type == "F":
form_class = PostUpdateForm
return form_class
def get_template_names(self):
template_name = "posts/news_update.html"
if self.object.post_type == "E":
template_name = "posts/news_update.html"
elif self.object.post_type == "F":
template_name = "posts/news_update.html"
return template_name
class PostDetailView(DetailView):
model = Post
def get(self, request, *args, **kwargs):
response = super().get(request, *args, **kwargs)
# check if etherpad server works
if self.post.agenda_link or self.post.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)
public_only = not self.request.user.is_authenticated
self.post = self.object
# files
files = FileUpload.objects.filter(post=self.post)
# author
author = None
author_image = None
post_author = Member.all_members.filter(username=self.post.author).first()
if post_author:
author = post_author
author_image = post_author.image["avatar"].url
related_posts = self.post.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.post,
"files": files,
"author": author,
"author_image": author_image,
"next": post_next(self.post, public_only),
"previous": post_previous(self.post, public_only),
"related_posts": related_posts[:4],
}
return context
def get_queryset(self):
public_only = not self.request.user.is_authenticated
return Post.objects.published(public_only)
def get_template_names(self):
template_name = "posts/show.html"
if self.post.post_type == "E":
template_name = "posts/event_detail.html"
elif self.post.post_type == "F":
template_name = "posts/fet_meeting_detail.html"
return template_name
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
def show_pdf_agenda(request, id):
post = __get_post_object(id)
html = post.agenda_html
return show_pdf(request, html, post.slug + "-agenda")
@authenticated_user
def show_pdf_protocol(request, id):
post = __get_post_object(id)
html = post.protocol_html
return show_pdf(request, html, post.slug + "-protokoll")