153 lines
5 KiB
Python
153 lines
5 KiB
Python
# This file is part of photo21
|
|
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
import datetime
|
|
|
|
from crispy_forms.helper import FormHelper
|
|
from crispy_forms.layout import Div, Layout, Submit
|
|
from django import forms
|
|
from django.utils.text import slugify
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from .models import Gallery, Tag
|
|
|
|
|
|
class MultipleFileInput(forms.ClearableFileInput):
|
|
allow_multiple_selected = True
|
|
|
|
|
|
class MultipleFileField(forms.FileField):
|
|
allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'tiff'] # Specify allowed extensions here
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
kwargs.setdefault(
|
|
"widget",
|
|
MultipleFileInput(
|
|
attrs={
|
|
"accept": "image/*",
|
|
"class": "mb-3",
|
|
}
|
|
),
|
|
)
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def clean(self, data, initial=None):
|
|
single_file_clean = super().clean
|
|
|
|
if isinstance(data, (list, tuple)):
|
|
result = [self.validate_file(d, single_file_clean, initial) for d in data]
|
|
else:
|
|
result = self.validate_file(data, single_file_clean, initial)
|
|
return result
|
|
|
|
def validate_file(self, file, single_file_clean, initial):
|
|
# Perform the default clean
|
|
cleaned_file = single_file_clean(file, initial)
|
|
|
|
# Check the file extension
|
|
extension = file.name.split('.')[-1].lower()
|
|
if extension not in self.allowed_extensions:
|
|
raise forms.ValidationError(
|
|
f"{file.name} has an invalid file extension. "
|
|
f"Allowed extensions are: {', '.join(self.allowed_extensions)}"
|
|
)
|
|
return cleaned_file
|
|
|
|
|
|
class UploadForm(forms.Form):
|
|
file_field = MultipleFileField(label="")
|
|
gallery = forms.ModelChoiceField(
|
|
Gallery.objects.all(),
|
|
label=_("Gallery"),
|
|
required=False,
|
|
empty_label=_("-- Create a new gallery --"),
|
|
help_text=_(
|
|
"Select a gallery to add these images to. Leave this empty to "
|
|
"create a new gallery from the supplied title."
|
|
),
|
|
)
|
|
new_gallery_title = forms.CharField(
|
|
label=_("New gallery title"),
|
|
max_length=250,
|
|
required=False,
|
|
)
|
|
new_gallery_date_start = forms.DateField(
|
|
label=_("New gallery event start date"),
|
|
initial=datetime.date.today,
|
|
required=False,
|
|
)
|
|
new_gallery_date_end = forms.DateField(
|
|
label=_("New gallery event end date"),
|
|
initial=datetime.date.today,
|
|
required=False,
|
|
)
|
|
new_gallery_description = forms.CharField(
|
|
label=_("Description"),
|
|
required=False
|
|
)
|
|
new_gallery_tags = forms.ModelMultipleChoiceField(
|
|
Tag.objects.all(),
|
|
label=_("New gallery tags"),
|
|
required=False,
|
|
help_text=_(
|
|
'Hold down "Control", or "Command" on a Mac, to select more than one.'
|
|
),
|
|
)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.helper = FormHelper()
|
|
self.helper.use_custom_control = False
|
|
self.helper.layout = Layout(
|
|
"file_field",
|
|
"gallery",
|
|
"new_gallery_title",
|
|
Div(
|
|
Div("new_gallery_date_start", css_class="col"),
|
|
Div("new_gallery_date_end", css_class="col"),
|
|
css_class="row",
|
|
),
|
|
"new_gallery_description",
|
|
"new_gallery_tags",
|
|
Submit("submit", _("Upload"), css_class="btn btn-success mt-2"),
|
|
)
|
|
|
|
def clean_new_gallery_title(self):
|
|
title = self.cleaned_data["new_gallery_title"]
|
|
if title and Gallery.objects.filter(title=title).exists():
|
|
raise forms.ValidationError(_("A gallery with that title already exists."))
|
|
return title
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
|
|
# Check that either an existing gallery is chosen, or new_gallery_title is filled
|
|
if not (
|
|
bool(cleaned_data["gallery"])
|
|
^ bool(cleaned_data.get("new_gallery_title", None))
|
|
):
|
|
raise forms.ValidationError(
|
|
_("Select an existing gallery, or enter a title for a new gallery.")
|
|
)
|
|
|
|
return cleaned_data
|
|
|
|
def get_or_create_gallery(self):
|
|
"""
|
|
Get or create gallery
|
|
"""
|
|
gallery = self.cleaned_data["gallery"]
|
|
if not gallery:
|
|
# Create new gallery
|
|
title = self.cleaned_data.get("new_gallery_title")
|
|
gallery = Gallery.objects.create(
|
|
title=title,
|
|
slug=slugify(title),
|
|
date_start=self.cleaned_data["new_gallery_date_start"],
|
|
date_end=self.cleaned_data["new_gallery_date_end"],
|
|
description=self.cleaned_data["new_gallery_description"]
|
|
)
|
|
for tag in self.cleaned_data["new_gallery_tags"]:
|
|
gallery.tags.add(tag)
|
|
return gallery
|