# -*- coding: utf-8 -*- import codecs import datetime import logging import os from django.apps import apps from django.contrib import messages from django.core.exceptions import PermissionDenied from django.urls import reverse_lazy from django.utils.translation import ugettext as _ from django.views import generic from .forms import UploadForm app_config = apps.get_containing_app_config(__package__) logger = logging.getLogger(__name__) class UploadView(generic.edit.FormView): initial = { # 'name': u'heinzel', # 'email_address': 'heinzel@heinzelwelt.de', # 'group': 'Alte Maschinen', # 'title': u'Mein Beitrag', # 'description': 'Foobar', # 'accepted': True, } template_name = 'dav_submission/upload_form.html' form_class = UploadForm success_url = reverse_lazy('dav_submission:success') def _sanitize_filename(self, input): max_length = None discard_chars = u'' allowed_chars = (u'abcdefghijklmnopqrstuvwxyz' u'äöüß' u'ABCDEFGHIJKLMNOPQRSTUVWXYZ' u'ÄÖÜ' u'0123456789' u'._-') non_allowed_substitute = u'_' space_substitute = u'_' if space_substitute is None: space_substitute = non_allowed_substitute r = '' for c in input: if c in discard_chars: continue elif allowed_chars is not None and c in allowed_chars: r += c elif allowed_chars is None and c.isalnum(): r += c elif c.isspace(): r += space_substitute else: r += non_allowed_substitute return r[:max_length] def get_context_data(self, **kwargs): c = super(UploadView, self).get_context_data(**kwargs) c['show_upload_form'] = app_config.settings.enable_upload return c def form_valid(self, form): base_path = app_config.settings.upload_path subdir_format_str = u'{datetime}--{title}' now = datetime.datetime.now() subdir_format_kwargs = {'datetime': now.strftime('%Y-%m-%d--%H%M%S'), 'date': now.strftime('%Y-%m-%d'), 'time': now.strftime('%H-%M-%S'), 'title': form.cleaned_data['title']} subdir_name = self._sanitize_filename( subdir_format_str.format(**subdir_format_kwargs) ) subdir_path = os.path.join(base_path, subdir_name) if os.path.isdir(subdir_path): message = _(u'Es gibt bereits einen Beitrag mit dem Titel "%(title)s".') % subdir_format_kwargs messages.error(self.request, message) form.add_error('title', message) return self.render_to_response(self.get_context_data(form=form)) os.makedirs(subdir_path) try: metadata_format_str = u"""Absender: {name} <{email_address}> Gruppe: {group} Datum: {date} {time} Titel: {title} Beschreibung: {description} """ metadata_format_kwargs = { 'date': now.strftime('%d.%m.%Y'), 'time': now.strftime('%H:%M:%S'), 'name': form.cleaned_data['name'], 'email_address': form.cleaned_data['email_address'], 'group': form.cleaned_data['group'], 'title': form.cleaned_data['title'], 'description': form.cleaned_data['description'], } metadata = metadata_format_str.format(**metadata_format_kwargs) metadata_file_name = app_config.settings.metadata_file_name metadata_file_path = os.path.join(subdir_path, metadata_file_name) with codecs.open(metadata_file_path, 'w', encoding='utf-8') as metadata_file: metadata_file.write(metadata) except Exception as e: message = _(u'Jetzt ist irgendwas schief gelaufen.') messages.error(self.request, message) logger.error('dav_submission.views.UploadView.form_valid(): Catched Exception #2: %s', str(e)) return super(UploadView, self).form_valid(form) try: for input_file in form.files.getlist('files'): file_name = self._sanitize_filename(input_file.name) file_path = os.path.join(subdir_path, file_name) if os.path.exists(file_path): message = _(u'Die Datei %(name)s haben wir bereits.') % {'name': input_file.name} messages.error(self.request, message) continue with open(file_path, 'wb+') as local_file: for chunk in input_file.chunks(): local_file.write(chunk) size = os.path.getsize(file_path) if size > (1024 * 1024): size_str = u'%s MiB' % ('%.3f' % (size / 1024.0 / 1024.0)).rstrip('0').rstrip('.') elif size > 1024: size_str = u'%s KiB' % ('%.3f' % (size / 1024.0)).rstrip('0').rstrip('.') else: size_str = u'%d Byte' % size message = _(u'Datei erfolgreich hochgeladen: %(name)s (%(size)s)') % {'name': input_file.name, 'size': size_str} messages.success(self.request, message) except Exception as e: message = _(u'Jetzt ist irgendwas schief gelaufen.') messages.error(self.request, message) 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) def post(self, request, *args, **kwargs): if not app_config.settings.enable_upload: raise PermissionDenied(_(u'Der Upload ist noch nicht freigeschaltet.')) return super(UploadView, self).post(request, *args, **kwargs) class SuccessView(generic.TemplateView): template_name = 'dav_submission/success.html'