angrybeanie_wagtail/env/lib/python3.12/site-packages/wagtailmedia/views/media.py
2025-07-25 21:32:16 +10:00

288 lines
9.2 KiB
Python

from django.core.paginator import Paginator
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.text import capfirst
from django.utils.translation import gettext as _
from django.views.decorators.vary import vary_on_headers
from wagtail.admin import messages
from wagtail.admin.admin_url_finder import AdminURLFinder
from wagtail.admin.auth import PermissionPolicyChecker, permission_denied
from wagtail.admin.forms.search import SearchForm
from wagtail.admin.models import popular_tags_for_model
from wagtail.models import Collection, Page
from wagtail.search.backends import get_search_backends
from wagtailmedia.forms import get_media_form
from wagtailmedia.models import get_media_model
from wagtailmedia.permissions import permission_policy
from wagtailmedia.utils import paginate
permission_checker = PermissionPolicyChecker(permission_policy)
@permission_checker.require_any("add", "change", "delete")
@vary_on_headers("X-Requested-With")
def index(request):
Media = get_media_model()
# Get media files (filtered by user permission)
media = permission_policy.instances_user_has_any_permission_for(
request.user, ["change", "delete"]
)
# Ordering
if request.GET.get("ordering") in ["title", "-title", "-created_at", "created_at"]:
ordering = request.GET["ordering"]
else:
ordering = "-created_at"
media = media.order_by(ordering)
# Filter by collection
current_collection = None
collection_id = request.GET.get("collection_id")
if collection_id:
try:
current_collection = Collection.objects.get(id=collection_id)
media = media.filter(collection=current_collection)
except (ValueError, Collection.DoesNotExist):
pass
# Search
query_string = ""
if "q" in request.GET and request.GET.get("q").strip():
form = SearchForm(request.GET, placeholder=_("Search media files"))
if form.is_valid():
query_string = form.cleaned_data["q"]
media = media.search(query_string)
else:
form = SearchForm(placeholder=_("Search media"))
# Filter by tag
if current_tag := request.GET.get("tag"):
try:
media = media.filter(tags__name=current_tag)
except AttributeError:
current_tag = None
# Pagination
paginator, media = paginate(request, media)
collections = permission_policy.collections_user_has_any_permission_for(
request.user, ["add", "change"]
)
if len(collections) < 2:
collections = None
# Create response
if request.headers.get("x-requested-with") == "XMLHttpRequest":
return render(
request,
"wagtailmedia/media/results.html",
{
"ordering": ordering,
"media_files": media,
"query_string": query_string,
"is_searching": bool(query_string),
"collections": collections,
},
)
else:
return render(
request,
"wagtailmedia/media/index.html",
{
"ordering": ordering,
"media_files": media,
"query_string": query_string,
"is_searching": bool(query_string),
"search_form": form,
"popular_tags": popular_tags_for_model(Media),
"current_tag": current_tag,
"user_can_add": permission_policy.user_has_permission(
request.user, "add"
),
"collections": collections,
"current_collection": current_collection,
},
)
@permission_checker.require("add")
def add(request, media_type):
Media = get_media_model()
MediaForm = get_media_form(Media)
if request.method == "POST":
media = Media(uploaded_by_user=request.user, type=media_type)
form = MediaForm(request.POST, request.FILES, instance=media, user=request.user)
if form.is_valid():
form.save()
# Reindex the media entry to make sure all tags are indexed
for backend in get_search_backends():
backend.add(media)
messages.success(
request,
_("Media file '{0}' added.").format(media.title),
buttons=[
messages.button(
reverse("wagtailmedia:edit", args=(media.id,)), _("Edit")
)
],
)
return redirect("wagtailmedia:index")
else:
messages.error(
request, _("The media file could not be saved due to errors.")
)
else:
media = Media(uploaded_by_user=request.user, type=media_type)
form = MediaForm(user=request.user, instance=media)
return render(
request,
"wagtailmedia/media/add.html",
{
"form": form,
"media_type": media_type,
},
)
@permission_checker.require("change")
def edit(request, media_id):
Media = get_media_model()
MediaForm = get_media_form(Media)
media = get_object_or_404(Media, id=media_id)
if not permission_policy.user_has_permission_for_instance(
request.user, "change", media
):
return permission_denied(request)
if request.method == "POST":
original_file = media.file
form = MediaForm(request.POST, request.FILES, instance=media, user=request.user)
if form.is_valid():
if "file" in form.changed_data:
# if providing a new media file, delete the old one.
# NB Doing this via original_file.delete() clears the file field,
# which definitely isn't what we want...
original_file.storage.delete(original_file.name)
media = form.save()
# Reindex the media entry to make sure all tags are indexed
for backend in get_search_backends():
backend.add(media)
messages.success(
request,
_("Media file '{0}' updated").format(media.title),
buttons=[
messages.button(
reverse("wagtailmedia:edit", args=(media.id,)), _("Edit")
)
],
)
return redirect("wagtailmedia:index")
else:
messages.error(request, _("The media could not be saved due to errors."))
else:
form = MediaForm(instance=media, user=request.user)
filesize = None
# Get file size when there is a file associated with the Media object
if media.file:
try:
filesize = media.file.size
except OSError:
# File doesn't exist
pass
if not filesize:
messages.error(
request,
_(
"The file could not be found. Please change the source or delete the media file"
),
buttons=[
messages.button(
reverse("wagtailmedia:delete", args=(media.id,)), _("Delete")
)
],
)
return render(
request,
"wagtailmedia/media/edit.html",
{
"media": media,
"filesize": filesize,
"form": form,
"user_can_delete": permission_policy.user_has_permission_for_instance(
request.user, "delete", media
),
},
)
@permission_checker.require("delete")
def delete(request, media_id):
Media = get_media_model()
media = get_object_or_404(Media, id=media_id)
if not permission_policy.user_has_permission_for_instance(
request.user, "delete", media
):
return permission_denied(request)
if request.method == "POST":
media.delete()
messages.success(request, _("Media file '{0}' deleted.").format(media.title))
return redirect("wagtailmedia:index")
return render(
request,
"wagtailmedia/media/confirm_delete.html",
{
"media": media,
},
)
@permission_checker.require_any("add", "change", "delete")
def usage(request, media_id):
Media = get_media_model()
media_item = get_object_or_404(Media, id=media_id)
paginator = Paginator(media_item.get_usage(), per_page=20)
object_page = paginator.get_page(request.GET.get("p"))
# Add edit URLs to each source object
url_finder = AdminURLFinder(request.user)
results = []
for entity, references in object_page:
edit_url = url_finder.get_edit_url(entity)
if edit_url is None:
label = _("(Private %s)") % entity._meta.verbose_name
edit_link_title = None
else:
label = str(entity)
edit_link_title = _("Edit this %s") % entity._meta.verbose_name
if isinstance(entity, Page):
verbose_name = capfirst(entity.specific_class._meta.verbose_name)
else:
verbose_name = capfirst(entity._meta.verbose_name)
results.append((label, edit_url, edit_link_title, verbose_name, references))
return render(
request,
"wagtailmedia/media/usage.html",
{"media_item": media_item, "results": results, "object_page": object_page},
)