322 lines
8.8 KiB
Python
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
|