lib/bolognese/utils.rb in bolognese-1.0.29 vs lib/bolognese/utils.rb in bolognese-1.0.30

- old
+ new

@@ -423,16 +423,16 @@ end def parse_attributes(element, options={}) content = options[:content] || "__content__" - if element.is_a?(String) - element + if element.is_a?(String) && options[:content].nil? + CGI.unescapeHTML(element) elsif element.is_a?(Hash) - element.fetch(content, nil) + element.fetch( CGI.unescapeHTML(content), nil) elsif element.is_a?(Array) - a = element.map { |e| e.is_a?(Hash) ? e.fetch(content, nil) : e }.uniq + a = element.map { |e| e.is_a?(Hash) ? e.fetch( CGI.unescapeHTML(content), nil) : e }.uniq a = options[:first] ? a.first : a.unwrap else nil end end @@ -474,11 +474,11 @@ def normalize_orcid(orcid) orcid = validate_orcid(orcid) return nil unless orcid.present? # turn ORCID ID into URL - "http://orcid.org/" + Addressable::URI.encode(orcid) + "https://orcid.org/" + Addressable::URI.encode(orcid) end def normalize_ids(ids: nil, relation_type: nil) Array.wrap(ids).select { |idx| idx["@id"].present? }.map do |idx| id = normalize_id(idx["@id"]) @@ -546,39 +546,46 @@ mapping = { "type" => "@type", "id" => "@id", "title" => "name" } map_hash_keys(element: element, mapping: mapping) end + def to_schema_org_creators(element) + element = Array.wrap(element).map do |c| + c["affiliation"] = { "@type" => "Organization", "name" => c["affiliation"] } if c["affiliation"].present? + c["@type"] = c["nameType"].present? ? c["nameType"][0..-3] : nil + c["@id"] = Array.wrap(c["nameIdentifiers"]).first.to_h.fetch("nameIdentifier", nil) + c["name"] = c["familyName"].present? ? [c["givenName"], c["familyName"]].join(" ") : c["name"] + c.except("nameIdentifiers", "nameType").compact + end.unwrap + end + + def to_schema_org_contributors(element) + element = Array.wrap(element).map do |c| + c["affiliation"] = { "@type" => "Organization", "name" => c["affiliation"] } if c["affiliation"].present? + c["@type"] = c["nameType"].present? ? c["nameType"][0..-3] : nil + c["@id"] = Array.wrap(c["nameIdentifiers"]).first.to_h.fetch("nameIdentifier", nil) + c["name"] = c["familyName"].present? ? [c["givenName"], c["familyName"]].join(" ") : c["name"] + c.except("nameIdentifiers", "nameType").compact + end.unwrap + end + def to_schema_org_container(element, options={}) return nil unless (element.is_a?(Hash) || (element.nil? && options[:container_title].present?)) { - "@id" => element["relatedIdentifier"], + "@id" => element["identifier"], "@type" => (options[:type] == "Dataset") ? "DataCatalog" : "Periodical", - "name" => element["title"] || options[:container_title] } + "name" => element["title"] || options[:container_title] }.compact end - def to_schema_org_identifier(element, options={}) - ident = { - "@type" => "PropertyValue", - "propertyID" => normalize_doi(element) ? "doi" : "url", - "value" => element } - - if options[:alternate_identifiers].present? - [ident] + Array.wrap(options[:alternate_identifiers]).map do |ai| - if ai["alternateIdentifierType"].to_s.downcase == "url" - ai["alternateIdentifier"] - else - { - "@type" => "PropertyValue", - "propertyID" => ai["alternateIdentifierType"], - "value" => ai["alternateIdentifier"] } - end - end - else - ident - end + def to_schema_org_identifiers(element, options={}) + Array.wrap(element).map do |ai| + { + "@type" => "PropertyValue", + "propertyID" => ai["identifierType"], + "value" => ai["identifier"] } + end.unwrap end def to_schema_org_relation(related_identifiers: nil, relation_type: nil) return nil unless related_identifiers.present? && relation_type.present? @@ -609,43 +616,82 @@ end def to_schema_org_spatial_coverage(geo_location) return nil unless geo_location.present? - Array.wrap(geo_location).map do |gl| + Array.wrap(geo_location).reduce([]) do |sum, gl| if gl.fetch("geoLocationPoint", nil) - { + sum << { "@type" => "Place", "geo" => { "@type" => "GeoCoordinates", "address" => gl["geoLocationPlace"], "latitude" => gl.dig("geoLocationPoint", "pointLatitude"), - "longitude" => gl.dig("geoLocationPoint", "pointLongitude") - }.compact - } - elsif gl.fetch("geoLocationBox", nil) - { + "longitude" => gl.dig("geoLocationPoint", "pointLongitude") } + }.compact + end + + if gl.fetch("geoLocationBox", nil) + sum << { "@type" => "Place", "geo" => { "@type" => "GeoShape", "address" => gl["geoLocationPlace"], "box" => [gl.dig("geoLocationBox", "southBoundLatitude"), gl.dig("geoLocationBox", "westBoundLongitude"), gl.dig("geoLocationBox", "northBoundLatitude"), - gl.dig("geoLocationBox", "eastBoundLongitude")].join(" ") - }.compact + gl.dig("geoLocationBox", "eastBoundLongitude")].compact.join(" ").presence }.compact + }.compact + end + + if gl.fetch("geoLocationPolygon", nil) + sum << { + "@type" => "Place", + "geo" => { + "@type" => "GeoShape", + "address" => gl["geoLocationPlace"], + "polygon" => Array.wrap(gl.dig("geoLocationPolygon")).map do |glp| + [glp.dig("polygonPoint", "pointLongitude"), glp.dig("polygonPoint", "pointLatitude")].compact + end.compact } } end - end.compact.unwrap + + if gl.fetch("geoLocationPlace", nil) && !gl.fetch("geoLocationPoint", nil) && !gl.fetch("geoLocationBox", nil) && !gl.fetch("geoLocationPolygon", nil) + sum << { + "@type" => "Place", + "geo" => { + "@type" => "GeoCoordinates", + "address" => gl["geoLocationPlace"] } + }.compact + end + + sum + end.unwrap end def from_schema_org(element) mapping = { "@type" => "type", "@id" => "id" } map_hash_keys(element: element, mapping: mapping) end + def from_schema_org_creators(element) + element = Array.wrap(element).map do |c| + c["nameIdentifier"] = [{ "__content__" => c["@id"], "nameIdentifierScheme" => "ORCID" }] if normalize_orcid(c["@id"]) + c["creatorName"] = { "nameType" => c["@type"].present? ? c["@type"].titleize + "al" : nil, "__content__" => c["name"] }.compact + c.except("@id", "@type", "name") + end + end + + def from_schema_org_contributors(element) + element = Array.wrap(element).map do |c| + c["nameIdentifier"] = [{ "__content__" => c["@id"], "nameIdentifierScheme" => "ORCID" }] if normalize_orcid(c["@id"]) + c["contributorName"] = { "nameType" => c["@type"].present? ? c["@type"].titleize + "al" : nil, "__content__" => c["name"] }.compact + c.except("@id", "@type", "name") + end + end + def map_hash_keys(element: nil, mapping: nil) Array.wrap(element).map do |a| a.map {|k, v| [mapping.fetch(k, k), v] }.reduce({}) do |hsh, (k, v)| if v.is_a?(Hash) hsh[k] = to_schema_org(v) @@ -683,11 +729,11 @@ def to_citeproc(element) Array.wrap(element).map do |a| a["family"] = a["familyName"] a["given"] = a["givenName"] a["literal"] = a["name"] unless a["familyName"].present? - a.except("type", "@type", "id", "@id", "name", "familyName", "givenName").compact + a.except("nameType", "type", "@type", "id", "@id", "name", "familyName", "givenName", "affiliation", "nameIdentifiers").compact end.presence end def to_ris(element) Array.wrap(element).map do |a| @@ -814,15 +860,69 @@ rescue nil end def get_date(dates, date_type) - dd = dates.find { |d| d["dateType"] == date_type } || {} + dd = Array.wrap(dates).find { |d| d["dateType"] == date_type } || {} dd.fetch("date", nil) end def get_contributor(contributor, contributor_type) contributor.select { |c| c["contributorType"] == contributor_type } + end + + def get_identifier(identifiers, identifier_type) + id = Array.wrap(identifiers).find { |i| i["identifierType"] == identifier_type } || {} + id.fetch("identifier", nil) + end + + def get_identifier_type(identifier_type) + identifierTypes = { + "ark" => "ARK", + "arxiv" => "arXiv", + "bibcode" => "bibcode", + "doi" => "DOI", + "ean13" => "EAN13", + "eissn" => "EISSN", + "handle" => "Handle", + "igsn" => "IGSN", + "isbn" => "ISBN", + "issn" => "ISSN", + "istc" => "ISTC", + "lissn" => "LISSN", + "lsid" => "LSID", + "pmid" => "PMID", + "purl" => "PURL", + "upc" => "UPC", + "url" => "URL", + "urn" => "URN", + "md5" => "md5", + "minid" => "minid", + "dataguid" => "dataguid" + } + + identifierTypes[identifier_type.downcase] || identifier_type + end + + def get_series_information(str) + return {} unless str.present? + + str = str.split(",").map(&:strip) + + title = str.first + volume_issue = str.length > 2 ? str[1].rpartition(/\(([^)]+)\)/) : nil + volume = volume_issue.present? ? volume_issue[0].presence || volume_issue[2].presence : nil + issue = volume_issue.present? ? volume_issue[1][1...-1].presence : nil + pages = str.length > 1 ? str.last : nil + first_page = pages.present? ? pages.split("-").map(&:strip).first : nil + last_page = pages.present? ? pages.split("-").map(&:strip).last : nil + + { + "title" => title, + "volume" => volume, + "issue" => issue, + "firstPage" => first_page, + "lastPage" => last_page }.compact end def jsonlint(json) return ["No JSON provided"] unless json.present?