-
Alexa Valentová authoredAlexa Valentová authored
forms.py 6.59 KiB
import os
import tempfile
from django import forms
from django.core.exceptions import ValidationError
from shared.forms import ArticlesPageForm as SharedArticlesPageForm
from shared.forms import JekyllImportForm as SharedJekyllImportForm
from .tasks import import_jekyll_articles
class MultipleFileInput(forms.ClearableFileInput):
allow_multiple_selected = True
class MultipleFileField(forms.FileField):
def __init__(self, *args, **kwargs):
kwargs.setdefault("widget", MultipleFileInput())
super().__init__(*args, **kwargs)
TOTAL_MAX_FILE_SIZE = 5 * 1024 * 1024 # 5 MB
def clean(self, data, initial=None):
single_file_clean = super().clean
if isinstance(data, (list, tuple)):
total_size = 0
for file in data:
total_size += file.size
if total_size > self.TOTAL_MAX_FILE_SIZE:
raise ValidationError(
"Celková velikost nahraných souborů je příliš velká."
)
result = [single_file_clean(d, initial) for d in data]
else:
result = [single_file_clean(data, initial)]
return result
# Allowed MIME types
ALLOWED_FILE_TYPES = [
"application/pdf", # PDF
"application/msword", # DOC
"application/vnd.openxmlformats-officedocument.wordprocessingml.document", # DOCX
"image/png", # PNG
"application/vnd.oasis.opendocument.text", # ODT
]
def validate_file_type(file):
if file.content_type not in ALLOWED_FILE_TYPES:
raise ValidationError(
f"Chybný formát souboru: {file.content_type}. Povolené jsou pouze PDF, DOC, DOCX, PNG, and ODT."
)
def validate_file_size(file, max_size=5 * 1024 * 1024): # Default: 5 MB
if file.size > max_size:
raise ValidationError(
f"Soubory mohou být max. {max_size / (1024 * 1024)} MB velké."
)
class CareerSubmissionForm(forms.Form):
name = forms.CharField(
min_length=1,
max_length=256,
required=True,
widget=forms.TextInput(
attrs={
"placeholder": "Jméno",
"class": "lg:w-auto w-full",
"value": "",
"autocomplete": "",
}
),
)
surname = forms.CharField(
min_length=1,
max_length=256,
required=True,
widget=forms.TextInput(
attrs={
"placeholder": "Příjmení",
"class": "lg:w-auto w-full",
"value": "",
"autocomplete": "",
}
),
)
email = forms.EmailField(
min_length=1,
max_length=256,
required=True,
widget=forms.EmailInput(
attrs={
"placeholder": "Email",
"class": "w-full",
"value": "",
"autocomplete": "",
}
),
)
phone = forms.IntegerField(
required=True,
widget=forms.NumberInput(
attrs={
"type": "tel",
"placeholder": "Telefon",
"class": "w-full",
"value": "",
"autocomplete": "",
}
),
)
own_text = forms.CharField(
widget=forms.Textarea(
attrs={
"placeholder": "Vlastní text (nepovinný)",
"class": "w-full",
"rows": 3,
}
),
max_length=65535,
required=False,
)
cv_file = forms.FileField(
required=True,
validators=[validate_file_type, validate_file_size],
widget=forms.FileInput(
attrs={
"class": "max-w-64 mr-auto overflow-hidden break-words",
"accept": ".pdf,.doc,.docx,.png,.odt",
}
),
)
cover_letter_file = forms.FileField(
required=True,
validators=[validate_file_type, validate_file_size],
widget=forms.FileInput(
attrs={
"class": "max-w-64 mr-auto overflow-hidden break-words",
"accept": ".pdf,.doc,.docx,.png,.odt",
}
),
)
other_files = MultipleFileField(
required=False,
validators=[validate_file_type, validate_file_size],
widget=MultipleFileInput(
attrs={
"class": "max-w-64 mr-auto overflow-hidden break-words",
"accept": ".pdf,.doc,.docx,.png,.odt",
}
),
)
personal_data_agreement = forms.BooleanField(required=True)
other_offers_agreement = forms.BooleanField(required=False)
class JekyllImportForm(SharedJekyllImportForm):
def handle_import(self):
lock_file_name = os.path.join(
tempfile.gettempdir(), f".{self.instance.id}.articles-import-lock"
)
if os.path.isfile(lock_file_name):
return
open(lock_file_name, "w").close()
import_jekyll_articles.delay(
article_parent_page_id=self.instance.id,
collection_id=self.cleaned_data["collection"].id,
url=self.cleaned_data["jekyll_repo_url"],
dry_run=self.cleaned_data["dry_run"],
use_git=True,
)
class MainArticlesPageForm(SharedArticlesPageForm, JekyllImportForm):
def __init__(self, *args, **kwargs):
from shared.models import SharedTag
from .models import MainArticleTag
super().__init__(*args, **kwargs)
self.fields["shared_tags"].queryset = SharedTag.objects.order_by("name")
if self.instance.pk:
valid_tag_ids = (
MainArticleTag.objects.filter(
content_object__in=self.instance.get_children().specific()
)
.values_list("tag_id", flat=True)
.distinct()
)
valid_shared_tag_ids = (
self.instance.shared_tags.values_list("id", flat=True).distinct().all()
)
self.fields["displayed_tags"].queryset = (
MainArticleTag.objects.filter(id__in=valid_tag_ids)
.order_by("tag__name")
.distinct("tag__name")
)
self.fields["displayed_shared_tags"].queryset = (
SharedTag.objects.filter(id__in=valid_shared_tag_ids)
.order_by("name")
.distinct("name")
)
else:
self.fields["displayed_tags"].queryset = MainArticleTag.objects.filter(
id=-1
)
self.fields["displayed_shared_tags"].queryset = SharedTag.objects.filter(
id=-1
)