Initial Attachment Management
This commit is contained in:
parent
5f30383c83
commit
057388e3b4
@ -89,6 +89,11 @@ def render(request, text, attachment_target_path, next_anchor=''):
|
||||
return creole.creole2html(text)
|
||||
|
||||
|
||||
def url_delete(request, rel_path, next_anchor=''):
|
||||
nxt = request.GET.get('next', request.get_full_path())
|
||||
return reverse('mycreole-delete', kwargs={'rel_path': rel_path}) + '?next=%s' % nxt + ('' if not next_anchor else '#%s' % next_anchor)
|
||||
|
||||
|
||||
def url_upload(request, rel_path, next_anchor=''):
|
||||
nxt = request.GET.get('next', request.get_full_path())
|
||||
return reverse('mycreole-upload', kwargs={'rel_path': rel_path}) + '?next=%s' % nxt + ('' if not next_anchor else '#%s' % next_anchor)
|
||||
|
32
context.py
32
context.py
@ -1,11 +1,35 @@
|
||||
from django.utils.translation import gettext as _
|
||||
import logging
|
||||
from mycreole import url_upload
|
||||
from users.context import menubar as user_menubar
|
||||
import themes
|
||||
from patt.context import navigationbar
|
||||
from themes import color_icon_url
|
||||
|
||||
try:
|
||||
from config import APP_NAME as ROOT_LOGGER_NAME
|
||||
except ImportError:
|
||||
ROOT_LOGGER_NAME = 'root'
|
||||
logger = logging.getLogger(ROOT_LOGGER_NAME).getChild(__name__)
|
||||
|
||||
NEW_ATTACHMENT_UID = 'new_attachment'
|
||||
|
||||
|
||||
def context_adaption(context, request, title, **kwargs):
|
||||
def context_adaption(context, request, title, rel_path, **kwargs):
|
||||
context.set_additional_title(title)
|
||||
user_menubar(context[context.MENUBAR], request)
|
||||
context[context.NAVIGATIONBAR].append_entry(*themes.empty_entry_parameters(request))
|
||||
context[context.ACTIONBAR].append_entry(*themes.empty_entry_parameters(request))
|
||||
navigationbar(context, request)
|
||||
add_new(request, context[context.ACTIONBAR], rel_path, kwargs.get('next'))
|
||||
for key in kwargs:
|
||||
context[key] = kwargs[key]
|
||||
logger.debug("context adapted: %s", repr(context))
|
||||
|
||||
|
||||
def add_new(request, bar, rel_path, nxt):
|
||||
bar.append_entry(
|
||||
NEW_ATTACHMENT_UID, # uid
|
||||
_('New Attachment'), # name
|
||||
color_icon_url(request, 'plus.png'), # icon
|
||||
url_upload(request, rel_path, nxt), # url
|
||||
True, # left
|
||||
False # active
|
||||
)
|
||||
|
17
templates/mycreole/delete.html
Normal file
17
templates/mycreole/delete.html
Normal file
@ -0,0 +1,17 @@
|
||||
{% extends "themes/"|add:settings.page_theme|add:"/base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<h1>Delete Attachment</h1>
|
||||
Are you sure deleting {{ filename }}?
|
||||
|
||||
<form class="form" method="post">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{{ next }}">
|
||||
<input type="submit" name="yes" value="{% trans "Yes" %}" class="button" />
|
||||
<input type="submit" name="no" value="{% trans "No" %}" class="button" />
|
||||
</form>
|
||||
|
||||
|
||||
{% endblock content %}
|
29
templates/mycreole/manageuploads.html
Normal file
29
templates/mycreole/manageuploads.html
Normal file
@ -0,0 +1,29 @@
|
||||
{% extends "themes/"|add:settings.page_theme|add:"/base.html" %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>Attachments</h1>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
{% for key, value in attachments.items %}
|
||||
<tr>
|
||||
<td>{{ key }}</td>
|
||||
<td>{{ value.size }}</td>
|
||||
<td>
|
||||
{% for icon, url, alt in value.actions %}
|
||||
<a href="{{ url }}"><img src="{{ icon }}" alt={{ alt }}></a>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% endblock content %}
|
@ -5,6 +5,9 @@
|
||||
<form class="form" method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{{ next }}">
|
||||
{% if rel_path_is_directory %}
|
||||
<p><label for="id_filename">Filename:</label> <input type="text" name="filename" maxlength="150" required id="id_filename"></p>
|
||||
{% endif %}
|
||||
<label class="required" for="f_file">Upload</label>
|
||||
<input class="required" required="required" type="file" name="file" id="f_file">
|
||||
<input type="submit" value="{% trans "Upload" %}" class="button" />
|
||||
|
1
urls.py
1
urls.py
@ -5,5 +5,6 @@ from . import views
|
||||
urlpatterns = [
|
||||
path('attachment/<path:rel_path>', views.mycreole_attachment, name='mycreole-attachment'),
|
||||
path('upload/<path:rel_path>', views.mycreole_upload, name='mycreole-upload'),
|
||||
path('delete/<path:rel_path>', views.mycreole_delete, name='mycreole-delete'),
|
||||
path('manageuploads/<path:rel_path>', views.mycreole_manageuploads, name='mycreole-manageuploads'),
|
||||
]
|
||||
|
95
views.py
95
views.py
@ -2,11 +2,14 @@ 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
|
||||
|
||||
@ -26,6 +29,13 @@ def get_method(import_string):
|
||||
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)
|
||||
@ -66,10 +76,20 @@ 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, next=request.GET.get('next', '/'))
|
||||
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:
|
||||
@ -77,12 +97,81 @@ def mycreole_upload(request, rel_path):
|
||||
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):
|
||||
messages.error(request, 'Manage Uploads: Not yet implemented!')
|
||||
return redirect(request.GET.get('next', '/'))
|
||||
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user