lib/bolognese/utils.rb in bolognese-0.15.9 vs lib/bolognese/utils.rb in bolognese-1.0

- old
+ new

@@ -23,11 +23,14 @@ "Service" => "Service", "Software" => "SoftwareSourceCode", "Sound" => "AudioObject", "Text" => "ScholarlyArticle", "Workflow" => nil, - "Other" => "CreativeWork" + "Other" => "CreativeWork", + # not part of DataCite schema, but used internally + "Periodical" => "Periodical", + "DataCatalog" => "DataCatalog" } DC_TO_CP_TRANSLATIONS = { "Audiovisual" => "motion_picture", "Collection" => nil, @@ -171,11 +174,10 @@ "AudioObject" => "Sound", "Blog" => "Text", "BlogPosting" => "Text", "Chapter" => "Text", "Collection" => "Collection", - "CreativeWork" => "Other", "DataCatalog" => "Dataset", "Dataset" => "Dataset", "Event" => "Event", "ImageObject" => "Image", "Movie" => "Audiovisual", @@ -360,11 +362,11 @@ "schema_org" elsif options[:ext] == ".json" && Maremma.from_json(string).to_h.dig("@context") == ("https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld") "codemeta" elsif options[:ext] == ".json" && Maremma.from_json(string).to_h.dig("ris_type") "crosscite" - elsif options[:ext] == ".json" && Maremma.from_json(string).to_h.dig("schemaVersion").to_s.start_with?("http://datacite.org/schema/kernel") + elsif options[:ext] == ".json" && Maremma.from_json(string).to_h.dig("schema-version").to_s.start_with?("http://datacite.org/schema/kernel") "datacite_json" elsif options[:ext] == ".json" && Maremma.from_json(string).to_h.dig("issued", "date-parts").present? "citeproc" end end @@ -469,15 +471,21 @@ # turn ORCID ID into URL "http://orcid.org/" + Addressable::URI.encode(orcid) end - def normalize_ids(ids: nil) - Array.wrap(ids).map do |id| - { "id" => normalize_id(id["@id"]), - "type" => id["@type"] || Metadata::DC_TO_SO_TRANSLATIONS[id["resourceTypeGeneral"]] || "CreativeWork", - "title" => id["title"] || id["name"] }.compact + def normalize_ids(ids: nil, relation_type: nil) + Array.wrap(ids).select { |idx| idx["@id"].present? }.map do |idx| + id = normalize_id(idx["@id"]) + related_identifier_type = doi_from_url(id).present? ? "DOI" : "URL" + id = doi_from_url(id) || id + + { "id" => id, + "relation_type" => relation_type, + "related_identifier_type" => related_identifier_type, + "resource_type_general" => Metadata::SO_TO_DC_TRANSLATIONS[idx["@type"]], + "title" => idx["title"] || idx["name"] }.compact end.unwrap end # find Creative Commons or OSI license in licenses array, normalize url and name def normalize_licenses(licenses) @@ -523,27 +531,24 @@ end def to_schema_org_container(element, options={}) return nil unless (element.is_a?(Hash) || (element.nil? && options[:container_title].present?)) - mapping = { "type" => "@type", "id" => "@id", "title" => "name" } - - element ||= {} - element["type"] = (options[:type] == "Dataset") ? "DataCatalog" : "Periodical" - element["title"] ||= options[:container_title] - - map_hash_keys(element: element, mapping: mapping) + { + "@id" => element["id"], + "@type" => (options[:type] == "Dataset") ? "DataCatalog" : "Periodical", + "name" => element["title"] || options[:container_title] } end def to_schema_org_identifier(element, options={}) ident = { "@type" => "PropertyValue", "propertyID" => normalize_doi(element) ? "doi" : "url", "value" => element } - if options[:alternate_identifier].present? - [ident] + Array.wrap(options[:alternate_identifier]).map do |ai| + if options[:alternate_identifiers].present? + [ident] + Array.wrap(options[:alternate_identifiers]).map do |ai| if ai["type"].to_s.downcase == "url" ai["name"] else { "@type" => "PropertyValue", @@ -554,10 +559,71 @@ else ident end end + def to_schema_org_relation(related_identifiers: nil, relation_type: nil) + return nil unless related_identifiers.present? && relation_type.present? + + relation_type = relation_type == "References" ? ["References", "Cites", "Documents"] : [relation_type] + + Array.wrap(related_identifiers).select { |ri| relation_type.include?(ri["relation_type"]) }.map do |r| + if r["related_identifier_type"] == "ISSN" && r["relation_type"] == "IsPartOf" + { + "@type" => "Periodical", + "issn" => r["id"], + "name" => r["title"] }.compact + else + { + "@id" => normalize_id(r["id"]), + "@type" => DC_TO_SO_TRANSLATIONS[r["resource_type_general"]] || "CreativeWork", + "name" => r["title"] }.compact + end + end.unwrap + end + + def to_schema_org_funder(funding_references) + return nil unless funding_references.present? + + Array.wrap(funding_references).map do |fr| + { + "@id" => fr["funder_identifier"], + "@type" => "Organization", + "name" => fr["funder_name"] }.compact + end.unwrap + end + + def to_schema_org_spatial_coverage(geo_location) + return nil unless geo_location.present? + + Array.wrap(geo_location).map do |gl| + if gl.fetch("geo_location_point", nil) + { + "@type" => "Place", + "geo" => { + "@type" => "GeoCoordinates", + "address" => gl["geo_location_place"], + "latitude" => gl.dig("geo_location_point", "point_latitude"), + "longitude" => gl.dig("geo_location_point", "point_longitude") + }.compact + } + elsif gl.fetch("geo_location_box", nil) + { + "@type" => "Place", + "geo" => { + "@type" => "GeoShape", + "address" => gl["geo_location_place"], + "box" => [gl.dig("geo_location_box", "south_bound_latitude"), + gl.dig("geo_location_box", "west_bound_longitude"), + gl.dig("geo_location_box", "north_bound_latitude"), + gl.dig("geo_location_box", "east_bound_longitude")].join(" ") + }.compact + } + end + end.compact.unwrap + end + def from_schema_org(element) mapping = { "@type" => "type", "@id" => "id" } map_hash_keys(element: element, mapping: mapping) end @@ -572,9 +638,16 @@ hsh[k] = v hsh end end end.unwrap + end + + def to_identifier(identifier) + { + "@type" => "PropertyValue", + "propertyID" => identifier["related_identifier_type"], + "value" => identifier["id"] } end def from_citeproc(element) Array.wrap(element).map do |a| if a["literal"].present?