@@ -30,12 +30,12 @@ class ImageProcessorHandler : RequestHandler<SQSEvent, String> {
30
30
init {
31
31
s3Service = S3ServiceImpl (Region .EU_WEST_2 )
32
32
sqsService = SQSServiceImpl (Region .EU_WEST_2 )
33
-
34
33
}
35
34
36
35
override fun handleRequest (event : SQSEvent , context : Context ): String {
37
36
val sourceBucket = System .getenv(" source_bucket" )
38
37
val destinationBucket = System .getenv(" destination_bucket" )
38
+ val generationBucket = System .getenv(" generation_bucket" )
39
39
logger = context.logger
40
40
processor = ImageProcessor (logger)
41
41
@@ -44,20 +44,17 @@ class ImageProcessorHandler : RequestHandler<SQSEvent, String> {
44
44
logger.info(" Received ${event.records.size} events received for image processing" )
45
45
46
46
try {
47
- val projectYaml= s3Service.getObjectAsString(S3_KEY .projectKey, sourceBucket)
48
- val project = Yaml .default.decodeFromString(CantileverProject .serializer(), projectYaml)
49
-
50
47
event.records.forEach { eventRecord ->
51
48
logger.info(" Event record: ${eventRecord.body} " )
52
49
53
50
when (val sqsMsg = Json .decodeFromString<ImageSQSMessage >(eventRecord.body)) {
54
51
is ImageSQSMessage .ResizeImageMsg -> {
55
- response = processImageResize(sqsMsg, sourceBucket)
52
+ response = processImageResize(sqsMsg, sourceBucket, generationBucket )
56
53
}
57
54
58
55
is ImageSQSMessage .CopyImagesMsg -> {
59
- logger.info(" Received request to copy images from source to destination bucket" )
60
- response = processImageCopy(sqsMsg, project, sourceBucket , destinationBucket)
56
+ logger.info(" Received request to copy images from generation to destination bucket" )
57
+ response = processImageCopy(sqsMsg, generationBucket , destinationBucket)
61
58
}
62
59
}
63
60
}
@@ -72,15 +69,17 @@ class ImageProcessorHandler : RequestHandler<SQSEvent, String> {
72
69
* Process the image resize message. For each resolution defined in the project metadata, create a new image based on the original
73
70
* @param imageMessage the SQS message containing the image to resize
74
71
* @param sourceBucket the bucket containing the image to resize
72
+ * @param generationBucket the bucket to write the resized images to
75
73
* @return a String response to the SQS message
76
74
*/
77
75
private fun processImageResize (
78
- imageMessage : ImageSQSMessage .ResizeImageMsg , sourceBucket : String
76
+ imageMessage : ImageSQSMessage .ResizeImageMsg , sourceBucket : String , generationBucket : String
79
77
): String {
80
78
var responseString = " 200 OK"
81
79
82
80
try {
83
- val projectString = s3Service.getObjectAsString(S3_KEY .projectKey, sourceBucket)
81
+ val domain = imageMessage.projectDomain
82
+ val projectString = s3Service.getObjectAsString(" $domain .yaml" , sourceBucket)
84
83
val project = Yaml .default.decodeFromString(CantileverProject .serializer(), projectString)
85
84
logger.info(" Project: $project " )
86
85
@@ -102,16 +101,18 @@ class ImageProcessorHandler : RequestHandler<SQSEvent, String> {
102
101
val destKey = calculateFilename(imageMessage, name)
103
102
logger.info(" Resize image: writing $destKey (${resizedBytes.size} bytes) to $sourceBucket " )
104
103
s3Service.putObjectAsBytes(
105
- destKey, sourceBucket , resizedBytes, contentType ? : " image/jpeg"
104
+ destKey, generationBucket , resizedBytes, contentType ? : " image/jpeg"
106
105
)
107
106
}
108
107
}
109
108
// finally, copy the original image to the generated folder, unchanged
110
109
logger.info(" Copying original image to generated folder" )
110
+ val copyToKey = " $domain /generated/images/${imageMessage.metadata.srcKey.substringAfterLast(" /" )} "
111
111
s3Service.copyObject(
112
112
imageMessage.metadata.srcKey,
113
- calculateFilename(imageMessage, null ),
114
- sourceBucket
113
+ copyToKey,
114
+ sourceBucket,
115
+ generationBucket
115
116
)
116
117
logger.info(" Creating internal thumbnail 100x100" )
117
118
val thumbNailRes = ImgRes (100 , 100 )
@@ -120,7 +121,7 @@ class ImageProcessorHandler : RequestHandler<SQSEvent, String> {
120
121
val destKey = calculateFilename(imageMessage, S3_KEY .thumbnail)
121
122
logger.info(" Resize image: writing $destKey (${resizedBytes.size} bytes) to $sourceBucket " )
122
123
s3Service.putObjectAsBytes(
123
- destKey, sourceBucket , resizedBytes, contentType ? : " image/jpeg"
124
+ destKey, generationBucket , resizedBytes, contentType ? : " image/jpeg"
124
125
)
125
126
} else {
126
127
logger.error(" Resize image: ${imageMessage.metadata.srcKey} is empty" )
@@ -133,7 +134,6 @@ class ImageProcessorHandler : RequestHandler<SQSEvent, String> {
133
134
return " 202 Accepted"
134
135
}
135
136
136
-
137
137
} catch (e: Exception ) {
138
138
logger.error(" Failed to process image file; ${e.message} " )
139
139
responseString = " 500 Internal Server Error"
@@ -143,10 +143,14 @@ class ImageProcessorHandler : RequestHandler<SQSEvent, String> {
143
143
}
144
144
145
145
// TODO: Need stronger error handling here; there's a good chance that the source image won't exist
146
- private fun processImageCopy (imageMessage : ImageSQSMessage .CopyImagesMsg , project : CantileverProject , sourceBucket : String , destinationBucket : String ): String {
146
+ private fun processImageCopy (imageMessage : ImageSQSMessage .CopyImagesMsg ,sourceBucket : String , destinationBucket : String ): String {
147
147
var responseString = " 200 OK"
148
148
149
149
try {
150
+ // load the project
151
+ val domain = imageMessage.projectDomain
152
+ val projectString = s3Service.getObjectAsString(" $domain /metadata.json" , sourceBucket)
153
+ val project = Yaml .default.decodeFromString(CantileverProject .serializer(), projectString)
150
154
imageMessage.imageList.forEach { imageKey ->
151
155
// imageKey will be as requested by the markdown file, e.g. /images/my-image.jpg
152
156
// sourceKey will be the full path in the source bucket, e.g. generated/images/my-image.jpg
@@ -172,17 +176,23 @@ class ImageProcessorHandler : RequestHandler<SQSEvent, String> {
172
176
/* *
173
177
* Calculate the filename for the resized image
174
178
* Based on the original file name, and the resolution name
179
+ * Will be in the format domain/generated/images/my-image.100x100.jpg
180
+ * @param imageMessage the SQS message containing details of the image to resize
181
+ * @param resName the name of the resolution to append to the filename
175
182
*/
176
183
private fun calculateFilename (
177
184
imageMessage : ImageSQSMessage .ResizeImageMsg , resName : String?
178
185
): String {
186
+ // original image key is in the format domain/sources/images/my-image.jpg
187
+ // destination image key should be in format domain/generated/images/my-image/100x100.jpg
188
+ val domain = imageMessage.projectDomain
189
+ val sourceLeafName = imageMessage.metadata.srcKey.substringAfterLast(" /" )
179
190
val origSuffix = imageMessage.metadata.srcKey.substringAfterLast(" ." )
180
- val newPrefix = S3_KEY .generated + " /"
181
- val leafName = imageMessage.metadata.srcKey.removePrefix(S3_KEY .sourcesPrefix).substringBeforeLast(" ." )
191
+ val newPrefix = " $domain /generated/images/"
182
192
val finalResName = if (resName != null ) {
183
193
" /$resName ."
184
194
} else " ."
185
- return " $newPrefix$leafName ${finalResName}${origSuffix} "
195
+ return " $newPrefix$sourceLeafName ${finalResName}${origSuffix} "
186
196
}
187
197
188
198
/* *
0 commit comments