Unverified Commit ccd007ee authored by Seb Brown's avatar Seb Brown Committed by GitHub
Browse files

Merge pull request #97 from neon-jungle/feat_support_wagtail4

Feat support wagtail4
parents d66ec4eb c6198e49
from django.urls import path, re_path
from wagtailvideos.views import chooser, multiple, videos
from wagtailvideos.views import multiple, videos
app_name = 'wagtailvideos'
urlpatterns = [
path('add/', videos.add, name='add'),
re_path(r'^usage/(\d+)/$', videos.usage, name='video_usage'),
......@@ -11,10 +12,6 @@ urlpatterns = [
re_path(r'^multiple/(\d+)/delete/$', multiple.delete, name='delete_multiple'),
re_path(r'^multiple/(\d+)/$', multiple.edit, name='edit_multiple'),
path('chooser/upload/', chooser.chooser_upload, name='chooser_upload'),
re_path(r'^chooser/(\d+)/$', chooser.video_chosen, name='video_chosen'),
path('chooser/', chooser.chooser, name='chooser'),
re_path(r'^(\d+)/delete/$', videos.delete, name='delete'),
re_path(r'^(\d+)/create_transcode/$', videos.create_transcode, name='create_transcode'),
re_path(r'^(\d+)/$', videos.edit, name='edit'),
......
from distutils.version import LooseVersion
import wagtail
from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, render
from django.conf import settings
from django.urls import reverse
from django.utils.translation import gettext as _
from wagtail.admin.forms.search import SearchForm
from wagtail.admin.modal_workflow import render_modal_workflow
from wagtail.core.models import Collection
from wagtail.search import index as search_index
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from django.views.generic.base import View
from wagtail.admin.auth import PermissionPolicyChecker
from wagtail.admin.models import popular_tags_for_model
from wagtail.admin.views.generic.chooser import (
BaseChooseView, ChooseResultsViewMixin, ChooseViewMixin,
ChosenResponseMixin, ChosenViewMixin, CreateViewMixin, CreationFormMixin)
from wagtail.admin.viewsets.chooser import ChooserViewSet
from wagtailvideos import get_video_model
from wagtailvideos.forms import get_video_form
from wagtailvideos.permissions import permission_policy
if LooseVersion(wagtail.__version__) >= LooseVersion('2.7'):
from wagtail.admin.auth import PermissionPolicyChecker
from wagtail.admin.models import popular_tags_for_model
else:
from wagtail.admin.utils import (
PermissionPolicyChecker, popular_tags_for_model)
permission_checker = PermissionPolicyChecker(permission_policy)
def get_chooser_js_data():
"""construct context variables needed by the chooser JS"""
return {
'step': 'chooser',
'error_label': _("Server Error"),
'error_message': _("Report this error to your webmaster with the following information:"),
'tag_autocomplete_url': reverse('wagtailadmin_tag_autocomplete'),
}
def get_video_json(video):
"""
helper function: given a video, return the json to pass back to the
video chooser panel
"""
return {
'id': video.id,
'edit_link': reverse('wagtailvideos:edit', args=(video.id,)),
'title': video.title,
'preview': {
'url': video.thumbnail.url if video.thumbnail else '',
class VideoChosenResponseMixin(ChosenResponseMixin):
def get_chosen_response_data(self, video):
response_data = super().get_chosen_response_data(video)
response_data["preview"] = {
"url": video.thumbnail.url if video.thumbnail else "",
"width": 165,
"height": 165,
}
}
def chooser(request):
Video = get_video_model()
VideoForm = get_video_form(Video)
uploadform = VideoForm()
videos = Video.objects.order_by('-created_at')
q = None
if (
'q' in request.GET or 'p' in request.GET or 'tag' in request.GET
or 'collection_id' in request.GET
):
# this request is triggered from search, pagination or 'popular tags';
# we will just render the results.html fragment
collection_id = request.GET.get('collection_id')
if collection_id:
videos = videos.filter(collection=collection_id)
collections = permission_policy.collections_user_has_any_permission_for(
request.user, ['choose'])
if len(collections) > 0:
videos = videos.filter(collection__in=collections)
searchform = SearchForm(request.GET)
if searchform.is_valid():
q = searchform.cleaned_data['q']
videos = videos.search(q)
is_searching = True
else:
is_searching = False
tag_name = request.GET.get('tag')
if tag_name:
videos = videos.filter(tags__name=tag_name)
# Pagination
paginator = Paginator(videos, per_page=12)
page = paginator.get_page(request.GET.get('p'))
return render(request, "wagtailvideos/chooser/results.html", {
'videos': page,
'is_searching': is_searching,
'query_string': q,
})
else:
searchform = SearchForm()
collections = permission_policy.collections_user_has_permission_for(
request.user, 'choose'
return response_data
class VideoCreationFormMixin(CreationFormMixin):
creation_tab_id = "upload"
create_action_label = _("Upload")
create_action_clicked_label = _("Uploading…")
permission_policy = permission_policy
def get_creation_form_class(self):
return get_video_form(self.model)
def get_creation_form_kwargs(self):
kwargs = super().get_creation_form_kwargs()
if self.request.method in ("POST", "PUT"):
kwargs["instance"] = self.model(uploaded_by_user=self.request.user)
return kwargs
class BaseVideoChooseView(BaseChooseView):
template_name = "wagtailvideos/chooser/chooser.html"
results_template_name = "wagtailvideos/chooser/results.html"
per_page = getattr(settings, "WAGTAILVIDEOS_CHOOSER_PAGE_SIZE", 12)
ordering = "-created_at"
def get_object_list(self):
return (
permission_policy.instances_user_has_any_permission_for(
self.request.user, ["choose"]
)
.select_related("collection")
)
def filter_object_list(self, objects):
tag_name = self.request.GET.get("tag")
if tag_name:
objects = objects.filter(tags__name=tag_name)
return super().filter_object_list(objects)
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:
collections = None
return None
return collections
paginator = Paginator(videos, per_page=12)
page = paginator.get_page(request.GET.get('p'))
def get(self, request):
self.model = get_video_model()
return super().get(request)
return render_modal_workflow(request, 'wagtailvideos/chooser/chooser.html', None, {
'videos': page,
'uploadform': uploadform,
'searchform': searchform,
'is_searching': False,
'query_string': q,
'popular_tags': popular_tags_for_model(Video),
'collections': collections,
}, json_data=get_chooser_js_data())
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update(
{
"collections": self.collections,
}
)
return context
def video_chosen(request, video_id):
video = get_object_or_404(get_video_model(), id=video_id)
class VideoChooseViewMixin(ChooseViewMixin):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["popular_tags"] = popular_tags_for_model(self.model)
return context
return render_modal_workflow(
request, None, json_data={
'step': 'video_chosen',
'result': get_video_json(video)
})
def get_response_json_data(self):
json_data = super().get_response_json_data()
json_data["tag_autocomplete_url"] = reverse("wagtailadmin_tag_autocomplete")
return json_data
@permission_checker.require('add')
def chooser_upload(request):
Video = get_video_model()
VideoForm = get_video_form(Video)
class VideoChooseView(
VideoChooseViewMixin, VideoCreationFormMixin, BaseVideoChooseView
):
pass
searchform = SearchForm()
if request.POST:
video = Video(uploaded_by_user=request.user)
form = VideoForm(request.POST, request.FILES, instance=video)
class VideoChooseResultsView(
ChooseResultsViewMixin, VideoCreationFormMixin, BaseVideoChooseView
):
pass
if form.is_valid():
video.uploaded_by_user = request.user
video.save()
# Reindex the video to make sure all tags are indexed
search_index.insert_or_update_object(video)
class VideoChosenView(ChosenViewMixin, VideoChosenResponseMixin, View):
def get(self, request, *args, pk, **kwargs):
self.model = get_video_model()
return super().get(request, *args, pk, **kwargs)
return render_modal_workflow(
request, None, json_data={
'step': 'video_chosen',
'result': get_video_json(video)
}
)
else:
form = VideoForm()
videos = Video.objects.order_by('title')
paginator = Paginator(videos, per_page=12)
page = paginator.get_page(request.GET.get('p'))
return render_modal_workflow(
request, 'wagtailvideos/chooser/chooser.html', None,
template_vars={'videos': page, 'uploadform': form, 'searchform': searchform},
json_data=get_chooser_js_data()
)
class VideoUploadViewMixin(CreateViewMixin):
def get(self, request):
self.model = get_video_model()
return super().get(request)
def post(self, request):
self.model = get_video_model()
self.form = self.get_creation_form()
if self.form.is_valid():
image = self.save_form(self.form)
# not specifying a format; return the image details now
return self.get_chosen_response(image)
else: # form is invalid
return self.get_reshow_creation_form_response()
class VideoUploadView(
VideoUploadViewMixin, VideoCreationFormMixin, VideoChosenResponseMixin, View
):
pass
class VideoChooserViewSet(ChooserViewSet):
choose_view_class = VideoChooseView
choose_results_view_class = VideoChooseResultsView
chosen_view_class = VideoChosenView
create_view_class = VideoUploadView
permission_policy = permission_policy
register_widget = False
icon = "media"
choose_one_text = _("Choose a video")
create_action_label = _("Upload")
create_action_clicked_label = _("Uploading…")
viewset = VideoChooserViewSet(
"wagtailvideos_chooser",
model=get_video_model(),
url_prefix="videos/chooser",
)
......@@ -13,6 +13,7 @@ from wagtail.core import hooks
from wagtailvideos import get_video_model, is_modeladmin_installed, urls
from wagtailvideos.edit_handlers import VideoChooserPanel
from wagtailvideos.forms import GroupVideoPermissionFormSet
from wagtailvideos.views.chooser import viewset as chooser_viewset
from .permissions import permission_policy
......@@ -55,7 +56,7 @@ def editor_js():
window.chooserUrls.videoChooser = '{0}';
</script>
""",
reverse('wagtailvideos:chooser')
reverse('wagtailvideos_chooser:choose')
)
......@@ -103,9 +104,9 @@ def hide_track_listing_main(request, menu_items):
class VideoSummaryItem(SummaryItem):
order = 300
template = "wagtailvideos/homepage/videos_summary.html"
template_name = "wagtailvideos/homepage/videos_summary.html"
def get_context(self):
def get_context_data(self, parent_context):
return {
"total_videos": Video.objects.count(),
}
......@@ -142,3 +143,8 @@ def register_media_search_area():
@hooks.register('insert_global_admin_css')
def summary_css():
return format_html('<link rel="stylesheet" href="{}">', static('wagtailvideos/css/summary-override.css'))
@hooks.register("register_admin_viewset")
def register_image_chooser_viewset():
return chooser_viewset
import json
from django.template.loader import render_to_string
from django import forms
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
from wagtail.admin.widgets import AdminChooser
from wagtail.admin.staticfiles import versioned_static
from wagtail.admin.widgets import BaseChooser, BaseChooserAdapter
from wagtail.telepath import register
from wagtailvideos import get_video_model
class AdminVideoChooser(AdminChooser):
class AdminVideoChooser(BaseChooser):
choose_one_text = _('Choose a video')
choose_another_text = _('Choose another video')
link_to_chosen_text = _('Edit this video')
template_name = "wagtailvideos/widgets/video_chooser.html"
chooser_modal_url_name = "wagtailvideos_chooser:choose"
icon = "media"
classname = "image-chooser"
def __init__(self, **kwargs):
super(AdminVideoChooser, self).__init__(**kwargs)
self.video_model = get_video_model()
def render_html(self, name, value, attrs):
instance, value_data = self.get_instance_and_id(self.video_model, value)
original_field_html = super(AdminVideoChooser, self).render_html(name, value, attrs)
return render_to_string("wagtailvideos/widgets/video_chooser.html", {
'widget': self,
'original_field_html': original_field_html,
'attrs': attrs,
'value': value_data,
'video': instance,
})
def render_js_init(self, id_, name, value):
return "createVideoChooser({0});".format(json.dumps(id_))
class Media:
js = [
'wagtailvideos/js/video-chooser-modal.js',
'wagtailvideos/js/video-chooser.js',
]
super().__init__(**kwargs)
self.model = get_video_model()
def get_value_data_from_instance(self, instance):
data = super().get_value_data_from_instance(instance)
data["preview"] = {
"url": instance.thumbnail.url if instance.thumbnail else "",
"width": 165,
"height": 165,
}
return data
def get_context(self, name, value_data, attrs):
context = super().get_context(name, value_data, attrs)
context["preview"] = value_data.get("preview", {})
return context
def render_js_init(self, id_, name, value_data):
return "new VideoChooser({0});".format(json.dumps(id_))
@property
def media(self):
return forms.Media(
js=[
versioned_static("wagtailimages/js/image-chooser-modal.js"),
versioned_static("wagtailimages/js/image-chooser.js"),
versioned_static("wagtailvideos/js/video-chooser.js"),
]
)
class VideoChooserAdapter(BaseChooserAdapter):
js_constructor = "wagtailvideos.widgets.VideoChooser"
@cached_property
def media(self):
return forms.Media(
js=[
versioned_static("wagtailimages/js/image-chooser-telepath.js"),
versioned_static("wagtailvideos/js/video-chooser-telepath.js"),
]
)
register(VideoChooserAdapter(), AdminVideoChooser)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment