Implement attachment removal
This commit is contained in:
parent
2e02163701
commit
e7655ccfe8
5 changed files with 74 additions and 3 deletions
|
@ -131,6 +131,7 @@
|
||||||
<th>Uploaded</th>
|
<th>Uploaded</th>
|
||||||
<th>By</th>
|
<th>By</th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
|
<th>Remove</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -140,6 +141,12 @@
|
||||||
<td>{{ attachment.timestamp }}</td>
|
<td>{{ attachment.timestamp }}</td>
|
||||||
<td>{{ attachment.added_by.get_full_name }}</td>
|
<td>{{ attachment.added_by.get_full_name }}</td>
|
||||||
<td>{{ attachment.extension.lower }}</td>
|
<td>{{ attachment.extension.lower }}</td>
|
||||||
|
<td>
|
||||||
|
<form action="{% url "todo:remove_attachment" attachment.id %}" method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="submit" value="X" class="btn btn-danger btn-sm">
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
|
@ -56,6 +56,11 @@ urlpatterns = [
|
||||||
'task/<int:task_id>/',
|
'task/<int:task_id>/',
|
||||||
views.task_detail,
|
views.task_detail,
|
||||||
name='task_detail'),
|
name='task_detail'),
|
||||||
|
|
||||||
|
path(
|
||||||
|
'attachment/remove/<int:attachment_id>/',
|
||||||
|
views.remove_attachment,
|
||||||
|
name='remove_attachment'),
|
||||||
]
|
]
|
||||||
|
|
||||||
if HAS_TASK_MERGE:
|
if HAS_TASK_MERGE:
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import email.utils
|
import email.utils
|
||||||
import time
|
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.sites.models import Site
|
from django.contrib.sites.models import Site
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
|
|
||||||
from todo.models import Comment, Task
|
from todo.models import Attachment, Comment, Task
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -153,3 +154,19 @@ def toggle_task_completed(task_id: int) -> bool:
|
||||||
except Task.DoesNotExist:
|
except Task.DoesNotExist:
|
||||||
log.info(f"Task {task_id} not found.")
|
log.info(f"Task {task_id} not found.")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def remove_attachment_file(attachment_id: int) -> bool:
|
||||||
|
"""Delete an Attachment object and its corresponding file from the filesystem."""
|
||||||
|
try:
|
||||||
|
attachment = Attachment.objects.get(id=attachment_id)
|
||||||
|
if attachment.file:
|
||||||
|
if os.path.isfile(attachment.file.path):
|
||||||
|
os.remove(attachment.file.path)
|
||||||
|
|
||||||
|
attachment.delete()
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Attachment.DoesNotExist:
|
||||||
|
log.info(f"Attachment {attachment_id} not found.")
|
||||||
|
return False
|
||||||
|
|
|
@ -2,10 +2,11 @@ from todo.views.add_list import add_list # noqa: F401
|
||||||
from todo.views.del_list import del_list # noqa: F401
|
from todo.views.del_list import del_list # noqa: F401
|
||||||
from todo.views.delete_task import delete_task # noqa: F401
|
from todo.views.delete_task import delete_task # noqa: F401
|
||||||
from todo.views.external_add import external_add # noqa: F401
|
from todo.views.external_add import external_add # noqa: F401
|
||||||
|
from todo.views.import_csv import import_csv # noqa: F401
|
||||||
from todo.views.list_detail import list_detail # noqa: F401
|
from todo.views.list_detail import list_detail # noqa: F401
|
||||||
from todo.views.list_lists import list_lists # noqa: F401
|
from todo.views.list_lists import list_lists # noqa: F401
|
||||||
|
from todo.views.remove_attachment import remove_attachment # noqa: F401
|
||||||
from todo.views.reorder_tasks import reorder_tasks # noqa: F401
|
from todo.views.reorder_tasks import reorder_tasks # noqa: F401
|
||||||
from todo.views.search import search # noqa: F401
|
from todo.views.search import search # noqa: F401
|
||||||
from todo.views.task_detail import task_detail # noqa: F401
|
from todo.views.task_detail import task_detail # noqa: F401
|
||||||
from todo.views.toggle_done import toggle_done # noqa: F401
|
from todo.views.toggle_done import toggle_done # noqa: F401
|
||||||
from todo.views.import_csv import import_csv # noqa: F401
|
|
||||||
|
|
41
todo/views/remove_attachment.py
Normal file
41
todo/views/remove_attachment.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from django.http import HttpResponse
|
||||||
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from todo.models import Attachment
|
||||||
|
from todo.utils import remove_attachment_file
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def remove_attachment(request, attachment_id: int) -> HttpResponse:
|
||||||
|
"""Delete a previously posted attachment object and its corresponding file
|
||||||
|
from the filesystem, permissions allowing.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if request.method == "POST":
|
||||||
|
attachment = get_object_or_404(Attachment, pk=attachment_id)
|
||||||
|
|
||||||
|
redir_url = reverse(
|
||||||
|
"todo:task_detail",
|
||||||
|
kwargs={"task_id": attachment.task.id},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Permissions
|
||||||
|
if not (
|
||||||
|
attachment.task.task_list.group in request.user.groups.all()
|
||||||
|
or request.user.is_superuser
|
||||||
|
):
|
||||||
|
raise PermissionDenied
|
||||||
|
|
||||||
|
if remove_attachment_file(attachment.id):
|
||||||
|
messages.success(request, f"Attachment {attachment.id} removed.")
|
||||||
|
else:
|
||||||
|
messages.error(request, f"Sorry, there was a problem deleting attachment {attachment.id}.")
|
||||||
|
|
||||||
|
return redirect(redir_url)
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise PermissionDenied
|
Loading…
Add table
Add a link
Reference in a new issue