158 lines
4.8 KiB
Python
158 lines
4.8 KiB
Python
import logging
|
|
|
|
from django import forms
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from files.validators import FileMIMETypeValidator
|
|
from constants.base import ALLOWED_PREVIEW_MIMETYPES
|
|
|
|
import extensions.models
|
|
import files.models
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class EditPreviewForm(forms.ModelForm):
|
|
class Meta:
|
|
model = extensions.models.Extension.previews.through
|
|
fields = (
|
|
'caption',
|
|
'position',
|
|
)
|
|
widgets = {
|
|
'position': forms.HiddenInput(attrs={'data-position': ''}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.base_fields['caption'].widget.attrs.update({'placeholder': 'Describe the preview'})
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
EditPreviewFormSet = forms.inlineformset_factory(
|
|
extensions.models.Extension,
|
|
extensions.models.Extension.previews.through,
|
|
form=EditPreviewForm,
|
|
extra=0,
|
|
)
|
|
|
|
|
|
class AddPreviewFileForm(forms.ModelForm):
|
|
msg_unexpected_file_type = _('Choose a JPEG, PNG or WebP image, or an MP4 video')
|
|
|
|
class Meta:
|
|
model = files.models.File
|
|
fields = ('caption', 'source')
|
|
|
|
source = forms.FileField(
|
|
allow_empty_file=False,
|
|
required=True,
|
|
validators=[
|
|
FileMIMETypeValidator(
|
|
allowed_mimetypes=ALLOWED_PREVIEW_MIMETYPES,
|
|
message=msg_unexpected_file_type,
|
|
),
|
|
],
|
|
widget=forms.ClearableFileInput(
|
|
attrs={'accept': ','.join(ALLOWED_PREVIEW_MIMETYPES)},
|
|
),
|
|
)
|
|
caption = forms.CharField(max_length=255, required=False)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
self.request = kwargs.pop('request')
|
|
self.extension = kwargs.pop('extension')
|
|
self.base_fields['caption'].widget.attrs.update({'placeholder': 'Describe the preview'})
|
|
super().__init__(*args, **kwargs)
|
|
|
|
def save(self, *args, **kwargs):
|
|
"""Save Preview from the cleaned form data."""
|
|
# If file with this hash was already uploaded by the same user, return it
|
|
hash_ = self.instance.generate_hash(self.instance.source)
|
|
model = self.instance.__class__
|
|
existing_image = model.objects.filter(original_hash=hash_, user=self.request.user).first()
|
|
if (
|
|
existing_image
|
|
and not existing_image.extension_preview.filter(extension_id=self.extension.id).count()
|
|
):
|
|
logger.warning('Found an existing %s pk=%s', model, existing_image.pk)
|
|
self.instance = existing_image
|
|
# Undelete the instance, if necessary
|
|
if self.instance.is_deleted:
|
|
self.instance.undelete(save=False)
|
|
|
|
# Fill in missing fields from request and the source file
|
|
self.instance.user = self.request.user
|
|
|
|
instance = super().save(*args, **kwargs)
|
|
|
|
# Create extension preview and save caption to it
|
|
instance.extension_preview.create(
|
|
caption=self.cleaned_data['caption'],
|
|
extension=self.extension,
|
|
)
|
|
return instance
|
|
|
|
|
|
class AddPreviewModelFormSet(forms.BaseModelFormSet):
|
|
def __init__(self, *args, **kwargs):
|
|
self.request = kwargs.pop('request')
|
|
self.extension = kwargs.pop('extension')
|
|
super().__init__(*args, **kwargs)
|
|
# Make sure formset doesn't attempt to select existing File records
|
|
self.queryset = files.models.File.objects.none()
|
|
|
|
def get_form_kwargs(self, *args, **kwargs):
|
|
form_kwargs = super().get_form_kwargs(*args, **kwargs)
|
|
form_kwargs['request'] = self.request
|
|
form_kwargs['extension'] = self.extension
|
|
return form_kwargs
|
|
|
|
|
|
AddPreviewFormSet = forms.modelformset_factory(
|
|
files.models.File,
|
|
form=AddPreviewFileForm,
|
|
formset=AddPreviewModelFormSet,
|
|
extra=1,
|
|
)
|
|
|
|
|
|
class ExtensionUpdateForm(forms.ModelForm):
|
|
class Meta:
|
|
model = extensions.models.Extension
|
|
fields = (
|
|
'description',
|
|
'support',
|
|
)
|
|
|
|
|
|
class ExtensionDeleteForm(forms.ModelForm):
|
|
class Meta:
|
|
model = extensions.models.Extension
|
|
fields = []
|
|
|
|
|
|
class VersionForm(forms.ModelForm):
|
|
class Meta:
|
|
model = extensions.models.Version
|
|
fields = {'file', 'release_notes'}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
"""Limit 'file' choices to the initial file value."""
|
|
super().__init__(*args, **kwargs)
|
|
|
|
# Mark 'file' field as disabled so that Django form allows using its initial value.
|
|
self.fields['file'].disabled = True
|
|
|
|
def clean_file(self, *args, **kwargs):
|
|
"""Return file that was passed to the form via the initial values.
|
|
|
|
This ensures that it doesn't have to be supplied by the form data.
|
|
"""
|
|
return self.initial['file']
|
|
|
|
|
|
class VersionDeleteForm(forms.ModelForm):
|
|
class Meta:
|
|
model = extensions.models.Version
|
|
fields = []
|