diff --git a/aleksis/core/dashboard/README.md b/aleksis/core/dashboard/README.md deleted file mode 100644 index 5246b5c011be74320aa37e498abc2bc982168314..0000000000000000000000000000000000000000 --- a/aleksis/core/dashboard/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Dashboard -Das Dashboard dient dazu, den Benutzer zu begrüßen (> Startseite) -und seine letzten Aktivitäten anzuzeigen. - -Edit: Außerdem zeigt das Dashboard aktuelle Nachrichten für den Benutzer an. - -## Aktivitäten -Als Aktivität gilt alles, was der Nutzer selbst macht, d.h., bewusst. - -### Eine Aktivität registrieren -1. Importieren - - from .apps import <Meine App>Config - from dashboard.models import Activity - -2. Registrieren - - act = Activity(title="<Titel der Aktion>", description="<Beschreibung der Aktion>", app=<Meine App>Config.verbose_name, user=<Benutzer Objekt>) - act.save() - -## Benachrichtigungen -Als Benachrichtigung gilt eine Aktion, die den Nutzer betrifft. - -### Eine Benachrichtigung verschicken -1. Importieren - - from .apps import <Meine App>Config - from dashboard.models import Notification - -2. Verschicken - - register_notification(title="<Titel der Nachricht>", - description="<Weitere Informationen>", - app=<Meine App>Config.verbose_name, user=<Benutzer Objekt>, - link=request.build_absolute_uri(<Link für weitere Informationen>)) - - **Hinweis:** Der angegebene Link muss eine absolute URL sein. - Dies wird durch übergabe eines dynamischen Linkes (z. B. /aub/1) an die Methode `request.build_absolute_uri()` erreicht. - - Um einen dynamischen Link durch den Namen einer Django-URL zu "errechnen", dient die Methode `reverse()`. - - Literatur: - - [1] https://docs.djangoproject.com/en/2.1/ref/request-response/#django.http.HttpRequest.build_absolute_uri - - [2] https://docs.djangoproject.com/en/2.1/ref/urlresolvers/#reverse - diff --git a/aleksis/core/dashboard/settings.py b/aleksis/core/dashboard/settings.py deleted file mode 100644 index 4dc09f18c3e8d8f2979aa5e8eb6dda8479f85735..0000000000000000000000000000000000000000 --- a/aleksis/core/dashboard/settings.py +++ /dev/null @@ -1,31 +0,0 @@ -import dbsettings - - -class LatestArticleSettings(dbsettings.Group): - latest_article_is_activated = dbsettings.BooleanValue("Funktion aktivieren?", default=True) - wp_domain = dbsettings.StringValue("WordPress-Domain", help_text="Ohne abschließenden Slash", - default="https://katharineum-zu-luebeck.de") - replace_vs_composer_stuff = dbsettings.BooleanValue("VisualComposer-Tags durch regulären Ausdruck entfernen?", - default=True) - - -class CurrentEventsSettings(dbsettings.Group): - current_events_is_activated = dbsettings.BooleanValue("Funktion aktivieren?", default=True) - calendar_url = dbsettings.StringValue("URL des Kalenders", help_text="Pfad zu einer ICS-Datei", - default="https://nimbus.katharineum.de/remote.php/dav/public-calendars" - "/owit7yysLB2CYNTq?export") - events_count = dbsettings.IntegerValue("Anzahl der Termine, die angezeigt werden sollen", default=5) - - -class MyStatusSettings(dbsettings.Group): - my_status_is_activated = dbsettings.BooleanValue("Funktion aktivieren?", default=True) - - -class CurrentExamsSettings(dbsettings.Group): - current_exams_is_activated = dbsettings.BooleanValue("Funktion aktivieren?", default=True) - - -latest_article_settings = LatestArticleSettings("Funktion: Letzter Artikel") -current_events_settings = CurrentEventsSettings("Funktion: Aktuelle Termine") -my_status_settings = MyStatusSettings("Funktion: Mein Status") -current_exams_settings = MyStatusSettings("Funktion: Aktuelle Klausuren") diff --git a/aleksis/core/dashboard/templates/dashboard/index.html b/aleksis/core/dashboard/templates/dashboard/index.html deleted file mode 100644 index 8450678118187c74ce34ce317a27047a844b8f0e..0000000000000000000000000000000000000000 --- a/aleksis/core/dashboard/templates/dashboard/index.html +++ /dev/null @@ -1,18 +0,0 @@ -{% load staticfiles %} -{% include 'partials/header.html' %} - -<main> - <script> - var API_URL = "{% url "api_information" %}"; - var MY_PLAN_URL = "{% url "timetable_my_plan" %}"; - </script> - <script src="{% static "js/moment-with-locales.min.js" %}"></script> - {% include "components/react.html" %} - <script src="{% static "js/dashboard.js" %}"></script> - - <div id="dashboard_container"> - - </div> -</main> - -{% include 'partials/footer.html' %} diff --git a/aleksis/core/dashboard/urls.py b/aleksis/core/dashboard/urls.py deleted file mode 100644 index 18c13061822957f21d4f87a51497170e392683ae..0000000000000000000000000000000000000000 --- a/aleksis/core/dashboard/urls.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.db import ProgrammingError -from django.urls import path - -from untisconnect.models import Terms, Schoolyear - -try: - import dashboard.views.dashboard as views - - urlpatterns = [ - path('', views.index, name='dashboard'), - path('api', views.api_information, name="api_information"), - path('api/notifications/read/<int:id>', views.api_read_notification, name="api_read_notification"), - path('api/my-plan', views.api_my_plan_html, name="api_my_plan_html"), - ] - -except (Terms.DoesNotExist, Schoolyear.DoesNotExist, ProgrammingError): - from timetable import fallback_view - - urlpatterns = [ - path('', fallback_view.fallback, name='dashboard'), - path('api', fallback_view.fallback, name="api_information"), - path('api/notifications/read/<int:id>', fallback_view.fallback, name="api_read_notification"), - path('api/my-plan', fallback_view.fallback, name="api_my_plan_html"), - ] - -import dashboard.views.tools as tools_views - -urlpatterns += [ - path('offline', tools_views.offline, name='offline'), - path('about/', tools_views.about, name='about') -] diff --git a/aleksis/core/dashboard/views/dashboard.py b/aleksis/core/dashboard/views/dashboard.py deleted file mode 100644 index a45100ed064711904d77895318c5614e4c530266..0000000000000000000000000000000000000000 --- a/aleksis/core/dashboard/views/dashboard.py +++ /dev/null @@ -1,142 +0,0 @@ -from email.utils import formatdate - -from django.contrib.auth.decorators import login_required -from django.http import JsonResponse -from django.shortcuts import get_object_or_404 -from django.shortcuts import render -from django.template.loader import render_to_string -from django.utils import timezone -from martor.templatetags.martortags import safe_markdown - -from dashboard.models import Activity, Notification -from dashboard.settings import latest_article_settings, current_events_settings -from timetable.hints import get_all_hints_by_class_and_time_period, get_all_hints_for_teachers_by_time_period -from timetable.views import get_next_weekday_with_time -from untisconnect.api import TYPE_TEACHER, TYPE_CLASS -from untisconnect.datetimeutils import get_name_for_next_week_day_from_today -from untisconnect.utils import get_type_and_object_of_user, get_plan_for_day -from util.network import get_newest_article_from_news, get_current_events_with_cal - - -@login_required -def index(request): - """ Dashboard: Show daily relevant information """ - - return render(request, 'dashboard/index.html') - - -@login_required -def api_information(request): - """ API request: Give information for dashboard in JSON """ - # Load activities - activities = Activity.objects.filter(user=request.user).order_by('-created_at')[:5] - - # Load notifications - notifications = request.user.notifications.all().filter(user=request.user).order_by('-created_at')[:5] - unread_notifications = request.user.notifications.all().filter(user=request.user, read=False).order_by( - '-created_at') - - # Get latest article from homepage - if latest_article_settings.latest_article_is_activated: - newest_article = get_newest_article_from_news(domain=latest_article_settings.wp_domain) - else: - newest_article = None - - # Get date information - date_formatted = get_name_for_next_week_day_from_today() - next_weekday = get_next_weekday_with_time(timezone.now(), timezone.now().time()) - - # Get user type (student, teacher, etc.) - _type, el = get_type_and_object_of_user(request.user) - - # Get hints - if _type == TYPE_TEACHER: - # Get hints for teachers - hints = list(get_all_hints_for_teachers_by_time_period(next_weekday, next_weekday)) - elif _type == TYPE_CLASS: - # Get hints for students - hints = list(get_all_hints_by_class_and_time_period(el, next_weekday, next_weekday)) - else: - hints = [] - - # Serialize hints - ser = [] - for hint in hints: - serialized = { - "from_date": formatdate(float(hint.from_date.strftime('%s'))), - "to_date": formatdate(float(hint.to_date.strftime('%s'))), - "html": safe_markdown(hint.text) - } - ser.append(serialized) - hints = ser - - context = { - 'activities': list(activities.values()), - 'notifications': list(notifications.values()), - "unread_notifications": list(unread_notifications.values()), - # 'user_type': UserInformation.user_type(request.user), - # 'user_type_formatted': UserInformation.user_type_formatted(request.user), - # 'classes': UserInformation.user_classes(request.user), - # 'courses': UserInformation.user_courses(request.user), - # 'subjects': UserInformation.user_subjects(request.user), - # 'has_wifi': UserInformation.user_has_wifi(request.user), - "newest_article": newest_article, - "current_events": get_current_events_with_cal() if current_events_settings.current_events_is_activated else None, - "date_formatted": date_formatted, - "user": { - "username": request.user.username, - "full_name": request.user.first_name - } - } - - # If plan is available for user give extra information - if _type is not None and request.user.has_perm("timetable.show_plan"): - context["plan"] = { - "type": _type, - "name": el.shortcode if _type == TYPE_TEACHER else el.name, - "hints": hints - } - context["has_plan"] = True - else: - context["has_plan"] = False - - return JsonResponse(context) - - -@login_required -def api_read_notification(request, id): - """ API request: Mark notification as read """ - - notification = get_object_or_404(Notification, id=id, user=request.user) - notification.read = True - notification.save() - - return JsonResponse({"success": True}) - - -@login_required -def api_my_plan_html(request): - """ API request: Get rendered lessons with substitutions for dashboard """ - - # Get user type (student, teacher, etc.) - _type, el = get_type_and_object_of_user(request.user) - - # Plan is only for teachers and students available - if (_type != TYPE_TEACHER and _type != TYPE_CLASS) or not request.user.has_perm("timetable.show_plan"): - return JsonResponse({"success": False}) - - # Get calendar week and monday of week - next_weekday = get_next_weekday_with_time() - - # Get plan - plan, holiday = get_plan_for_day(_type, el.id, next_weekday) - - # Serialize plan - lessons = [] - for lesson_container, time in plan: - html = render_to_string("timetable/lesson.html", {"col": lesson_container, "type": _type}, request=request) - lessons.append({"time": time, "html": html}) - - # Return JSON - return JsonResponse( - {"success": True, "lessons": lessons, "holiday": holiday[0].__dict__ if len(holiday) > 0 else None}) diff --git a/aleksis/core/dashboard/views/tools.py b/aleksis/core/dashboard/views/tools.py deleted file mode 100644 index 5c088dcf6744118713f15924f9d56069dee7d01a..0000000000000000000000000000000000000000 --- a/aleksis/core/dashboard/views/tools.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.shortcuts import render - -from meta import OPEN_SOURCE_COMPONENTS - - -def about(request): - return render(request, "common/about.html", context={"components": OPEN_SOURCE_COMPONENTS}) diff --git a/aleksis/core/mailer.py b/aleksis/core/mailer.py deleted file mode 100644 index e4dc6b4479ccd9e1ca5644108c3e0be7ed6ca4d5..0000000000000000000000000000000000000000 --- a/aleksis/core/mailer.py +++ /dev/null @@ -1,24 +0,0 @@ -from django.core.mail import send_mail -from django.template.loader import render_to_string - -from constance import config - - -mail_out = "{} <{}>".format(config.MAIL_OUT_NAME, - config.MAIL_OUT) if config.MAIL_OUT_NAME else config.MAIL_OUT - - -def send_mail_with_template(title, receivers, plain_template, html_template, context={}, mail_out=mail_out): - msg_plain = render_to_string(plain_template, context) - msg_html = render_to_string(html_template, context) - - try: - send_mail( - title, - msg_plain, - mail_out, - receivers, - html_message=msg_html, - ) - except Exception as e: - print("[EMAIL PROBLEM] ", e) diff --git a/aleksis/core/templates/components/react.html b/aleksis/core/templates/components/react.html deleted file mode 100644 index 452959486f3e4a317b650e1219575c08a4065df2..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/components/react.html +++ /dev/null @@ -1,11 +0,0 @@ -{% load staticfiles %} - -{% if debug %} - <script src="{% static "js/react/prop-types.development.js" %}"></script> - <script src="{% static "js/react/react.development.js" %}"></script> - <script src="{% static "js/react/react-dom.development.js" %}"></script> -{% else %} - <script src="{% static "js/react/prop-types.production.min.js" %}"></script> - <script src="{% static "js/react/react.production.min.js" %}"></script> - <script src="{% static "js/react/react-dom.production.min.js" %}"></script> -{% endif %} diff --git a/aleksis/core/templates/mail/email.html b/aleksis/core/templates/mail/email.html deleted file mode 100644 index 58f6f6b639a423649f425ea12997aa28e6ec7007..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/mail/email.html +++ /dev/null @@ -1,13 +0,0 @@ -{% include "mail/header.html" %} - -<main> - Hallo {{ user.get_full_name }}, - vielen Dank, dass Sie <b>SchoolApps</b> benutzen. - <hr> - Weitere Informationen finden Sie hier: - <ul> - <li><a href="https://forum.katharineum.de">FORUM</a></li> - </ul> - <hr> - Ihre Computer-AG -</main> diff --git a/aleksis/core/templates/mail/email.txt b/aleksis/core/templates/mail/email.txt deleted file mode 100644 index c781ae1d5fe821a8c1903eea66f284083d4c1ec4..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/mail/email.txt +++ /dev/null @@ -1,9 +0,0 @@ -Hallo {{ user.name }}, -vielen Dank, dass du SchoolApps benutzt. - ----- -Weitere Informationen findest du hier: -- FORUM (forum.katharineum.de) ----- - -Deine Computer-AG diff --git a/aleksis/core/templates/mail/header.html b/aleksis/core/templates/mail/header.html deleted file mode 100644 index ad452e53be3e7ada776b02ce2b64ab605e206b9f..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/mail/header.html +++ /dev/null @@ -1,8 +0,0 @@ -<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> -<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css"> - -<style> - main { - padding: 10px; - } -</style> diff --git a/aleksis/core/templates/mail/notification.html b/aleksis/core/templates/mail/notification.html deleted file mode 100644 index a5619f9aa49bdc693e106a8b5cca888a5d8b29a4..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/mail/notification.html +++ /dev/null @@ -1,15 +0,0 @@ -{% include "mail/header.html" %} - -<main> - <p>Hallo {{ notification.user.get_full_name }}, <br> - wir haben eine neue Nachricht für dich:</p> - <blockquote> - <p>{{ notification.description }}</p> - {% if notification.link %} - <a href="{{ notification.link }}">Weitere Informationen →</a> - {% endif %} - </blockquote> - <p>Von {{ notification.app }} am {{ notification.created_at }}</p> - - <i>Dein SchoolApps-Team</i> -</main> diff --git a/aleksis/core/templates/mail/notification.txt b/aleksis/core/templates/mail/notification.txt deleted file mode 100644 index ca927a4fd764d6d1e02d225a9dc43a201adf695d..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/mail/notification.txt +++ /dev/null @@ -1,13 +0,0 @@ -Hallo {{ notification.user.name }}, -wir haben eine neue Nachricht für dich: - - -{{ notification.description }} - -{% if notification.link %} - Weitere Informationen: {{ notification.link }} -{% endif %} - -Von {{ notification.app }} am {{ notification.created_at }} - -Dein SchoolApps-Team diff --git a/aleksis/core/templates/partials/footer.html b/aleksis/core/templates/partials/footer.html deleted file mode 100644 index b682bd0cfd699c9148522b80308bd3e1e2c62d66..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/partials/footer.html +++ /dev/null @@ -1,76 +0,0 @@ -{% load static %} - - -<footer class="page-footer primary-color"> - <div class="container"> - <div class="row no-margin footer-row-large"> - <div class="col l6 s12 no-pad-left height-inherit"> - <p class="white-text valign-bot"> - <a href="{% url "about" %}" class="blue-text text-lighten-4">Ãœber Schoolapps · Entwickler, Copyright - und Lizenz - </a> - </p> - </div> - <div class="col xl15 l6 offset-xl01 s12 no-pad-right"> - <ul class="no-margin right"> - <a class="blue-text text-lighten-4 btn-flat no-pad-left" href="https://katharineum-zu-luebeck.de"><i - class="material-icons footer-icon left">home</i> Homepage - </a> - <a class="blue-text text-lighten-4 btn-flat" href="https://forum.katharineum.de"><i - class="material-icons footer-icon left">account_balance</i> Forum - </a> - <a class="blue-text text-lighten-4 btn-flat" href="https://nimbus.katharineum.de"><i - class="material-icons footer-icon left">cloud</i> Nimbus - </a> - <a class="blue-text text-lighten-4 btn-flat no-pad-right" href="https://webmail.katharineum.de"><i - class="material-icons footer-icon left">email</i> Webmail - </a> - </ul> - </div> - </div> - <div class="row no-margin footer-row-small"> - <span class="white-text make-it-higher"> - <a href="{% url "about" %}" class="blue-text text-lighten-4">Ãœber Schoolapps · Entwickler, Copyright - und Lizenz - </a> - </span> - <ul class="no-margin footer-ul"> - <a class="blue-text text-lighten-4 btn-flat no-pad-left" href="https://katharineum-zu-luebeck.de"><i - class="material-icons footer-icon left">home</i> Homepage - </a> - <a class="blue-text text-lighten-4 btn-flat" href="https://forum.katharineum.de"><i - class="material-icons footer-icon left">account_balance</i> Forum - </a> - <a class="blue-text text-lighten-4 btn-flat" href="https://nimbus.katharineum.de"><i - class="material-icons footer-icon left">cloud</i> Nimbus - </a> - <a class="blue-text text-lighten-4 btn-flat no-pad-right" href="https://webmail.katharineum.de"><i - class="material-icons footer-icon left">email</i> Webmail - </a> - </ul> - </div> - </div> - <div class="footer-copyright"> - <div class="container"> - <span class="left">Version {{ VERSION }} · {{ COPYRIGHT_SHORT }}</span> - <span class="right"> - <span id="doit"></span> - - <a class="blue-text text-lighten-4" href="https://katharineum-zu-luebeck.de/impressum/">Impressum</a> - · - <a class="blue-text text-lighten-4" href="https://katharineum-zu-luebeck.de/datenschutzerklaerung/"> - Datenschutzerklärung - </a> - </span> - </div> - </div> -</footer> - -<!----------------> -<!-- JavaScript (jquery v. 3.4.1.slim)--> -<!----------------> -<script src="{% static 'common/manup.min.js' %}"></script> -<script src="{% static 'js/materialize.min.js' %}"></script> -<script src="{% static 'common/helper.js' %}"></script> -</body> -</html> diff --git a/aleksis/core/templates/partials/header.html b/aleksis/core/templates/partials/header.html deleted file mode 100644 index c3edc1caa05eb2e6863ffef1ea3e7672059b05bb..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/partials/header.html +++ /dev/null @@ -1,420 +0,0 @@ -{% load static %} -{% load pwa %} -{% load url_name %} - -<!DOCTYPE html> -<html lang="de"> -<head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width,initial-scale=1"> - <meta name="description" content="Selbst programmierte Anwendungen für den Schullaltag am Katharineum zu Lübeck"> - <title>SchoolApps – Katharineum zu Lübeck</title> - - <!-- Android --> - <meta name="theme-color" content="#da1f3d"> - <meta name="mobile-web-app-capable" content="yes"> - - <!-- iOS --> - <meta name="apple-mobile-web-app-title" content="SchoolApps"> - <meta name="apple-mobile-web-app-capable" content="yes"> - <meta name="apple-mobile-web-app-status-bar-style" content="default"> - - <!-- Windows --> - <meta name="msapplication-navbutton-color" content="#da1f3d"> - <meta name="msapplication-TileColor" content="#da1f3d"> - <meta name="msapplication-TileImage" content="ms-icon-144x144.png"> - <meta name="msapplication-config" content="browserconfig.xml"> - - <!-- Pinned Sites --> - <meta name="application-name" content="SchoolApps"> - <meta name="msapplication-tooltip" content="SchoolApps"> - <meta name="msapplication-starturl" content="/"> - - <!-- Tap highlighting --> - <meta name="msapplication-tap-highlight" content="no"> - - <!-- UC Mobile Browser --> - <meta name="full-screen" content="yes"> - <meta name="browsermode" content="application"> - - - <!-- Main Link Tags --> - <link href="{% static "icons/favicon_16.png" %}" rel="icon" type="image/png" sizes="16x16"> - <link href="{% static "icons/favicon_32.png" %}" rel="icon" type="image/png" sizes="32x32"> - <link href="{% static "icons/favicon_48.png" %}" rel="icon" type="image/png" sizes="48x48"> - - <!-- iOS --> - <!-- non-retina iPad iOS 7 --> - <link rel="apple-touch-icon" href="{% static "icons/apple_76.png" %}" sizes="76x76"> - <!-- retina iPhone vor iOS 7 --> - <link rel="apple-touch-icon" href="{% static "icons/apple_114.png" %}" sizes="114x114"> - <!-- retina iPad iOS 7 --> - <link rel="apple-touch-icon" href="{% static "icons/apple_152.png" %}" sizes="152x152"> - <!-- retina iPad iOS 7 für iPhone 6 Plus --> - <link rel="apple-touch-icon" href="{% static "icons/apple_180.png" %}" sizes="180x180"> - - - <!-- Pinned Tab --> - {# <link href="path/to/icon.svg" rel="mask-icon" size="any" color="red">#} - - <!-- Android --> - <link href="{% static "icons/android_192.png" %}" rel="icon" sizes="192x192"> - - <!-- Others --> - {# <link href="favicon.icon" rel="shortcut icon" type="image/x-icon">#} - - - <!-- Favicon --> - <link rel="shortcut icon" type="image/x-icon" href="{% static 'common/favicon.ico' %}"> - - - <!---------> - <!-- CSS --> - <!---------> - <link href="{% static 'css/materialdesignicons-webfont/material-icons.css' %}" rel="stylesheet"> - <link rel="stylesheet" type="text/css" media="screen" - href="{% static 'css/materialize.min.css' %}"> - <link rel="stylesheet" type="text/css" href="{% static 'common/style.css' %}"> - <script src="{% static 'js/jquery/jquery-3.3.1.min.js' %}"></script> - - - <!-- location (for "active" in sidenav --> - <meta name="active-loaction" content="{{ request|url_name }}"> - - {% if martor %} - <link href="{% static 'plugins/css/ace.min.css' %}" type="text/css" media="all" rel="stylesheet"/> - <link href="{% static 'plugins/css/resizable.min.css' %}" type="text/css" media="all" rel="stylesheet"/> - <link href="{% static 'martor/css/martor.min.css' %}" type="text/css" media="all" rel="stylesheet"/> - {% endif %} -</head> -<body> -<header> - <!-- Menu button (sidenav) --> - <div class="container"> - <a href="#" data-target="slide-out" class="top-nav sidenav-trigger hide-on-large-only"> - <i class="material-icons">menu</i> - </a> - </div> - - <!-- Nav bar (logged in as, logout) --> - <nav class="primary-color"> - <a class="brand-logo" href="/">SchoolApps</a> - - <div class="nav-wrapper"> - <ul id="nav-mobile" class="right hide-on-med-and-down"> - {% if user.is_authenticated %} - <li>Angemeldet als {{ user.get_username }}</li> - <li> - <a href="{% url 'logout' %}">Abmelden <i class="material-icons right">exit_to_app</i></a> - </li> - {% endif %} - </ul> - </div> - </nav> - - <div id="print-header" class="row"> - <div class="col s6 logo"> - <img src="{% static 'common/logo.png' %}"> - </div> - <div class="col s6 right-align"> - <a href="/"><strong>SchoolApps</strong></a> - <br> - Katharineum zu Lübeck - </div> - </div> - - <!-- Main nav (sidenav) --> - <ul id="slide-out" class="sidenav sidenav-fixed"> - <li class="logo"> - <a id="logo-container" href="/" class="brand-logo"> - <img src="{% static 'common/logo.png' %}" alt="Logo des Katharineums"> - </a> - </li> - - {% if user.is_authenticated %} - <li class="url-dashboard"> - <a href="{% url 'dashboard' %}"> - <i class="material-icons">home</i> Dashboard - </a> - </li> - <li> - <div class="divider"></div> - </li> - - <li class="no-padding"> - <ul class="collapsible collapsible-accordion"> - - {% if perms.aub.apply_for_aub or perms.aub.check1_aub or perms.aub.check2_aub %} - <li class="bold url-aub_index url-aub_details url-ab_edit url-aub_apply_for urlaub_applied_for"> - <a class="collapsible-header waves-effect waves-primary" href="{% url 'aub_index' %}"><i - class="material-icons">business_center</i> - Unterrichtsbefreiungen - </a> - <div class="collapsible-body"> - <ul> - {% if perms.aub.check1_aub %} - <li class="url-aub_check1"> - <a href="{% url 'aub_check1' %}"><i class="material-icons">done</i> Anträge - genehmigen 1 - </a> - </li> - {% endif %} - {% if perms.aub.check2_aub %} - <li class="url-aub_check2"> - <a href="{% url 'aub_check2' %}"><i class="material-icons">done_all</i> - Anträge - genehmigen 2 - </a> - </li> - {% endif %} - {% if perms.aub.view_archive %} - <li class="url-aub_archive"> - <a href="{% url 'aub_archive' %}"><i class="material-icons">archive</i> - Archiv - </a> - </li> - {% endif %} - </ul> - </div> - </li> - - <li> - <div class="divider"></div> - </li> - {% endif %} - {% if perms.fibu.request_booking or perms.fibu.manage_booking or perms.fibu.manage_costcenter or perms.fibu.manage.account %} - <li class="bold url-fibu_index url-fibu_bookings_user_edit"> - <a class="collapsible-header waves-effect waves-primary" href="{% url 'fibu_index' %}"><i - class="material-icons">euro_symbol</i> - Finanzen - </a> - <div class="collapsible-body"> - <ul> - {% if perms.fibu.check_booking %} - <li class="url-fibu_bookings_check"> - <a href="{% url 'fibu_bookings_check' %}"><i class="material-icons">done_all</i>Anträge - prüfen - </a> - </li> - {% endif %} - {% if perms.fibu.manage_booking %} - <li class="url-fibu_bookings url-fibu_bookings_edit url-fibu_bookings_new"> - <a href="{% url 'fibu_bookings' %}"><i class="material-icons">receipt</i>Buchungen - </a> - </li> - {% endif %} - {% if perms.fibu.manage_costcenter %} - <li class="url-fibu_cost_centers url-fibu_cost_centers_edit"> - <a href="{% url 'fibu_cost_centers' %}"><i class="material-icons">done</i>Kostenstellen - </a> - </li> - <li class="url-fibu_accounts url-fibu_accounts_edit"> - <a href="{% url 'fibu_accounts' %}"><i class="material-icons">done</i>Buchungskonten - </a> - </li> - {% endif %} - {% if perms.fibu.manage_booking %} - <li class="url-fibu_reports url-fibu_reports_expenses"> - <a href="{% url 'fibu_reports' %}"><i class="material-icons">list</i>Berichte</a> - </li> - {% endif %} - </ul> - </div> - </li> - <li> - <div class="divider"></div> - </li> - {% endif %} - - {% if perms.timetable.show_plan %} - <li class="bold"> - <a class="collapsible-header waves-effect waves-primary"><i class="material-icons">school</i> - Stundenplan - </a> - <div class="collapsible-body"> - <ul> - <li class="url-timetable_my_plan"> - <a href="{% url 'timetable_my_plan' %}" style="padding-right: 10px;"> - <i class="material-icons">person</i> Mein Plan - <span class="badge new primary-color sidenav-badge">SMART PLAN</span> - </a> - </li> - {# <li>#} - {# <a href="{% url 'timetable_admin_all' %}">#} - {# <i class="material-icons">grid_on</i> Alle Pläne#} - {# </a>#} - {# </li>#} - <li class="url-timetable_quicklaunch url-timetable_smart_plan url-timetable_regular_plan url-timetable_smart_plan_week"> - <a href="{% url 'timetable_quicklaunch' %}"> - <i class="material-icons">grid_on</i> Alle Pläne - </a> - </li> - <li class="url-timetable_substitutions_date url-timetable_substitutions"> - <a href="{% url 'timetable_substitutions' %}"> - <i class="material-icons">update</i> Vertretungsplan - </a> - </li> - {% if perms.timetable.view_hint %} - <li class="url-timetable_hints url-timetable_add_hint url-timetable_edit_hint url-timetable_delete_hint"> - <a href="{% url 'timetable_hints' %}"> - <i class="material-icons">announcement</i> Hinweismanagement - </a> - </li> - {% endif %} - {% if perms.debug.can_view_debug_log %} - <li class="url-debug_logs url-debug"> - <a href="{% url 'debug_logs' %}"> - <i class="material-icons">error</i> Debuggingtool - </a> - </li> - {% endif %} - </ul> - </div> - </li> - - <li> - <div class="divider"></div> - </li> - {% endif %} - - <li> - <a href="{% url 'menu_show_current' %}" target="_blank"> - <i class="material-icons">picture_as_pdf</i> Aktueller Speiseplan - </a> - </li> - - {% if perms.menu.add_menu %} - <li class="url-menu_index url-menu_upload url-menu_index_msg"> - <a href="{% url 'menu_index' %}"> - <i class="material-icons">restaurant_menu</i> Speiseplan hochladen - </a> - </li> - {% endif %} - - <li> - <div class="divider"></div> - </li> - - <li class="bold"> - <a class="collapsible-header waves-effect waves-primary"><i class="material-icons">help</i> Support</a> - <div class="collapsible-body"> - <ul> - <li class="url-rebus"> - <a href="{% url 'rebus' %}"> - <i class="material-icons">bug_report</i> Fehler melden - </a> - </li> - <li class="url-feedback"> - <a href="{% url 'feedback' %}"> - <i class="material-icons">feedback</i> Feedback - </a> - </li> - <li class="url-faq"> - <a href="{% url 'faq' %}"> - <i class="material-icons">question_answer</i>FAQ - </a> - </li> - </ul> - </div> - </li> - {% endif %} - - {% if not user.is_authenticated %} - <li class="url-faq"> - <a href="{% url 'faq' %}"> - <i class="material-icons">question_answer</i>FAQ - </a> - </li> - {% endif %} - - {% if user.is_authenticated %} - {% if user.is_superuser %} - <li> - <div class="divider"></div> - </li> - <li class="bold"> - <a class="collapsible-header waves-effect waves-primary"><i class="material-icons">security</i>Administration - </a> - <div class="collapsible-body"> - <ul> - <li id="tools"> - <a href="{% url "tools" %}"> - <i class="material-icons">build</i> Tools - </a> - </li> - <li> - <a href="/admin/"> - <i class="material-icons">dashboard</i> Django-Administration - </a> - </li> - <li> - <a href="/settings/"> - <i class="material-icons">settings</i> Einstellungen - </a> - </li> - </ul> - </div> - </li> - {% endif %} - - <li> - <div class="divider"></div> - </li> - - <li> - <a href="{% url 'logout' %}"> - <i class="material-icons">exit_to_app</i> Abmelden - </a> - </li> - - </ul> - </li> - {% else %} - - <li class="url-login"> - <a href="{% url 'login' %}"> - <i class="material-icons">lock_open</i> Anmelden - </a> - </li> - {% endif %} - </ul> -</header> -{#<header class="alert success">#} -{# <p>#} -{# <i class="material-icons left">info</i>#} -{# Du befindest dich in der ersten veröffentlichten Version von SchoolApps. Daher kann es immer mal wieder noch zu#} -{# bislang unvorhergesehenen#} -{# Problemen kommen. Es würde uns sehr helfen, wenn du uns dann über#} -{# <a href="mailto:support@katharineum.de">support@katharineum.de</a>#} -{# schreibst oder die in SchoolApps integrierten#} -{# <a href="{% url 'rebus' %}">Fehlermelde-</a>#} -{# und#} -{# <a href="{% url 'feedback' %}">Feedbackfunktionen</a>#} -{# nutzt.#} -{# </p>#} -{#</header>#} - - - -{% if user.is_authenticated %} - <div class="fixed-action-btn"> - <a class="btn-floating btn-large green"> - <i class="large material-icons">help</i> - </a> - <ul> - <li> - <a class="btn-floating tooltipped red" data-position="left" data-tooltip="Fehler melden" - href="{% url 'rebus' %}"><i class="material-icons">bug_report</i></a> - </li> - <li> - <a class="btn-floating tooltipped yellow darken-1" data-position="left" data-tooltip="FAQ" - href="{% url 'faq' %}"><i class="material-icons">question_answer</i></a> - </li> - <li> - <a class="btn-floating tooltipped blue" data-position="left" data-tooltip="Frage stellen" - href="{% url 'ask-faq' %}"><i class="material-icons">chat</i></a> - </li> - </ul> - </div> -{% endif %} diff --git a/aleksis/core/templates/partials/paper/footer.html b/aleksis/core/templates/partials/paper/footer.html deleted file mode 100644 index 1dc3a88b8281509e4eb8d18212b4513d32189845..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/partials/paper/footer.html +++ /dev/null @@ -1,32 +0,0 @@ -{% load static %} -<footer> - <div class="left"> - Katharineum zu Lübeck - </div> - - <div class="right"> - Umsetzung: {{ COPYRIGHT_SHORT }} - </div> -</footer> -</div> -</td> -</tr> -</tbody> -<tfoot> -<tr class="no-border"> - <td> - <div class="footer-space"> </div> - </td> -</tr> -</tfoot> -</table> -</main> - -<!----------------> -<!-- JavaScript (jquery v. 3.4.1.slim)--> -<!----------------> -<script src="{% static 'common/manup.min.js' %}"></script> -<script src="{% static 'js/materialize.min.js' %}"></script> -<script src="{% static 'common/helper.js' %}"></script> -</body> -</html> diff --git a/aleksis/core/templates/partials/paper/header.html b/aleksis/core/templates/partials/paper/header.html deleted file mode 100644 index 845672ab118cc0112332f292b7899661a6b64ebd..0000000000000000000000000000000000000000 --- a/aleksis/core/templates/partials/paper/header.html +++ /dev/null @@ -1,144 +0,0 @@ -{% load static %} -{% load pwa %} -{% load url_name %} - -<!DOCTYPE html> -<html lang="de"> -<head> - <meta charset="utf-8"> - <meta http-equiv="X-UA-Compatible" content="IE=edge"> - <meta name="viewport" content="width=device-width,initial-scale=1"> - <meta name="description" content="Selbst programmierte Anwendungen für den Schullaltag am Katharineum zu Lübeck"> - <title>SchoolApps – Katharineum zu Lübeck</title> - - <!---------> - <!-- CSS --> - <!---------> - <link href="{% static 'css/materialdesignicons-webfont/material-icons.css' %}" rel="stylesheet"> - <link rel="stylesheet" type="text/css" href="{% static 'css/materialize.min.css' %}"> - <link rel="stylesheet" type="text/css" href="{% static 'css/paper.css' %}"> - <link rel="stylesheet" type="text/css" href="{% static 'common/style.css' %}"> - <script src="{% static 'js/jquery/jquery-3.3.1.min.js' %}"></script> - - - <style> - body { - font-family: Cabin, sans-serif; - } - - @page { - size: A4; - padding: 30mm; - } - - header { - display: block; - width: 190mm; - } - - - #print-header { - display: block !important; - border-bottom: 1px solid; - margin-bottom: 0; - height: 22mm; - background: white; - } - - header, main, footer { - margin: 0; - } - - #print-header .col.right-align { - padding: 15px; - } - - .sheet { - padding: 10mm; - } - - - .header-space, .footer-space { - height: 0; - } - - .print-layout-table td { - padding: 0; - } - - .print-layout-table .no-border { - border: 0; - } - - - footer { - margin-top: 5mm; - text-align: center; - width: 190mm; - - } - - header .row, header .col { - padding: 0 !important; - margin: 0 !important; - } - - @media print { - .header-space { - height: 32mm; - } - - .footer-space { - height: 20mm - } - - header, footer { - height: 22mm; - } - - header { - position: fixed; - top: 10mm; - } - - footer { - position: fixed; - bottom: 0; - } - - @page { - @bottom-center { - content: "Seite " counter(page) " von " counter(pages); - } - } - } - </style> -</head> -<body class="A4"> - - -<div style="margin-top: -10mm;"></div> -<main class="sheet infinitive"> - <table class="print-layout-table"> - <thead> - <tr class="no-border"> - <td> - <div class="header-space"> </div> - </td> - </tr> - </thead> - <tbody> - <tr class="no-border"> - <td> - <div class="content"> - <header> - <div id="print-header" class="row"> - <div class="col s6 logo"> - <img src="{% static 'common/logo.png' %}"> - </div> - <div class="col s6 right-align"> - <h5>SchoolApps</h5> - {% now "j. F Y H:i" %} - </div> - </div> - </header> diff --git a/aleksis/core/userinformation.py b/aleksis/core/userinformation.py deleted file mode 100644 index 69bd84938444dcfe31aa44e4259d7c6d7d84672f..0000000000000000000000000000000000000000 --- a/aleksis/core/userinformation.py +++ /dev/null @@ -1,64 +0,0 @@ -import re - - -class UserInformation: - OTHER = 0 - TEACHER = 1 - STUDENT = 2 - - @staticmethod - def regexr(regex, groups): - reg = re.compile(regex) - return reg.findall("\n".join(groups)) - - @staticmethod - def user_groups(user): - raw_groups = user.groups.all() - groups = [group.name for group in raw_groups] - # print(groups) - return groups - - @staticmethod - def user_type(user): - groups = UserInformation.user_groups(user) - if "teachers" in groups: - return UserInformation.TEACHER - elif "students" in groups: - return UserInformation.STUDENT - else: - return UserInformation.OTHER - - @staticmethod - def _user_type_formatted(user_type): - return "Lehrer" if user_type == UserInformation.TEACHER else ( - "Schüler" if user_type == UserInformation.STUDENT else "Sonstiges Mitglied") - - @staticmethod - def user_type_formatted(user): - user_type = UserInformation.user_type(user) - return UserInformation._user_type_formatted(user_type) - - @staticmethod - def user_classes(user): - groups = UserInformation.user_groups(user) - classes = UserInformation.regexr(r"class_(\w{1,3})", groups) - return classes - - @staticmethod - def user_courses(user): - groups = UserInformation.user_groups(user) - classes = UserInformation.regexr(r"course_(.{1,10})", groups) - return classes - - @staticmethod - def user_subjects(user): - groups = UserInformation.user_groups(user) - classes = UserInformation.regexr(r"subject_(\w{1,3})", groups) - return classes - - @staticmethod - def user_has_wifi(user): - groups = UserInformation.user_groups(user) - if "teachers" in groups or "students-wifi" in groups: - return True - return False diff --git a/aleksis/core/util/network.py b/aleksis/core/util/network.py deleted file mode 100644 index 6c81df3330006f4ba8f591615d1c3aa06d939bcd..0000000000000000000000000000000000000000 --- a/aleksis/core/util/network.py +++ /dev/null @@ -1,167 +0,0 @@ -import re - -import requests -from django.utils import timezone, formats -from ics import Calendar -from requests import RequestException - -from dashboard import settings -from dashboard.caches import LATEST_ARTICLE_CACHE, CURRENT_EVENTS_CACHE - -WP_DOMAIN: str = "https://katharineum-zu-luebeck.de" - -VS_COMPOSER_REGEX = re.compile(r"\[[\w\s\d!\"§$%&/()=?#'+*~’¸´`;,·.:…\-_–]*\]") - - -def get_newest_articles(domain: str = WP_DOMAIN, - limit: int = 5, - author_whitelist: list = None, - author_blacklist: list = None, - category_whitelist: list = None, - category_blacklist: list = None - ): - """ - This function returns the newest articles/posts of a WordPress site. - - :param domain: The domain to get the newest posts from (for example https://wordpress.com). Don't put a slash (/) at the end! - :param limit: if 0: all posts will be shown, else nly the certain number - :param author_whitelist: If this list is filled, only articles which are written by one of this authors will be shown - :param author_blacklist: If the author's id (an integer) is in this list, the article won't be shown - :param category_whitelist: If this list is filled, only articles which are in one of this categories will be shown - :param category_blacklist: If the category's id (an integer) is in this list, the article won't be shown - :return: a list of the newest posts/articles - """ - # Make mutable default arguments unmutable - if category_whitelist is None: - category_whitelist = [] - if category_blacklist is None: - category_blacklist = [] - if author_whitelist is None: - author_whitelist = [] - if author_blacklist is None: - author_blacklist = [] - - suffix: str = "/wp-json/wp/v2/posts" - url: str = domain + suffix - try: - site: requests.request = requests.get(url, timeout=10) - data: dict = site.json() - except RequestException as e: - print("E", str(e)) - return [] - posts: list = [] - - for post in data: - if post["author"] not in author_blacklist: - if len(author_whitelist) > 0 and post["author"] not in author_whitelist: - continue - - if post["categories"][0] not in category_blacklist: - if len(category_whitelist) > 0 and post["categories"][0] not in category_whitelist: - continue - - # Now get the link to the image - if post["_links"].get("wp:featuredmedia", False): - media_site: requests.request = requests.get(post["_links"]["wp:featuredmedia"][0]["href"]).json() - image_url: str = media_site["guid"]["rendered"] - else: - image_url: str = "" - - # Replace VS composer tags if activated - if settings.latest_article_settings.replace_vs_composer_stuff: - excerpt = VS_COMPOSER_REGEX.sub("", post["excerpt"]["rendered"]) - else: - excerpt = post["excerpt"]["rendered"] - - posts.append( - { - "title": post["title"]["rendered"], - "short_text": excerpt, - "link": post["link"], - "image_url": image_url, - } - ) - if len(posts) >= limit and limit >= 0: - break - - return posts - - -@LATEST_ARTICLE_CACHE.decorator -def get_newest_article_from_news(domain=WP_DOMAIN): - newest_articles: list = get_newest_articles(domain=domain, limit=1, category_whitelist=[1, 27]) - if len(newest_articles) > 0: - return newest_articles[0] - else: - return None - - -def get_current_events(calendar: Calendar, limit: int = 5) -> list: - """ - Get upcoming events from calendar - :param calendar: The calendar object - :param limit: Count of events - :return: List of upcoming events - """ - i: int = 0 - events: list = [] - for event in calendar.timeline.start_after(timezone.now()): - # Check for limit - if i >= limit: - break - i += 1 - - # Create formatted dates and times for begin and end - begin_date_formatted = formats.date_format(event.begin) - end_date_formatted = formats.date_format(event.end) - begin_time_formatted = formats.time_format(event.begin.time()) - end_time_formatted = formats.time_format(event.end.time()) - - if event.begin.date() == event.end.date(): - # Event is only on one day - formatted = begin_date_formatted - - if not event.all_day: - # No all day event - formatted += " " + begin_time_formatted - - if event.begin.time != event.end.time(): - # Event has an end time - formatted += " – " + end_time_formatted - - else: - # Event is on multiple days - if event.all_day: - # Event is all day - formatted = "{} – {}".format(begin_date_formatted, end_date_formatted) - else: - # Event has begin and end times - formatted = "{} {} – {} {}".format(begin_date_formatted, begin_time_formatted, end_date_formatted, - end_time_formatted) - - events.append({ - "name": event.name, - "begin_timestamp": event.begin.timestamp, - "end_timestamp": event.end.timestamp, - "formatted": formatted - }) - - return events - - -@CURRENT_EVENTS_CACHE.decorator -def get_current_events_with_cal(limit: int = 5) -> list: - # Get URL - calendar_url: str = settings.current_events_settings.calendar_url - if calendar_url is None or calendar_url == "": - return [] - - # Get ICS - try: - calendar: Calendar = Calendar(requests.get(calendar_url, timeout=3).text) - except RequestException as e: - print("E", str(e)) - return [] - - # Get events - return get_current_events(calendar, settings.current_events_settings.events_count)