From 65407529f9694f6ad940ce58d19aa2fd68365c28 Mon Sep 17 00:00:00 2001 From: Seb Brown Date: Tue, 13 Aug 2024 09:41:43 +1000 Subject: [PATCH] Cleanup template + js --- .../static/wagtailvideos/js/add-multiple.js | 31 ++- .../templates/wagtailvideos/multiple/add.html | 11 +- .../wagtailvideos/multiple/edit_form.html | 20 +- wagtailvideos/urls.py | 20 +- wagtailvideos/views/multiple.py | 245 +++++++++--------- 5 files changed, 167 insertions(+), 160 deletions(-) diff --git a/wagtailvideos/static/wagtailvideos/js/add-multiple.js b/wagtailvideos/static/wagtailvideos/js/add-multiple.js index ee72473..170b6b9 100644 --- a/wagtailvideos/static/wagtailvideos/js/add-multiple.js +++ b/wagtailvideos/static/wagtailvideos/js/add-multiple.js @@ -15,7 +15,6 @@ $(function() { maxFileSize: window.fileupload_opts.errormessages.max_file_size }, add: function(e, data) { - $('.messages').empty(); var $this = $(this); var that = $this.data('blueimp-fileupload') || $this.data('fileupload'); var li = $($('#upload-list-item').html()).addClass('upload-uploading'); @@ -116,24 +115,32 @@ $(function() { // ajax-enhance forms added on done() $('#upload-list').on('submit', 'form', function(e) { var form = $(this); + var formData = new FormData(this); var itemElement = form.closest('#upload-list > li'); e.preventDefault(); - $.post(this.action, form.serialize(), function(data) { + $.ajax({ + contentType: false, + data: formData, + processData: false, + type: 'POST', + url: this.action, + }).done(function (data) { if (data.success) { - var statusText = $('.status-msg.update-success').text(); - addMessage('success', statusText); - itemElement.slideUp(function() { - $(this).remove(); - }); + var text = $('.status-msg.update-success').first().text(); + document.dispatchEvent( + new CustomEvent('w-messages:add', { + detail: { clear: true, text, type: 'success' }, + }), + ); + itemElement.slideUp(function () { + $(this).remove(); + }); } else { - form.replaceWith(data.form); - - // run tagit enhancement on new form - $('.tag_field input', form).tagit(window.tagit_opts); + form.replaceWith(data.form); } - }); + }); }); $('#upload-list').on('click', '.delete', function(e) { diff --git a/wagtailvideos/templates/wagtailvideos/multiple/add.html b/wagtailvideos/templates/wagtailvideos/multiple/add.html index b321a48..a584311 100644 --- a/wagtailvideos/templates/wagtailvideos/multiple/add.html +++ b/wagtailvideos/templates/wagtailvideos/multiple/add.html @@ -3,7 +3,7 @@ {% block titletag %}{% trans "Add multiple videos" %}{% endblock %} {% block extra_css %} {{ block.super }} - + {{ form_media.css }} {% endblock %} {% block content %} @@ -43,7 +43,7 @@ - + {% endblock %} {% block extra_js %} {{ block.super }} - + {{ form_media.js }} @@ -88,8 +88,5 @@ accepted_file_types: "{{ error_accepted_file_types }}" } }; - window.tagit_opts = { - autocomplete: {source: "{{ autocomplete_url|addslashes }}"} - }; {% endblock %} diff --git a/wagtailvideos/templates/wagtailvideos/multiple/edit_form.html b/wagtailvideos/templates/wagtailvideos/multiple/edit_form.html index 1a39d7a..9fa122e 100644 --- a/wagtailvideos/templates/wagtailvideos/multiple/edit_form.html +++ b/wagtailvideos/templates/wagtailvideos/multiple/edit_form.html @@ -1,20 +1,8 @@ {% load i18n %} -
- -
+ +{% include "wagtailadmin/generic/multiple_upload/edit_form.html" %} + +{# little bit of js ran to update the video thumbnail #}
{% if video.thumbnail %} {% trans 'Video thumbnail' %} diff --git a/wagtailvideos/urls.py b/wagtailvideos/urls.py index 5b88976..8f8eb53 100644 --- a/wagtailvideos/urls.py +++ b/wagtailvideos/urls.py @@ -8,9 +8,23 @@ path('add/', videos.add, name='add'), re_path(r'^usage/(\d+)/$', videos.usage, name='video_usage'), - path('multiple/add/', multiple.add, name='add_multiple'), - re_path(r'^multiple/(\d+)/delete/$', multiple.delete, name='delete_multiple'), - re_path(r'^multiple/(\d+)/$', multiple.edit, name='edit_multiple'), + path("multiple/add/", multiple.AddView.as_view(), name="add_multiple"), + path("multiple//", multiple.EditView.as_view(), name="edit_multiple"), + path( + "multiple/create_from_uploaded_image//", + multiple.CreateFromUploadedVideoView.as_view(), + name="create_multiple_from_uploaded_image", + ), + path( + "multiple//delete/", + multiple.DeleteView.as_view(), + name="delete_multiple", + ), + path( + "multiple/delete_upload//", + multiple.DeleteUploadView.as_view(), + name="delete_upload_multiple", + ), re_path(r'^(\d+)/delete/$', videos.delete, name='delete'), re_path(r'^(\d+)/create_transcode/$', videos.create_transcode, name='create_transcode'), diff --git a/wagtailvideos/views/multiple.py b/wagtailvideos/views/multiple.py index 90c496f..fdbf2a9 100644 --- a/wagtailvideos/views/multiple.py +++ b/wagtailvideos/views/multiple.py @@ -1,26 +1,30 @@ -from django.http import HttpResponseBadRequest, JsonResponse -from django.shortcuts import get_object_or_404, render -from django.template.loader import render_to_string -from django.utils.encoding import force_str -from django.views.decorators.http import require_POST -from django.views.decorators.vary import vary_on_headers -from wagtail.admin.auth import PermissionPolicyChecker -from wagtail.search.backends import get_search_backends +import os +from wagtail.admin.auth import PermissionPolicyChecker +from wagtail.admin.views.generic.multiple_upload import AddView as BaseAddView +from wagtail.admin.views.generic.multiple_upload import ( + CreateFromUploadView as BaseCreateFromUploadView, +) +from wagtail.admin.views.generic.multiple_upload import ( + DeleteUploadView as BaseDeleteUploadView, +) +from wagtail.admin.views.generic.multiple_upload import DeleteView as BaseDeleteView +from wagtail.admin.views.generic.multiple_upload import EditView as BaseEditView from wagtailvideos import get_video_model from wagtailvideos.forms import get_video_form from wagtailvideos.permissions import permission_policy +from wagtailvideos.permissions import permission_policy + permission_checker = PermissionPolicyChecker(permission_policy) -def get_video_edit_form(VideoModel): - VideoForm = get_video_form(VideoModel) +def get_video_edit_form(video_model): + VideoForm = get_video_form(video_model) - # Make a new form with the file and focal point fields excluded class VideoEditForm(VideoForm): class Meta(VideoForm.Meta): - model = VideoModel + model = video_model exclude = ( 'file', ) @@ -28,115 +32,112 @@ class Meta(VideoForm.Meta): return VideoEditForm -@vary_on_headers('X-Requested-With') -def add(request): - # TODO replace with wagtail.admin.views.generic.multiple_upload.AddView subclass - Video = get_video_model() - VideoForm = get_video_form(Video) - - collections = permission_policy.collections_user_has_permission_for(request.user, 'add') - if len(collections) > 1: - collections_to_choose = collections - else: - # no need to show a collections chooser - collections_to_choose = None - - if request.method == 'POST': - if request.headers.get('x-requested-with') != 'XMLHttpRequest': - return HttpResponseBadRequest("Cannot POST to this view without AJAX") - - if not request.FILES: - return HttpResponseBadRequest("Must upload a file") - - # Build a form for validation - form = VideoForm({ - 'title': request.FILES['files[]'].name, - 'collection': request.POST.get('collection'), - }, { - 'file': request.FILES['files[]'], - }) - if form.is_valid(): - # Save - video = form.save(commit=False) - video.uploaded_by_user = request.user - video.save() - - # Success! Send back an edit form - return JsonResponse({ - 'success': True, - 'video_id': int(video.id), - 'form': render_to_string('wagtailvideos/multiple/edit_form.html', { - 'video': video, - 'form': get_video_edit_form(Video)( - instance=video, prefix='video-%d' % video.id), - }, request=request), - }) - else: - # Validation error - return JsonResponse({ - 'success': False, - - # https://github.com/django/django/blob/stable/1.6.x/django/forms/util.py#L45 - 'error_message': '\n'.join(['\n'.join([force_str(i) for i in v]) for k, v in form.errors.items()]), - }) - else: - form = VideoForm() - - return render(request, 'wagtailvideos/multiple/add.html', { - 'max_filesize': form.fields['file'].max_upload_size, - 'help_text': form.fields['file'].help_text, - 'error_max_file_size': form.fields['file'].error_messages['file_too_large_unknown_size'], - 'error_accepted_file_types': form.fields['file'].error_messages['invalid_video_format'], - 'collections': collections_to_choose, - }) - - -@require_POST -def edit(request, video_id, callback=None): - Video = get_video_model() - VideoForm = get_video_edit_form(Video) - - video = get_object_or_404(Video, id=video_id) - - if request.headers.get('x-requested-with') != 'XMLHttpRequest': - return HttpResponseBadRequest("Cannot POST to this view without AJAX") - - form = VideoForm( - request.POST, request.FILES, instance=video, prefix='video-' + video_id - ) - - if form.is_valid(): +class AddView(BaseAddView): + permission_policy = permission_policy + template_name = 'wagtailvideos/multiple/add.html' + edit_form_template_name = 'wagtailvideos/multiple/edit_form.html' + + edit_object_url_name = "wagtailvideos:edit_multiple" + delete_object_url_name = "wagtailvideos:delete_multiple" + edit_object_form_prefix = "video" + context_object_name = "video" + context_object_id_name = "video_id" + + edit_upload_url_name = "wagtailvideos:create_multiple_from_uploaded_image" + delete_upload_url_name = "wagtailvideos:delete_upload_multiple" + edit_upload_form_prefix = "uploaded-video" + context_upload_name = "uploaded_video" + context_upload_id_name = "uploaded_file_id" + + def get_model(self): + return get_video_model() + + def get_upload_form_class(self): + return get_video_form(self.model) + + def get_edit_form_class(self): + return get_video_edit_form(self.model) + + def save_object(self, form): + video = form.save(commit=False) + video.uploaded_by_user = self.request.user + video.save() + return video + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + + context.update( + { + "max_filesize": self.form.fields["file"].max_upload_size, + "max_title_length": self.form.fields["title"].max_length, + "error_max_file_size": self.form.fields["file"].error_messages[ + "file_too_large_unknown_size" + ], + "error_accepted_file_types": self.form.fields["file"].error_messages[ + "invalid_video_format" + ], + } + ) + + return context + + +class EditView(BaseEditView): + permission_policy = permission_policy + pk_url_kwarg = "video_id" + edit_object_form_prefix = "video" + context_object_name = "video" + context_object_id_name = "video_id" + edit_object_url_name = "wagtailvideos:edit_multiple" + delete_object_url_name = "wagtailvideos:delete_multiple" + + def get_model(self): + return get_video_model() + + def get_edit_form_class(self): + return get_video_edit_form(self.model) + + +class DeleteView(BaseDeleteView): + permission_policy = permission_policy + pk_url_kwarg = "image_id" + context_object_id_name = "image_id" + + def get_model(self): + return get_video_model() + + +class CreateFromUploadedVideoView(BaseCreateFromUploadView): + edit_upload_url_name = "wagtailvideos:create_multiple_from_uploaded_image" + delete_upload_url_name = "wagtailvideos:delete_upload_multiple" + upload_pk_url_kwarg = "uploaded_file_id" + edit_upload_form_prefix = "uploaded-video" + context_object_id_name = "video_id" + context_upload_name = "uploaded_video" + + def get_model(self): + return get_video_model() + + def get_edit_form_class(self): + return get_video_edit_form(self.model) + + def save_object(self, form): + # See wagtailimages.views.multiple.CreateFromUploadedImageView.save_object + self.object.file.save( + os.path.basename(self.upload.file.name), self.upload.file.file, save=False + ) + self.object.uploaded_by_user = self.request.user + + self.object._set_image_file_metadata() + form.save() - # Reindex the video to make sure all tags are indexed - for backend in get_search_backends(): - backend.add(video) - - return JsonResponse({ - 'success': True, - 'video_id': int(video_id), - }) - else: - return JsonResponse({ - 'success': False, - 'video_id': int(video_id), - 'form': render_to_string('wagtailvideos/multiple/edit_form.html', { - 'video': video, - 'form': form, - }, request=request), - }) - - -@require_POST -def delete(request, video_id): - video = get_object_or_404(get_video_model(), id=video_id) - - if request.headers.get('x-requested-with') != 'XMLHttpRequest': - return HttpResponseBadRequest("Cannot POST to this view without AJAX") - - video.delete() - - return JsonResponse({ - 'success': True, - 'video_id': int(video_id), - }) + + + +class DeleteUploadView(BaseDeleteUploadView): + upload_pk_url_kwarg = "uploaded_file_id" + + def get_model(self): + return get_video_model() \ No newline at end of file