123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- from .context import context_adaption
- from django.conf import settings
- from django.shortcuts import render, redirect, HttpResponse
- from django.http import HttpResponseNotFound, HttpResponseForbidden
- import fstools
- import importlib
- import mimetypes
- from mycreole import url_upload, url_attachment, url_delete
- import logging
- import mycreole
- import os
- import stringtools
- import themes
- from django.contrib import messages
-
- try:
- from config import APP_NAME as ROOT_LOGGER_NAME
- except ImportError:
- ROOT_LOGGER_NAME = 'root'
- logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
-
-
- def get_method(import_string):
- class_data = import_string.split(".")
- module_path = ".".join(class_data[:-1])
- class_str = class_data[-1]
- #
- module = importlib.import_module(module_path)
- return getattr(module, class_str)
-
-
- def get_next(request):
- if not request.POST:
- return request.GET.get('next', '/')
- else:
- return request.POST.get('next', '/')
-
-
- def access(access_type, request, rel_path):
- def log_warning(access_type, e):
- logger.warning('Could not import %s_access method for checking access rights: %s - %s', access_type, type(e).__name__, e)
-
- try:
- method_name = settings.MYCREOLE_ATTACHMENT_ACCESS[access_type]
- except (AttributeError, KeyError) as e:
- log_warning(access_type, e)
- return False
- else:
- if method_name in [True, None]:
- return True
- elif method_name is False:
- return False
- else:
- try:
- return get_method(method_name)(request, rel_path)
- except AttributeError as e:
- log_warning(access_type, e)
- return False
-
-
- def mycreole_attachment(request, rel_path):
- full_path = mycreole.get_full_path(rel_path)
- if access('read', request, rel_path):
- if os.path.isfile(full_path):
- mimetypes.init()
- mime_type = mimetypes.types_map.get(os.path.splitext(full_path)[1])
- data = open(full_path, 'rb').read()
- return HttpResponse(data, content_type=mime_type)
- else:
- return HttpResponseNotFound(rel_path)
- else:
- return HttpResponseForbidden(rel_path)
-
-
- def mycreole_upload(request, rel_path):
- if access('modify', request, rel_path):
- if not request.POST:
- context = themes.Context(request)
- context_adaption(
- context,
- request,
- 'Upload %s' % rel_path,
- os.path.dirname(rel_path),
- rel_path_is_directory=os.path.isdir(mycreole.get_full_path(rel_path)),
- next=request.GET.get('next', '/')
- )
- return render(request, 'mycreole/upload.html', context=context)
- else:
- filename = request.POST.get('filename')
- full_path = mycreole.get_full_path(rel_path)
- if filename is not None:
- full_path = os.path.join(full_path, filename)
- try:
- os.makedirs(os.path.dirname(full_path), exist_ok=True)
- except PermissionError:
- raise PermissionError("Ensure that we have access to MYCREOLE_ROOT=%s" % repr(settings.MYCREOLE_ROOT))
- else:
- with open(full_path, 'wb') as fh:
- fh.write(request.FILES['file'].read())
- messages.info(request, 'File %s successfully uploaded.' % os.path.basename(full_path))
- return redirect(request.POST.get('next', '/'))
- else:
- messages.error(request, "Upload: Access denied!")
- return redirect(request.GET.get('next', '/'))
-
-
- def mycreole_delete(request, rel_path):
- context = themes.Context(request) # needs to be executed first because of time mesurement
- nxt = get_next(request)
- modify_access = access('modify', request, rel_path)
- full_path = mycreole.get_full_path(rel_path)
- if not modify_access:
- messages.error(request, 'Detele Attachment: Access denied!')
- else:
- if not request.POST:
- context_adaption(
- context,
- request,
- 'Delete %s' % os.path.basename(rel_path),
- os.path.dirname(rel_path),
- next=nxt,
- filename=os.path.basename(rel_path)
- )
- return render(request, 'mycreole/delete.html', context=context)
- else:
- if request.POST.get('yes') is not None:
- try:
- os.remove(full_path)
- except Exception:
- messages.error(request, 'Error while deleting file from filesystem.')
- logger.exception('Fatal error while deleting Attachment!')
- else:
- messages.info(request, "Attachment %s deleted..." % os.path.basename(full_path))
- else:
- messages.info(request, 'Delete request aborded.')
- return redirect(nxt)
-
-
- def mycreole_manageuploads(request, rel_path):
- context = themes.Context(request) # needs to be executed first because of time mesurement
- nxt = get_next(request)
- read_access = access('read', request, rel_path)
- modify_access = access('modify', request, rel_path)
- #
- if not read_access:
- messages.error(request, "Manageupload: Access denied!")
- return redirect(nxt)
-
- basepath = mycreole.get_full_path(rel_path)
- if not os.path.exists(basepath):
- logger.info('Creating path for attachments: %s', basepath)
- fstools.mkdir(basepath)
- logger.debug("Searching for files in %s", basepath)
- attachments = {}
- for file in fstools.filelist(basepath):
- filename = os.path.basename(file)
- actions = []
- if modify_access:
- actions.append((themes.gray_icon_url(request, 'delete.png'), url_delete(request, os.path.join(rel_path, filename)), 'delete'))
- actions.append((themes.gray_icon_url(request, 'shuffle.png'), url_upload(request, os.path.join(rel_path, filename)), 'replace'))
- actions.append((themes.gray_icon_url(request, 'view.png'), url_attachment(os.path.join(rel_path, filename)), 'view'))
- attachments[filename] = {
- 'size': stringtools.physical_value_repr(os.path.getsize(file), 'B'),
- 'modify_access': modify_access,
- 'actions': actions,
- }
- logger.debug("%d attachments detected: %s", len(attachments), ', '.join(attachments.keys()))
- #
- mycreole.context.context_adaption(
- context,
- request,
- 'Manageuploads for %s' % rel_path,
- rel_path,
- next=nxt,
- attachments=attachments
- )
- return render(request, 'mycreole/manageuploads.html', context=context)
|