diff --git a/resize_rich_link_images/.gitignore b/resize_rich_link_images/.gitignore new file mode 100644 index 0000000..f412002 --- /dev/null +++ b/resize_rich_link_images/.gitignore @@ -0,0 +1,3 @@ +# created by virtualenv automatically +lib/ +bin/ diff --git a/resize_rich_link_images/config.yaml b/resize_rich_link_images/config.yaml new file mode 100644 index 0000000..c028e4c --- /dev/null +++ b/resize_rich_link_images/config.yaml @@ -0,0 +1,42 @@ +region: us-east-1 + +function_name: resize_rich_link_images +handler: serve_thumb.lambda_handler +description: Serve thumbnail for rich link. If thumbnail does not exist, create it +runtime: python3.9 +# role: lambda_basic_execution + +# S3 upload requires appropriate role with s3:PutObject permission +# (ex. basic_s3_upload), a destination bucket, and the key prefix +# bucket_name: 'example-bucket' +# s3_key_prefix: 'path/to/file/' + +# if access key and secret are left blank, boto will use the credentials +# defined in the [default] section of ~/.aws/credentials. + +# In this project the aws access keys are injected via github actions +# when deploying the lambda function +aws_access_key_id: AWS_ACCESS_KEY_ID +aws_secret_access_key: AWS_SECRET_ACCESS_KEY + +# dist_directory: dist +# timeout: 15 +# memory_size: 512 +# concurrency: 500 +# + +# Experimental Environment variables +# environment_variables: +# env_1: foo +# env_2: baz + +# If `tags` is uncommented then tags will be set at creation or update +# time. During an update all other tags will be removed except the tags +# listed here. +#tags: +# tag_1: foo +# tag_2: bar + +# Build options +build: + source_directories: lib # a comma delimited list of directories in your project root that contains source to package. diff --git a/resize_rich_link_images/event.json b/resize_rich_link_images/event.json new file mode 100644 index 0000000..2aad0c1 --- /dev/null +++ b/resize_rich_link_images/event.json @@ -0,0 +1,25 @@ +{ + "Records": [ + { + "cf": { + "config": { + "distributionId": "EXAMPLE" + }, + "request": { + "uri": "/api/rich_link", + "method": "GET", + "clientIp": "2001:cdba::3257:9652", + "body": "", + "headers": { + "host": [ + { + "key": "Host", + "value": "d123.cf.net" + } + ] + } + } + } + } + ] +} \ No newline at end of file diff --git a/resize_rich_link_images/inject_secrets.sh b/resize_rich_link_images/inject_secrets.sh new file mode 100644 index 0000000..3d80d0b --- /dev/null +++ b/resize_rich_link_images/inject_secrets.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +echo "Injectig AWS keys" + +sed -i "s/AWS_ACCESS_KEY_ID/$1/g" config.yaml +sed -i "s/AWS_SECRET_ACCESS_KEY/$2/g" config.yaml + +echo "Injection complete" diff --git a/resize_rich_link_images/pyvenv.cfg b/resize_rich_link_images/pyvenv.cfg new file mode 100644 index 0000000..ffc88e6 --- /dev/null +++ b/resize_rich_link_images/pyvenv.cfg @@ -0,0 +1,8 @@ +home = /usr +implementation = CPython +version_info = 3.9.13.final.0 +virtualenv = 20.16.3 +include-system-site-packages = false +base-prefix = /usr +base-exec-prefix = /usr +base-executable = /usr/bin/python3.9 diff --git a/resize_rich_link_images/serve_thumb.py b/resize_rich_link_images/serve_thumb.py new file mode 100644 index 0000000..ead4976 --- /dev/null +++ b/resize_rich_link_images/serve_thumb.py @@ -0,0 +1,67 @@ +import json +import boto3 +from bs4 import BeautifulSoup +from PIL import Image +from io import BytesIO + + +def get_image_name(html_body): + body = BeautifulSoup(html_body, "html.parser") + image_tag = body.find("meta", property="og:image") + image_name = image_tag["content"].split("/")[-1] + return image_name + + +def resize_image(image): + sizeX = image.size[0] + sizeY = image.size[1] + if sizeX > 300: + image.thumbnail((299, sizeY)) + + +def create_thumbnail(s3_client, s3_bucket, original_image, path): + image_object = s3_client.get_object(Bucket=s3_bucket, Key=original_image) + image = Image.open(BytesIO(image_object["Body"].read())) + resize_image(image) + file_object = BytesIO() + image.save(file_object, "png") + file_object.seek(0) + s3_client.put_object( + Body=file_object, + Bucket=s3_bucket, + Key=path, + ContentType=image_object["ContentType"], + ) + + +def object_exists(s3_client, s3_bucket, path): + try: + s3_client.head_object(Bucket=s3_bucket, Key=path) + return True + except: + return False + + +def lambda_handler(event, context): + + request = event["Records"][0]["cf"]["request"] + + if "api/rich_link" in request["uri"]: + s3_bucket = "cambiatus-uploads" + s3_image_path = "cambiatus-uploads/" + s3_thumb_path = "cambiatus-uploads/thumbnails/" + s3_client = boto3.client("s3") + + image_name = get_image_name(request["body"]) + + if not object_exists(s3_client, s3_bucket, s3_thumb_path + image_name): + create_thumbnail( + s3_client, + s3_bucket, + s3_image_path + image_name, + s3_thumb_path + image_name, + ) + + request["body"] = request["body"].replace(s3_image_path, s3_thumb_path) + + return {"statusCode": 200, "body": json.dumps(request["body"])}