bolognese 0.3 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/{LICENSE → LICENSE.md} +0 -0
  4. data/README.md +81 -1
  5. data/lib/bolognese.rb +1 -0
  6. data/lib/bolognese/author_utils.rb +1 -0
  7. data/lib/bolognese/cli.rb +6 -6
  8. data/lib/bolognese/crossref.rb +23 -19
  9. data/lib/bolognese/datacite.rb +21 -17
  10. data/lib/bolognese/datacite_utils.rb +14 -5
  11. data/lib/bolognese/doi_utils.rb +2 -3
  12. data/lib/bolognese/metadata.rb +11 -5
  13. data/lib/bolognese/orcid.rb +1 -1
  14. data/lib/bolognese/schema_org.rb +157 -0
  15. data/lib/bolognese/utils.rb +31 -1
  16. data/lib/bolognese/version.rb +1 -1
  17. data/spec/crossref_spec.rb +86 -26
  18. data/spec/datacite_spec.rb +43 -2
  19. data/spec/{doi_spec.rb → doi_utils_spec.rb} +2 -2
  20. data/spec/fixtures/vcr_cassettes/Bolognese_CLI/read/crossref/as_crossref.yml +8 -8
  21. data/spec/fixtures/vcr_cassettes/Bolognese_CLI/read/crossref/as_datacite.yml +12 -12
  22. data/spec/fixtures/vcr_cassettes/Bolognese_CLI/read/crossref/as_schema_org.yml +12 -12
  23. data/spec/fixtures/vcr_cassettes/Bolognese_CLI/read/datacite/as_datacite.yml +10 -10
  24. data/spec/fixtures/vcr_cassettes/Bolognese_CLI/read/datacite/as_schema_org.yml +16 -16
  25. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/doi_registration_agency/crossref.yml +931 -4
  26. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/doi_registration_agency/datacite.yml +931 -4
  27. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/doi_registration_agency/medra.yml +931 -4
  28. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/doi_registration_agency/not_found.yml +931 -4
  29. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata/DOI_with_ORCID_ID.yml +506 -0
  30. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata/DOI_with_SICI_DOI.yml +31 -94
  31. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata/DOI_with_data_citation.yml +138 -14992
  32. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata/date_in_future.yml +19 -2405
  33. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata/journal_article.yml +107 -884
  34. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata/not_found_error.yml +92 -2
  35. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata/posted_content.yml +89 -5415
  36. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata_as_datacite_xml/DOI_with_ORCID_ID.yml +506 -0
  37. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata_as_datacite_xml/DOI_with_data_citation.yml +137 -671
  38. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata_as_string/DOI_with_data_citation.yml +719 -0
  39. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/SICI_doi.yml +930 -0
  40. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/doi.yml +930 -0
  41. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/doi_from_url_without_doi_proxy.yml +930 -0
  42. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/doi_prefix_too_long.yml +930 -0
  43. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/doi_prefix_with_string.yml +930 -0
  44. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/doi_with_protocol.yml +930 -0
  45. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/dx_doi_org_url.yml +930 -0
  46. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/https_url.yml +930 -0
  47. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_doi/not_valid_doi_prefix.yml +930 -0
  48. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_ids/doi.yml +930 -0
  49. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_ids/url.yml +930 -0
  50. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_url/doi.yml +930 -0
  51. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/normalize_url/url.yml +930 -0
  52. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/parse_attribute/array.yml +930 -0
  53. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/parse_attribute/hash.yml +930 -0
  54. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/parse_attribute/nil.yml +930 -0
  55. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/parse_attribute/string.yml +930 -0
  56. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/parse_attributes/array.yml +930 -0
  57. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/parse_attributes/hash.yml +930 -0
  58. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/parse_attributes/nil.yml +930 -0
  59. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/parse_attributes/string.yml +930 -0
  60. data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata/BlogPosting.yml +248 -78
  61. data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata/Dataset.yml +1687 -105
  62. data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata/Date.yml +458 -0
  63. data/spec/fixtures/vcr_cassettes/Bolognese_Datacite/get_metadata_as_string/Dataset.yml +173 -0
  64. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/find_PID_provider/crossref.yml +4 -4
  65. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/find_PID_provider/crossref_doi_not_url.yml +4 -4
  66. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/find_PID_provider/datacite.yml +4 -4
  67. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/find_PID_provider/datacite_doi_http.yml +4 -4
  68. data/spec/fixtures/vcr_cassettes/Bolognese_Metadata/find_PID_provider/orcid.yml +2 -2
  69. data/spec/fixtures/vcr_cassettes/Bolognese_SchemaOrg/get_metadata/BlogPosting.yml +632 -0
  70. data/spec/fixtures/vcr_cassettes/Bolognese_SchemaOrg/get_metadata/not_found_error.yml +93 -0
  71. data/spec/metadata_spec.rb +11 -5
  72. data/spec/schema_org_spec.rb +31 -0
  73. data/spec/utils_spec.rb +87 -0
  74. metadata +35 -6
  75. data/lib/bolognese/pid_utils.rb +0 -23
  76. data/spec/fixtures/vcr_cassettes/Bolognese_Crossref/get_metadata/DOI_test.yml +0 -843
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4728c17ca6677056bae7bb34fd334b2a018bbf5
4
- data.tar.gz: 69525494936ec8e6e4fe396f9b490b9fe19f1aa8
3
+ metadata.gz: 782e0858e5840b106b79b3c340a3d4bf572840b9
4
+ data.tar.gz: d85f7f7b269377b12a0ab25581001448ecd1dc92
5
5
  SHA512:
