diff --git a/config/urls.py b/config/urls.py index 8b5c6e5..5be76d2 100644 --- a/config/urls.py +++ b/config/urls.py @@ -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 = [ @@ -49,6 +49,7 @@ path("batch//close", close_batch_view, name="close_batch"), path("batch//reopen", reopen_batch_view, name="reopen_batch"), path("batch//archive", archive_batch_view, name="archive_batch"), + path("batch//delete", delete_batch_view, name="delete_batch"), path("batch//download", download_collection_zip_view, name="download_batch_archive"), path("batch//details", batch_details_view, name="batch_details"), path("batch//edit", batch_edit_view, name="batch_edit"), diff --git a/video_downloading_platform/core/admin.py b/video_downloading_platform/core/admin.py index b6e77b8..542d21b 100644 --- a/video_downloading_platform/core/admin.py +++ b/video_downloading_platform/core/admin.py @@ -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) diff --git a/video_downloading_platform/core/management/commands/delete_collection.py b/video_downloading_platform/core/management/commands/delete_collection.py new file mode 100644 index 0000000..516236b --- /dev/null +++ b/video_downloading_platform/core/management/commands/delete_collection.py @@ -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) diff --git a/video_downloading_platform/core/models.py b/video_downloading_platform/core/models.py index f0828ef..1912e8e 100644 --- a/video_downloading_platform/core/models.py +++ b/video_downloading_platform/core/models.py @@ -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 @@ -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 @@ -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): diff --git a/video_downloading_platform/core/tasks.py b/video_downloading_platform/core/tasks.py index 8a7b169..c1dbef6 100644 --- a/video_downloading_platform/core/tasks.py +++ b/video_downloading_platform/core/tasks.py @@ -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) diff --git a/video_downloading_platform/core/views.py b/video_downloading_platform/core/views.py index b69d514..a118c9d 100644 --- a/video_downloading_platform/core/views.py +++ b/video_downloading_platform/core/views.py @@ -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 @@ -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: diff --git a/video_downloading_platform/templates/pages/batch_list.html b/video_downloading_platform/templates/pages/batch_list.html index e1100dd..b4c67f2 100644 --- a/video_downloading_platform/templates/pages/batch_list.html +++ b/video_downloading_platform/templates/pages/batch_list.html @@ -25,19 +25,71 @@

{% trans "My collections" %}

{% for batch in batches %} {{ batch.download_requests.count }} - {{ batch.name }} + + {{ batch.name }}
+ ID: {{ batch.id }} + {{ batch.owner }} {{ batch.status }} - {{ batch.created_at }} - {{ batch.updated_at }} + + {{ batch.created_at }}
+ {{ batch.created_at|timesince }} ago + + + {{ batch.updated_at }}
+ {{ batch.updated_at|timesince }} ago + {% translate "Details" %} + {% if request.user.is_superuser %} + + + {% endif %} {% endfor %}