This commit is contained in:
2020-10-17 11:04:52 +00:00
18 changed files with 357 additions and 124 deletions

View File

@@ -19,3 +19,23 @@ def authenticated_user(view_func):
return redirect('home')
return wrapper_func
def ep_unauthenticated_user(view_func):
def wrapper_func(request, *args, **kwargs):
if request.user.is_authenticated:
return None, None
else:
return view_func(request, *args, **kwargs)
return wrapper_func
def ep_authenticated_user(view_func):
def wrapper_func(request, *args, **kwargs):
if request.user.is_authenticated:
return view_func(request, *args, **kwargs)
else:
return None, None
return wrapper_func

View File

@@ -5,6 +5,9 @@ import urllib.parse
from etherpad_lite import EtherpadLiteClient, EtherpadException
import logging
logger = logging.getLogger(__name__)
SERVER_URL = settings.ETHERPAD_CLIENT["exturl"]
@@ -22,7 +25,8 @@ def get_ep_client():
)
group = epc.createGroupIfNotExistsFor(groupMapper="fet")
except Exception as e:
raise e
logger.info("Can't get connection to Etherpad Server. Error: {}".format(e))
return None, None
return epc, group
@@ -32,7 +36,7 @@ def __checkPadExists(padID=None):
return False
epc, group = get_ep_client()
if not epc:
if not epc or not group:
return None
try:
@@ -64,12 +68,6 @@ def createPadifNotExists(padID):
return padID
def getReadOnlyID(padID):
epc, group = get_ep_client()
url = epc.getReadOnlyID(padID=group["groupID"] + "$" + padID)['readOnlyID']
return url
def getPadHTML(padID):
epc, group = get_ep_client()
text = epc.getHTML(padID=group["groupID"] + "$" + padID)["html"]
@@ -87,7 +85,7 @@ def get_pad_link(padID):
return "#"
epc, group = get_ep_client()
if epc:
return urllib.parse.urljoin(SERVER_URL, 'p/' + group["groupID"] + '$' + str(padID))
return ""

View File