6
- metadata.gz: 85aa5235f96786e7f005ee588abb8d9f6bff889102d4b8d7a5b2ec91badcfd6b1f84cf2f0fdf33813768b396f98774a1ed4cd570089255628f105c2effc862d9
7
- data.tar.gz: 6db1eb5f1ab14ec751468e4192a0d09a05a12dbf79193a80c0ceb30e9deb41c641d76d9331eba1775422308baa94f531abbae8d92cb2b0908c8f9c84ebec06ca
6
+ metadata.gz: e59c29a2b61e97623e4ff6b1284e695c26cdb780bac6458006d9863e84b4e1728d47983222fc5d1ee86e18683a796ba717f167af03e2952aaa3d0fa8ce8be19c
7
+ data.tar.gz: 5f6eaeabccd3a86ff1534ad78bd34934539c3aa7351636983c299e9e953038068641aea0cfb5f18954be61b5db5e5c2de5e1ac9398ef2b6345fffc3b22ec1fbf
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bolognese (0.3)
4
+ bolognese (0.4.1)
5
5
  activesupport (~> 4.2, >= 4.2.5)
6
6
  builder (~> 3.2, >= 3.2.2)
7
7
  dotenv (~> 2.1, >= 2.1.1)
File without changes
data/README.md CHANGED
@@ -1,3 +1,83 @@
1
1
  # bolognese
2
2
 
