From 6f999e419d960b880d9ee8c49980b2f658590ee4 Mon Sep 17 00:00:00 2001 From: Jens Kleineheismann Date: Wed, 6 Nov 2019 13:25:06 +0100 Subject: [PATCH] dav_submission: added email notification, zip-download and permission check. --- dav_submission/apps.py | 4 +- .../settings-dav_submission.py | 6 ++- dav_submission/emails.py | 32 +++++++++++++++ .../dav_submission/emails/new_submission.txt | 14 +++++++ .../templates/dav_submission/list.html | 15 ++++--- dav_submission/views.py | 39 ++++++++++++++++--- 6 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 dav_submission/emails.py create mode 100644 dav_submission/templates/dav_submission/emails/new_submission.txt diff --git a/dav_submission/apps.py b/dav_submission/apps.py index bf87975..4a87038 100644 --- a/dav_submission/apps.py +++ b/dav_submission/apps.py @@ -5,12 +5,14 @@ from django.conf import settings from dav_base.config.apps import AppConfig as _AppConfig, DefaultSetting DEFAULT_SETTINGS = ( + DefaultSetting('notify_address', 'webmaster@alpenverein-karlsruhe.de'), DefaultSetting('enable_upload', True), DefaultSetting('upload_path', os.path.join(settings.BASE_VAR_DIR, 'lib', 'dav_submission', 'submissions')), - DefaultSetting('max_files', 100), + DefaultSetting('max_files', 5), DefaultSetting('max_file_size_mib', 50), DefaultSetting('max_total_size_mib', 100), DefaultSetting('metadata_file_name', 'metadata.txt'), + DefaultSetting('cached_zip_file_name', '.cache.zip'), ) diff --git a/dav_submission/django_project_config/settings-dav_submission.py b/dav_submission/django_project_config/settings-dav_submission.py index 7ae2552..413cf2c 100644 --- a/dav_submission/django_project_config/settings-dav_submission.py +++ b/dav_submission/django_project_config/settings-dav_submission.py @@ -2,8 +2,10 @@ import os from django.conf import settings +# NOTIFY_ADDRESS = 'webmaster@alpenverein-karlsruhe.de' # UPLOAD_PATH = os.path.join(settings.BASE_VAR_DIR, 'lib', 'dav_submission', 'submissions') -MAX_FILES = 5 +# MAX_FILES = 5 # MAX_FILE_SIZE_MIB = 50 # MAX_TOTAL_SIZE_MIB = 100 -# METADATA_FILE_NAME = 'metadata.txt' \ No newline at end of file +# METADATA_FILE_NAME = 'metadata.txt' +# CACHED_ZIP_FILE_NAME = '.cache.zip' \ No newline at end of file diff --git a/dav_submission/emails.py b/dav_submission/emails.py new file mode 100644 index 0000000..230e927 --- /dev/null +++ b/dav_submission/emails.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from django.apps import apps + +from dav_base.emails import AbstractMail + +app_config = apps.get_containing_app_config(__package__) + + +class NewSubmissionMail(AbstractMail): + _subject = u'Neuer Beitrag: {title}' + _template_name = 'dav_submission/emails/new_submission.txt' + + def __init__(self, metadata): + self._metadata = metadata + + def _get_subject(self, subject_fmt=None, **kwargs): + kwargs['title'] = self._metadata['title'] + return super(NewSubmissionMail, self)._get_subject(subject_fmt=subject_fmt, **kwargs) + + def _get_reply_to(self): + s = u'"{fullname}" <{email}>'.format(fullname=self._metadata['name'], + email=self._metadata['email_address']) + return [s] + + def _get_recipients(self): + r = app_config.settings.notify_address + return [r] + + def _get_context_data(self, extra_context=None): + context = super(NewSubmissionMail, self)._get_context_data(extra_context=extra_context) + context['metadata'] = self._metadata + return context diff --git a/dav_submission/templates/dav_submission/emails/new_submission.txt b/dav_submission/templates/dav_submission/emails/new_submission.txt new file mode 100644 index 0000000..7278ae7 --- /dev/null +++ b/dav_submission/templates/dav_submission/emails/new_submission.txt @@ -0,0 +1,14 @@ +Hallo Mein-DAV-Team, + +jemand hat einen neuen Beitrag eingereicht: + +Absender: {{ metadata.name }} <{{ metadata.email_address }}> +Gruppe: {{ metadata.group }} +Datum: {{ metadata.date }} {{ metadata.time }} +Titel: {{ metadata.title }} +Beschreibung: +{{ metadata.description }} + +Ihr könnt den Beitrag unter + https://mein-dav.alpenverein-karlsruhe.de/download +herunterladen. \ No newline at end of file diff --git a/dav_submission/templates/dav_submission/list.html b/dav_submission/templates/dav_submission/list.html index 3307eb8..6e0149b 100644 --- a/dav_submission/templates/dav_submission/list.html +++ b/dav_submission/templates/dav_submission/list.html @@ -2,7 +2,7 @@ {% load i18n %} {% load bootstrap3 %} -{% block page-container %} +{% block page-container-fluid %}

