Skip to content

Commit

Permalink
Support collection deletion (admin only)
Browse files Browse the repository at this point in the history
  • Loading branch information
U039b committed Nov 15, 2023
1 parent a38a669 commit 653194c
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 9 deletions.
3 changes: 2 additions & 1 deletion config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
reopen_batch_view, BatchTeamUpdateView, download_collection_zip_view,
hide_download_request_view, show_download_request_view, mark_all_notification_read_view, batch_edit_view,
edit_download_request_view, statistics_view, add_content_to_batch_view, search_view,
get_downloaded_content_thumbnail, download_request_details_view, force_download_content_view,
get_downloaded_content_thumbnail, download_request_details_view, force_download_content_view, delete_batch_view,
)

urlpatterns = [
Expand Down Expand Up @@ -49,6 +49,7 @@
path("batch/<str:batch_id>/close", close_batch_view, name="close_batch"),
path("batch/<str:batch_id>/reopen", reopen_batch_view, name="reopen_batch"),
path("batch/<str:batch_id>/archive", archive_batch_view, name="archive_batch"),
path("batch/<str:batch_id>/delete", delete_batch_view, name="delete_batch"),
path("batch/<str:batch_id>/download", download_collection_zip_view, name="download_batch_archive"),
path("batch/<str:batch_id>/details", batch_details_view, name="batch_details"),
path("batch/<str:batch_id>/edit", batch_edit_view, name="batch_edit"),
Expand Down
2 changes: 1 addition & 1 deletion video_downloading_platform/core/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class BatchAdmin(admin.ModelAdmin):
list_display = ('name', 'created_at')
list_display = ('name', 'owner', 'created_at', 'updated_at', 'url_count')


admin.site.register(Batch, BatchAdmin)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.core.management import BaseCommand

from video_downloading_platform.core.models import Batch


class Command(BaseCommand):
help = 'Delete the specified collection'

def add_arguments(self, parser):
parser.add_argument('collection_id', type=str)

def handle(self, *args, **options):
collection_id = options.get('collection_id', None)
if collection_id:
try:
collection = Batch.objects.get(id=collection_id)
collection.delete()
self.stdout.write(self.style.SUCCESS(f'{collection_id} successfully deleted.'))
except Exception as e:
print(e)
32 changes: 29 additions & 3 deletions video_downloading_platform/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from django_q.humanhash import HumanHasher
from django_q.models import Schedule
from django_q.tasks import async_task, schedule
from elasticsearch_dsl import Index
from gallery_dl.extractor import find as gdl_find_extractors
from taggit.managers import TaggableManager
from taggit.models import GenericUUIDTaggedItemBase, TaggedItemBase
Expand Down Expand Up @@ -292,6 +293,10 @@ def status_class(self):
if self.status == Batch.ARCHIVED:
return 'secondary'

@property
def url_count(self):
return self.download_requests.count()

def __str__(self):
return self.name

Expand Down Expand Up @@ -792,18 +797,39 @@ def cleanup_upload_request(request_id):
upload_request = UploadRequest.objects.get(id=request_id)
upload_request.cleanup()
except Exception as e:
print(e)
logger.error(e)


@receiver(pre_delete, sender=DownloadedContent, dispatch_uid='delete_stored_file')
def delete_downloaded_content_stored_files(sender, instance: DownloadedContent, using, **kwargs):
instance.content.delete()
print(f'Delete downloaded content [{instance.owner}] {instance.id}')
try:
instance.content.delete()
except Exception as e:
logger.error(e)


@receiver(pre_delete, sender=DownloadReport, dispatch_uid='delete_stored_archive_file')
def delete_download_report_stored_files(sender, instance: DownloadReport, using, **kwargs):
instance.archive.delete()
print(f'Delete the archive [{instance.owner}] {instance.id}')
try:
instance.archive.delete()
except Exception as e:
logger.error(e)


@receiver(pre_delete, sender=DownloadRequest, dispatch_uid='delete_stored_archive_file')
def delete_download_request(sender, instance: DownloadRequest, using, **kwargs):
print(f'Delete the download request [{instance.owner}] {instance.id}')
from elasticsearch_dsl import connections
connections.create_connection(hosts=['elasticsearch'], timeout=20)
index_name = instance.get_es_index()
try:
index = Index(index_name)
if index.exists():
index.delete()
except Exception as e:
logger.error(e)

@receiver(pre_delete, sender=UploadRequest, dispatch_uid='delete_upload_request_file')
def delete_upload_request_stored_files(sender, instance: UploadRequest, using, **kwargs):
Expand Down
10 changes: 10 additions & 0 deletions video_downloading_platform/core/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,3 +630,13 @@ def index_collection_by_id(batch_id: str):
return
for dr in batch.download_requests.all():
index_download_request(dr)


def delete_collection_by_id(batch_id: str):
batch: Batch = Batch.objects.get(id=batch_id)
if not batch:
return
try:
batch.delete()
except Exception as e:
logger.error(e)
16 changes: 15 additions & 1 deletion video_downloading_platform/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from video_downloading_platform.core.models import Batch, DownloadRequest, DownloadedContent, DownloadReport, \
_get_request_types_to_run, BatchTeam
from video_downloading_platform.core.tasks import compute_downloaded_content_metadata, index_collection_by_id, \
index_download_request
index_download_request, delete_collection_by_id
from video_downloading_platform.users.admin import User


Expand Down Expand Up @@ -254,6 +254,20 @@ def reopen_batch_view(request, batch_id):
return redirect(request.META.get('HTTP_REFERER'))


@login_required
def delete_batch_view(request, batch_id):
user = request.user
if not user.is_authenticated:
return redirect(reverse_lazy(settings.LOGIN_URL))
if batch_id:
batch = Batch.objects.get(id=batch_id)
batch.status = Batch.ARCHIVED
batch.save()
async_task(delete_collection_by_id, batch_id)
messages.success(request, _(f'The deletion of the collection {batch.name} is processing.'))
return redirect(request.META.get('HTTP_REFERER'))


@login_required
def archive_batch_view(request, batch_id):
if batch_id:
Expand Down
58 changes: 55 additions & 3 deletions video_downloading_platform/templates/pages/batch_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,71 @@ <h1>{% trans "My collections" %}</h1>
{% for batch in batches %}
<tr class="table-{{ batch.status_class }}">
<td>{{ batch.download_requests.count }}</td>
<td>{{ batch.name }}</td>
<td>
{{ batch.name }}<br>
<span class="font-monospace small text-muted">ID: {{ batch.id }}</span>
</td>
<td><i class="fa fa-user" aria-hidden="true"></i> {{ batch.owner }}</td>
<td>
<span class="badge bg-{{ batch.status_class }}">
{{ batch.status }}
</span>
</td>
<td><i class="fa fa-clock-o" aria-hidden="true"></i> {{ batch.created_at }}</td>
<td><i class="fa fa-clock-o" aria-hidden="true"></i> {{ batch.updated_at }}</td>
<td>
<i class="fa fa-clock-o" aria-hidden="true"></i> {{ batch.created_at }}<br>
<span class="text-muted">{{ batch.created_at|timesince }} ago</span>
</td>
<td>
<i class="fa fa-clock-o" aria-hidden="true"></i> {{ batch.updated_at }}<br>
<span class="text-muted">{{ batch.updated_at|timesince }} ago</span>
</td>
<td>
<a href="{% url 'batch_details' batch.id %}" class="btn btn-sm btn-primary" role="button">
<i class="fa fa-search" aria-hidden="true"></i> {% translate "Details" %}
</a>
{% if request.user.is_superuser %}
<button type="button" class="btn btn-sm btn-danger" data-bs-toggle="modal"
data-bs-target="#modal-{{ batch.id }}">
<i class="fa fa-trash-o"></i>
Delete
</button>
<div class="modal fade" id="modal-{{ batch.id }}" tabindex="-1"
aria-labelledby="modal-label-{{ batch.id }}" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable modal-lg">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="modal-label-{{ batch.id }}">
Delete the collection {{ batch.name }}
</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>
You are about to entirely delete the collection named "<i>{{ batch.name }}</i>".
This operation will be processed in background since it could take several minutes
to be completed. This operation cannot be cancelled nor reverted.
</p>
<p>
This collection contains the following URLs:
</p>
<ul>
{% for u in batch.download_requests.all %}
<li class="font-monospace">{{ u.url }}</li>
{% empty %}
<li>Nothing</li>
{% endfor %}
</ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<a href="{% url 'delete_batch' batch.id %}" class="btn btn-primary" role="button">
<i class="fa fa-trash-o" aria-hidden="true"></i> {% translate "Delete" %}
</a>
</div>
</div>
</div>
</div>
{% endif %}
</td>
</tr>
{% endfor %}
Expand Down

0 comments on commit 653194c

Please sign in to comment.