dav_submission: added email notification, zip-download and permission

check.
This commit is contained in:
2019-11-06 13:25:06 +01:00
parent bcacb033df
commit 6f999e419d
6 changed files with 95 additions and 15 deletions

View File

@@ -5,12 +5,14 @@ from django.conf import settings
from dav_base.config.apps import AppConfig as _AppConfig, DefaultSetting from dav_base.config.apps import AppConfig as _AppConfig, DefaultSetting
DEFAULT_SETTINGS = ( DEFAULT_SETTINGS = (
DefaultSetting('notify_address', 'webmaster@alpenverein-karlsruhe.de'),
DefaultSetting('enable_upload', True), DefaultSetting('enable_upload', True),
DefaultSetting('upload_path', os.path.join(settings.BASE_VAR_DIR, 'lib', 'dav_submission', 'submissions')), 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_file_size_mib', 50),
DefaultSetting('max_total_size_mib', 100), DefaultSetting('max_total_size_mib', 100),
DefaultSetting('metadata_file_name', 'metadata.txt'), DefaultSetting('metadata_file_name', 'metadata.txt'),
DefaultSetting('cached_zip_file_name', '.cache.zip'),
) )

View File

@@ -2,8 +2,10 @@
import os import os
from django.conf import settings from django.conf import settings
# NOTIFY_ADDRESS = 'webmaster@alpenverein-karlsruhe.de'
# UPLOAD_PATH = os.path.join(settings.BASE_VAR_DIR, 'lib', 'dav_submission', 'submissions') # 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_FILE_SIZE_MIB = 50
# MAX_TOTAL_SIZE_MIB = 100 # MAX_TOTAL_SIZE_MIB = 100
# METADATA_FILE_NAME = 'metadata.txt' # METADATA_FILE_NAME = 'metadata.txt'
# CACHED_ZIP_FILE_NAME = '.cache.zip'

32
dav_submission/emails.py Normal file
View File

@@ -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

View File

@@ -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.

View File

@@ -2,7 +2,7 @@
{% load i18n %} {% load i18n %}
{% load bootstrap3 %} {% load bootstrap3 %}
{% block page-container %} {% block page-container-fluid %}
<h3 class="top-most">Einreichungen</h3> <h3 class="top-most">Einreichungen</h3>
<div> <div>
<table id="objects_table" class="table table-striped"> <table id="objects_table" class="table table-striped">
@@ -11,20 +11,18 @@
<th>{% trans 'Titel' %}</th> <th>{% trans 'Titel' %}</th>
<th>{% trans 'Absender' %}</th> <th>{% trans 'Absender' %}</th>
<th>{% trans 'Datum' %}</th> <th>{% trans 'Datum' %}</th>
<th>&nbsp;</th>
</tr> </tr>
<tr> <tr>
<th><input type="text" placeholder="{% trans 'Filter' %}" /></th> <th><input type="text" placeholder="{% trans 'Filter' %}" /></th>
<th><input type="text" placeholder="{% trans 'Filter' %}" /></th> <th><input type="text" placeholder="{% trans 'Filter' %}" /></th>
<th><input type="text" placeholder="{% trans 'Filter' %}" /></th> <th><input type="text" placeholder="{% trans 'Filter' %}" /></th>
<th>&nbsp;</th>
</tr> </tr>
<tbody> <tbody>
{% for object in object_list %} {% for object in object_list %}
<tr> <tr>
<td> <td>
<a href="{% url 'dav_submission:download' object.pk %}"
class="btn btn-xs btn-primary"
title="Download">{% bootstrap_icon 'download-alt' %}</a>
&nbsp;
{{ object.title }} {{ object.title }}
</td> </td>
<td> <td>
@@ -33,6 +31,11 @@
<td data-order="{{ object.timestamp|date:'U' }}"> <td data-order="{{ object.timestamp|date:'U' }}">
{{ object.timestamp|date:'l, d. F Y H:i:s e' }} {{ object.timestamp|date:'l, d. F Y H:i:s e' }}
</td> </td>
<td>
<a href="{% url 'dav_submission:download' object.pk %}"
class="btn btn-xs btn-primary"
title="Download">{% bootstrap_icon 'download-alt' %}</a>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@@ -64,4 +67,4 @@
} ); } );
</script> </script>
</div> </div>
{% endblock page-container %} {% endblock page-container-fluid %}

View File

@@ -6,15 +6,19 @@ import os
import pytz import pytz
import re import re
import urllib import urllib
import zipfile
from django.apps import apps from django.apps import apps
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.http import FileResponse, Http404 from django.http import FileResponse, Http404
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views import generic from django.views import generic
from .emails import NewSubmissionMail
from .forms import UploadForm from .forms import UploadForm
app_config = apps.get_containing_app_config(__package__) app_config = apps.get_containing_app_config(__package__)
@@ -71,9 +75,16 @@ class ListView(generic.ListView):
qs = [all_metadata[subdir] for subdir in subdirs] qs = [all_metadata[subdir] for subdir in subdirs]
return qs 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): class DownloadView(generic.DetailView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
cached_zip_file_name = app_config.settings.cached_zip_file_name
base_path = app_config.settings.upload_path base_path = app_config.settings.upload_path
pk = kwargs.get('pk') pk = kwargs.get('pk')
@@ -82,11 +93,22 @@ class DownloadView(generic.DetailView):
else: else:
subdir = urllib.parse.unquote_plus(pk) 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() 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_name = subdir
file_ext = '.zip' file_ext = '.zip'
mime_type = 'application/zip' mime_type = 'application/zip'
@@ -95,15 +117,18 @@ class DownloadView(generic.DetailView):
file_ext=file_ext, file_ext=file_ext,
) )
raise Exception('Not Implemented yet') response = FileResponse(streaming_content=zip_f, content_type=mime_type)
file_obj = open(path, 'rb')
response = FileResponse(streaming_content=file_obj, content_type=mime_type)
disposition_header = 'attachment; filename="{}"'.format(disposition_file_name) disposition_header = 'attachment; filename="{}"'.format(disposition_file_name)
response['Content-Disposition'] = disposition_header response['Content-Disposition'] = disposition_header
return response 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): class UploadView(generic.edit.FormView):
initial = { initial = {
@@ -235,6 +260,8 @@ Beschreibung:
logger.error('dav_submission.views.UploadView.form_valid(): Catched Exception #3: %s', str(e)) logger.error('dav_submission.views.UploadView.form_valid(): Catched Exception #3: %s', str(e))
return super(UploadView, self).form_valid(form) return super(UploadView, self).form_valid(form)
mail = NewSubmissionMail(metadata_format_kwargs)
mail.send()
return super(UploadView, self).form_valid(form) return super(UploadView, self).form_valid(form)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):