diff --git a/fet2020/fet2020/settings.py b/fet2020/fet2020/settings.py index 8eed5b81..1958da8f 100644 --- a/fet2020/fet2020/settings.py +++ b/fet2020/fet2020/settings.py @@ -81,6 +81,7 @@ INSTALLED_APPS = [ "documents.apps.DocumentsConfig", "blackboard.apps.BlackboardConfig", "tasks.apps.TasksConfig", + "intern.apps.InternConfig", ] MIDDLEWARE = [ diff --git a/fet2020/fet2020/urls.py b/fet2020/fet2020/urls.py index 8f009383..d6014ec0 100644 --- a/fet2020/fet2020/urls.py +++ b/fet2020/fet2020/urls.py @@ -38,6 +38,7 @@ urlpatterns = [ path("member/", include(member_urlpatterns), name="member"), path("blackboard/", include("blackboard.urls"), name="blackboard"), path("tasks/", include("tasks.urls"), name="tasks"), + path("intern/", include("intern.urls"), name="intern"), path( "sitemap.xml", sitemap, diff --git a/fet2020/intern/__init__.py b/fet2020/intern/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/fet2020/intern/admin.py b/fet2020/intern/admin.py new file mode 100644 index 00000000..fe2b8dec --- /dev/null +++ b/fet2020/intern/admin.py @@ -0,0 +1,57 @@ +from django.contrib import admin + +from .models import TopicGroup, Topic, Documentation +from .forms import TopicGroupAdminForm, TopicAdminForm + + +class DocumentationInline(admin.TabularInline): + model = Documentation + extra = 0 + verbose_name = "Dokument" + verbose_name_plural = "Dokument-Übersicht" + + +class TopicInline(admin.TabularInline): + model = Topic + extra = 0 + verbose_name = "Topic" + verbose_name_plural = "Topic-Übersicht" + + +class TopicGroupAdmin(admin.ModelAdmin): + form = TopicGroupAdminForm + model = TopicGroup + search_fields = ("title",) + inlines = (TopicInline,) + + def save_model(self, request, obj, form, change): + obj.created_by = request.user + super().save_model(request, obj, form, change) + + +class TopicAdmin(admin.ModelAdmin): + form = TopicAdminForm + model = Topic + search_fields = ("title",) + inlines = (DocumentationInline,) + + def save_model(self, request, obj, form, change): + obj.created_by = request.user + super().save_model(request, obj, form, change) + + +""" +class DocumentationAdmin(admin.ModelAdmin): + form = DocumentationAdminForm + model = Documentation + + list_display = ["title", "topic"] + + def save_model(self, request, obj, form, change): + obj.created_by = request.user + super().save_model(request, obj, form, change) +""" + +admin.site.register(TopicGroup, TopicGroupAdmin) +admin.site.register(Topic, TopicAdmin) +# admin.site.register(Documentation, DocumentationAdmin) diff --git a/fet2020/intern/apps.py b/fet2020/intern/apps.py new file mode 100644 index 00000000..b2d0203a --- /dev/null +++ b/fet2020/intern/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class InternConfig(AppConfig): + name = "intern" diff --git a/fet2020/intern/forms.py b/fet2020/intern/forms.py new file mode 100644 index 00000000..f2863d49 --- /dev/null +++ b/fet2020/intern/forms.py @@ -0,0 +1,49 @@ +from django import forms +from django.utils.translation import gettext_lazy as _ + +from ckeditor_uploader.widgets import CKEditorUploadingWidget + +from .models import TopicGroup, Topic, Documentation, Document + + +class TopicGroupAdminForm(forms.ModelForm): + class Meta: + model = TopicGroup + fields = [ + "title", + ] + + +class TopicAdminForm(forms.ModelForm): + class Meta: + model = Topic + fields = [ + "title", + "description", + "topic_group", + ] + + widgets = {"description": CKEditorUploadingWidget(config_name="default")} + + +class DocumentationAdminForm(forms.ModelForm): + class Meta: + model = Documentation + fields = [ + "title", + "description", + "topic", + ] + + +class DocumentForm(forms.ModelForm): + class Meta: + model = Document + + fields = [ + "title", + ] + + labels = { + "title": _("Titel des Protokolls"), + } diff --git a/fet2020/intern/models.py b/fet2020/intern/models.py new file mode 100644 index 00000000..8715e6f4 --- /dev/null +++ b/fet2020/intern/models.py @@ -0,0 +1,101 @@ +import logging +from django.db import models +from django.utils.text import slugify +from documents import createPadifNotExists +from urllib.request import URLError + +logger = logging.getLogger(__name__) + + +class TopicGroup(models.Model): + title = models.CharField(max_length=128) + + slug = models.SlugField(unique=True, blank=True) + + objects = models.Manager() + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.title) + + super().save(*args, **kwargs) + + def __str__(self): + return self.title + + +class Topic(models.Model): + title = models.CharField(max_length=128) + + slug = models.SlugField(unique=True, blank=True) + description = models.TextField(null=True, blank=True) + + topic_group = models.ForeignKey(TopicGroup, on_delete=models.CASCADE) + + objects = models.Manager() + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.title) + + super().save(*args, **kwargs) + + def __str__(self): + return self.title + + +class Documentation(models.Model): + title = models.CharField(max_length=128) + + slug = models.SlugField(unique=True, blank=True) + description = models.TextField(null=True, blank=True) + + topic = models.ForeignKey(Topic, on_delete=models.CASCADE) + + objects = models.Manager() + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.title) + + super().save(*args, **kwargs) + + def __str__(self): + return self.title + + +class Document(models.Model): + title = models.CharField(max_length=128) + + etherpad_key = models.CharField(max_length=128, null=True, blank=True) + + documentation = models.ForeignKey(Documentation, on_delete=models.CASCADE) + + objects = models.Manager() + + def save(self, *args, **kwargs): + try: + self.etherpad_key = createPadifNotExists( + self.documentation.topic.slug + + "-" + + self.documentation.slug + + "-" + + slugify(self.title) + ) + except URLError as error: + logger.info( + "Can't create a Etherpad '%s' from the slug. Error: %s", + slugify(self.title), + error, + ) + self.etherpad_key = None + + super().save(*args, **kwargs) + + def __str__(self): + return self.title + + +class Protocol(Document): + event_start = models.DateTimeField(null=True, blank=True) + event_end = models.DateTimeField(null=True, blank=True) diff --git a/fet2020/intern/tests.py b/fet2020/intern/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/fet2020/intern/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/fet2020/intern/urls.py b/fet2020/intern/urls.py new file mode 100644 index 00000000..453b14a6 --- /dev/null +++ b/fet2020/intern/urls.py @@ -0,0 +1,10 @@ +from django.urls import path + +from . import views + + +urlpatterns = [ + path("", views.index, name="intern"), + path("", views.show_topic, name="topic"), + path("/", views.show_docu, name="docu"), +] diff --git a/fet2020/intern/views.py b/fet2020/intern/views.py new file mode 100644 index 00000000..298d3f9e --- /dev/null +++ b/fet2020/intern/views.py @@ -0,0 +1,85 @@ +import logging + +from django.http import HttpResponseRedirect +from django.shortcuts import render +from documents.api import get_pad_link +from collections import deque + +from .forms import DocumentForm +from .models import TopicGroup, Topic, Documentation, Document + +logger = logging.getLogger(__name__) + + +def index(request): + + topic_group = deque(TopicGroup.objects.all()) + topic = Topic.objects.all() + + context = { + "topic_group": topic_group, + "topic": topic, + } + + return render(request, "intern/index.html", context) + + +def show_topic(request, slug=None): + + topic_group = deque(TopicGroup.objects.all()) + topic = deque(Topic.objects.all()) + active_topic = Topic.objects.filter(slug=slug).first() + docu = deque(Documentation.objects.filter(topic__slug=slug)) + + context = { + "topic_group": topic_group, + "topic": topic, + "active_topic": active_topic, + "docus": docu, + } + + return render(request, "intern/topic.html", context) + + +def show_docu(request, slug=None, foo=None): + + active_docu = Documentation.objects.filter(slug=foo).first() + active_topic = Topic.objects.filter(slug=slug).first() + + if request.method == "POST": + if "btn_input" in request.POST: + form = DocumentForm(request.POST) + + if form.is_valid(): + docu = form.save(commit=False) + docu.created_by = request.user + docu.documentation = active_docu + docu.save() + + return HttpResponseRedirect(request.path) + + form = DocumentForm() + docus = deque(Document.objects.filter(documentation=active_docu)) + documents = deque([]) + + for elem in docus: + try: + documents.append( + { + "title": elem.title, + "etherpad_key": get_pad_link(elem.etherpad_key), + } + ) + except Exception as e: + logger.error( + "Can't get the agenda link from '%s'. Error: %s", elem.etherpad_key, e + ) + + context = { + "formset": form, + "active_topic": active_topic, + "active_docu": active_docu, + "documents": documents, + } + + return render(request, "intern/docu.html", context) diff --git a/fet2020/static/intern.css b/fet2020/static/intern.css new file mode 100644 index 00000000..fa206b30 --- /dev/null +++ b/fet2020/static/intern.css @@ -0,0 +1,75 @@ +.intern-topic { + border-radius: 5px; + margin-top: 1rem !important; + margin-bottom: 1rem !important; + height: 100px; } + @media print, screen and (min-width: 40em) { + .intern-topic { + height: 15vh; } } + @media print, screen and (min-width: 64em) { + .intern-topic { + height: 15vh; } } + +.intern-topic, .intern-topic-large { + background-color: #444; + position: relative; + background-size: cover; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + vertical-align: middle; + text-align: left; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + width: 100%; } + .intern-topic .intern-topic-text, .intern-topic-large .intern-topic-text { + color: #fefefe; + text-shadow: 1px 1px 2px #0a0a0a; } + + +.internheader { + border-radius: 5px; + margin-top: 1rem !important; + margin-bottom: 1rem !important; + height: 30px; } + @media print, screen and (min-width: 40em) { + .internheader { + height: 5vh; } } + @media print, screen and (min-width: 64em) { + .internheader { + height: 5vh; } } + +.internheader, .internheader-large { + background-color: grey; + position: relative; + background-size: cover; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + vertical-align: middle; + text-align: left; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + width: 100%; } + .internheader, .internheader-large { + color: #fefefe; + text-shadow: 1px 1px 2px #0a0a0a; } + + +.intern-hero { + background-color: white; +} diff --git a/fet2020/templates/intern/docu.html b/fet2020/templates/intern/docu.html new file mode 100644 index 00000000..41196da4 --- /dev/null +++ b/fet2020/templates/intern/docu.html @@ -0,0 +1,75 @@ +{% extends "layout.html" %} + +{% block content %} +
+ + + +
+ + {{ active_docu.description|safe }} + +
+ +
+ +
+

Neues Protokoll hinzufügen

+ +
+ {% csrf_token %} + +
+ + {{ formset.management_form }} + + {% for form in formset %} +
+ {{ form.label }} + {{ form }} +
+ {% endfor %} + +
+ +
+ +
+ +
+ +
+ +
+ +{% endblock %} diff --git a/fet2020/templates/intern/index.html b/fet2020/templates/intern/index.html new file mode 100644 index 00000000..66908ce2 --- /dev/null +++ b/fet2020/templates/intern/index.html @@ -0,0 +1,29 @@ +{% extends "layout.html" %} + +{% block content %} +
+ + {% regroup topic by topic_group as topic_list %} + + {% for topic in topic_list %} +
+ {{ topic.grouper.title }} +
+ +
+ {% for tp in topic.list %} + + {% endfor %} +
+ {% endfor %} + +
+{% endblock %} diff --git a/fet2020/templates/intern/topic.html b/fet2020/templates/intern/topic.html new file mode 100644 index 00000000..31738a0d --- /dev/null +++ b/fet2020/templates/intern/topic.html @@ -0,0 +1,49 @@ +{% extends "layout.html" %} + +{% block content %} +
+ + + +
+ + {{ active_topic.description|safe }} + + +
+ {% for docu in docus %} + + {% endfor %} +
+ +
+ +
+ +{% endblock %} diff --git a/fet2020/templates/layout.html b/fet2020/templates/layout.html index 26961578..a5477cbd 100644 --- a/fet2020/templates/layout.html +++ b/fet2020/templates/layout.html @@ -9,6 +9,7 @@ FET + {% block extraheader %} {% endblock %} @@ -62,7 +63,8 @@ footer {
  • Admin
  • Tasks
  • -
  • Intern
  • +
  • Intern
  • +
  • Legacy Intern
  • {% endif %}
  • Aktuelles