3
- Command-line utility for conversion of DOI metadata.
3
+ Command-line utility for conversion of DOI metadata from and to [schema.org](https://schema.org) in JSON-LD.
4
+
5
+ ## Features
6
+
7
+ * convert [Crossref XML](https://support.crossref.org/hc/en-us/articles/214936283-UNIXREF-query-output-format) to schema.org/JSON-LD
8
+ * convert [DataCite XML](http://schema.datacite.org/) to schema.org/JSON-LD
9
+ * fetch schema.org/JSON-LD from a URL
10
+ * convert schema.org/JSON-LD to [DataCite XML](http://schema.datacite.org/)
11
+ * convert Crossref XML to [DataCite XML](http://schema.datacite.org/)
12
+
13
+ Conversion to Crossref XML is not yet supported.
14
+
15
+ ## Installation
16
+
17
+ The usual way with Bundler: add the following to your `Gemfile` to install the
18
+ current version of the gem:
19
+
20
+ ```ruby
21
+ gem 'bolognese'
22
+ ```
23
+
24
+ Then run `bundle install` to install into your environment.
25
+
26
+ You can also install the gem system-wide in the usual way:
27
+
28
+ ```bash
29
+ gem install bolognese
30
+ ```
31
+
32
+ ## Commands
33
+
34
+ The bolognese commands understand URLs and DOIs as arguments. The `--as` command
35
+ line flag sets the format, either `crossref`, `datacite`, or `schema_org` (default).
36
+
37
+ ## Examples
38
+
39
+ Convert Crossref XML to schema.org/JSON-LD:
40
+ ```
41
+ bolognese read https://doi.org/10.7554/elife.01567
42
+ ```
43
+
44
+ Read Crossref XML:
45
+ ```
46
+ bolognese read https://doi.org/10.7554/elife.01567 --as crossref
47
+ ```
48
+
49
+ Convert Crossref XML to DataCite XML:
50
+ ```
51
+ bolognese read https://doi.org/10.7554/elife.01567 --as datacite
52
+ ```
53
+
54
+ Convert DataCite XML to schema.org/JSON-LD:
55
+ ```
56
+ bolognese read 10.5061/DRYAD.8515
57
+ ```
58
+
59
+ Read DataCite XML:
60
+ ```
61
+ bolognese read 10.5061/DRYAD.8515 --as datacite
62
+ ```
63
+
64
+ ## Development
65
+
66
+ We use rspec for unit testing:
67
+
68
+ ```
69
+ bundle exec rspec
70
+ ```
71
+
72
+ Follow along via [Github Issues](https://github.com/datacite/bolognese/issues).
73
+
74
+ ### Note on Patches/Pull Requests
75
+
76
+ * Fork the project
77
+ * Write tests for your new feature or a test that reproduces a bug
78
+ * Implement your feature or make a bug fix
79
+ * Do not mess with Rakefile, version or history
80
+ * Commit, push and make a pull request. Bonus points for topical branches.
81
+
82
+ ## License
83
+ **bolognese** is released under the [MIT License](https://github.com/datacite/bolognese/blob/master/LICENSE.md).
@@ -7,6 +7,7 @@ require "bolognese/version"
7
7
  require "bolognese/metadata"
8
8
  require "bolognese/crossref"
9
9
  require "bolognese/datacite"
10
+ require "bolognese/schema_org"
10
11
  require "bolognese/orcid"
11
12
  require "bolognese/cli"
12
13
  require "bolognese/string"
@@ -48,6 +48,7 @@ module Bolognese
48
48
  Array(authors).map { |author| get_one_author(author, options) }
49
49
  end
50
50
 
51
+ # pase nameIdentifier from DataCite
51
52
  def get_name_identifier(author)
52
53
  name_identifier = author.dig("nameIdentifier", "text")
53
54
  name_identifier_scheme = author.dig("nameIdentifier", "nameIdentifierScheme") || "ORCID"
@@ -19,19 +19,19 @@ module Bolognese
19
19
  desc "read pid", "read metadata for PID"
20
20
  method_option :as, default: "schema_org"
21
21
  def read(pid)
22
- provider = Metadata.new(pid).provider
22
+ provider = Metadata.new(id: pid).provider
23
23
 
24
24
  case
25
25
  when provider == "crossref" && options[:as] == "crossref"
26
- puts Crossref.new(pid).raw
26
+ puts Crossref.new(id: pid).raw
27
27
  when provider == "crossref" && options[:as] == "datacite"
28
- puts Crossref.new(pid).as_datacite
28
+ puts Crossref.new(id: pid).as_datacite
29
29
  when provider == "crossref"
30
- puts Crossref.new(pid).as_schema_org
30
+ puts Crossref.new(id: pid).as_schema_org
31
31
  when provider == "datacite" && options[:as] == "datacite"
32
- puts Datacite.new(pid).raw
32
+ puts Datacite.new(id: pid).raw
33
33
  when "datacite"
34
- puts Datacite.new(pid).as_schema_org
34
+ puts Datacite.new(id: pid).as_schema_org
35
35
  else
36
36
  puts "not implemented"
37
37
  end
@@ -1,12 +1,5 @@
1
- require_relative 'doi_utils'
2
- require_relative 'datacite_utils'
3
- require_relative 'utils'
4
-
5
1
  module Bolognese
6
2
  class Crossref < Metadata
7
- include Bolognese::DoiUtils
8
- include Bolognese::Utils
9
- include Bolognese::DataciteUtils
10
3
 
11
4
  # CrossRef types from https://api.crossref.org/types
12
5
  CR_TO_SO_TRANSLATIONS = {
@@ -38,15 +31,17 @@ module Bolognese
38
31
  "PostedContent" => nil
39
32
  }
40
33
 
41
- attr_reader = :id, :metadata, :schema_org
34
+ attr_reader = :id, :raw, :metadata, :schema_org
42
35
 
43
- def initialize(doi)
44
- @id = normalize_doi(doi)
45
- end
36
+ def initialize(id: nil, string: nil)
37
+ id = normalize_doi(id) if id.present?
46
38
 
47
- def raw
48
- response = Maremma.get(@id, accept: "application/vnd.crossref.unixref+xml", host: true, raw: true)
49
- @raw ||= response.body.fetch("data", nil)
39
+ if string.present?
40
+ @raw = string
41
+ elsif id.present?
42
+ response = Maremma.get(id, accept: "application/vnd.crossref.unixref+xml", host: true, raw: true)
43
+ @raw = response.body.fetch("data", nil)
44
+ end
50
45
  end
51
46
 
52
47
  def metadata
@@ -58,7 +53,11 @@ module Bolognese
58
53
  end
59
54
 
60
55
  def doi
61
- doi_from_url(id)
56
+ bibliographic_metadata.dig("doi_data", "doi")
57
+ end
58
+
59
+ def id
60
+ normalize_doi(doi)
62
61
  end
63
62
 
64
63
  def journal_metadata
@@ -69,7 +68,7 @@ module Bolognese
69
68
  if metadata.dig("crossref", "journal", "journal_article").present?
70
69
  metadata.dig("crossref", "journal", "journal_article")
71
70
  else
72
- k = metadata.dig("crossref").keys.last
71
+ k = metadata.fetch("crossref", {}).keys.last
73
72
  metadata.dig("crossref", k).presence || {}
74
73
  end
75
74
  end
@@ -104,7 +103,12 @@ module Bolognese
104
103
  end
105
104
 
106
105
  def description
107
- bibliographic_metadata.fetch("abstract", {}).values.first
106
+ des = bibliographic_metadata.fetch("abstract", {}).values.first
107
+ if des.is_a?(Hash)
108
+ des.to_xml
109
+ elsif des.is_a?(String)
110
+ des
111
+ end
108
112
  end
109
113
 
110
114
  def license
@@ -124,7 +128,7 @@ module Bolognese
124
128
  person = bibliographic_metadata.dig("contributors", "person_name")
125
129
  Array(person).select { |a| a["contributor_role"] == "author" }.map do |a|
126
130
  { "@type" => "Person",
127
- "@id" => a["ORCID"],
131
+ "@id" => parse_attribute(a["ORCID"]),
128
132
  "givenName" => a["given_name"],
129
133
  "familyName" => a["surname"] }.compact
130
134
  end
@@ -134,7 +138,7 @@ module Bolognese
134
138
  person = bibliographic_metadata.dig("contributors", "person_name")
135
139
  Array(person).select { |a| a["contributor_role"] == "editor" }.map do |a|
136
140
  { "@type" => "Person",
137
- "@id" => a["ORCID"],
141
+ "@id" => parse_attribute(a["ORCID"]),
138
142
  "givenName" => a["given_name"],
139
143
  "familyName" => a["surname"] }.compact
140
144
  end.presence
@@ -1,12 +1,5 @@
1
- require_relative 'doi_utils'
2
- require_relative 'datacite_utils'
3
- require_relative 'utils'
4
-
5
1
  module Bolognese
6
2
  class Datacite < Metadata
7
- include Bolognese::DoiUtils
8
- include Bolognese::DataciteUtils
9
- include Bolognese::Utils
10
3
 
11
4
  DC_TO_SO_TRANSLATIONS = {
12
5
  "Audiovisual" => "VideoObject",
@@ -25,15 +18,17 @@ module Bolognese
25
18
  "Other" => "CreativeWork"
26
19
  }
27
20
 
28
- attr_reader = :id, :metadata, :schema_org
21
+ attr_reader = :id, :raw, :metadata, :schema_org
29
22
 
30
- def initialize(doi)
31
- @id = normalize_doi(doi)
32
- end
23
+ def initialize(id: nil, string: nil)
24
+ id = normalize_doi(id) if id.present?
33
25
 
34
- def raw
35
- response = Maremma.get(id, accept: "application/vnd.datacite.datacite+xml", raw: true)
36
- @raw = response.body.fetch("data", nil)
26
+ if string.present?
27
+ @raw = string
28
+ elsif id.present?
29
+ response = Maremma.get(id, accept: "application/vnd.datacite.datacite+xml", raw: true)
30
+ @raw = response.body.fetch("data", nil)
31
+ end
37
32
  end
38
33
 
39
34
  def metadata
@@ -45,7 +40,11 @@ module Bolognese
45
40
  end
46
41
 
47
42
  def doi
48
- doi_from_url(id)
43
+ metadata.fetch("identifier", {}).fetch("text", nil)
44
+ end
45
+
46
+ def id
47
+ normalize_doi(doi)
49
48
  end
50
49
 
51
50
  def type
@@ -67,7 +66,12 @@ module Bolognese
67
66
  end
68
67
 
69
68
  def description
70
- metadata.dig("descriptions", "description", "text")
69
+ des = metadata.dig("descriptions", "description", "text")
70
+ if des.is_a?(Hash)
71
+ des.to_xml
72
+ elsif des.is_a?(String)
73
+ des.strip
74
+ end
71
75
  end
72
76
 
73
77
  def license
@@ -89,7 +93,7 @@ module Bolognese
89
93
  end
90
94
 
91
95
  def dates
92
- Array(metadata.dig("dates", "date"))
96
+ Array.wrap(metadata.dig("dates", "date"))
93
97
  end
94
98
 
95
99
  def date_created
@@ -22,6 +22,7 @@ module Bolognese
22
22
 
23
23
  LICENSE_NAMES = {
24
24
  "http://creativecommons.org/publicdomain/zero/1.0/" => "Public Domain (CC0 1.0)",
25
+ "http://creativecommons.org/licenses/by/3.0/" => "Creative Commons Attribution 3.0 (CC-BY 3.0)",
25
26
  "https://creativecommons.org/licenses/by/4.0/" => "Creative Commons Attribution 4.0 (CC-BY 4.0)",
26
27
  "https://creativecommons.org/licenses/by-nc/4.0/" => "Creative Commons Attribution Noncommercial 4.0 (CC-BY-NC 4.0)",
27
28
  "https://creativecommons.org/licenses/by-sa/4.0/" => "Creative Commons Attribution Share Alike 4.0 (CC-BY-SA 4.0)",
@@ -88,7 +89,7 @@ module Bolognese
88
89
 
89
90
  xml.contributors do
90
91
  Array(editor).each do |contributor|
91
- xml.contributor("contributorType" => contributor[:contributor_type]) do
92
+ xml.contributor("contributorType" => "Editor") do
92
93
  insert_person(xml, contributor, "contributor")
93
94
  end
94
95
  end
@@ -96,12 +97,12 @@ module Bolognese
96
97
  end
97
98
 
98
99
  def insert_person(xml, person, type)
99
- person_name = [person["familyName"], person["givenName"], person["name"]].compact.join(", ")
100
+ person_name = [person["familyName"], person["givenName"]].compact.join(", ").presence || person["name"]
100
101
 
101
102
  xml.send(:'creatorName', person_name) if type == "creator"
102
103
  xml.send(:'contributorName', person_name) if type == "contributor"
103
- xml.send(:'givenName', person[:given_name]) if person["givenName"].present?
104
- xml.send(:'familyName', person[:family_name]) if person["familyName"].present?
104
+ xml.send(:'givenName', person["givenName"]) if person["givenName"].present?
105
+ xml.send(:'familyName', person["familyName"]) if person["familyName"].present?
105
106
  xml.nameIdentifier(person["@id"], 'schemeURI' => 'http://orcid.org/', 'nameIdentifierScheme' => 'ORCID') if person["@id"].present?
106
107
  end
107
108
 
@@ -165,6 +166,14 @@ module Bolognese
165
166
  xml.version(version)
166
167
  end
167
168
 
169
+ def is_part_of
170
+ related_identifiers("IsPartOf").first
171
+ end
172
+
173
+ def related_identifiers
174
+ Array.wrap(is_part_of) + Array(has_part) + Array(citation)
175
+ end
176
+
168
177
  def insert_related_identifiers(xml)
169
178
  return xml unless related_identifiers.present?
170
179
 
@@ -187,7 +196,7 @@ module Bolognese
187
196
  return xml unless description.present?
188
197
 
189
198
  xml.descriptions do
190
- xml.description(description)
199
+ xml.description(description, 'descriptionType' => "Abstract")
191
200
  end
192
201
  end
193
202
 
@@ -18,9 +18,9 @@ module Bolognese
18
18
  def doi_from_url(url)
19
19
  if /(http|https):\/\/(dx\.)?doi\.org\/(\w+)/.match(url)
20
20
  uri = Addressable::URI.parse(url)
21
- uri.path[1..-1].upcase
21
+ uri.path[1..-1].downcase
22
22
  elsif url.is_a?(String) && url.starts_with?("doi:")
23
- url[4..-1].upcase
23
+ url[4..-1].downcase
24
24
  end
25
25
  end
26
26
 
@@ -43,6 +43,5 @@ module Bolognese
43
43
  { "errors" => response.body.fetch("errors", nil) || response.body.fetch("data", nil) }
44
44
  end
45
45
  end
46
-
47
46
  end
48
47
  end
@@ -1,7 +1,7 @@
1
1
  require_relative 'doi_utils'
2
2
  require_relative 'author_utils'
3
3
  require_relative 'date_utils'
4
- require_relative 'pid_utils'
4
+ require_relative 'datacite_utils'
5
5
  require_relative 'utils'
6
6
 
7
7
  module Bolognese
@@ -9,12 +9,12 @@ module Bolognese
9
9
  include Bolognese::DoiUtils
10
10
  include Bolognese::AuthorUtils
11
11
  include Bolognese::DateUtils
12
- include Bolognese::PidUtils
12
+ include Bolognese::DataciteUtils
13
13
  include Bolognese::Utils
14
14
 
15
- attr_reader :id, :provider
15
+ attr_reader :id, :raw, :provider
16
16
 
17
- def initialize(id)
17
+ def initialize(id: nil)
18
18
  @id = normalize_id(id)
19
19
  @provider = find_provider(@id)
20
20
  end
@@ -24,7 +24,13 @@ module Bolognese
24
24
  end
25
25
 
26
26
  def find_provider(id)
27
- get_doi_ra(id).fetch("id", nil) || "orcid"
27
+ if /(http|https):\/\/(dx\.)?doi\.org\/(\w+)/.match(id)
28
+ get_doi_ra(id).fetch("id", nil)
29
+ elsif /\A(?:http:\/\/orcid\.org\/)?(\d{4}-\d{4}-\d{4}-\d{3}[0-9X]+)\z/.match(id)
30
+ "orcid"
31
+ else
32
+ "schema_org"
33
+ end
28
34
  end
29
35
  end
30
36
  end
@@ -1,6 +1,6 @@
1
1
  module Bolognese
2
2
  class Orcid < Metadata
3
- include Bolognese::PidUtils
3
+ include Bolognese::Utils
4
4
  # def get_orcid_metadata(orcid, options = {})
5
5
  # return {} if orcid.blank?
6
6
 
@@ -0,0 +1,157 @@
1
+ module Bolognese
2
+ class SchemaOrg < Metadata
3
+
4
+ DC_TO_SO_TRANSLATIONS = {
5
+ "Audiovisual" => "VideoObject",
6
+ "Collection" => "Collection",
7
+ "Dataset" => "Dataset",
8
+ "Event" => "Event",
9
+ "Image" => "ImageObject",
10
+ "InteractiveResource" => nil,
11
+ "Model" => nil,
12
+ "PhysicalObject" => nil,
13
+ "Service" => "Service",
14
+ "Software" => "SoftwareSourceCode",
15
+ "Sound" => "AudioObject",
16
+ "Text" => "ScholarlyArticle",
17
+ "Workflow" => nil,
18
+ "Other" => "CreativeWork"
19
+ }
20
+
21
+ attr_reader = :id, :raw, :metadata, :schema_org
22
+
23
+ def initialize(id: nil, string: nil)
24
+ id = normalize_url(id) if id.present?
25
+
26
+ if string.present?
27
+ @raw = string
28
+ elsif id.present?
29
+ response = Maremma.get(id)
30
+ @raw = response.body.fetch("data", nil)
31
+ end
32
+ end
33
+
34
+ def metadata
35
+ @metadata ||= begin
36
+ if raw.present?
37
+ doc = Nokogiri::XML(raw)
38
+ tag = doc.at_xpath('//script[@type="application/ld+json"]')
39
+ Maremma.from_json(tag)
40
+ else
41
+ {}
42
+ end
43
+ end
44
+ end
45
+
46
+ def exists?
47
+ metadata.present?
48
+ end
49
+
50
+ def doi
51
+ doi_from_url(id)
52
+ end
53
+
54
+ def id
55
+ normalize_url(metadata.fetch("@id", nil))
56
+ end
57
+
58
+ def url
59
+ normalize_url(metadata.fetch("url", nil))
60
+ end
61
+
62
+ def type
63
+ metadata.fetch("@type", nil)
64
+ end
65
+
66
+ def additional_type
67
+ metadata.fetch("additionalType", nil)
68
+ end
69
+
70
+ def name
71
+ metadata.fetch("name", nil)
72
+ end
73
+
74
+ def alternate_name
75
+ metadata.fetch("alternateName", nil)
76
+ end
77
+
78
+ def author
79
+ Array(metadata.fetch("author", nil)).map { |a| a.except("name") }
80
+ end
81
+
82
+ def description
83
+ metadata.fetch("description", nil)
84
+ end
85
+
86
+ def license
87
+ metadata.fetch("license", nil)
88
+ end
89
+
90
+ def version
91
+ metadata.fetch("version", nil)
92
+ end
93
+
94
+ def keywords
95
+ metadata.fetch("keywords", nil)
96
+ end
97
+
98
+ def date_created
99
+ metadata.fetch("dateCreated", nil)
100
+ end
101
+
102
+ def date_published
103
+ metadata.fetch("datePublished", nil)
104
+ end
105
+
106
+ def date_modified
107
+ metadata.fetch("dateModified", nil)
108
+ end
109
+
110
+ def related_identifiers(relation_type)
111
+ normalize_ids(metadata.fetch(relation_type, nil))
112
+ end
113
+
114
+ def is_part_of
115
+ related_identifiers("isPartOf").first
116
+ end
117
+
118
+ def has_part
119
+ related_identifiers("hasPart")
120
+ end
121
+
122
+ def citation
123
+ related_identifiers("citation")
124
+ end
125
+
126
+ def publisher
127
+ metadata.fetch("publisher", nil)
128
+ end
129
+
130
+ def provider
131
+ metadata.fetch("provider", nil)
132
+ end
133
+
134
+ def as_schema_org
135
+ { "@context" => "http://schema.org",
136
+ "@type" => type,
137
+ "@id" => id,
138
+ "url" => url,
139
+ "name" => name,
140
+ "alternateName" => alternate_name,
141
+ "author" => author,
142
+ "description" => description,
143
+ "license" => license,
144
+ "version" => version,
145
+ "keywords" => keywords,
146
+ "dateCreated" => date_created,
147
+ "datePublished" => date_published,
148
+ "dateModified" => date_modified,
149
+ "isPartOf" => is_part_of,
150
+ "hasPart" => has_part,
151
+ "citation" => citation,
152
+ "publisher" => publisher,
153
+ "provider" => provider
154
+ }.compact
155
+ end
156
+ end
157
+ end