From 1afd527efe4e2a1a481b9cf52cdd915356b1d58a Mon Sep 17 00:00:00 2001 From: Matthew Lemon Date: Sat, 3 Aug 2024 17:24:35 +0100 Subject: Adds ability to update the thumbnail/feature images --- pyblackbird_cc/resources/forms.py | 28 +++++++++++++++----- pyblackbird_cc/resources/views.py | 30 ++++++++++++++++++++++ .../templates/resources/resource_card.html | 2 ++ .../templates/resources/resource_detail.html | 3 --- .../templates/resources/update_thumbnails.html | 29 +++++++++++++++++++++ 5 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 pyblackbird_cc/templates/resources/update_thumbnails.html diff --git a/pyblackbird_cc/resources/forms.py b/pyblackbird_cc/resources/forms.py index 1a5b51a..4b7df38 100644 --- a/pyblackbird_cc/resources/forms.py +++ b/pyblackbird_cc/resources/forms.py @@ -183,7 +183,10 @@ class ResourceUpdateMetadataForm(forms.ModelForm): class ResourceUpdateThumbnailsForm(forms.Form): def __init__(self, *args, **kwargs): - self.resource = kwargs.pop("resource") + try: + self.resource = kwargs.pop("resource") + except KeyError: + pass super().__init__(*args, **kwargs) self.helper = FormHelper(self) self.helper.add_input(Submit("submit", "Submit")) @@ -197,11 +200,22 @@ class ResourceUpdateThumbnailsForm(forms.Form): }, ), 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.", + label="Thumbnail files", + help_text="You can provide X number of files here." ) + 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 diff --git a/pyblackbird_cc/resources/views.py b/pyblackbird_cc/resources/views.py index 2feb655..4ce2472 100644 --- a/pyblackbird_cc/resources/views.py +++ b/pyblackbird_cc/resources/views.py @@ -210,6 +210,29 @@ def upload_to_s3(pdf_files, thumbnail_files, snapshotted_pages) -> bool: return False +def upload_thumbnails_to_s3(thumbnail_files) -> bool: + session = boto3.Session() + client = session.client( + "s3", + endpoint_url=settings.AWS_S3_ENDPOINT_URL, + aws_access_key_id=settings.AWS_ACCESS_KEY_ID, + aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY, + region_name=settings.AWS_S3_REGION_NAME, + ) + try: + for f in thumbnail_files: + logger.info(f"Uploading {f.name} to S3") + client.upload_fileobj( + f, + settings.AWS_STORAGE_BUCKET_NAME, + f"thumbnails/{f.name}", + ) + return True + except Exception as e: # Any exceptions generated by boto3 client will be caught here + logger.error(f"Error uploading thumbnail files to S3: {e}") + return False + + def _write_pdf_to_tempdir(f) -> str: temp_dir = tempfile.mkdtemp() file_path = os.path.join(temp_dir, f.name) @@ -376,6 +399,13 @@ def update_resource_thumbnails(request, pk): resource = get_object_or_404(Resource, pk=pk) if request.method == "POST": form = ResourceUpdateThumbnailsForm(request.POST, request.FILES) + if form.is_valid(): + thumbnail_files = form.cleaned_data["thumbnail_files"] + resource.thumbnail_filenames = [f.name for f in thumbnail_files] + if not upload_thumbnails_to_s3(thumbnail_files): + raise Exception("Error uploading files to S3") + resource.save() + return redirect("resources:resource_detail", resource_id=resource.id) else: form = ResourceUpdateThumbnailsForm(resource=pk) diff --git a/pyblackbird_cc/templates/resources/resource_card.html b/pyblackbird_cc/templates/resources/resource_card.html index 67807cc..687438c 100644 --- a/pyblackbird_cc/templates/resources/resource_card.html +++ b/pyblackbird_cc/templates/resources/resource_card.html @@ -37,6 +37,8 @@ {% endif %} \ No newline at end of file diff --git a/pyblackbird_cc/templates/resources/resource_detail.html b/pyblackbird_cc/templates/resources/resource_detail.html index f520340..4a513af 100644 --- a/pyblackbird_cc/templates/resources/resource_detail.html +++ b/pyblackbird_cc/templates/resources/resource_detail.html @@ -34,9 +34,6 @@
{% if request.user.is_authenticated %}Replace the PDFs{% endif %}
-
- {% if request.user.is_authenticated %}Replace the preview images{% endif %} -
diff --git a/pyblackbird_cc/templates/resources/update_thumbnails.html b/pyblackbird_cc/templates/resources/update_thumbnails.html new file mode 100644 index 0000000..e473a00 --- /dev/null +++ b/pyblackbird_cc/templates/resources/update_thumbnails.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} +{% load static %} +{% load crispy_forms_tags %} + +{% block content %} +
+
+

Update feature images for {{ resource.name }} resource

+ +

The current thumbnails for this resource are:

+ +
    + {% for t in resource.thumbnail_filenames %} +
  • {{ t }}
  • + {% endfor %} +
+ +
+ {% csrf_token %} + {% crispy form form.helper %} +
+ + +
+
+ + +{% endblock %} -- cgit v1.2.3