@@ -1,12 +1,14 @@
from datetime import datetime, timedelta
from .api import get_ep_client
from authentications.decorators import authenticated_user
from authentications.decorators import ep_authenticated_user
@authenticated_user
@ep_authenticated_user
def __get_ep_sessionid(request):
epc, group = get_ep_client()
if not epc or not group:
return None, None
author = epc.createAuthorIfNotExistsFor(
name=str(request.user),

View File

@@ -61,6 +61,8 @@ else:
ALLOWED_HOSTS = ["127.0.0.1", env('HOST_NAME')]
HOST_NAME = env('HOST_NAME')
DATA_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 1024
# Application definition
@@ -79,6 +81,7 @@ INSTALLED_APPS = [
'ckeditor_uploader',
'easy_thumbnails',
'rest_framework',
'django_crontab',
'django_filters',
'django_static_jquery_ui',
'posts.apps.PostsConfig',
@@ -213,6 +216,7 @@ CKEDITOR_CONFIGS = {
}
}
# THUMBNAIL
THUMBNAIL_ALIASES = {
'': {
'avatar': {'size': (50, 50), 'crop': True},
@@ -238,4 +242,19 @@ REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
}
# ETHERPAD SETTINGS
# DJANGO MAIL
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'buran.htu.tuwien.ac.at'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
# CRON JOBS
CRONJOBS = [
('0 16 * * *', 'posts.cronjobs.check_to_send_agenda_mail'),
]
>>>>>>> b9c1517be5fca7a97ca270bfaa0624b5a7ef7148

View File

@@ -34,12 +34,12 @@ def index(request):
featured_meeting = FetMeeting.objects.get_meetings()
context = {
'posts': posts,
'posts': deque(list(posts)[:5]),
'events': Event.all_events.get_five_events(),
'featured_post': featured_post,
'featured_event': featured_event,
'featured_meeting': featured_meeting,
'tags_list': ", ".join(t)
'tags_list': " ".join(t)
}
return render(request, 'home.html', context)

View File

@@ -94,7 +94,7 @@ class Member(models.Model):
role = models.CharField(max_length=1, choices=MemberRole.choices, default=MemberRole.ACTIVE)
description = models.TextField(null=True, blank=True)
image = ThumbnailerImageField()
image = ThumbnailerImageField(upload_to='uploads/members/image/')
birthday = models.DateField(null=True, blank=True)

View File

@@ -1,19 +1,57 @@
# import django.contrib.auth.admin
# import django.contrib.auth.models
import taggit.admin
from django.contrib import admin, auth
from django.contrib import admin, auth, messages
from django.utils.translation import gettext_lazy as _
from .models import Post, Event, News, FetMeeting
from .forms import MyPostForm, MyEventForm, MyNewsForm, MyFetMeetingForm
from documents.api import createPadifNotExists
import taggit.admin
admin.site.unregister(auth.models.User)
admin.site.unregister(auth.models.Group)
admin.site.unregister(taggit.models.Tag)
def make_fetmeeting(modeladmin, request, queryset):
queryset.update(post_type='F')
def make_fetmeeting(self, request, queryset):
qs = self.get_queryset(request).filter(id=request.POST['_selected_action']).first()
failed = False
agenda_key = None
protocol_key = None
try:
agenda_key = createPadifNotExists(qs.slug + "-agenda")
except Exception as e:
self.message_user(
request,
_('Das Agenda konnte nicht erstellt werden. Error: %s') % str(e),
messages.ERROR,
)
failed = True
try:
protocol_key = createPadifNotExists(qs.slug + "-protocol")
except Exception as e:
self.message_user(
request,
_('Das Protokoll konnte nicht erstellt werden. Error: %s') % str(e),
messages.ERROR,
)
failed = True
if not failed:
queryset.update(
post_type='F',
has_agenda=True,
has_protocol=True,
agenda_key=agenda_key,
protocol_key=protocol_key,
)
self.message_user(
request,
_('Das Event %s wurde erfolgreich in eine FET Sitzung konvertiert.') % (qs.title),
messages.SUCCESS,
)
make_fetmeeting.short_description = "In eine Fachschaftssitzung konvertieren"
@@ -82,6 +120,7 @@ class MyFetMeetingAdmin(MyEventAdmin):
model = FetMeeting
list_filter = []
list_display = ['title', 'slug', 'event_start', 'public_date']
actions = []
admin.site.register(FetMeeting, MyFetMeetingAdmin)

23
fet2020/posts/cronjobs.py Normal file
View File

@@ -0,0 +1,23 @@
# HOW TO ADD CRONJOBS
# write a cronjob function
# add cronjob to fet2020/settings.py
# add cronjob with cmd 'fet2020/manage.py crontab add'
from django.utils import timezone
from .models import FetMeeting
from .mails import send_agenda_mail
from datetime import timedelta
def check_to_send_agenda_mail():
agenda_date = timezone.now().date() + timedelta(days=2)
next_meeting = FetMeeting.objects.filter(event_start__date=agenda_date).first()
if next_meeting and next_meeting.has_agenda:
send_agenda_mail(
self.event_start.date().strftime("%d.%m.%Y"),
self.event_start.time(),
self.slug,
)

17
fet2020/posts/mails.py Normal file
View File

@@ -0,0 +1,17 @@
from django.conf import settings
from django.core.mail import send_mail
def send_agenda_mail(date, time, slug):
msg = "Liebe Alle,\n\n" \
"wir haben am " + str(date) + " um " + str(time) + " wieder Sitzung.\n" \
"du hast noch bis morgen Zeit, weitere Themen auf die Agenda zu schreiben: " \
+ settings.HOST_NAME + '/posts/' + str(slug) + ".\n\n" \
"LG deine FET"
send_mail(
subject = 'Test - Agenda der FET Sitzung von ' + str(date),
message = msg,
from_email = 'patrick@fet.at',
recipient_list = ['all@fet.at', ],
)

View File

@@ -1,17 +1,18 @@
django==3.1.*
django==3.1.2
django-ckeditor==6.0.0
django-crontab==0.7.1
django-environ==0.4.5
django-filter==2.3.0
django-static-jquery-ui==1.12.1.1
django-taggit==1.3.0
djangorestframework==3.12.1
configparser==5.0.1
docutils==0.16
easy-thumbnails==2.7.0
configparser
etherpad-lite==0.5
#mysql-python
ghostscript==0.6
ldap3==2.8.1
mysqlclient==2.0.1
Pillow==7.2.0
ghostscript==0.6

View File

@@ -1,4 +1,5 @@
from django import forms
from django.utils.translation import gettext_lazy as _
from .models import Task
@@ -13,3 +14,14 @@ class TaskForm(forms.ModelForm):
'due_date',
'assigned_to',
]
labels = {
'title': _('Titel des Tasks'),
'task_list': _('Task-Gruppe'),
'due_date': _('Fälligkeitsdatum'),
'assigned_to': _('Zuweisen an'),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # to get the self.fields set
self.fields['assigned_to'].empty_label = "Alle"

View File

@@ -46,7 +46,7 @@ def index(request):
users = User.objects.all()
context = {
"form": form,
"formset": form,
"tasks": tasks,
"users": users,
"current_user": current_user,

View File

@@ -5,8 +5,7 @@
<div class="grid-container">
<h1>Blackboard</h1>
<!-- Tab panes -->
<div class="tabs-content">
<div class="grid-x grid-margin-x">
{% for job in jobPostings %}
{% include 'blackboard/partials/_jobPosting.html' %}
{% endfor %}

View File

@@ -1,10 +1,9 @@
<div class="grid-x">
<div class="medium-3 large-2 small-6 cell">
<div class="cell medium-4 large-3 small-12">
<h2>{{job.companyName}}</h2>
<p>{{job.jobName}}<br>
Mindestgehalt: {{job.salary}}€</p>
{# only thumb and name of member #}
<a class="thumbnail member-thumb" href="{{job.pdfLocation.url}}" style="width:200px;height:300px">
<a class="thumbnail member-thumb" href="{{job.pdfLocation.url}}" style="width:200px;height:280px">
<img src="{{job.pdf_thumb_location}}" alt="" />
<div class="thumb-layer">
<div>
@@ -15,4 +14,3 @@
</div>
</a>
</div>
</div>

View File

@@ -4,60 +4,67 @@
{% block content %}
<div class="grid-x">
<div class="grid-x small-padding-left-1">
<div class="medium-8 small cell" style="background: grey">
{% with post=featured_post %}
<a href="{{ post.url }}">
<div class="news-hero-large"style="background-image: url('{{ post.imageurl }}');)">
<div class="news-hero-text" >
<hr>
<div class="article-date">
<p>{{ post.public_date }}</p>
</div>
<div class="article-title">
<h1>{{ post.title|safe }}</h1>
<p>{{ post.subtitle|default_if_none:"&nbsp;"|safe }}</p>
</div>
<div class="news-hero-text">
<hr>
<div class="article-date">
<p>{{ post.public_date }}</p>
</div>
<div class="article-title">
<h1>{{ post.title|safe }}</h1>
<p>{{ post.subtitle|default_if_none:"&nbsp;"|safe }}</p>
</div>
</div>
</div>
</a>
{% endwith %}
</div>
<div class="medium-4 responsive-side-box cell">
<a href="{% url 'posts.index' %}"><h1>Neuigkeiten</h1></a>
<div class="cell medium-4 responsive-side-box">
<div class="article-row-section">
{% with post=featured_event %}
{% include 'posts/partials/_article_row.html' %}
{% endwith %}
{% for post in featured_meeting %}
{% include 'posts/partials/_meeting_row.html' %}
{% endfor %}
<div class="article-row-section-inner">
<h1 class="article-row-section-header"><a href="{% url 'posts.index' %}">Neuigkeiten</a></h1>
{% with post=featured_event %}
{% include 'posts/partials/_article_row.html' %}
{% endwith %}
{% for post in featured_meeting %}
{% include 'posts/partials/_meeting_row.html' %}
{% endfor %}
</div>
</div>
</div>
</div>
<div class="grid-container">
<div class="grid-x grid-padding-x padding-top-1">
<div class="grid-x grid-padding-x padding-top-1 padding-left-1 padding-right-1">
{{ tags_list|tags_to_url }}
</div>
<div class="grid-x grid-x-padding">
<div class="medium-8 small-12 small-order-2 medium-order-1"">
<div class="large-8 medium-7 small-12 small-order-2 medium-order-1">
{% for post in posts %}
{% include 'posts/partials/_posts_hero.html' %}
{% endfor %}
</div>
<div class="medium-4 small-12 small-order-1 medium-order-2 padding-1">
<div class="large-4 medium-5 small-12 small-order-1 medium-order-1 padding-top-1 large-padding-left-1 medium-padding-left-1">
{% for post in events %}
{% include 'posts/partials/_date_box.html' %}
{% endfor %}
<iframe src="https://discordapp.com/widget?id=691755025697079347&theme=dark" style="width: 100%;" height="500" allowtransparency="true" frameborder="0" sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"></iframe>
</div>
</div>
<a class="button" href="{% url 'posts.index' %}" style="background: gray">Mehr anzeigen</a>
</div>
{% endblock %}

View File

@@ -1,5 +1,5 @@
{% load static %}
<!doctype html>
<html class="no-js" lang="en">
<head>
@@ -8,45 +8,92 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FET</title>
<link rel="stylesheet" href="{% static 'app.css' %}">
{% csrf_token %}
{% block header %}
{% endblock %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
</head>
<body style="min-height:100%; position:relative">
<div class="top-bar" id="main-menu">
<div class="top-bar-left"><a href="{% url 'home' %}">
<img style="height:40px; width:40px" src="/assets/img/logo2014_64.png"/></a>
</div>
<div class="top-bar-right">
<ul class="menu vertical medium-horizontal expanded medium-text-center">
{% if request.user.is_authenticated %}
Hallo {{request.user.username}}
<li class=""><a href="/admin">Admin</a></li>
<li class=""><a href="{%url 'tasks'%}">Tasks</a> </li>
<li class=""><a href="{%url 'logout'%}">Logout</a> </li>
{% else %}
<li class=""><a href="{%url 'login'%}">Login</a> </li>
{% endif %}
<li class=""><a href="{%url 'home'%}">Aktuelles</a> </li>
<li class=""><a href="/fotos">Fotos</a> </li>
<li class=""><a href="/blackboard">Blackboard</a> </li>
<li class=""><a href="{%url 'members'%}">Mitarbeiter</a> </li>
</ul>
<div id="fb-root"></div>
<script async defer crossorigin="anonymous" src="https://connect.facebook.net/de_DE/sdk.js#xfbml=1&version=v8.0" nonce="WSEL84CK"></script>
<div class="header-title-bar" data-responsive-toggle="example-menu" data-hide-for="large">
<div class="title-bar" style="background: None">
<div class="title-bar-left">
<a href="{% url 'home' %}">
<img style="height:40px; width:40px" src="/assets/img/logo2014_64.png"/>
</a>
</div>
<div class="title-bar-right">
<button class="menu-icon dark"type="button" data-toggle="example-menu"></button>
</div>
</div>
</div>
<div class="top-bar" id="example-menu">
<div class="top-bar-left show-for-large">
<a href="{% url 'home' %}">
<img style="height:40px; width:40px" src="/assets/img/logo2014_64.png"/>
</a>
</div>
<div class="top-bar-right">
<ul class="dropdown vertical medium-horizontal menu" data-responsive-menu="drilldown medium-dropdown" data-animate-heigt="true">
{% if request.user.is_authenticated %}
<li class=""><a role="menuitem" style="color: black">Hallo {{request.user.username}}</a></li>
<li class=""><a href="/admin">Admin</a></li>
<li class=""><a href="{%url 'tasks'%}">Tasks</a></li>
{% endif %}
<li class=""><a href="{% url 'posts.index' %}">Aktuelles</a></li>
<li class=""><a href="/fotos">Fotos</a></li>
<li class=""><a href="/blackboard">Blackboard</a></li>
<li class=""><a href="{%url 'members'%}">Mitarbeiter</a></li>
{% if request.user.is_authenticated %}
<li class=""><a href="{%url 'logout'%}">Logout</a></li>
{% else %}
<li class=""><a href="{%url 'login'%}">Login</a></li>
{% endif %}
</ul>
</div>
</div>
{% block content %}
{% endblock %}
<div class="grid-y footer" style="height:8em; bottom:-8em; position: absolute; right:0; left:0">
<div class="footer">
<div class="grid-x medium-padding-1 large-padding-left-2" style="">
<div class="cell">
<ul class="no-bullet">
<li><a href="{% url 'posts.show' 'impressum'%}">Impressum</a></li>
<div class="grid-x medium-padding-1 padding-top-1 padding-left-1 padding-bottom-1 padding-right-1">
<div class="cell medium-6 large-9">
<div class="grid-y" style="height: 150px;">
<div class="cell small-6 medium-6 large-6">
<a href="{% url 'posts.show' 'impressum'%}">Impressum</a>
</div>
<div class="cell small-6 medium-6 large-6">
<a class="button" href="https://www.facebook.com/FachschaftET"><i class="fa fa-facebook" style="font-size:24px"></i></a>
<a class="button" href="https://www.instagram.com/fet_tuwien/"><i class="fa fa-instagram" style="font-size:24px"></i></a>
<a class="button" href="https://t.me/FETInfo"><i class="fa fa-telegram" style="font-size:24px"></i></a>
</div>
</div>
</div>
<div class="cell medium-6 large-3">
<div class="fb-page"
data-href="https://www.facebook.com/FachschaftET"
data-width="500"
data-height="150"
data-hide-cover="false"
data-show-facepile="false"></div>
</div>
</div>
</div>
</div>
<!-- App.js -->
<script src="{%static 'app.js' %}"></script>
</body>

View File

@@ -49,6 +49,8 @@
Start: {{ post.event_start }}<br>
Ende: {{ post.event_end }}<br>
{% if request.user.is_authenticated %}
{% if post.has_agenda %}
<a href="{{ ep_agenda_link }}">Agenda</a><br>
{% endif %}
@@ -57,7 +59,6 @@
<a href="{{ ep_protocol_link }}">Protokoll</a>
{% endif %}
{% if request.user.is_authenticated %}
<br>------<br>
<a href="{% url "admin:posts_news_change" post.id %}">Bearbeiten</a>
{% endif %}

View File

@@ -2,11 +2,72 @@
{% block content %}
<div class="grid-container">
<h1>Tasks</h1>
<div class="grid-x">
<form action="" method="post">
{% csrf_token %}
{% if current_user != None %}
{% for user in users %}
{% if current_user == user.id %}
<h1>Task-Übersicht für {{ user.username }}</h1>
{% endif %}
{% endfor %}
{% else %}
<h1>Task-Übersicht für alle Mitarbeiter_innen</h1>
{% endif %}
<form action="" method="post">
{% csrf_token %}
<div class="grid-x grid-margin-x">
{% regroup tasks by task_list as section_list %}
{% for group in section_list %}
<div class="cell">
<ul class="no-bullet">
<h3>{{ group.grouper }}</h3>
{% for task in group.list %}
<div class="grid-x">
<div class="cell medium-3 large-3 small-10">
<input type="checkbox" name="checkbox" value="{{ task.id }}" {% if task.completed %} checked {% endif %}>
{{ task.title }}</a>
</div>
<div class="cell medium-4 large-4 small-10">
{% if task.due_date is not None %}
Fälligkeitsdatum: {{ task.due_date|date:"d.m.Y" }}
{% endif %}
</div>
</div>
{% endfor %}
</ul>
</div>
{% endfor %}
<div class="cell">
<ul class="no-bullet">
<input type="submit" class="button" name="btn_checkbox" value="Task abschließen">
</ul>
</div>
</div>
</form>
<h2>Andere Task-Übersicht anzeigen</h2>
<form action="" method="post">
{% csrf_token %}
<div class="grid-x grid-margin-x">
<div class="cell medium-4 large-3 small-10">
<label>User
<select id="id_user" name="user">
<option value="all">
@@ -19,59 +80,48 @@
{% endfor %}
</select>
</label>
</div>
<div class="cell medium-4 large-3 small-10">
<label>Aktion
<select id="id_action" name="action">
<option value="show_incompleted" {% if not current_action %} selected {% endif %}>unvollständige Tasks</option>
<option value="show_all" {% if current_action %} selected {% endif %}>alle Tasks</option>
</select>
</label>
</div>
<div class="cell medium-3 large-3 small-10 align-self-bottom">
<input type="submit" class="button" name="btn_user" value="Anzeigen">
</form>
</div>
</div>
<div class="grid-x">
</form>
<form action="" method="post">
{% csrf_token %}
{% regroup tasks by task_list as section_list %}
{% for group in section_list %}
<h2>Neuen Task hinzufügen</h2>
<div class="cell">
<ul class="no-bullet">
<form action="" method="post">
{% csrf_token %}
<h3>{{ group.grouper }}</h3>
<div class="grid-x grid-margin-x">
{% for task in group.list %}
<input type="checkbox" name="checkbox" value="{{ task.id }}" {% if task.completed %} checked {% endif %}>
{{ task.title }}</a>
{{ task.due_date|date:"d.m.Y" }}
<br>
{% endfor %}
</div>
{{ formset.management_form }}
{% for form in formset %}
<div class="cell medium-3 large-2 small-10">
{{ form.label }}
{{ form }}
</div>
{% endfor %}
<div class="cell medium-3 large-2 small-10 align-self-bottom">
<input type="submit" class="button" name="btn_input" value="Hinzufügen">
</div>
<input type="submit" class="button" name="btn_checkbox" value="Task abschließen">
</form>
</div>
</div>
<div class="grid-x">
<form action="" method="post">
<h2>neue Tasks hinzufügen</h2>
{% csrf_token %}
{{ form }}
<input type="submit" class="button" name="btn_input" value="Hinzufügen">
</form>
</div>
</form>
</div>