Allow staff to upload photos has another user.
All checks were successful
Docker / build (release) Successful in 9s
All checks were successful
Docker / build (release) Successful in 9s
This commit is contained in:
parent
b0027be96c
commit
1de1cb4086
4 changed files with 48 additions and 14 deletions
|
|
@ -7,12 +7,15 @@ import datetime
|
|||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Div, Layout, Submit
|
||||
from django import forms
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_select2.forms import ModelSelect2MultipleWidget
|
||||
from django_select2.forms import ModelSelect2MultipleWidget, ModelSelect2Widget
|
||||
|
||||
from .models import Gallery, Tag
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class MultipleFileInput(forms.ClearableFileInput):
|
||||
allow_multiple_selected = True
|
||||
|
|
@ -87,11 +90,27 @@ class UploadForm(forms.Form):
|
|||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
is_staff = kwargs.pop("is_staff", False)
|
||||
super().__init__(*args, **kwargs)
|
||||
if is_staff:
|
||||
self.fields["owner"] = forms.ModelChoiceField(
|
||||
User.objects.all(),
|
||||
label=_("Upload as"),
|
||||
required=False,
|
||||
empty_label=_("-- Myself --"),
|
||||
widget=ModelSelect2Widget(
|
||||
model=User,
|
||||
search_fields=["username__icontains", "first_name__icontains", "last_name__icontains"],
|
||||
attrs={
|
||||
"data-minimum-input-length": 0,
|
||||
"data-placeholder": "-- Myself --",
|
||||
},
|
||||
),
|
||||
)
|
||||
self.helper = FormHelper()
|
||||
self.helper.include_media = False
|
||||
self.helper.use_custom_control = False
|
||||
self.helper.layout = Layout(
|
||||
layout_fields = [
|
||||
"file_field",
|
||||
"gallery",
|
||||
"new_gallery_title",
|
||||
|
|
@ -102,8 +121,11 @@ class UploadForm(forms.Form):
|
|||
),
|
||||
"new_gallery_description",
|
||||
"new_gallery_tags",
|
||||
Submit("submit", _("Upload"), css_class="btn btn-success mt-2"),
|
||||
)
|
||||
]
|
||||
if is_staff:
|
||||
layout_fields.append("owner")
|
||||
layout_fields.append(Submit("submit", _("Upload"), css_class="btn btn-success mt-2"))
|
||||
self.helper.layout = Layout(*layout_fields)
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
|
|
@ -119,6 +141,9 @@ class UploadForm(forms.Form):
|
|||
|
||||
return cleaned_data
|
||||
|
||||
def get_owner(self, fallback):
|
||||
return self.cleaned_data.get("owner") or fallback
|
||||
|
||||
def get_or_create_gallery(self):
|
||||
"""
|
||||
Get or create gallery
|
||||
|
|
|
|||
|
|
@ -95,11 +95,12 @@ pausebtn.addEventListener('click', () => {
|
|||
pausebtn.className = pause ? 'btn btn-success' : 'btn btn-warning';
|
||||
});
|
||||
|
||||
async function uploadFile(file, galleryID, csrfvalue) {
|
||||
async function uploadFile(file, galleryID, csrfvalue, ownerID) {
|
||||
const sendform = new FormData();
|
||||
sendform.append('csrfmiddlewaretoken', csrfvalue);
|
||||
sendform.append('file_field', file);
|
||||
sendform.append('gallery', galleryID);
|
||||
if (ownerID) sendform.append('owner', ownerID);
|
||||
const start = performance.now();
|
||||
const res = await fetch('/upload/', {
|
||||
method: 'POST',
|
||||
|
|
@ -146,6 +147,8 @@ ctnbtn.addEventListener('click', async () => {
|
|||
}
|
||||
|
||||
const galleryID = returned.galleryID;
|
||||
const ownerSelect = document.getElementById('id_owner');
|
||||
const ownerID = ownerSelect ? ownerSelect.value : null;
|
||||
|
||||
uploadInput.disabled = true;
|
||||
gallerySelect.disabled = true;
|
||||
|
|
@ -194,7 +197,7 @@ ctnbtn.addEventListener('click', async () => {
|
|||
while (!pause && active < concurrency && queue.length > 0) {
|
||||
const file = queue.shift();
|
||||
active++;
|
||||
uploadFile(file, galleryID, csrfvalue)
|
||||
uploadFile(file, galleryID, csrfvalue, ownerID)
|
||||
.catch(e => console.error(e))
|
||||
.finally(() => { completed++; tuneConcurrency(); active--; updateProgress(); next(); });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,6 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||
{% trans "Drag and drop photos here" %}
|
||||
</div>
|
||||
{% crispy form %}
|
||||
<p class="mt-3">
|
||||
{% trans "Owner will be" %} <code>{{ request.user.get_full_name }} ({{ request.user.username}})</code>.
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -299,15 +299,20 @@ class GalleryUpload(PermissionRequiredMixin, FormView):
|
|||
success_url = reverse_lazy("photologue:pl-gallery-upload")
|
||||
permission_required = "photologue.add_gallery"
|
||||
|
||||
def _upload_media(self, model, file_field, file_obj, gallery, gallery_dir, post_save=None):
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs["is_staff"] = self.request.user.is_staff
|
||||
return kwargs
|
||||
|
||||
def _upload_media(self, model, file_field, file_obj, gallery, gallery_dir, owner, post_save=None):
|
||||
"""
|
||||
Create a media object, save it to the DB, schedule file save on commit.
|
||||
Returns True if uploaded, False if already exists.
|
||||
"""
|
||||
title = Path(file_obj.name).stem
|
||||
if model.objects.filter(title=title, owner=self.request.user, galleries=gallery).exists():
|
||||
if model.objects.filter(title=title, owner=owner, galleries=gallery).exists():
|
||||
return False
|
||||
obj = model(title=title, slug=unique_slug(model, title), owner=self.request.user)
|
||||
obj = model(title=title, slug=unique_slug(model, title), owner=owner)
|
||||
file_path = str(gallery_dir / file_obj.name)
|
||||
with transaction.atomic():
|
||||
obj.save()
|
||||
|
|
@ -345,6 +350,10 @@ class GalleryUpload(PermissionRequiredMixin, FormView):
|
|||
|
||||
gallery_year = Path(str(gallery.date_start.year))
|
||||
gallery_dir = gallery_year / gallery.slug
|
||||
owner = form.get_owner(self.request.user)
|
||||
if owner != self.request.user and not self.request.user.is_staff:
|
||||
from django.core.exceptions import PermissionDenied
|
||||
raise PermissionDenied
|
||||
|
||||
# Upload pictures and videos
|
||||
uploaded_photo_name = []
|
||||
|
|
@ -352,9 +361,9 @@ class GalleryUpload(PermissionRequiredMixin, FormView):
|
|||
files = form.cleaned_data["file_field"]
|
||||
for photo_file in files:
|
||||
if is_photo(photo_file):
|
||||
uploaded = self._upload_media(Photo, "image", photo_file, gallery, gallery_dir)
|
||||
uploaded = self._upload_media(Photo, "image", photo_file, gallery, gallery_dir, owner)
|
||||
elif is_video(photo_file):
|
||||
uploaded = self._upload_media(Video, "file", photo_file, gallery, gallery_dir, post_save=generate_video_thumbnail)
|
||||
uploaded = self._upload_media(Video, "file", photo_file, gallery, gallery_dir, owner, post_save=generate_video_thumbnail)
|
||||
else:
|
||||
messages.error(self.request, f"{photo_file.name} is not a recognized image or video")
|
||||
jsondata["code"] = 400
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue