diff --git a/src/wagtailmedia/deprecation.py b/src/wagtailmedia/deprecation.py index b61831e..51a8588 100644 --- a/src/wagtailmedia/deprecation.py +++ b/src/wagtailmedia/deprecation.py @@ -1,6 +1,6 @@ -class RemovedInWagtailMedia015Warning(PendingDeprecationWarning): +class RemovedInWagtailMedia016Warning(PendingDeprecationWarning): pass -class RemovedInWagtailMedia016Warning(DeprecationWarning): +class RemovedInWagtailMedia017Warning(DeprecationWarning): pass diff --git a/src/wagtailmedia/edit_handlers.py b/src/wagtailmedia/edit_handlers.py index 77c07f4..096a3e4 100644 --- a/src/wagtailmedia/edit_handlers.py +++ b/src/wagtailmedia/edit_handlers.py @@ -1,11 +1,14 @@ from __future__ import annotations +import warnings + from typing import TYPE_CHECKING from django.template.loader import render_to_string from wagtail.admin.compare import ForeignObjectComparison from wagtail.admin.panels import FieldPanel +from .deprecation import RemovedInWagtailMedia017Warning from .models import MediaType from .utils import format_audio_html, format_video_html from .widgets import AdminAudioChooser, AdminMediaChooser, AdminVideoChooser @@ -23,6 +26,26 @@ def __init__(self, field_name, *args, media_type=None, **kwargs): self.media_type = media_type + if self.media_type is None: + warnings.warn( + ( + "The `MediaChooserPanel` field panel is deprecated. " + "Please use the `FieldPanel()` instead." + ), + RemovedInWagtailMedia017Warning, + stacklevel=2, + ) + else: + warnings.warn( + ( + "The `MediaChooserPanel` field panel is deprecated. Please use the " + "specialised `AudioChooserPanel()` for audio only " + "and `VideoChooserPanel()` for video only." + ), + RemovedInWagtailMedia017Warning, + stacklevel=2, + ) + def clone_kwargs(self): kwargs = super().clone_kwargs() kwargs.update(media_type=self.media_type) diff --git a/src/wagtailmedia/views/viewsets.py b/src/wagtailmedia/views/viewsets.py new file mode 100644 index 0000000..2529d0a --- /dev/null +++ b/src/wagtailmedia/views/viewsets.py @@ -0,0 +1,110 @@ +from django.utils.functional import cached_property +from django.utils.translation import gettext_lazy as _ +from wagtail.admin.ui.tables import Column +from wagtail.admin.views.generic.chooser import ( + ChooseResultsView, + ChooseView, + ChosenView, +) +from wagtail.admin.viewsets.chooser import ChooserViewSet + +from ..forms import get_media_form +from ..models import get_media_model +from ..permissions import permission_policy + + +Media = get_media_model() + + +class MediaChooserMixin: + construct_queryset_hook_name = "construct_media_chooser_queryset" + + def get_object_list(self): + return ( + permission_policy.instances_user_has_any_permission_for( + self.request.user, ["choose"] + ) + .select_related("collection") + .only("title", "file", "type", "collection__name", "created_at") + ) + + @property + def columns(self): + return super().columns + [ + Column("file", label="File", accessor="file"), + Column("type", label="Type", accessor="type"), + Column("collection", label="Collection", accessor="collection"), + Column("created_at", label="Uploaded", accessor="created_at"), + ] + + def get_filter_form(self): + FilterForm = self.get_filter_form_class() + return FilterForm(self.request.GET, collections=self.collections) + + @cached_property + def collections(self): + collections = self.permission_policy.collections_user_has_permission_for( + self.request.user, "choose" + ) + if len(collections) < 2: + return None + + return collections + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["collections"] = self.collections + return context + + +class MediaChooseView(MediaChooserMixin, ChooseView): + pass + + +class MediaChooseResultsView(MediaChooserMixin, ChooseResultsView): + pass + + +class MediaChosenView(ChosenView): + def get_object(self, pk): + return Media.objects.only("title", "thumbnail").get(pk=pk) + + def get_chosen_response_data(self, media_item, preview_image_filter="max-165x165"): + """ + Given a media item, return the json data to pass back to the image chooser panel + """ + response_data = super().get_chosen_response_data(media_item) + if not media_item.thumbnail: + return response_data + + preview_image = media_item.thumbnail + response_data["preview"] = { + "url": preview_image.url, + "width": 128, + "height": 128, + } + return response_data + + +class MediaChooserViewSet(ChooserViewSet): + choose_view_class = MediaChooseView + chosen_view_class = MediaChosenView + choose_results_view_class = MediaChooseResultsView + creation_form_class = get_media_form(Media) + permission_policy = permission_policy + + icon = "media" + choose_one_text = _("Choose a media item") + choose_another_text = _("Choose another media item") + edit_item_text = _("Edit this media item") + creation_tab_label = _("Upload") + create_action_label = _("Upload") + create_action_clicked_label = _("Uploading…") + form_fields = ["type", "title", "file", "collection", "thumbnail"] + + +media_chooser_viewset = MediaChooserViewSet( + "media_chooser", + model=Media, + url_prefix="media/chooser", +) diff --git a/src/wagtailmedia/wagtail_hooks.py b/src/wagtailmedia/wagtail_hooks.py index 47c6e41..92ba4cf 100644 --- a/src/wagtailmedia/wagtail_hooks.py +++ b/src/wagtailmedia/wagtail_hooks.py @@ -17,6 +17,7 @@ from wagtailmedia.forms import GroupMediaPermissionFormSet from wagtailmedia.models import get_media_model from wagtailmedia.permissions import permission_policy +from wagtailmedia.views.viewsets import media_chooser_viewset @hooks.register("register_admin_urls") @@ -107,8 +108,8 @@ def describe_collection_media(collection): class MediaAdminURLFinder(ModelAdminURLFinder): - permission_policy = permission_policy edit_url_name = "wagtailmedia:edit" + permission_policy = permission_policy register_admin_url_finder(get_media_model(), MediaAdminURLFinder) @@ -136,3 +137,8 @@ def register_icons(icons): "wagtailmedia/icons/wagtailmedia-audio.svg", # {% icon "wagtailmedia-audio" %} "wagtailmedia/icons/wagtailmedia-video.svg", # {% icon "wagtailmedia-video" %} ] + + +@hooks.register("register_admin_viewset") +def register_viewset(): + return media_chooser_viewset