Skip to content

Commit b515a9e

Browse files
author
Phil Varner
authored
Add endpoint and link for retrieving a thumbnail (#341)
1 parent 84994b0 commit b515a9e

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
2525
- POST /collections endpoint to create collections
2626
- Configuration of shards and replicas for the indices containing Items can now be done
2727
with environment variables ITEMS_INDICIES_NUM_OF_SHARDS and ITEMS_INDICIES_NUM_OF_REPLICAS.
28+
- (Experimental) Adds Item 'thumbnail' link to presign an s3 protocol thumbnail asset ARN
2829

2930
### Changed
3031

src/lambdas/api/app.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,31 @@ app.delete('/collections/:collectionId/items/:itemId', async (req, res, next) =>
321321
}
322322
})
323323

324+
app.get('/collections/:collectionId/items/:itemId/thumbnail', async (req, res, next) => {
325+
try {
326+
const { itemId, collectionId } = req.params
327+
328+
const response = await api.getItemThumbnail(
329+
collectionId,
330+
itemId,
331+
database,
332+
)
333+
334+
if (response instanceof Error) {
335+
if (response.message === 'Item not found'
336+
|| response.message === 'Thumbnail not found') {
337+
next(createError(404))
338+
} else {
339+
next(createError(500))
340+
}
341+
} else {
342+
res.redirect(response.location)
343+
}
344+
} catch (error) {
345+
next(error)
346+
}
347+
})
348+
324349
// catch 404 and forward to error handler
325350
app.use((_req, _res, next) => {
326351
next(createError(404))

src/lib/api.js

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const { pickBy, assign, get: getNested } = require('lodash')
22
const extent = require('@mapbox/extent')
33
const { DateTime } = require('luxon')
4+
const AWS = require('aws-sdk')
45
const { isIndexNotFoundError } = require('./database')
56
const logger = console
67

@@ -374,6 +375,10 @@ const addItemLinks = function (results, endpoint) {
374375
type: 'application/geo+json',
375376
href: `${endpoint}`
376377
})
378+
links.push({
379+
rel: 'thumbnail',
380+
href: `${endpoint}/collections/${collection}/items/${id}/thumbnail`
381+
})
377382
result.type = 'Feature'
378383
return result
379384
})
@@ -862,6 +867,39 @@ const deleteItem = async function (collectionId, itemId, backend) {
862867
return new Error(`Error deleting item ${collectionId}/${itemId}`)
863868
}
864869

870+
const getItemThumbnail = async function (collectionId, itemId, backend) {
871+
const itemQuery = { collections: [collectionId], id: itemId }
872+
const { results } = await backend.search(itemQuery)
873+
const [item] = results
874+
if (!item) {
875+
return new Error('Item not found')
876+
}
877+
878+
const thumbnailAsset = Object.values(item.assets || []).find((x) => x.roles.includes('thumbnail'))
879+
if (!thumbnailAsset) {
880+
return new Error('Thumbnail not found')
881+
}
882+
883+
let location
884+
if (thumbnailAsset.href && thumbnailAsset.href.startsWith('http')) {
885+
location = thumbnailAsset.href
886+
} else if (thumbnailAsset.href && thumbnailAsset.href.startsWith('s3')) {
887+
const withoutProtocol = thumbnailAsset.href.substring(5) // chop off s3://
888+
const [bucket, ...keyArray] = withoutProtocol.split('/')
889+
const key = keyArray.join('/')
890+
location = new AWS.S3().getSignedUrl('getObject', {
891+
Bucket: bucket,
892+
Key: key,
893+
Expires: 60 * 5, // expiry in seconds
894+
RequestPayer: 'requester'
895+
})
896+
} else {
897+
return new Error('Thumbnail not found')
898+
}
899+
900+
return { location }
901+
}
902+
865903
const healthCheck = async function (backend) {
866904
const response = await backend.healthCheck()
867905
logger.debug(`Health check: ${response}`)
@@ -890,5 +928,6 @@ module.exports = {
890928
extractLimit,
891929
extractDatetime,
892930
aggregate,
893-
healthCheck
931+
getItemThumbnail,
932+
healthCheck,
894933
}

0 commit comments

Comments
 (0)