Skip to content

Commit de88c00

Browse files
authored
Merge pull request #10855 from IQSS/10831-standardize-image-url-of-search-api
standardize image url
2 parents 2bdc7b3 + d215221 commit de88c00

6 files changed

Lines changed: 129 additions & 11 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Search API (/api/search) response will now include new image_url format for the Datafile and Dataverse logo.
2+
Note to release note writer: this supersedes the release note 10810-search-api-payload-extensions.md
3+
4+
For Dataverse:
5+
6+
- "image_url" (optional)
7+
8+
```javascript
9+
"items": [
10+
{
11+
"name": "Darwin's Finches",
12+
...
13+
"image_url":"/api/access/dvCardImage/{identifier}"
14+
(etc, etc)
15+
```
16+
17+
For DataFile:
18+
19+
- "image_url" (optional)
20+
21+
```javascript
22+
"items": [
23+
{
24+
"name": "test.txt",
25+
...
26+
"image_url":"/api/access/datafile/{identifier}?imageThumb=true"
27+
(etc, etc)
28+
```

doc/sphinx-guides/source/api/search.rst

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ https://demo.dataverse.org/api/search?q=trees
6161
"name":"Trees",
6262
"type":"dataverse",
6363
"url":"https://demo.dataverse.org/dataverse/trees",
64-
"image_url":"data:image/png;base64,iVBORw0...",
64+
"image_url":"https://demo.dataverse.org/api/access/dvCardImage/1",
6565
"identifier":"trees",
6666
"description":"A tree dataverse with some birds",
6767
"published_at":"2016-05-10T12:53:38Z",
@@ -76,7 +76,7 @@ https://demo.dataverse.org/api/search?q=trees
7676
"name":"Chestnut Trees",
7777
"type":"dataverse",
7878
"url":"https://demo.dataverse.org/dataverse/chestnuttrees",
79-
"image_url":"data:image/png;base64,iVBORw0...",
79+
"image_url":"https://demo.dataverse.org/api/access/dvCardImage/2",
8080
"identifier":"chestnuttrees",
8181
"description":"A dataverse with chestnut trees and an oriole",
8282
"published_at":"2016-05-10T12:52:38Z",
@@ -91,7 +91,7 @@ https://demo.dataverse.org/api/search?q=trees
9191
"name":"trees.png",
9292
"type":"file",
9393
"url":"https://demo.dataverse.org/api/access/datafile/12",
94-
"image_url":"data:image/png;base64,iVBORw0...",
94+
"image_url":"https://demo.dataverse.org/api/access/datafile/12?imageThumb=true",
9595
"file_id":"12",
9696
"description":"",
9797
"published_at":"2016-05-10T12:53:39Z",
@@ -113,7 +113,7 @@ https://demo.dataverse.org/api/search?q=trees
113113
"name":"Birds",
114114
"type":"dataverse",
115115
"url":"https://demo.dataverse.org/dataverse/birds",
116-
"image_url":"data:image/png;base64,iVBORw0...",
116+
"image_url":"https://demo.dataverse.org/api/access/dvCardImage/3",
117117
"identifier":"birds",
118118
"description":"A bird Dataverse collection with some trees",
119119
"published_at":"2016-05-10T12:57:27Z",
@@ -173,8 +173,6 @@ https://demo.dataverse.org/api/search?q=trees
173173
}
174174
}
175175
176-
Note that the image_url field, if exists, will be returned as a regular URL for Datasets, while for Files and Dataverses, it will be returned as a Base64 URL. We plan to standardize this behavior so that the field always returns a regular URL. (See: https://github.com/IQSS/dataverse/issues/10831)
177-
178176
.. _advancedsearch-example:
179177

180178
Advanced Search Examples
@@ -202,7 +200,7 @@ In this example, ``show_relevance=true`` matches per field are shown. Available
202200
"name":"Finches",
203201
"type":"dataverse",
204202
"url":"https://demo.dataverse.org/dataverse/finches",
205-
"image_url":"data:image/png;base64,iVBORw0...",
203+
"image_url":"https://demo.dataverse.org/api/access/dvCardImage/2",
206204
"identifier":"finches",
207205
"description":"A Dataverse collection with finches",
208206
"published_at":"2016-05-10T12:57:38Z",

src/main/java/edu/harvard/iq/dataverse/DataverseServiceBean.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,15 @@ public String getDataverseLogoThumbnailAsBase64ById(Long dvId) {
361361
}
362362
return null;
363363
}
364-
364+
365+
public String getDataverseLogoThumbnailAsUrl(Long dvId) {
366+
File dataverseLogoFile = getLogoById(dvId);
367+
if (dataverseLogoFile != null && dataverseLogoFile.exists()) {
368+
return SystemConfig.getDataverseSiteUrlStatic() + "/api/access/dvCardImage/" + dvId;
369+
}
370+
return null;
371+
}
372+
365373
private File getLogo(Dataverse dataverse) {
366374
if (dataverse.getId() == null) {
367375
return null;

src/main/java/edu/harvard/iq/dataverse/ThumbnailServiceWrapper.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import edu.harvard.iq.dataverse.dataaccess.StorageIO;
1111
import edu.harvard.iq.dataverse.dataset.DatasetUtil;
1212
import edu.harvard.iq.dataverse.search.SolrSearchResult;
13+
import edu.harvard.iq.dataverse.util.FileUtil;
1314
import edu.harvard.iq.dataverse.util.SystemConfig;
1415

1516
import java.io.IOException;
@@ -48,6 +49,19 @@ public class ThumbnailServiceWrapper implements java.io.Serializable {
4849
private Map<Long, DvObject> dvobjectViewMap = new HashMap<>();
4950
private Map<Long, Boolean> hasThumbMap = new HashMap<>();
5051

52+
public String getFileCardImageAsUrl(SolrSearchResult result) {
53+
DataFile dataFile = result != null && result.getEntity() != null ? ((DataFile) result.getEntity()) : null;
54+
if (dataFile == null || result.isHarvested()
55+
|| !isThumbnailAvailable(dataFile)
56+
|| dataFile.isRestricted()
57+
|| !dataFile.isReleased()
58+
|| FileUtil.isActivelyEmbargoed(dataFile)
59+
|| FileUtil.isRetentionExpired(dataFile)) {
60+
return null;
61+
}
62+
return SystemConfig.getDataverseSiteUrlStatic() + "/api/access/datafile/" + dataFile.getId() + "?imageThumb=true";
63+
}
64+
5165
// it's the responsibility of the user - to make sure the search result
5266
// passed to this method is of the Datafile type!
5367
public String getFileCardImageAsBase64Url(SolrSearchResult result) {
@@ -208,7 +222,13 @@ public String getDatasetCardImageAsUrl(Dataset dataset, Long versionId, boolean
208222
public String getDataverseCardImageAsBase64Url(SolrSearchResult result) {
209223
return dataverseService.getDataverseLogoThumbnailAsBase64ById(result.getEntityId());
210224
}
211-
225+
226+
// it's the responsibility of the user - to make sure the search result
227+
// passed to this method is of the Dataverse type!
228+
public String getDataverseCardImageAsUrl(SolrSearchResult result) {
229+
return dataverseService.getDataverseLogoThumbnailAsUrl(result.getEntityId());
230+
}
231+
212232
public void resetObjectMaps() {
213233
dvobjectThumbnailsMap = new HashMap<>();
214234
dvobjectViewMap = new HashMap<>();

src/main/java/edu/harvard/iq/dataverse/search/SearchServiceBean.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,7 @@ public SolrQueryResponse search(
593593
solrSearchResult.setDataverseAffiliation(dataverseAffiliation);
594594
solrSearchResult.setDataverseParentAlias(dataverseParentAlias);
595595
solrSearchResult.setDataverseParentName(dataverseParentName);
596-
solrSearchResult.setImageUrl(thumbnailServiceWrapper.getDataverseCardImageAsBase64Url(solrSearchResult));
596+
solrSearchResult.setImageUrl(thumbnailServiceWrapper.getDataverseCardImageAsUrl(solrSearchResult));
597597
/**
598598
* @todo Expose this API URL after "dvs" is changed to
599599
* "dataverses". Also, is an API token required for published
@@ -652,7 +652,7 @@ public SolrQueryResponse search(
652652
}
653653
solrSearchResult.setHtmlUrl(baseUrl + "/dataset.xhtml?persistentId=" + parentGlobalId);
654654
solrSearchResult.setDownloadUrl(baseUrl + "/api/access/datafile/" + entityid);
655-
solrSearchResult.setImageUrl(thumbnailServiceWrapper.getFileCardImageAsBase64Url(solrSearchResult));
655+
solrSearchResult.setImageUrl(thumbnailServiceWrapper.getFileCardImageAsUrl(solrSearchResult));
656656
/**
657657
* @todo We are not yet setting the API URL for files because
658658
* not all files have metadata. Only subsettable files (those

src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,4 +1283,68 @@ public void tearDownDataverse() {
12831283
public static void cleanup() {
12841284
}
12851285

1286+
@Test
1287+
public void testSearchFilesAndUrlImages() {
1288+
Response createUser = UtilIT.createRandomUser();
1289+
createUser.prettyPrint();
1290+
String username = UtilIT.getUsernameFromResponse(createUser);
1291+
String apiToken = UtilIT.getApiTokenFromResponse(createUser);
1292+
1293+
Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken);
1294+
createDataverseResponse.prettyPrint();
1295+
String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse);
1296+
1297+
Response createDatasetResponse = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, apiToken);
1298+
createDatasetResponse.prettyPrint();
1299+
Integer datasetId = UtilIT.getDatasetIdFromResponse(createDatasetResponse);
1300+
System.out.println("id: " + datasetId);
1301+
String datasetPid = JsonPath.from(createDatasetResponse.getBody().asString()).getString("data.persistentId");
1302+
System.out.println("datasetPid: " + datasetPid);
1303+
1304+
String pathToFile = "src/main/webapp/resources/images/dataverseproject.png";
1305+
Response uploadImage = UtilIT.uploadFileViaNative(datasetId.toString(), pathToFile, apiToken);
1306+
uploadImage.prettyPrint();
1307+
uploadImage.then().assertThat()
1308+
.statusCode(200);
1309+
pathToFile = "src/main/webapp/resources/js/mydata.js";
1310+
Response uploadFile = UtilIT.uploadFileViaNative(datasetId.toString(), pathToFile, apiToken);
1311+
uploadImage.prettyPrint();
1312+
uploadImage.then().assertThat()
1313+
.statusCode(200);
1314+
1315+
Response publishDataverse = UtilIT.publishDataverseViaSword(dataverseAlias, apiToken);
1316+
publishDataverse.prettyPrint();
1317+
publishDataverse.then().assertThat()
1318+
.statusCode(OK.getStatusCode());
1319+
Response publishDataset = UtilIT.publishDatasetViaNativeApi(datasetId, "major", apiToken);
1320+
publishDataset.prettyPrint();
1321+
publishDataset.then().assertThat()
1322+
.statusCode(OK.getStatusCode());
1323+
1324+
Response searchResp = UtilIT.search("dataverseproject", apiToken);
1325+
searchResp.prettyPrint();
1326+
searchResp.then().assertThat()
1327+
.statusCode(OK.getStatusCode())
1328+
.body("data.items[0].type", CoreMatchers.is("file"))
1329+
.body("data.items[0].file_content_type", CoreMatchers.is("image/png"))
1330+
.body("data.items[0].url", CoreMatchers.containsString("/api/access/datafile/"))
1331+
.body("data.items[0].image_url", CoreMatchers.containsString("/api/access/datafile/"))
1332+
.body("data.items[0].image_url", CoreMatchers.containsString("imageThumb=true"));
1333+
1334+
searchResp = UtilIT.search(dataverseAlias, apiToken);
1335+
searchResp.prettyPrint();
1336+
searchResp.then().assertThat()
1337+
.statusCode(OK.getStatusCode())
1338+
.body("data.items[0].type", CoreMatchers.is("dataverse"))
1339+
.body("data.items[0].url", CoreMatchers.containsString("/dataverse/"))
1340+
.body("data.items[0]", CoreMatchers.not(CoreMatchers.hasItem("url_image")));
1341+
1342+
searchResp = UtilIT.search("mydata", apiToken);
1343+
searchResp.prettyPrint();
1344+
searchResp.then().assertThat()
1345+
.statusCode(OK.getStatusCode())
1346+
.body("data.items[0].type", CoreMatchers.is("file"))
1347+
.body("data.items[0].url", CoreMatchers.containsString("/datafile/"))
1348+
.body("data.items[0]", CoreMatchers.not(CoreMatchers.hasItem("url_image")));
1349+
}
12861350
}

0 commit comments

Comments
 (0)