From 722f530c80c522e154cf1db16932be14f38b9bdb Mon Sep 17 00:00:00 2001 From: Nick Sweeting Date: Sat, 10 Apr 2021 04:11:32 -0400 Subject: [PATCH] support adding and removing multiple tags at once using autocomplete multiselect field --- .gitmodules | 3 +++ archivebox/core/admin.py | 48 +++++++++++++++++++++++++++++++-------- archivebox/vendor/tzlocal | 1 + 3 files changed, 42 insertions(+), 10 deletions(-) create mode 160000 archivebox/vendor/tzlocal diff --git a/.gitmodules b/.gitmodules index 196c9a92..a6857c62 100644 --- a/.gitmodules +++ b/.gitmodules @@ -26,3 +26,6 @@ [submodule "archivebox/vendor/python-atomicwrites"] path = archivebox/vendor/python-atomicwrites url = https://github.com/untitaker/python-atomicwrites +[submodule "archivebox/vendor/tzlocal"] + path = archivebox/vendor/tzlocal + url = https://github.com/regebro/tzlocal diff --git a/archivebox/core/admin.py b/archivebox/core/admin.py index 93da7a0e..ab3d588c 100644 --- a/archivebox/core/admin.py +++ b/archivebox/core/admin.py @@ -45,10 +45,36 @@ class TagInline(admin.TabularInline): model = Snapshot.tags.through from django.contrib.admin.helpers import ActionForm +from django.contrib.admin.widgets import AutocompleteSelectMultiple + +class AutocompleteTags: + model = Tag + search_fields = ['name'] + +class AutocompleteTagsAdminStub: + name = 'admin' class SnapshotActionForm(ActionForm): - tag = forms.ModelChoiceField(queryset=Tag.objects.all(), required=False) + tags = forms.ModelMultipleChoiceField( + queryset=Tag.objects.all(), + required=False, + widget=AutocompleteSelectMultiple( + AutocompleteTags(), + AutocompleteTagsAdminStub(), + ), + ) + + # TODO: allow selecting actions for specific extractors? is this useful? + # EXTRACTOR_CHOICES = [ + # (name, name.title()) + # for name, _, _ in get_default_archive_methods() + # ] + # extractor = forms.ChoiceField( + # choices=EXTRACTOR_CHOICES, + # required=False, + # widget=forms.MultileChoiceField(attrs={'class': "form-control"}) + # ) class SnapshotAdmin(SearchResultsAdminMixin, admin.ModelAdmin): @@ -59,7 +85,7 @@ class SnapshotAdmin(SearchResultsAdminMixin, admin.ModelAdmin): fields = ('timestamp', 'url', 'title', 'tags', *readonly_fields) list_filter = ('added', 'updated', 'tags', 'archiveresult__status') ordering = ['-added'] - actions = ['delete_snapshots', 'overwrite_snapshots', 'update_snapshots', 'update_titles', 'verify_snapshots', 'add_tag', 'remove_tag'] + actions = ['add_tags', 'remove_tags', 'update_titles', 'update_snapshots', 'resnapshot_snapshot', 'overwrite_snapshots', 'delete_snapshots'] autocomplete_fields = ['tags'] inlines = [ArchiveResultInline] list_per_page = SNAPSHOTS_PER_PAGE @@ -212,19 +238,21 @@ class SnapshotAdmin(SearchResultsAdminMixin, admin.ModelAdmin): delete_snapshots.short_description = "Delete" - def add_tag(self, request, queryset): - tag = request.POST['tag'] + def add_tags(self, request, queryset): + tags = request.POST.getlist('tags') + print('[+] Adding tags', tags, 'to Snapshots', queryset) for obj in queryset: - obj.tags.add(tag) + obj.tags.add(*tags) - add_tag.short_description = "Add tag" + add_tags.short_description = "+" - def remove_tag(self, request, queryset): - tag = request.POST['tag'] + def remove_tags(self, request, queryset): + tags = request.POST.getlist('tags') + print('[-] Removing tags', tags, 'to Snapshots', queryset) for obj in queryset: - obj.tags.remove(tag) + obj.tags.remove(*tags) - remove_tag.short_description = "Remove tag" + remove_tags.short_description = "–" diff --git a/archivebox/vendor/tzlocal b/archivebox/vendor/tzlocal new file mode 160000 index 00000000..c5282c6f --- /dev/null +++ b/archivebox/vendor/tzlocal @@ -0,0 +1 @@ +Subproject commit c5282c6feded0d576937c0dcdf1f4fd00a95fbee