Einreichungen

@@ -11,20 +11,18 @@ + + {% for object in object_list %} + {% endfor %} @@ -64,4 +67,4 @@ } ); -{% endblock page-container %} +{% endblock page-container-fluid %} diff --git a/dav_submission/views.py b/dav_submission/views.py index 64de78e..521f442 100644 --- a/dav_submission/views.py +++ b/dav_submission/views.py @@ -6,15 +6,19 @@ import os import pytz import re import urllib +import zipfile from django.apps import apps from django.contrib import messages +from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.http import FileResponse, Http404 from django.urls import reverse_lazy from django.utils import timezone +from django.utils.decorators import method_decorator from django.utils.translation import ugettext as _ from django.views import generic +from .emails import NewSubmissionMail from .forms import UploadForm app_config = apps.get_containing_app_config(__package__) @@ -71,9 +75,16 @@ class ListView(generic.ListView): qs = [all_metadata[subdir] for subdir in subdirs] return qs + @method_decorator(login_required) + def dispatch(self, request, *args, **kwargs): + if not request.user.has_perm('download_submissions'): + raise PermissionDenied() + return super(ListView, self).dispatch(request, *args, **kwargs) + class DownloadView(generic.DetailView): def get(self, request, *args, **kwargs): + cached_zip_file_name = app_config.settings.cached_zip_file_name base_path = app_config.settings.upload_path pk = kwargs.get('pk') @@ -82,11 +93,22 @@ class DownloadView(generic.DetailView): else: subdir = urllib.parse.unquote_plus(pk) - path = os.path.join(base_path, subdir) + submission_dir = os.path.join(base_path, subdir) - if not os.path.isdir(path): + if not os.path.isdir(submission_dir): raise Http404() + cached_zip = os.path.join(submission_dir, cached_zip_file_name) + if not os.path.isfile(cached_zip): + with open(cached_zip, 'wb') as cache_f: + with zipfile.ZipFile(cache_f, 'w') as z: + for filename in os.listdir(submission_dir): + if filename == cached_zip_file_name: + continue + z.write(os.path.join(submission_dir, filename), os.path.join(subdir, filename)) + + zip_f = open(cached_zip, 'rb') + file_name = subdir file_ext = '.zip' mime_type = 'application/zip' @@ -95,15 +117,18 @@ class DownloadView(generic.DetailView): file_ext=file_ext, ) - raise Exception('Not Implemented yet') - file_obj = open(path, 'rb') - - response = FileResponse(streaming_content=file_obj, content_type=mime_type) + response = FileResponse(streaming_content=zip_f, content_type=mime_type) disposition_header = 'attachment; filename="{}"'.format(disposition_file_name) response['Content-Disposition'] = disposition_header return response + @method_decorator(login_required) + def dispatch(self, request, *args, **kwargs): + if not request.user.has_perm('download_submissions'): + raise PermissionDenied() + return super(DownloadView, self).dispatch(request, *args, **kwargs) + class UploadView(generic.edit.FormView): initial = { @@ -235,6 +260,8 @@ Beschreibung: logger.error('dav_submission.views.UploadView.form_valid(): Catched Exception #3: %s', str(e)) return super(UploadView, self).form_valid(form) + mail = NewSubmissionMail(metadata_format_kwargs) + mail.send() return super(UploadView, self).form_valid(form) def post(self, request, *args, **kwargs):
{% trans 'Titel' %} {% trans 'Absender' %} {% trans 'Datum' %} 
 
- {% bootstrap_icon 'download-alt' %} -   {{ object.title }} @@ -33,6 +31,11 @@ {{ object.timestamp|date:'l, d. F Y H:i:s e' }} + {% bootstrap_icon 'download-alt' %} +