import logging import magic from crispy_forms.helper import FormHelper from crispy_forms.layout import Submit from django import forms from .models import ResourceCategory from .models import ResourceType logger = logging.getLogger(__name__) ALLOWED_THUMBNAILS = 5 ALLOWED_PDFS = 20 class ResourceCreateForm(forms.Form): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper(self) self.helper.add_input(Submit("submit", "Submit")) error_css_class = "error" required_css_class = "required" name = forms.CharField( max_length=255, help_text="Concisely describe what the resource is, aiming for" " in 35-45 characters. " "eg: 'Fractions KS2 Worksheet and Answers.'", ) description = forms.CharField( max_length=1000, widget=forms.Textarea, help_text="This is your opportunity to clearly explain what your resource " "is all " "about! It’s worth remembering that you are using the space to " "communicate to two " "different audiences. Firstly, think about what fellow teachers " "would like " "to know, such as exactly what the resource contains and how it " "could be used in the classroom. Secondly, the words you include " "on this page are also talking to internal and external search " "engines." " External search engines, like Google, show the first 155 characters " "of the resource description, so make sure you take advantage " "of these " "characters by using lots of relevant keywords as part of an " "enticing pitch.", ) resource_type = forms.ModelChoiceField(queryset=ResourceType.objects.all()) age_range = forms.ChoiceField( choices=[ ("3-5", "3-5"), ("5-7", "5-7"), ("7-11", "7-11"), ("11-14", "11-14"), ("14-16", "14-16"), ("16+", "16+"), ("Age not applicable", "Age not applicable"), ], help_text="Try to be accurate in your choice of age range so that your resource " "shows up in the correct searches. (Although we don't have searches yet!)", ) curriculum = forms.ChoiceField( choices=[ ("No curriculum", "No curriculum"), ("English", "English"), ("Scottish", "Scottish"), ], ) main_resource_category = forms.ModelChoiceField( queryset=ResourceCategory.objects.all(), help_text="Categorise your resource by subject so it shows up in the correct " "searches. It's a good idea to limit the number of subjects you select " "to one or two to make your resource easier to find.", ) additional_resource_category = forms.ModelChoiceField( queryset=ResourceCategory.objects.all(), required=False, ) pdf_files = forms.FileField( widget=forms.TextInput( attrs={ "multiple": True, "type": "File", "required": True, }, ), required=False, help_text="You can multi-select up to 20 .pdf files here.", label="PDF files", ) thumbnail_files = forms.FileField( widget=forms.TextInput( attrs={ "multiple": True, "type": "File", "required": True, }, ), required=False, label="Cover images", help_text="Your cover image will be displayed in the search results and as " "the first image on your resource page in the preview function. " "It is important to add an eye catching cover image that gives " "other teachers an idea about what your resource contains. " "You can multi-select up to 5 .png or .jpg files here.", ) pdf_files.widget.attrs.update({"class": "file_upload", "accept": ".pdf"}) thumbnail_files.widget.attrs.update({"class": "file_upload", "accept": ".png,.jpg"}) def clean_thumbnail_files(self): thumbnail_files = self.files.getlist("thumbnail_files") if not thumbnail_files: raise forms.ValidationError("Please select at least one thumbnail file.") acceptable = ["image/png", "image/jpeg"] for f in thumbnail_files: content_type = magic.from_buffer(f.file.read(), mime=True) f.file.seek(0) if content_type not in acceptable: raise forms.ValidationError("Please select only PNG or JPG files.") if len(thumbnail_files) > ALLOWED_THUMBNAILS: raise forms.ValidationError("Please select up to 5 files.") return thumbnail_files def clean_pdf_files(self): pdf_files = self.files.getlist("pdf_files") if not pdf_files: raise forms.ValidationError("Please select at least one PDF file.") acceptable = ["application/pdf"] for f in pdf_files: content_type = magic.from_buffer(f.file.read(), mime=True) f.file.seek(0) if content_type not in acceptable: raise forms.ValidationError("Please select only PDF files.") if len(pdf_files) > ALLOWED_PDFS: raise forms.ValidationError("Please select up to 20 PDF files.") return pdf_files