Skip to content

Commit

Permalink
work-in-progress: convert heic to jpeg on Asset creation
Browse files Browse the repository at this point in the history
  • Loading branch information
nikolas committed Jan 13, 2025
1 parent 60d34cf commit c911e8b
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 5 deletions.
2 changes: 1 addition & 1 deletion mediathread/assetmgr/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
path('pdfjs/<int:pk>/', PDFViewerDetailView.as_view(), {},
name='pdfjs'),

path('sign_s3/', S3SignView.as_view()),
path('sign_s3/', S3SignView.as_view(), name='s3sign'),

# Load this CSS asset as a TemplateView so we can use the static
# template tag.
Expand Down
60 changes: 56 additions & 4 deletions mediathread/assetmgr/utils.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,67 @@
from urllib.parse import urlparse
import boto3
from s3sign.utils import create_presigned_url, s3_config
import requests
from django.conf import settings
from os.path import basename, splitext, join
from PIL import Image
from pi_heif import register_heif_opener
from s3sign.utils import create_presigned_url, s3_config, upload_file
from urllib.parse import urlparse


def get_s3_private_bucket_name() -> str:
return getattr(
settings,
'S3_PRIVATE_STORAGE_BUCKET_NAME',
'mediathread-private-uploads')

def get_signed_s3_url(url, bucket, aws_key, aws_secret):
s3_client = boto3.client(

def get_s3_client(aws_key, aws_secret):
return boto3.client(
's3', config=s3_config,
aws_access_key_id=aws_key,
aws_secret_access_key=aws_secret)


def get_signed_s3_url(url: str, bucket: str, aws_key: str, aws_secret: str):
s3_client = get_s3_client(aws_key, aws_secret)

url = urlparse(url)
object_name = url.path.lstrip('/')
object_name = object_name.replace(bucket + '/', '')
return create_presigned_url(s3_client, bucket, object_name, 3600)


def convert_heic_to_jpg(
url: str, request: object, bucket: str,
aws_key: str, aws_secret: str
) -> str:
"""
Given an heic image url, convert it to a JPEG. This comprises a
few steps:
* Download the file
* Do the conversion
* Upload jpeg to S3
* Return new url
"""
response = requests.get(url, stream=True)

# Sort out the new filename
parsed_url = urlparse(url)
filename = splitext(basename(parsed_url.path))[0]
filename = filename + '.jpg'

# Open the file and convert it
register_heif_opener()
im = Image.open(response.raw)
rgb_im = im.convert('RGB')
tmp_jpeg = join('/tmp/', filename)
rgb_im.save(tmp_jpeg)

# upload to S3, return source url
mime_type = 'image/jpeg'
private = True
data = upload_file(
get_s3_client(aws_key, aws_secret), bucket, mime_type, object_name,
max_file_size, acl, expiration_time, private
)
print(data)
16 changes: 16 additions & 0 deletions mediathread/assetmgr/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
Asset, Source, ExternalCollection,
SuggestedExternalCollection
)
from mediathread.assetmgr.utils import (
get_signed_s3_url, get_s3_private_bucket_name, convert_heic_to_jpg
)
from mediathread.djangosherd.api import DiscussionIndexResource
from mediathread.djangosherd.models import SherdNote, DiscussionIndex
from mediathread.djangosherd.views import create_annotation, edit_annotation, \
Expand Down Expand Up @@ -375,6 +378,19 @@ def post(self, request, *args, **kwargs):
width = request.POST.get('width')
height = request.POST.get('height')

if url.endswith('.heic') or url.endswith('.heif'):
# Convert to JPG
s3_private_bucket = get_s3_private_bucket_name()
signed_url = get_signed_s3_url(
url, s3_private_bucket,
settings.AWS_ACCESS_KEY,
settings.AWS_SECRET_KEY)

# Pass in the signed url because we need to download it.
url = convert_heic_to_jpg(
signed_url, request, s3_private_bucket,
settings.AWS_ACCESS_KEY, settings.AWS_SECRET_KEY)

# If the form passed in a valid label, use it.
lbl = request.POST.get('label')
if lbl and lbl in Asset.primary_labels:
Expand Down
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ click-plugins>=1.1.1
wcwidth==0.2.5
django-celery-results<2.6.0

Pillow==11.1.0
pi-heif==0.21.0

# memcached
pylibmc==1.6.3;sys_platform == "linux" and python_version<"3.9"
Expand Down

0 comments on commit c911e8b

Please sign in to comment.