diff --git a/README.md b/README.md index 0272a7a..8be31c9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# bie-index [![Build Status](https://travis-ci.com/AtlasOfLivingAustralia/bie-index.svg?branch=master)](https://travis-ci.com/AtlasOfLivingAustralia/bie-index) +# bie-index [![Build Status](https://travis-ci.com/AtlasOfLivingAustralia/bie-index.svg?branch=master)](https://app.travis-ci.com/github/AtlasOfLivingAustralia/bie-index) bie-index is a grails web application that indexes taxonomic content in DwC-A and provides search web services for this content. This includes: diff --git a/build.gradle b/build.gradle index 6a548b5..dd9263c 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { } } -version "1.5" +version "1.6" group "au.org.ala" apply plugin:"eclipse" @@ -65,7 +65,7 @@ dependencies { exclude group: 'com.google.guava', module: 'guava' } compile "com.google.guava:guava:19.0" - compile group: "au.org.ala", name: "ala-name-matching-model", version:"4.0" + compile group: "au.org.ala", name: "ala-name-matching-model", version:"4.1" compile "org.jsoup:jsoup:1.8.3" compile 'org.grails.plugins:external-config:1.1.1' diff --git a/grails-app/controllers/au/org/ala/bie/SearchController.groovy b/grails-app/controllers/au/org/ala/bie/SearchController.groovy index d9b85e1..79b6fcf 100755 --- a/grails-app/controllers/au/org/ala/bie/SearchController.groovy +++ b/grails-app/controllers/au/org/ala/bie/SearchController.groovy @@ -58,6 +58,38 @@ class SearchController implements GrailsConfigurationAware { render ([searchResults:searchService.imageSearch(regularise(params.id), start, rows, params.qc, locales)] as JSON) } + /** + * Bulk lookup of image information for a list of + * taxon GUIDs + */ + // Documented in apenapi.yml + def bulkImageLookup() { + final locales = [request.locale, defaultLocale] + final req = request.getJSON() + if (!req) { + response.sendError(400, "Body could not be parsed or was empty") + } + def result = [] + req.each { guid -> + def taxon = searchService.getTaxon(guid, locales) + def imageId = taxon?.imageIdentifier + def image = null + if (imageId) { + image = [ + imageId: imageId, + thumbnail: searchService.formatImage(imageId, 'thumbnail'), + small: searchService.formatImage(imageId, 'small'), + large: searchService.formatImage(imageId, 'large'), + metadata: searchService.formatImage(imageId, 'metadata') + ] + } + result << image + } + + render result as JSON + + } + /** * Returns a redirect to an image of the appropriate type */ diff --git a/grails-app/controllers/bie/index/UrlMappings.groovy b/grails-app/controllers/bie/index/UrlMappings.groovy index f66e648..9f2b224 100755 --- a/grails-app/controllers/bie/index/UrlMappings.groovy +++ b/grails-app/controllers/bie/index/UrlMappings.groovy @@ -13,6 +13,7 @@ class UrlMappings { "/species/image/thumbnail/$id**"(controller: "search", action: "imageLinkSearch") { imageType = "thumbnail" } "/species/image/small/$id**"(controller: "search", action: "imageLinkSearch") { imageType = "small" } "/species/image/large/$id**"(controller: "search", action: "imageLinkSearch") { imageType = "large" } + "/species/image/bulk"(controller: "search", action: "bulkImageLookup") "/species/lookup/bulk(.$format)?"(controller: "search", action: "speciesLookupBulk") "/species/shortProfile/$id**"(controller: "search", action: "shortProfile") "/species/shortProfile/$id**.json"(controller: "search", action: "shortProfile") diff --git a/grails-app/services/au/org/ala/bie/SearchService.groovy b/grails-app/services/au/org/ala/bie/SearchService.groovy index dbb6f97..3ec5ace 100644 --- a/grails-app/services/au/org/ala/bie/SearchService.groovy +++ b/grails-app/services/au/org/ala/bie/SearchService.groovy @@ -74,17 +74,25 @@ class SearchService { if (!taxon.image || taxon.image.isEmpty()) { return null } + return formatImage(taxon.image, type) + } + + def formatImage(String imageId, String type) { + if (!imageId) + return null if (type == 'thumbnail') { - return MessageFormat.format(grailsApplication.config.images.service.thumbnail, taxon.image) + return MessageFormat.format(grailsApplication.config.images.service.thumbnail, imageId) } else if (type == 'small') { - return MessageFormat.format(grailsApplication.config.images.service.small, taxon.image) + return MessageFormat.format(grailsApplication.config.images.service.small, imageId) } else if (type == 'large') { - return MessageFormat.format(grailsApplication.config.images.service.large, taxon.image) + return MessageFormat.format(grailsApplication.config.images.service.large, imageId) + } else if (type == 'metadata') { + return MessageFormat.format(grailsApplication.config.images.service.metadata, imageId) } else { - return MessageFormat.format(grailsApplication.config.images.service.large, taxon.image) + return MessageFormat.format(grailsApplication.config.images.service.large, imageId) } - } + } /** * General search service. diff --git a/src/main/resources/public/openapi.yml b/src/main/resources/public/openapi.yml index 655e265..7c4a4bb 100644 --- a/src/main/resources/public/openapi.yml +++ b/src/main/resources/public/openapi.yml @@ -495,6 +495,45 @@ paths: schema: type: string format: url + /species/image/bulk: + post: + summary: Get a list of images for a list of taxon identifiers + description: Return a list of "hero shot" preferred image identifiers and links for each taxon specified by the guid or null for no image + tags: + - bulk + requestBody: + content: + application/json: + schema: + type: array + items: + type: string + description: The guids to look up + responses: + 400: + description: If the request is not a list of guids or is empty + 200: + description: Images + content: + application/json: + schema: + type: array + description: An array of either nulls for not found or packages of image information + items: + type: object + properties: + imageId: + type: string + description: The image identifier + thumbnail: + type: string + description: The URL of the thumbnail version of the image + small: + type: string + description: The URL of the small version of the image + large: + type: string + description: The URL of the large version of the imag /species/shortProfile/{id}: get: summary: Get a short description of a taxon