Last active
June 29, 2020 14:52
-
-
Save mankind/4e35946737496feb5d3ee25b803c0864 to your computer and use it in GitHub Desktop.
auto-populate forms using datacite and crossref api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Ubiquity | |
class CrossrefResponse | |
attr_reader :error, :attributes | |
def initialize(response_hash = nil) | |
@error = error | |
@attributes = response_hash['message'] | |
end | |
def title | |
attributes['title'] | |
end | |
def abstract | |
# For removing the Jat tags inside the abstract | |
ActionView::Base.full_sanitizer.sanitize attributes['abstract'] | |
end | |
def version | |
attributes['message-version'] | |
end | |
def date_published_year | |
date_hash = attributes['published-online'].presence || attributes['published-print'] | |
return date_hash['date-parts'].first[0] if date_hash | |
end | |
def date_published_month | |
date_hash = attributes['published-online'].presence || attributes['published-print'] | |
return date_hash['date-parts'].first[1] if date_hash | |
end | |
def license | |
return nil if attributes['license'].blank? | |
url_array = fetch_url_from_response.split('/') | |
url_collection = Hyrax::LicenseService.new.select_active_options.map(&:last) | |
url_array.pop if url_array.last == 'legalcode' | |
url_array.shift(2) # Removing the http, https and // part in the url | |
regex_url_str = "(?:http|https)://" + url_array.map { |ele| "(#{ele})" }.join('/') | |
regex_url_exp = Regexp.new regex_url_str | |
url_collection.select { |e| e.match regex_url_exp }.first | |
end | |
def date_published_day | |
date_hash = attributes['published-online'].presence || attributes['published-print'] | |
return date_hash['date-parts'].first[2] if date_hash | |
end | |
def issn | |
return nil if attributes['issn-type'].blank? | |
print_value = attributes['issn-type'].detect { |h| h['type'] == 'print' } | |
return print_value['value'] if print_value | |
end | |
def eissn | |
return nil if attributes['issn-type'].blank? | |
print_value = attributes['issn-type'].detect { |h| h['type'] == 'electronic' } | |
return print_value['value'] if print_value | |
end | |
def isbn | |
return nil if attributes['isbn-type'].blank? | |
print_value = attributes['isbn-type'].detect { |h| h['type'] == 'print' } || attributes['isbn-type'].detect { |h| h['type'] == 'electronic' } | |
return print_value['value'] if print_value['value'] | |
attributes['isbn-type'].first['value'] | |
end | |
def doi | |
attributes['DOI'] | |
end | |
def volume | |
attributes['volume'] | |
end | |
def pagination | |
attributes['page'] | |
end | |
def issue | |
attributes['issue'] | |
end | |
def journal_title | |
attributes['container-title'].first if attributes['container-title'].present? | |
end | |
def keyword | |
attributes['subject'] | |
end | |
def publisher | |
attributes['publisher'] | |
end | |
def official_url | |
attributes['URL'] | |
end | |
#retuns an array of hash eg | |
# [{"DOI"=>"10.13039/501100000664", "name"=>"Health Technology Assessment Programme", "doi-asserted-by"=>"publisher", "award"=>["HTA 06/301/233", "HTA 09/127/53", "HTA 10/34/01", "HTA 96/20/06, HTA 96/20/99"]}] | |
# | |
#def funder | |
#attributes[['funder'].] | |
#end | |
def creator | |
creator_group = attributes.dig('author') || attributes.dig('editor') | |
if creator_group.present? | |
extract_creators(creator_group) | |
=begin | |
if creator_group.first.keys && ['given', 'family', 'ORCID'].any? | |
creator_with_seperated_names(creator_group) | |
else | |
creator_without_seperated_names(creator_group) | |
end | |
=end | |
end | |
end | |
def extract_creators(creator_data) | |
new_creator_group = [] | |
creator_data.each_with_index do |hash, index| | |
if (hash.keys & ['given', 'family', 'ORCID']).any? | |
record = creator_with_seperated_names(hash, index) | |
else | |
record = creator_without_seperated_names(hash, index) | |
end | |
new_creator_group << record | |
end | |
new_creator_group | |
end | |
def creator_with_seperated_names(hash, index) | |
#def creator_with_seperated_names(data) | |
#new_creator_group = [] | |
#data.each_with_index do |hash, index| | |
hash = { | |
creator_orcid: hash.try(:fetch, 'ORCID', '').split('/').last, | |
creator_given_name: hash["given"], | |
creator_family_name: hash["family"], | |
creator_name_type: 'Personal', | |
creator_position: index | |
} | |
#new_creator_group << hash | |
#end | |
#new_creator_group | |
end | |
def creator_without_seperated_names(hash, index) | |
#def creator_without_seperated_names(data) | |
#data.each_with_index do |hash, index| | |
hash = { | |
#creator_orcid: hash.try(:fetch, 'ORCID', '').split('/').last, | |
creator_organization_name: hash["name"], | |
creator_name_type: 'Organisational', | |
creator_position: index | |
} | |
#new_creator_group << hash | |
#end | |
#new_creator_group | |
end | |
def fetch_url_from_response | |
vor_version_license = attributes['license'].detect { |h| h['content-version'] == 'vor' } | |
return vor_version_license['URL'] if vor_version_license.present? | |
max_time_stamp_license = attributes['license'].max_by { |h| h.try(:fetch, 'date-parts', '')['time-stamp'].to_f } | |
return max_time_stamp_license['URL'] if max_time_stamp_license.present? | |
attributes['license'].first['URL'] | |
end | |
# creator_group: creator, in front of doi | |
# issn: issn, | |
def data | |
if error.present? | |
{ 'error' => error } | |
else | |
{ | |
title: title, published_year: date_published_year , | |
published_month: date_published_month, published_day: date_published_day, | |
issn: issn, eissn: eissn, journal_title: journal_title, | |
abstract: abstract, version: version, isbn: isbn, | |
creator_group: creator, doi: doi, keyword: keyword, license: license, | |
publisher: publisher, volume: volume, pagination: pagination, issue: issue, | |
official_url: official_url | |
} | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(document).on("turbolinks:load", function(event){ | |
return $("body").on("submit", ".get-datacite-doi-metadata-select", function(event){ | |
var dataciteUrl = $(".ubiquity-datacite-value").val(); | |
$(".ubiquity-fields-populated").hide() | |
$(".ubiquity-fields-populated-error").hide() | |
event.preventDefault(); | |
fetchDataciteData(dataciteUrl); | |
$("#get-datacite-doi-metadata").modal('hide') | |
}); | |
}); | |
function fetchDataciteData(url) { | |
var host = window.document.location.host; | |
var protocol = window.document.location.protocol; | |
var fullHost = protocol + '//' + host + '/available_ubiquity_titles/call_datasite'; | |
var field_array = []; | |
$.ajax({ | |
url: fullHost, | |
type: "POST", | |
data: {"url": url}, | |
success: function(result){ | |
if (result.data.error === undefined) { | |
if($('.ubiquity-title').length != 0 && result.data.title != null) { | |
$(".ubiquity-title").val(result.data.title) | |
field_array.push('Title') | |
} | |
if ($('.ubiquity-abstract').length != 0 && result.data.abstract != null) { | |
field_array.push('Abstract') | |
$('.ubiquity-abstract').val(result.data.abstract) | |
} | |
if($('.ubiquity-doi').length != 0 && result.data.doi != null) { | |
field_array.push('DOI') | |
$('.ubiquity-doi').val(result.data.doi) | |
} | |
if($('.ubiquity-official-link').length != 0 && result.data.official_url != null) { | |
field_array.push('Official URL') | |
$('.ubiquity-official-link').val(result.data.official_url) | |
} | |
//populate dropdown | |
if($('.ubiquity-date-published-year').length != 0 && result.data.published_year != null) { | |
field_array.push('Published Year') | |
$('.ubiquity-date-published-year').val(result.data.published_year); | |
} | |
if($('.ubiquity-date-published-month').length != 0 && result.data.published_month != null) { | |
field_array.push('Published Month') | |
$('.ubiquity-date-published-month').val(result.data.published_month); | |
} | |
if($('.ubiquity-date-published-day').length != 0 && result.data.published_day != null) { | |
field_array.push('Published Day') | |
$('.ubiquity-date-published-day').val(result.data.published_day); | |
} | |
if($('.ubiquity-volume').length != 0 && result.data.volume != null) { | |
field_array.push('Volume') | |
$('.ubiquity-volume').val(result.data.volume); | |
} | |
if($('.ubiquity-issue').length != 0 && result.data.issue != null) { | |
field_array.push('Issue') | |
$('.ubiquity-issue').val(result.data.issue); | |
} | |
if($('.ubiquity-pagination').length != 0 && result.data.pagination != null) { | |
field_array.push('Pagination') | |
$('.ubiquity-pagination').val(result.data.pagination); | |
} | |
if($('.ubiquity-license').length != 0 && result.data.license != null && (result.data.license && result.data.license.active) == undefined) { | |
field_array.push('Licence') | |
$('.ubiquity-license').val(result.data.license) | |
} else if ($('.ubiquity-license').length != 0 && result.data.license && result.data.license.active == false && result.data.license.license != null ) { | |
field_array.push('Licence') | |
$(".ubiquity-license").append(new Option(result.data.license.label, result.data.license.license)) | |
$('.ubiquity-license').val(result.data.license.license) | |
} | |
if($('.ubiquity-funder').length != 0 && result.data.funder != null) { | |
field_array.push('Funder') | |
$('.ubiquity-funder').val(result.data.funder); | |
} | |
if($('.ubiquity-issn').length != 0 && result.data.issn != null) { | |
field_array.push('ISSN') | |
$('.ubiquity-issn').val(result.data.issn); | |
} | |
if($('.ubiquity-journal-title').length != 0 && result.data.journal_title != null) { | |
field_array.push('Journal Title') | |
$('.ubiquity-journal-title').val(result.data.journal_title); | |
} | |
if($('.ubiquity-eissn').length != 0 && result.data.eissn != null) { | |
field_array.push('eISSN') | |
$('.ubiquity-eissn').val(result.data.eissn); | |
} | |
if($('.ubiquity-isbn').length != 0 && result.data.isbn != null) { | |
field_array.push('ISBN') | |
$('.ubiquity-isbn').val(result.data.isbn); | |
} | |
if($('.ubiquity-publisher').length != 0 && result.data.publisher != null) { | |
field_array.push('Publisher') | |
$('.ubiquity-publisher').val(result.data.publisher); | |
} | |
if ($(".ubiquity-meta-related-identifier") != 0 && result.data.related_identifier_group != null) { | |
field_array.push('Related Identifier') | |
populateRelatedIdentifierValues(result.data.related_identifier_group) | |
} | |
if ($(".ubiquity-meta-creator").length != 0 && result.data.creator_group != null) { | |
field_array.push('Creator') | |
populateCreatorValues(result.data.creator_group); | |
} | |
if ($(".ubiquity-meta-contributor").length != 0 && result.data.contributor_group != null) { | |
field_array.push('Contributor') | |
populateContributorValues(result.data.contributor_group); | |
} | |
if ($(".ubiquity-keyword").length != 0 && result.data.keyword != null) { | |
field_array.push('Keyword') | |
populateKeyword(result.data.keyword) | |
} | |
if ($(".ubiquity-version-number").length != 0 && result.data.version != null) { | |
field_array.push('Version') | |
$(".ubiquity-version-number").val(result.data.version) | |
} | |
//IE11 will not show the ,message when .val() is used hence .html() | |
var message = "The following fields were auto-populated " + field_array.slice(0, field_array.length - 1).join(', ') + ", and " + field_array.slice(-1); | |
$(".ubiquity-fields-populated").html(message) | |
$(".ubiquity-fields-populated").show() | |
} else { | |
$(".ubiquity-fields-populated-error").html(result.data.error) | |
$(".ubiquity-fields-populated-error").show() | |
} | |
} | |
}) //closes $.ajax | |
} | |
function populateRelatedIdentifierValues(relatedArray){ | |
$.each(relatedArray, function(key, value){ | |
addValues(key, value); | |
}) | |
} | |
function populateKeyword(keywordArray){ | |
$.each(keywordArray, function(key, value){ | |
addKeywordValues(key, value); | |
}) | |
} | |
function addKeywordValues(key, value){ | |
if (key == 0) { | |
$(".ubiquity-keyword:last").val(value) | |
} | |
else{ | |
var parent_li = $(".ubiquity-keyword:last").parent(); | |
var clonedParent = parent_li.clone(); | |
var parent_ul = parent_li.parent(); | |
parent_ul.append(clonedParent); | |
$(".ubiquity-keyword:last").val(value); | |
} | |
} | |
function addValues(key, value) { | |
if (key === 0) { | |
var div = $(".ubiquity-meta-related-identifier"); | |
div.children(".related_identifier").val(value.related_identifier) | |
$('.related_identifier_type').val(value.related_identifier_type).change() | |
div.children(".related_identifier_relation:last").val(value.relation_type).change() | |
}else { | |
var div = $(".ubiquity-meta-related-identifier:last") | |
var cloned = div.clone(); | |
cloned.find('input').val(''); | |
cloned.find('option').attr('selected', false); | |
div.after(cloned) | |
cloned.children(".related_identifier:last").val(value.related_identifier) | |
$('.related_identifier_type').val(value.related_identifier_type).change() | |
cloned.children(".related_identifier_relation:last").val(value.relation_type).change() | |
} | |
} | |
function populateCreatorValues(creatorArray){ | |
$.each(creatorArray, function(key, value){ | |
//if (creatorArray[0].creator_name_type == "Organisational") { | |
if (value && value.creator_name_type == "Organisational") { | |
addOrganizationalValues('creator', key, value); | |
} else if (value && value.creator_name_type == "Personal") { | |
addPersonalValues('creator', key, value); | |
} | |
}) | |
} | |
function populateContributorValues(contributorArray){ | |
$.each(contributorArray, function(key, value){ | |
if (value && value.creator_name_type == "Personal") { | |
addPersonalValues('contributor', key, value); | |
} else if (value && value.creator_name_type == "Organisational") { | |
addOrganizationalValues('contributor', key, value); | |
} | |
}) | |
} | |
function addPersonalValues(fieldName, key, value) { | |
var familyName = '.' + fieldName + '_family_name:last' | |
var givenName = '.' + fieldName + '_given_name:last' | |
var givenName2 = '.' + fieldName + '_given_name' | |
var orcid = '.' + fieldName + '_orcid:last' | |
var isni = '.ubiquity_' + fieldName + '_isni:last' | |
var position = '.' + fieldName + '_position:last' | |
var nameType = '.' + 'ubiquity_' + fieldName + '_name_type:last' | |
if (key === 0) { | |
var newParent = '.ubiquity-meta-' + fieldName | |
var parent = $(newParent); | |
var div = parent.children(".ubiquity_personal_fields:last") | |
div.children(familyName).val(value[fieldName + '_family_name']) | |
div.children(givenName2).val(value[fieldName + '_given_name']) | |
parent.children(isni).val(value[fieldName + '_isni']) | |
div.children(orcid).val(getValidOrcid(value[fieldName + '_orcid'])) | |
div.children(position).val(value[fieldName + '_position']) | |
parent.children(nameType).val('Personal').change() | |
}else { | |
var newParent = '.ubiquity-meta-' + fieldName + ':last' | |
var parent = $(newParent); | |
var parentClone = parent.clone(); | |
var div = parentClone.children(".ubiquity_personal_fields:last") | |
parentClone.find('input').val(''); | |
parentClone.find('option').attr('selected', false); | |
parent.after(parentClone) | |
parentClone.find(familyName).val(value[fieldName + '_family_name']) | |
parentClone.find(givenName).val(value[fieldName + '_given_name']) | |
parentClone.children(isni).val(value[fieldName + '_isni']) | |
div.children(orcid).val(getValidOrcid(value[fieldName + '_orcid'])) | |
parentClone.find(position).val(value[fieldName + '_position']) | |
parentClone.find(nameType).val('Personal').change() | |
} | |
} | |
function addOrganizationalValues(fieldName, key, value) { | |
var name = '.ubiquity_' + fieldName + '_organization_name:last' | |
var name2 = '.ubiquity_' + fieldName + '_organization_name' | |
var isni = '.ubiquity_' + fieldName + '_isni:last' | |
var position = '.' + fieldName + '_position:last' | |
var nameType = '.' + 'ubiquity_' + fieldName + '_name_type:last' | |
if (key === 0) { | |
var newParent = '.ubiquity-meta-' + fieldName | |
var parent = $(newParent); | |
var div = parent.children(".ubiquity_organization_fields:last") | |
div.children(name).val(value[fieldName + '_organization_name']) | |
parent.children(isni).val(value[fieldName + '_isni']) | |
div.children(position).val(value[fieldName + '_position']) | |
parent.children(nameType).val('Organisational').change() | |
}else { | |
var newParent = '.ubiquity-meta-' + fieldName + ':last' | |
var parent = $(newParent); | |
var parentClone = parent.clone(); | |
var div = parentClone.children(".ubiquity_organization_fields:last") | |
parentClone.find('input').val(''); | |
parentClone.find('option').attr('selected', false); | |
parent.after(parentClone) | |
parentClone.find(name).val(value[fieldName + '_organization_name']) | |
parentClone.children(isni).val(value[fieldName + '_isni']) | |
parentClone.find(position).val(value[fieldName + '_position']) | |
parentClone.find(nameType).val('Organisational').change() | |
} | |
} | |
function getValidOrcid(orcidPath) { | |
if (orcidPath != null) { | |
var orcidArray = orcidPath.split("/") | |
var validOrcid = orcidArray.slice(-1)[0] | |
} | |
return validOrcid | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Ubiquity | |
class DataciteClient | |
attr_accessor :path | |
def initialize(url) | |
#sets the value of the path ,method | |
decoded_url = CGI.unescape(url) | |
parse_url(decoded_url) | |
end | |
def fetch_record | |
result = fetch_record_from_crossref | |
if result.class == HTTParty::Response | |
response_hash = result.parsed_response | |
return response_object_from_crossref(response_hash) if response_hash.class == Hash && response_hash['message'].class == Hash | |
end | |
result = fetch_record_from_datacite | |
if result.class == HTTParty::Response | |
response_hash = result.parsed_response | |
response_object_from_datacite(response_hash, result) | |
else | |
Ubiquity::DataciteResponse.new(error: error_message, result: result) | |
end | |
end | |
def fetch_record_from_crossref | |
handle_client do | |
HTTParty.get("https://api.crossref.org/works/#{path}") | |
end | |
end | |
def fetch_record_from_datacite | |
handle_datacite_client do | |
puts "pata #{path}" | |
HTTParty.get("https://api.datacite.org/dois/#{path}") | |
end | |
end | |
private | |
def response_object_from_datacite(response_hash, result) | |
if response_hash.present? && response_hash.class == Hash && response_hash['data'].class == Hash | |
Ubiquity::DataciteResponse.new(response_hash: response_hash, result: result) | |
else | |
puts "Successful DataciteClient api call but HTTParty parsed_response returned a string instead of hash, so change url" | |
Ubiquity::DataciteResponse.new(error: error_message, result: result) | |
end | |
end | |
def response_object_from_crossref(response_hash) | |
Ubiquity::CrossrefResponse.new(response_hash) | |
end | |
def parse_url(url) | |
url = url.strip | |
handle_client do | |
uri = Addressable::URI.convert_path(url) | |
puts "debo #{uri}" | |
if (uri.scheme.present? && uri.host.present?) | |
path_name = uri.path | |
puts "insidi-1 #{path_name}" | |
use_path(path_name) | |
elsif (uri.scheme.present? == false && uri.host.present? == false && uri.path.present?) | |
puts "insidoelse #{uri.path}" | |
use_path(uri.path) | |
end | |
end | |
end | |
def use_path(path_name) | |
puts "uri #{path_name}" | |
split_path = path_name.split('/').reject(&:empty?) | |
if (split_path.length == 3 && split_path.first == 'works') || ( split_path.length == 4 && split_path.first == 'works') | |
puts "lagos" | |
#changes "works/10.5438/0012" to "/works/10.5438/0012" | |
path_name = path_name.prepend('/') if path_name.slice(0) != "/" | |
@path = path_name | |
elsif split_path.length == 4 && split_path.first == 'api.datacite.org' | |
puts "abuja" | |
#data here is ["api.datacite.org", "works", "10.5438", "0012"] | |
#shift removes the first element | |
split_path.shift | |
#we get back "works/#{path_name}" | |
url_path =split_path.join('/') | |
#we get back "/works/#{path_name}" | |
new_url_path = url_path.prepend('/') | |
@path = new_url_path | |
#when split_path returns ["10.7488", "ds", "2109"] | |
#we get the first two elements that is "10" with | |
#split_path.first.slice(0..1) | |
elsif (split_path.length == 2 && (not split_path.include? 'works')) || (split_path.length == 3 && split_path.first.slice(0..1) == '10') | |
path_name = path_name.prepend('/') if path_name.slice(0) != "/" | |
puts "no-api #{path_name}" | |
@path = path_name | |
end | |
end | |
def handle_client | |
begin | |
yield | |
rescue URI::InvalidURIError, HTTParty::Error, Net::HTTPNotFound, NoMethodError, Net::OpenTimeout, StandardError => e | |
puts "DataciteClient error #{e.inspect}" | |
end | |
end | |
def handle_datacite_client | |
begin | |
yield | |
rescue URI::InvalidURIError, HTTParty::Error, Net::HTTPNotFound, NoMethodError, Net::OpenTimeout, StandardError => e | |
puts " This is from the datacitre client #{e.inspect}" | |
end | |
end | |
def error_message | |
"Sorry no data was fetched. Please ensure this is a valid DataCite DOI or URL eg 10.5438/0012 or https://doi.org/10.5438/0012 or | |
http://dx.doi.org/10.18154/RWTH-CONV-020567 or http://api.crossref.org/works/10.11647/OBP.0172. If you are sure it is valid please refresh the page and try again." | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Ubiquity | |
class DataciteResponse | |
attr_accessor :api_response, :error | |
attr_reader :raw_http_response, :attributes | |
def initialize(response_hash: nil, result: nil, error: nil) | |
@api_response = response_hash | |
@raw_http_response = result | |
@error = error | |
@attributes = response_hash['data']['attributes'] if !response_hash.nil? && response_hash.class == Hash | |
end | |
def title | |
if attributes['titles'].present? | |
attributes['titles'][0]['title'] | |
end | |
end | |
def date_published_year | |
attributes['published'] | |
end | |
def abstract | |
if attributes['descriptions'].present? && attributes['descriptions'][0]['description'].present? | |
ActionView::Base.full_sanitizer.sanitize attributes['descriptions'][0]['description'] | |
end | |
end | |
def version | |
attributes.dig('version') | |
end | |
def funder | |
if attributes.dig('fundingReferences').present? | |
attributes.dig('fundingReferences').first["funderName"] | |
end | |
end | |
def license | |
if attributes.dig("rightsList").present? | |
url_array = attributes.dig("rightsList").last["rightsUri"].split('/') | |
url_active_collection = Hyrax::LicenseService.new.select_active_options.map(&:last) | |
url_all_collection = Hyrax::LicenseService.new.select_all_options.map(&:last) | |
url_inactive_collection = url_all_collection - url_active_collection | |
url_array.pop if url_array.last == 'legalcode' | |
url_array.shift(2) # Removing the http, https and // part in the url | |
regex_url_str = "(?:http|https)://" + url_array.map { |ele| "(#{ele})" }.join('/') | |
regex_url_exp = Regexp.new regex_url_str | |
license_result = url_active_collection.select { |e| e.match regex_url_exp }.first | |
return_license(license_result, url_inactive_collection, regex_url_exp) | |
end | |
end | |
def doi | |
attributes.dig('doi') | |
end | |
def official_url | |
identifiers_array = attributes.dig('identifiers') | |
result = identifiers_array.map do |hash| | |
hash['identifier'] if hash.has_value?('URL') || hash['identifier'] if hash.has_value?('DOI') | |
end | |
result.compact.first | |
end | |
def publisher | |
attributes.dig('publisher') | |
end | |
def creator | |
creator_group = attributes.dig('creators') | |
if creator_group.present? | |
extract_creators(creator_group) | |
end | |
end | |
def extract_creators(creator_data) | |
new_creator_group = [] | |
creator_data.each_with_index do |hash, index| | |
if hash["nameType"] == "Personal" | |
record = json_with_personal_name_type(hash, index) | |
elsif hash["nameType"] == "Organizational" | |
record = json_with_organisation_name_type(hash, index) | |
end | |
new_creator_group << record | |
end | |
new_creator_group | |
end | |
def contributor | |
contributor_group = attributes.dig('contributors') | |
if contributor_group.present? | |
if contributor_group.first.keys.to_set.intersect? ["nameType", :nameType].to_set | |
json_with_personal_name_type('contributor', contributor_group) | |
else | |
json_with_organisation_name_type('contributor', contributor_group) | |
end | |
end | |
end | |
def related_identifier | |
related_group = attributes['relatedIdentifiers'] | |
if related_group.present? | |
related_group.map do |hash| | |
{ | |
"relation_type" => hash["relation-type-id"], | |
"related_identifier" => hash["related-identifier"], | |
"related_identifier_type" => 'DOI' | |
} | |
end | |
end | |
end | |
def data | |
if error.present? | |
{ 'error' => error } | |
else | |
{ | |
'related_identifier_group': related_identifier, | |
"title": title, "published_year": date_published_year, | |
"abstract": abstract, "version": version, | |
"creator_group": creator, "license": license, | |
"doi": doi, "contributor_group": contributor, | |
"publisher": publisher, "official_url": official_url, | |
"funder": funder | |
} | |
end | |
end | |
private | |
def return_license(license_result, url_inactive_collection, regex_url_exp) | |
if license_result != nil | |
license_result | |
else | |
object = {} | |
label = attributes.dig("rightsList").last["rights"].split(':')[1] | |
license_result = url_inactive_collection.select { |e| e.match regex_url_exp }.first | |
object = { | |
"license": license_result, | |
"active": false, | |
"label": label | |
} | |
object | |
end | |
end | |
def json_with_personal_name_type(hash, index) | |
hash = { | |
"creator_given_name" => hash["givenName"], | |
"creator_family_name" => hash["familyName"], | |
"creator_orcid" => get_isni_from_nameIdentifiers(hash['nameIdentifiers']), #nameIdentifiers(hash), | |
"creator_isni" => get_isni_from_nameIdentifiers(hash['nameIdentifiers']), | |
"creator_name_type" => hash['nameType'], | |
"creator_position" => index | |
} | |
end | |
=begin | |
def nameIdentifiers(hash) | |
if hash["nameIdentifiers"].present? | |
orcid = hash["nameIdentifiers"][0]['nameIdentifier'] | |
end | |
orcid | |
end | |
=end | |
def get_orcid_from_nameIdentifiers(array_of_identifiers) | |
if hash["nameIdentifiers"].present? | |
orcid = array_of_identifiers.map do |hash_idenifier| | |
if hash_idenifier["nameIdentifierScheme"] == "ORCID" | |
hash_idenifier['nameIdentifier'] | |
end | |
end | |
end | |
orcid.first | |
end | |
def get_isni_from_nameIdentifiers(array_of_identifiers) | |
if array_of_identifiers.present? | |
identifier = array_of_identifiers.map do |hash_idenifier| | |
if hash_idenifier["nameIdentifierScheme"] == "ISNI" | |
hash_idenifier['nameIdentifier'] | |
elsif hash_idenifier["nameIdentifierScheme"] == "ORCID" | |
hash_idenifier['nameIdentifier'] | |
end | |
end | |
end | |
identifier.try(:first).presence | |
end | |
def json_with_organisation_name_type(hash, index) | |
remap_organization = {'Organization' => 'Organisation'} | |
hash = { | |
creator_isni: get_isni_from_nameIdentifiers(hash['nameIdentifiers']), | |
creator_organization_name: hash["name"], | |
creator_name_type: 'Organisational', | |
creator_position: index | |
} | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Ubiquity | |
class CrossrefResponse | |
attr_reader :error, :attributes | |
def initialize(response_hash = nil) | |
@error = error | |
@attributes = response_hash['message'] | |
end | |
def title | |
attributes['title'] | |
end | |
def abstract | |
# For removing the Jat tags inside the abstract | |
ActionView::Base.full_sanitizer.sanitize attributes['abstract'] | |
end | |
def version | |
attributes['message-version'] | |
end | |
def date_published_year | |
date_hash = attributes['published-online'].presence || attributes['published-print'] | |
return date_hash['date-parts'].first[0] if date_hash | |
end | |
def date_published_month | |
date_hash = attributes['published-online'].presence || attributes['published-print'] | |
return date_hash['date-parts'].first[1] if date_hash | |
end | |
def license | |
return nil if attributes['license'].blank? | |
url_array = fetch_url_from_response.split('/') | |
url_collection = Hyrax::LicenseService.new.select_active_options.map(&:last) | |
rurl_array.pop if url_array.last == 'legalcode' | |
url_array.shift(2) # Removing the http, https and // part in the url | |
regex_url_str = "(?:http|https)://" + url_array.map { |ele| "(#{ele})" }.join('/') | |
regex_url_exp = Regexp.new regex_url_str | |
url_collection.select { |e| e.match regex_url_exp }.first | |
end | |
def date_published_day | |
date_hash = attributes['published-online'].presence || attributes['published-print'] | |
return date_hash['date-parts'].first[2] if date_hash | |
end | |
def issn | |
return nil if attributes['issn-type'].blank? | |
print_value = attributes['issn-type'].detect { |h| h['type'] == 'print' } | |
return print_value['value'] if print_value | |
end | |
def eissn | |
return nil if attributes['issn-type'].blank? | |
print_value = attributes['issn-type'].detect { |h| h['type'] == 'electronic' } | |
return print_value['value'] if print_value | |
end | |
def isbn | |
return nil if attributes['isbn-type'].blank? | |
print_value = attributes['isbn-type'].detect { |h| h['type'] == 'print' } || attributes['isbn-type'].detect { |h| h['type'] == 'electronic' } | |
return print_value['value'] if print_value['value'] | |
attributes['isbn-type'].first['value'] | |
end | |
def doi | |
attributes['DOI'] | |
end | |
def volume | |
attributes['volume'] | |
end | |
def pagination | |
attributes['page'] | |
end | |
def issue | |
attributes['issue'] | |
end | |
def journal_title | |
attributes['container-title'].first if attributes['container-title'].present? | |
end | |
def creator | |
creator_group = attributes.dig('author') || attributes.dig('editor') | |
if creator_group.present? | |
if creator_group.first.keys && ['given', 'family', 'ORCID'].any? | |
creator_with_seperated_names(creator_group) | |
else | |
creator_without_seperated_names(creator_group) | |
end | |
end | |
end | |
def keyword | |
attributes['subject'] | |
end | |
def publisher | |
attributes['publisher'] | |
end | |
def official_url | |
attributes['URL'] | |
end | |
def creator_with_seperated_names(data) | |
new_creator_group = [] | |
data.each_with_index do |hash, index| | |
hash = { | |
creator_orcid: hash.try(:fetch, 'ORCID', '').split('/').last, | |
creator_given_name: hash["given"], | |
creator_family_name: hash["family"], | |
creator_name_type: 'Personal', | |
creator_position: index | |
} | |
new_creator_group << hash | |
end | |
new_creator_group | |
end | |
url = def fetch_url_from_response | |
vor_version_license = attributes['license'].detect { |h| h['content-version'] == 'vor' } | |
return vor_version_license['URL'] if vor_version_license.present? | |
max_time_stamp_license = attributes['license'].max_by { |h| h.try(:fetch, 'date-parts', '')['time-stamp'].to_f } | |
return max_time_stamp_license['URL'] if max_time_stamp_license.present? | |
attributes['license'].first['URL'] | |
end | |
def data | |
if error.present? | |
{ 'error' => error } | |
else | |
{ | |
title: title, published_year: date_published_year, | |
published_month: date_published_month, published_day: date_published_day, | |
issn: issn, eissn: eissn, journal_title: journal_title, | |
abstract: abstract, version: version, isbn: isbn, | |
creator_group: creator, doi: doi, keyword: keyword, license: license, | |
publisher: publisher, volume: volume, pagination: pagination, issue: issue, | |
official_url: official_url | |
} | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RSpec.describe Ubiquity::DataciteResponse do | |
include DataCiteCrossrefClientHelpers | |
let (:json_data) {File.read(Rails.root.join("spec/fixtures/json/datacite_v2.json")) } | |
let (:full_datacite_url) { 'https://dx.doi.org/10.15123%2FPUB.7627' } | |
let (:datacite_client_1) {Ubiquity::DataciteClient.new(full_datacite_url)} | |
let (:crossref_client_1) {Ubiquity::DataciteClient.new(full_datacite_url)} | |
before(:each) do | |
stub_request_datacite_client1(datacite_client_1, json_data) | |
stub_request_crossref_client1(crossref_client_1, json_data) | |
result = datacite_client_1.fetch_record | |
@response_hash = result.api_response | |
@response_object = described_class.new(response_hash: @response_hash, result: result) | |
@data_hash = @response_object.api_response["data"]["attributes"] | |
@json_object = JSON.parse(json_data) | |
end | |
context 'check values in response hash' do | |
describe '#title' do | |
it 'returns the property title' do | |
title_from_json_data = @json_object["data"]["attributes"]["title"] | |
title_from_response = @data_hash["title"] | |
expect(title_from_response).to eq title_from_json_data | |
end | |
end | |
describe '#date_published_year' do | |
it 'returns the property date_published_year' do | |
year_from_response = @response_object.date_published_year | |
year_from_json_data = @json_object["data"]["attributes"]["published"] | |
expect(year_from_response).to eq year_from_json_data | |
end | |
end | |
describe '#abstract' do | |
it 'returns the property description/abstract' do | |
description_from_response = @data_hash["description"] | |
description_from_json_data = @json_object["data"]["attributes"]["description"] | |
expect(description_from_response).to eq description_from_json_data | |
end | |
end | |
describe '#version' do | |
it 'returns the property version' do | |
version_from_response = @response_object.version | |
version_from_json_data = @json_object["data"]["attributes"].dig('version') | |
expect(version_from_response).to eq version_from_json_data | |
end | |
end | |
describe '#doi' do | |
it 'returns the property doi identifier' do | |
doi_from_response = @response_object.doi["doi"] | |
doi_from_json_data = @json_object["data"]["attributes"].dig('identifier') | |
expect(doi_from_response).to eq doi_from_json_data | |
end | |
end | |
describe '#funder' do | |
it 'returns the property funder' do | |
funder_from_response = @response_object.funder | |
funder_from_json_data = nil if @json_object["data"]["attributes"].dig('fundingReferences') == [] | |
expect(funder_from_response).to eq nil | |
end | |
end | |
describe '#official_url' do | |
it 'returns the property official_url' do | |
official_url_from_response = @response_object.official_url | |
official_url_from_json_data = @json_object["data"]["attributes"]["identifiers"][0]["identifier"] | |
expect(official_url_from_response).to eq official_url_from_json_data | |
end | |
end | |
describe '#publisher' do | |
it 'returns the property publisher' do | |
official_url_from_response = @response_object.publisher | |
official_url_from_json_data = @json_object["data"]["attributes"]["publisher"] | |
expect(official_url_from_response).to eq official_url_from_json_data | |
end | |
end | |
describe '#creator' do | |
it 'returns the property creator' do | |
creator_name_from_response = @response_object.creator[0]["creator_given_name"] | |
creator_name_from_json_data = @json_object["data"]["attributes"].dig('creators')[0]['givenName'] | |
creator_family_name_from_response = @response_object.creator[0]["creator_family_name"] | |
creator_family_name_from_json_data = @json_object["data"]["attributes"].dig('creators')[0]['familyName'] | |
expect(creator_name_from_response).to eq creator_name_from_json_data | |
expect(creator_family_name_from_response).to eq creator_family_name_from_json_data | |
end | |
end | |
describe '#contributor' do | |
it 'returns the property contributor' do | |
contributor_name_from_response = @response_object.contributor | |
contributor_name_from_response = [] if contributor_name_from_response == nil | |
contributor_name_from_json_data = @json_object["data"]["attributes"]['contributors'] | |
expect(contributor_name_from_response).to eq contributor_name_from_json_data | |
end | |
end | |
describe '#license' do | |
it 'returns the property license' do | |
license_from_response = @response_object.license[:license] | |
if license_from_response.present? | |
license_from_json_data = @json_object["data"]["attributes"]["rightsList"].last["rightsUri"] | |
else | |
license_from_json_data = nil | |
end | |
expect(license_from_response).to eq license_from_json_data | |
end | |
end | |
describe '#related_identifier' do | |
it 'returns the property related_identifier' do | |
identifier_from_response = @response_object.related_identifier | |
identifier_from_json_data = nil if @json_object["data"]["attributes"]['relatedIdentifiers'] == [] | |
expect(identifier_from_response).to eq identifier_from_json_data | |
end | |
end | |
describe '#Instance of DataciteResponse' do | |
it 'returns an instance of DataciteResponse' do | |
expect(@response_object).to be_an_instance_of(Ubiquity::DataciteResponse) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module DataCiteCrossrefClientHelpers | |
def stub_request_datacite_client1(datacite_client_1, json_data) | |
stub_request(:get, "https://api.datacite.org/dois/#{datacite_client_1.path}"). | |
with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}). | |
to_return(status: 200, body: json_data, headers: {'Content-Type'=>'application/json; charset=utf-8'}) | |
end | |
def stub_request_datacite_client2(datacite_client_2, json_data) | |
stub_request(:get, "https://api.datacite.org/dois/#{datacite_client_2.path}"). | |
with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}). | |
to_return(status: 200, body: json_data, headers: {'Content-Type'=>'application/json; charset=utf-8'}) | |
end | |
def stub_request_crossref_client1(crossref_client_1, json_data) | |
stub_request(:get, "https://api.crossref.org/works/#{crossref_client_1.path}"). | |
with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}). | |
to_return(status: 200, body: json_data, headers: {'Content-Type'=>'application/json; charset=utf-8'}) | |
end | |
def stub_request_crossref_client2(crossref_client_2, json_data) | |
stub_request(:get, "https://api.crossref.org/works/#{crossref_client_2.path}"). | |
with(headers: {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}). | |
to_return(status: 200, body: json_data, headers: {'Content-Type'=>'application/json; charset=utf-8'}) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
RSpec.describe Ubiquity::DataciteClient do | |
include DataCiteCrossrefClientHelpers | |
let (:json_data) {File.read(Rails.root.join("spec/fixtures/json/datacite_v1.json")) } | |
let (:full_datacite_url) { 'https://dx.doi.org/10.15123%2FPUB.7627' } | |
let (:partial_datacite_url) { '10.15123%2FPUB.7627' } | |
let (:datacite_client_1) {described_class.new(full_datacite_url)} | |
let (:datacite_client_2) {described_class.new(partial_datacite_url)} | |
context 'initialize datacite client with an HTTP GET to /api.datacite.org' do | |
#fetch_record_from_datacite | |
describe '#path' do | |
it 'returns a path ' do | |
stub_request_datacite_client1(datacite_client_1, json_data) | |
expect(datacite_client_1.path).to eq "/10.15123/PUB.7627" | |
end | |
end | |
end | |
context 'fetch_record_from_datacite' do | |
describe '#fetch_record with full url' do | |
it 'returns a HTTParty::Response' do | |
stub_request_datacite_client1(datacite_client_1, json_data) | |
response_object = datacite_client_1.fetch_record_from_datacite | |
fetch_record_expectations(response_object, json_data) | |
end | |
end | |
describe '#fetch_record with url path' do | |
it 'returns a HTTParty::Response' do | |
stub_request_datacite_client2(datacite_client_2, json_data) | |
response_object = datacite_client_2.fetch_record_from_datacite | |
fetch_record_expectations(response_object, json_data) | |
end | |
end | |
end | |
private | |
def fetch_record_expectations(response_object, json_record) | |
expect(response_object.class).to eq HTTParty::Response | |
expect(response_object.success?).to eq true | |
expect(response_object.headers['content-type']).to eq "application/json; charset=utf-8" | |
expect(response_object.parsed_response).to eq JSON.parse(json_record) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment