aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pyblackbird_cc/resources/forms.py28
-rw-r--r--pyblackbird_cc/resources/views.py30
-rw-r--r--pyblackbird_cc/templates/resources/resource_card.html2
-rw-r--r--pyblackbird_cc/templates/resources/resource_detail.html3
-rw-r--r--pyblackbird_cc/templates/resources/update_thumbnails.html29
5 files changed, 82 insertions, 10 deletions
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 @@
<div class="card-footer">
<a href="{% url 'resources:resource_update_metadata' resource.id %}"
class="btn btn-outline-primary btn-sm">Edit</a>
+ <a href="{% url 'resources:resource_update_thumbnails' resource.id %}"
+ class="btn btn-outline-primary btn-sm">Edit Feature Images</a>
</div>
{% endif %}
</div> \ 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 @@
<div>
{% if request.user.is_authenticated %}<a href="#" class="text-danger">Replace the PDFs</a>{% endif %}
</div>
- <div>
- {% if request.user.is_authenticated %}<a href="{% url "resources:resource_update_thumbnails" resource.id %}" class="text-danger">Replace the preview images</a>{% endif %}
- </div>
</div>
</div>
</div>
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 %}
+ <div class="row d-flex justify-content-center">
+ <div class="col bg-light mt-lg-4 p-4 border border-success border-opacity-25 rounded">
+ <h1>Update feature images for <strong>{{ resource.name }}</strong> resource</h1>
+
+ <p>The current thumbnails for this resource are:</p>
+
+ <ul>
+ {% for t in resource.thumbnail_filenames %}
+ <li><em>{{ t }}</em></li>
+ {% endfor %}
+ </ul>
+
+ <form action="{% url "resources:resource_update_thumbnails" resource.id %}"
+ method="post" enctype="multipart/form-data">
+ {% csrf_token %}
+ {% crispy form form.helper %}
+ </form>
+
+ <button class="btn btn-danger" onclick="location.href='{{ resource.get_absolute_url }}';">Cancel</button>
+ </div>
+ </div>
+
+
+{% endblock %}