diff --git a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json index 8b05cb3f205..a34479ee6c5 100644 --- a/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json +++ b/schemas/iso19115-3.2018/src/main/plugin/iso19115-3.2018/config/associated-panel/default.json @@ -1069,6 +1069,16 @@ "isTemplate": "n" } }, + "doiapi": { + "datacite": { + "url": "https://api.datacite.org/dois", + "params": {"query": "titles.title:{query}* OR doi:{query} OR id:{query}"} + }, + "crossref": { + "url": "https://api.crossref.org/works?mailto=GroovyBib@example.org", + "params": {"query": "rows=10&query.title={query}"} + } + }, "remoteurl": {"multiple": true} } } diff --git a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js index b08df082594..7838006efe0 100644 --- a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js +++ b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcDirective.js @@ -2452,7 +2452,8 @@ */ .directive("gnDoiSearchPanel", [ "gnDoiSearchService", - function (gnDoiSearchService) { + "$q", + function (gnDoiSearchService, $q) { return { restrict: "A", replace: true, @@ -2460,6 +2461,8 @@ doiUrl: "=?", doiPrefix: "=?", doiQueryPattern: "=?", + doiCrossrefUrl: "=?", + doiCrossrefQueryPattern: "=?", mode: "@", addToSelectionCb: "&?", removeFromSelectionCb: "&?" @@ -2469,6 +2472,7 @@ link: function (scope, element, attrs) { // select (single value) / add mode (used in siblings dialog) scope.mode = scope.mode || "select"; + scope.searchedValue = false; scope.updateSelection = angular.isFunction(scope.addToSelectionCb) ? function (md) { if (scope.isSelected(md)) { @@ -2491,49 +2495,147 @@ scope.isSearching = false; scope.clearSearch = function () { + scope.searchedValue = false; scope.queryValue = ""; scope.results = []; }; scope.$on("resetSearch", scope.clearSearch); - scope.search = function () { - var searchQuery = - scope.queryValue !== "" - ? scope.doiQueryPattern.replaceAll("{query}", scope.queryValue) - : ""; + var processResultsDatacite = function (resultsDatacite) { + var results = []; + + angular.forEach(resultsDatacite, function (r) { + results.push({ + uuid: r.id, + remoteUrl: r.attributes.url, + resourceTitle: + r.attributes.titles.length > 0 ? r.attributes.titles[0].title : r.url, + title: + r.attributes.titles.length > 0 ? r.attributes.titles[0].title : r.url, + description: + r.attributes.descriptions.length > 0 + ? r.attributes.descriptions[0].descriptions + : "", + source: "Datacite" + }); + }); + + return results; + }; + + var processResultsCrossref = function (resultsCrossref) { + var results = []; + + angular.forEach(resultsCrossref, function (r) { + results.push({ + uuid: r.DOI, + remoteUrl: r.URL, + resourceTitle: r.title && r.title.length > 0 ? r.title[0] : "", + title: r.title && r.title.length > 0 ? r.title[0] : "", + description: r.abstract && r.abstract.length > 0 ? r.abstract[0] : "", + source: "Crossref" + }); + }); + + return results; + }; + + var sortResults = function () { + scope.results.sort(function (a, b) { + if (a.resourceTitle < b.resourceTitle) { + return -1; + } + if (a.resourceTitle > b.resourceTitle) { + return 1; + } + return 0; + }); + }; + var dataciteQuery = function () { + return scope.queryValue && scope.queryValue !== '' + ? scope.doiQueryPattern.replaceAll( + "{query}", + encodeURIComponent(scope.queryValue) + ) + : ""; + }; + + + var crossrefQuery = function () { + if (!scope.queryValue) { + return ""; + } + + // https://api.crossref.org/swagger-ui/index.html#/Works/get_works + // Crossref query does not allow a search to be done on the title (or other search field) + // and DOI which is a filter eg. filter=doi:10.prefix/suffix. + // If the query value is a DOI, we will use the DOI filter. + var isDoi = scope.queryValue.match(/10\..+\/[^ ]+$/); + if (isDoi) { + return "filter=doi:" + scope.queryValue; + } + + return scope.queryValue !== "" + ? scope.doiCrossrefQueryPattern + .replaceAll("{query}", encodeURIComponent(scope.queryValue)) + .replaceAll("{prefix}", scope.doiPrefix) + : ""; + }; + + var internalSearch = function (doDataciteSearch, doCrossrefSearch) { scope.isSearching = true; - gnDoiSearchService.search(scope.doiUrl, scope.doiPrefix, searchQuery).then( + var results = []; + var promises = []; + if (doDataciteSearch) { + promises.push( + gnDoiSearchService.search( + scope.doiUrl, + scope.doiPrefix, + dataciteQuery() + ) + ); + } + if (doCrossrefSearch) { + promises.push( + gnDoiSearchService.searchCrossref( + scope.doiCrossrefUrl, + scope.doiPrefix, + crossrefQuery() + ) + ); + } + $q.all(promises).then( function (response) { - scope.isSearching = false; - var results = []; - - angular.forEach(response.data.data, function (r) { - results.push({ - uuid: r.id, - remoteUrl: r.attributes.url, - resourceTitle: - r.attributes.titles.length > 0 - ? r.attributes.titles[0].title - : r.url, - title: - r.attributes.titles.length > 0 - ? r.attributes.titles[0].title - : r.url, - description: - r.attributes.descriptions.length > 0 - ? r.attributes.descriptions[0].descriptions - : "" - }); - }); - - scope.results = results; + for (var i = 0; i < response.length; i++) { + if (response[i].data.data) { + results = results.concat( + processResultsDatacite(response[i].data.data) + ); + } else if (response[i].data.message.items) { + results = results.concat( + processResultsCrossref(response[i].data.message.items) + ); + } + scope.results = results; + sortResults(); + scope.isSearching = false; + } }, function (response) { scope.isSearching = false; } ); }; + + scope.search = function () { + scope.searchedValue = true; + + var doDataciteSearch = !!scope.doiUrl; + var doCrossrefSearch = !!scope.doiCrossrefUrl; + + internalSearch(doDataciteSearch, doCrossrefSearch); + }; } }; } diff --git a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcService.js b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcService.js index 7755bcee53e..d4cbbecb107 100644 --- a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcService.js +++ b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/OnlineSrcService.js @@ -930,14 +930,25 @@ module.service("gnDoiSearchService", [ "$http", function ($http) { + function buildBaseUrl(url) { + var containsQuestionMark = url.indexOf("?") >= 0; + return url + (containsQuestionMark ? "&" : "?"); + } return { search: function (url, prefix, query) { + var url = buildBaseUrl(url); + if (prefix) { + url += "prefix=" + prefix + "&"; + } return $http.get( - url + - "?prefix=" + - prefix + - "&query=" + - query.replaceAll("https://doi.org/", "") + url + "query=" + query.replaceAll(encodeURIComponent("https://doi.org/"), "") + ); + }, + searchCrossref: function (url, prefix, query) { + return $http.get( + buildBaseUrl(url) + + "select=DOI%2Ctitle%2Ctype%2Cprefix%2Cabstract%2CURL&" + + query ); } }; diff --git a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/doisearchpanel.html b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/doisearchpanel.html index 35e33c568f9..403967ac079 100644 --- a/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/doisearchpanel.html +++ b/web-ui/src/main/resources/catalog/components/edit/onlinesrc/partials/doisearchpanel.html @@ -32,35 +32,37 @@
- zarooResult + {{ 'zarooResult' | translate }}
-