diff --git a/fet2020/authentications/decorators.py b/fet2020/authentications/decorators.py index d3af1cae..812721fd 100644 --- a/fet2020/authentications/decorators.py +++ b/fet2020/authentications/decorators.py @@ -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 diff --git a/fet2020/documents/api.py b/fet2020/documents/api.py index 942619c3..4555c58b 100644 --- a/fet2020/documents/api.py +++ b/fet2020/documents/api.py @@ -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 "" diff --git a/fet2020/documents/etherpadlib.py b/fet2020/documents/etherpadlib.py index 520fa5ea..9014d8b6 100644 --- a/fet2020/documents/etherpadlib.py +++ b/fet2020/documents/etherpadlib.py @@ -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), diff --git a/fet2020/fet2020/settings.py b/fet2020/fet2020/settings.py index 878dffa9..d993a93a 100644 --- a/fet2020/fet2020/settings.py +++ b/fet2020/fet2020/settings.py @@ -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', ] -} \ No newline at end of file +} + +# 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 diff --git a/fet2020/fet2020/views.py b/fet2020/fet2020/views.py index 33a212ba..3d2e5bdf 100644 --- a/fet2020/fet2020/views.py +++ b/fet2020/fet2020/views.py @@ -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) diff --git a/fet2020/members/models.py b/fet2020/members/models.py index 855c83d1..00e63f04 100644 --- a/fet2020/members/models.py +++ b/fet2020/members/models.py @@ -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) diff --git a/fet2020/posts/admin.py b/fet2020/posts/admin.py index 638194b4..33417518 100644 --- a/fet2020/posts/admin.py +++ b/fet2020/posts/admin.py @@ -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) diff --git a/fet2020/posts/cronjobs.py b/fet2020/posts/cronjobs.py new file mode 100644 index 00000000..fba4fe7b --- /dev/null +++ b/fet2020/posts/cronjobs.py @@ -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, + ) diff --git a/fet2020/posts/mails.py b/fet2020/posts/mails.py new file mode 100644 index 00000000..8b6ef842 --- /dev/null +++ b/fet2020/posts/mails.py @@ -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', ], + ) diff --git a/fet2020/requirements.txt b/fet2020/requirements.txt index 457a21e6..2ee39ebc 100644 --- a/fet2020/requirements.txt +++ b/fet2020/requirements.txt @@ -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 diff --git a/fet2020/tasks/forms.py b/fet2020/tasks/forms.py index 2ef71ee2..e4097c02 100644 --- a/fet2020/tasks/forms.py +++ b/fet2020/tasks/forms.py @@ -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" diff --git a/fet2020/tasks/views.py b/fet2020/tasks/views.py index b5870267..679f3b5f 100644 --- a/fet2020/tasks/views.py +++ b/fet2020/tasks/views.py @@ -46,7 +46,7 @@ def index(request): users = User.objects.all() context = { - "form": form, + "formset": form, "tasks": tasks, "users": users, "current_user": current_user, diff --git a/fet2020/templates/blackboard/index.html b/fet2020/templates/blackboard/index.html index b13fbc01..6ae266ac 100644 --- a/fet2020/templates/blackboard/index.html +++ b/fet2020/templates/blackboard/index.html @@ -5,8 +5,7 @@

Blackboard

- -
+
{% for job in jobPostings %} {% include 'blackboard/partials/_jobPosting.html' %} {% endfor %} diff --git a/fet2020/templates/blackboard/partials/_jobPosting.html b/fet2020/templates/blackboard/partials/_jobPosting.html index 6fefc75b..2bdc2694 100644 --- a/fet2020/templates/blackboard/partials/_jobPosting.html +++ b/fet2020/templates/blackboard/partials/_jobPosting.html @@ -1,10 +1,9 @@ -
-
+

{{job.companyName}}

{{job.jobName}}
Mindestgehalt: {{job.salary}}€

{# only thumb and name of member #} - + -
diff --git a/fet2020/templates/home.html b/fet2020/templates/home.html index d627f8dc..a9576468 100644 --- a/fet2020/templates/home.html +++ b/fet2020/templates/home.html @@ -4,60 +4,67 @@ {% block content %} -
- +
{% with post=featured_post %} -
-

Neuigkeiten

+
+
- {% with post=featured_event %} - {% include 'posts/partials/_article_row.html' %} - {% endwith %} - {% for post in featured_meeting %} - {% include 'posts/partials/_meeting_row.html' %} - {% endfor %} +
+ +

Neuigkeiten

+ + {% with post=featured_event %} + {% include 'posts/partials/_article_row.html' %} + {% endwith %} + {% for post in featured_meeting %} + {% include 'posts/partials/_meeting_row.html' %} + {% endfor %} +
-
+
{{ tags_list|tags_to_url }}
-
+
{% for post in posts %} {% include 'posts/partials/_posts_hero.html' %} {% endfor %}
-
+ +
{% for post in events %} {% include 'posts/partials/_date_box.html' %} {% endfor %} -
+
+ + Mehr anzeigen +
{% endblock %} diff --git a/fet2020/templates/layout.html b/fet2020/templates/layout.html index cc0fba63..cca8e03c 100644 --- a/fet2020/templates/layout.html +++ b/fet2020/templates/layout.html @@ -1,5 +1,5 @@ - {% load static %} + @@ -8,45 +8,92 @@ FET - {% csrf_token %} - {% block header %} - {% endblock %} + -