serrano 0.6.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +5 -3
- data/.gitignore +1 -1
- data/CHANGELOG.md +4 -0
- data/Gemfile +1 -1
- data/README.md +2 -1
- data/Rakefile +17 -20
- data/lib/serrano.rb +62 -63
- data/lib/serrano/cn.rb +3 -3
- data/lib/serrano/cnrequest.rb +30 -30
- data/lib/serrano/faraday.rb +11 -11
- data/lib/serrano/filterhandler.rb +20 -20
- data/lib/serrano/filters.rb +67 -67
- data/lib/serrano/request.rb +31 -31
- data/lib/serrano/request_cursor.rb +49 -49
- data/lib/serrano/styles.rb +15 -15
- data/lib/serrano/utils.rb +6 -7
- data/lib/serrano/version.rb +1 -1
- data/serrano.gemspec +34 -34
- metadata +48 -57
- data/.rubocop.yml +0 -50
- data/.rubocop_todo.yml +0 -105
- data/Gemfile.lock +0 -82
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75729f32a4cfabb79a33d78638a91c253fb76a8ec3abc8d9ecc743056464d38d
|
4
|
+
data.tar.gz: 8e47227794125651a8c35450a8f7f5aaa5c377ac461ea2433836d00b76fdb699
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1be1549ce95a4fa7bac8d417f28f9c2d70e800b48f1f7b8c4471cf8461ca37288dd9a2f06c5c15376364e3af4f8d4e61589ad0b4e0f8cdbbd6c1bf46fc170db
|
7
|
+
data.tar.gz: d21603574250c471ea20c3fe7f433d5ef56715307442d8067814757b522306afdca717bbcd612eda4055c1e1b41fc2a8a3f9d340d45dd57127c9a3950b24f70a
|
data/.github/workflows/ruby.yml
CHANGED
@@ -14,6 +14,8 @@ jobs:
|
|
14
14
|
os: [ ubuntu-latest, macos-latest ]
|
15
15
|
ruby: [ 2.5, 2.6, 2.7 ]
|
16
16
|
runs-on: ${{ matrix.os }}
|
17
|
+
env:
|
18
|
+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
17
19
|
steps:
|
18
20
|
- uses: actions/checkout@v2
|
19
21
|
- name: Setup Ruby
|
@@ -23,6 +25,6 @@ jobs:
|
|
23
25
|
- name: Install dependencies
|
24
26
|
run: bundle install
|
25
27
|
- name: Run tests
|
26
|
-
run:
|
27
|
-
|
28
|
-
|
28
|
+
run: |
|
29
|
+
bundle exec rake install
|
30
|
+
bundle exec rake test TESTOPTS="-v"
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -5,10 +5,11 @@ serrano
|
|
5
5
|
[![Ruby](https://github.com/sckott/serrano/workflows/Ruby/badge.svg)](https://github.com/sckott/serrano/actions)
|
6
6
|
[![codecov.io](https://codecov.io/github/sckott/serrano/coverage.svg?branch=master)](https://codecov.io/github/sckott/serrano?branch=master)
|
7
7
|
[![DOI](https://zenodo.org/badge/2600/sckott/serrano.svg)](https://zenodo.org/badge/latestdoi/2600/sckott/serrano)
|
8
|
+
[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
|
8
9
|
|
9
10
|
`serrano` is a low level client for Crossref APIs
|
10
11
|
|
11
|
-
Docs:
|
12
|
+
Docs: https://www.rubydoc.info/gems/serrano
|
12
13
|
|
13
14
|
Other Crossref API clients:
|
14
15
|
|
data/Rakefile
CHANGED
@@ -1,49 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
require "standard"
|
6
|
+
require "standard/rake"
|
6
7
|
|
7
8
|
Rake::TestTask.new do |t|
|
8
|
-
t.libs <<
|
9
|
-
t.test_files = FileList[
|
9
|
+
t.libs << "test"
|
10
|
+
t.test_files = FileList["test/test_*.rb"]
|
10
11
|
t.verbose = true
|
11
12
|
t.warning = false
|
12
13
|
end
|
13
14
|
|
14
|
-
desc
|
15
|
+
desc "Run tests"
|
15
16
|
task default: :test
|
16
17
|
|
17
|
-
|
18
|
-
t.options = ['--display-cop-names']
|
19
|
-
end
|
20
|
-
|
21
|
-
desc 'Build serrano docs'
|
18
|
+
desc "Build serrano docs"
|
22
19
|
task :docs do
|
23
|
-
system
|
20
|
+
system "yardoc"
|
24
21
|
end
|
25
22
|
|
26
|
-
desc
|
23
|
+
desc "bundle install"
|
27
24
|
task :bundle do
|
28
|
-
system
|
25
|
+
system "bundle install"
|
29
26
|
end
|
30
27
|
|
31
|
-
desc
|
28
|
+
desc "clean out builds"
|
32
29
|
task :clean do
|
33
|
-
system
|
30
|
+
system "ls | grep [0-9].gem | xargs rm"
|
34
31
|
end
|
35
32
|
|
36
|
-
desc
|
33
|
+
desc "Build serrano"
|
37
34
|
task :build do
|
38
|
-
system
|
35
|
+
system "gem build serrano.gemspec"
|
39
36
|
end
|
40
37
|
|
41
|
-
desc
|
38
|
+
desc "Install serrano"
|
42
39
|
task install: %i[bundle build] do
|
43
40
|
system "gem install serrano-#{Serrano::VERSION}.gem"
|
44
41
|
end
|
45
42
|
|
46
|
-
desc
|
43
|
+
desc "Release to Rubygems"
|
47
44
|
task release: :build do
|
48
45
|
system "gem push serrano-#{Serrano::VERSION}.gem"
|
49
46
|
end
|
data/lib/serrano.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
|
12
|
-
require
|
13
|
-
require
|
3
|
+
require "erb"
|
4
|
+
require "serrano/version"
|
5
|
+
require "serrano/request"
|
6
|
+
require "serrano/request_cursor"
|
7
|
+
require "serrano/filterhandler"
|
8
|
+
require "serrano/cnrequest"
|
9
|
+
require "serrano/filters"
|
10
|
+
require "serrano/styles"
|
11
|
+
|
12
|
+
require "rexml/document"
|
13
|
+
require "rexml/xpath"
|
14
14
|
|
15
15
|
# @!macro serrano_params
|
16
16
|
# @param offset [Fixnum] Number of record to start at, any non-negative integer up to 10,000
|
@@ -152,8 +152,8 @@ module Serrano
|
|
152
152
|
|
153
153
|
define_setting :access_token
|
154
154
|
define_setting :access_secret
|
155
|
-
define_setting :mailto, ENV[
|
156
|
-
define_setting :base_url,
|
155
|
+
define_setting :mailto, ENV["CROSSREF_EMAIL"]
|
156
|
+
define_setting :base_url, "https://api.crossref.org/"
|
157
157
|
|
158
158
|
##
|
159
159
|
# Search the works route
|
@@ -229,14 +229,14 @@ module Serrano
|
|
229
229
|
# # select certain fields
|
230
230
|
# Serrano.works(select: ['DOI', 'title'], limit: 3)
|
231
231
|
def self.works(ids: nil, query: nil, filter: nil, offset: nil,
|
232
|
-
|
233
|
-
|
234
|
-
|
232
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
233
|
+
select: nil, options: nil, verbose: false, cursor: nil,
|
234
|
+
cursor_max: 5000, **args)
|
235
235
|
|
236
236
|
assert_valid_filters(filter) if filter
|
237
|
-
RequestCursor.new(
|
238
|
-
|
239
|
-
|
237
|
+
RequestCursor.new("works", ids, query, filter, offset,
|
238
|
+
limit, sample, sort, order, facet, select, nil, nil, options,
|
239
|
+
verbose, cursor, cursor_max, args).perform
|
240
240
|
end
|
241
241
|
|
242
242
|
##
|
@@ -286,14 +286,14 @@ module Serrano
|
|
286
286
|
# # select certain fields
|
287
287
|
# Serrano.members(ids: 340, works: true, select: ['DOI', 'title'], limit: 3)
|
288
288
|
def self.members(ids: nil, query: nil, filter: nil, offset: nil,
|
289
|
-
|
290
|
-
|
291
|
-
|
289
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
290
|
+
select: nil, works: false, options: nil, verbose: false,
|
291
|
+
cursor: nil, cursor_max: 5000, **args)
|
292
292
|
|
293
293
|
assert_valid_filters(filter) if filter
|
294
|
-
RequestCursor.new(
|
295
|
-
|
296
|
-
|
294
|
+
RequestCursor.new("members", ids, query, filter, offset,
|
295
|
+
limit, sample, sort, order, facet, select, works, nil,
|
296
|
+
options, verbose, cursor, cursor_max, args).perform
|
297
297
|
end
|
298
298
|
|
299
299
|
##
|
@@ -334,14 +334,14 @@ module Serrano
|
|
334
334
|
# # select certain fields
|
335
335
|
# Serrano.prefixes(ids: "10.1016", works: true, select: ['DOI', 'title'], limit: 3)
|
336
336
|
def self.prefixes(ids:, filter: nil, offset: nil,
|
337
|
-
|
338
|
-
|
339
|
-
|
337
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
338
|
+
select: nil, works: false, options: nil, verbose: false,
|
339
|
+
cursor: nil, cursor_max: 5000, **args)
|
340
340
|
|
341
341
|
assert_valid_filters(filter) if filter
|
342
|
-
RequestCursor.new(
|
343
|
-
|
344
|
-
|
342
|
+
RequestCursor.new("prefixes", ids, nil, filter, offset,
|
343
|
+
limit, sample, sort, order, facet, select, works, nil,
|
344
|
+
options, verbose, cursor, cursor_max, args).perform
|
345
345
|
end
|
346
346
|
|
347
347
|
##
|
@@ -387,14 +387,14 @@ module Serrano
|
|
387
387
|
# # select certain fields
|
388
388
|
# Serrano.funders(ids: "10.13039/100000001", works: true, select: ['DOI', 'title'], limit: 3)
|
389
389
|
def self.funders(ids: nil, query: nil, filter: nil, offset: nil,
|
390
|
-
|
391
|
-
|
392
|
-
|
390
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
391
|
+
select: nil, works: false, options: nil, verbose: false,
|
392
|
+
cursor: nil, cursor_max: 5000, **args)
|
393
393
|
|
394
394
|
assert_valid_filters(filter) if filter
|
395
|
-
RequestCursor.new(
|
396
|
-
|
397
|
-
|
395
|
+
RequestCursor.new("funders", ids, query, filter, offset,
|
396
|
+
limit, sample, sort, order, facet, select, works, nil, options,
|
397
|
+
verbose, cursor, cursor_max, args).perform
|
398
398
|
end
|
399
399
|
|
400
400
|
##
|
@@ -440,14 +440,14 @@ module Serrano
|
|
440
440
|
# # select certain fields
|
441
441
|
# Serrano.journals(ids: "2167-8359", works: true, select: ['DOI', 'title'], limit: 3)
|
442
442
|
def self.journals(ids: nil, query: nil, filter: nil, offset: nil,
|
443
|
-
|
444
|
-
|
445
|
-
|
443
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
444
|
+
select: nil, works: false, options: nil, verbose: false,
|
445
|
+
cursor: nil, cursor_max: 5000, **args)
|
446
446
|
|
447
447
|
assert_valid_filters(filter) if filter
|
448
|
-
RequestCursor.new(
|
449
|
-
|
450
|
-
|
448
|
+
RequestCursor.new("journals", ids, query, filter, offset,
|
449
|
+
limit, sample, sort, order, facet, select, works, nil, options,
|
450
|
+
verbose, cursor, cursor_max, args).perform
|
451
451
|
end
|
452
452
|
|
453
453
|
##
|
@@ -485,11 +485,11 @@ module Serrano
|
|
485
485
|
# # select certain fields
|
486
486
|
# Serrano.types(ids: "journal", works: true, select: ['DOI', 'title'], limit: 3)
|
487
487
|
def self.types(ids: nil, offset: nil, limit: nil, select: nil, works: false,
|
488
|
-
|
488
|
+
options: nil, verbose: false, cursor: nil, cursor_max: 5000, **args)
|
489
489
|
|
490
|
-
RequestCursor.new(
|
491
|
-
|
492
|
-
|
490
|
+
RequestCursor.new("types", ids, nil, nil, offset,
|
491
|
+
limit, nil, nil, nil, nil, select, works, nil, options,
|
492
|
+
verbose, cursor, cursor_max, args).perform
|
493
493
|
end
|
494
494
|
|
495
495
|
##
|
@@ -525,11 +525,11 @@ module Serrano
|
|
525
525
|
# Serrano.licenses()
|
526
526
|
# Serrano.licenses(limit: 3)
|
527
527
|
def self.licenses(query: nil, offset: nil,
|
528
|
-
|
529
|
-
|
528
|
+
limit: nil, sample: nil, sort: nil, order: nil,
|
529
|
+
facet: nil, options: nil, verbose: false)
|
530
530
|
|
531
|
-
Request.new(
|
532
|
-
|
531
|
+
Request.new("licenses", nil, query, nil, offset,
|
532
|
+
limit, sample, sort, order, facet, nil, nil, nil, options, verbose).perform
|
533
533
|
end
|
534
534
|
|
535
535
|
##
|
@@ -544,8 +544,8 @@ module Serrano
|
|
544
544
|
# Serrano.registration_agency(ids: '10.1371/journal.pone.0033693')
|
545
545
|
# Serrano.registration_agency(ids: ['10.1007/12080.1874-1746','10.1007/10452.1573-5125', '10.1111/(issn)1442-9993'])
|
546
546
|
def self.registration_agency(ids:, options: nil, verbose: false)
|
547
|
-
Request.new(
|
548
|
-
|
547
|
+
Request.new("works", ids, nil, nil, nil,
|
548
|
+
nil, nil, nil, nil, nil, nil, false, true, options, verbose).perform
|
549
549
|
end
|
550
550
|
|
551
551
|
##
|
@@ -566,9 +566,9 @@ module Serrano
|
|
566
566
|
# Serrano.random_dois(sample: 10)
|
567
567
|
# Serrano.random_dois(sample: 100)
|
568
568
|
def self.random_dois(sample: 10, options: nil, verbose: false)
|
569
|
-
tmp = Request.new(
|
570
|
-
|
571
|
-
tmp[
|
569
|
+
tmp = Request.new("works", nil, nil, nil, nil,
|
570
|
+
nil, sample, nil, nil, nil, nil, false, nil, options, verbose).perform
|
571
|
+
tmp["message"]["items"].collect { |x| x["DOI"] }
|
572
572
|
end
|
573
573
|
|
574
574
|
##
|
@@ -631,7 +631,7 @@ module Serrano
|
|
631
631
|
# '10.5167/UZH-38402','10.5167/UZH-41217']
|
632
632
|
# x = Serrano.content_negotiation(ids: dois)
|
633
633
|
# puts x
|
634
|
-
def self.content_negotiation(ids:, format:
|
634
|
+
def self.content_negotiation(ids:, format: "bibtex", style: "apa", locale: "en-US")
|
635
635
|
ids = Array(ids).map { |x| ERB::Util.url_encode(x) }
|
636
636
|
CNRequest.new(ids, format, style, locale).perform
|
637
637
|
end
|
@@ -651,17 +651,16 @@ module Serrano
|
|
651
651
|
# Serrano.citation_count(doi: "10.1016/j.fbr.2012.01.001")
|
652
652
|
# # DOI not found
|
653
653
|
# Serrano.citation_count(doi: "10.1016/j.fbr.2012")
|
654
|
-
def self.citation_count(doi:, url:
|
655
|
-
|
654
|
+
def self.citation_count(doi:, url: "https://www.crossref.org/openurl/",
|
655
|
+
key: "cboettig@ropensci.org", options: nil)
|
656
656
|
|
657
|
-
args = {
|
657
|
+
args = {id: "doi:" + doi, pid: key, noredirect: true}
|
658
658
|
opts = args.delete_if { |_k, v| v.nil? }
|
659
659
|
conn = Faraday.new(url: url, request: options)
|
660
|
-
res = conn.get
|
660
|
+
res = conn.get "", opts
|
661
661
|
x = res.body
|
662
662
|
oc = REXML::Document.new("<doc>#{x}</doc>")
|
663
|
-
|
664
|
-
value
|
663
|
+
REXML::XPath.first(oc, "//query").attributes["fl_count"].to_i
|
665
664
|
end
|
666
665
|
|
667
666
|
# Get csl styles
|
data/lib/serrano/cn.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "serrano/version"
|
4
|
+
require "serrano/cnrequest"
|
5
5
|
|
6
6
|
##
|
7
7
|
# ContentNegotiation - Content Negotiation class
|
@@ -14,7 +14,7 @@ module Serrano
|
|
14
14
|
attr_accessor :style
|
15
15
|
attr_accessor :locale
|
16
16
|
|
17
|
-
def initialize(ids, format =
|
17
|
+
def initialize(ids, format = "bibtex", style = "apa", locale = "en-US")
|
18
18
|
self.ids = ids
|
19
19
|
self.format = format
|
20
20
|
self.style = style
|
data/lib/serrano/cnrequest.rb
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
3
|
+
require "faraday"
|
4
|
+
require "faraday_middleware"
|
5
|
+
require "multi_json"
|
6
|
+
require "serrano/error"
|
7
|
+
require "serrano/utils"
|
8
|
+
require "serrano/helpers/configuration"
|
9
9
|
|
10
|
-
CN_FORMAT_HEADERS = {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
10
|
+
CN_FORMAT_HEADERS = {"rdf-xml" => "application/rdf+xml",
|
11
|
+
"turtle" => "text/turtle",
|
12
|
+
"citeproc-json" => "transform/application/vnd.citationstyles.csl+json",
|
13
|
+
"text" => "text/x-bibliography",
|
14
|
+
"ris" => "application/x-research-info-systems",
|
15
|
+
"bibtex" => "application/x-bibtex",
|
16
|
+
"crossref-xml" => "application/vnd.crossref.unixref+xml",
|
17
|
+
"datacite-xml" => "application/vnd.datacite.datacite+xml",
|
18
|
+
"bibentry" => "application/x-bibtex",
|
19
|
+
"crossref-tdm" => "application/vnd.crossref.unixsd+xml"}.freeze
|
20
20
|
|
21
21
|
##
|
22
22
|
# Serrano::CNRequest
|
@@ -30,9 +30,9 @@ module Serrano
|
|
30
30
|
attr_accessor :locale
|
31
31
|
|
32
32
|
CN_FORMATS = %w[rdf-xml turtle citeproc-json
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
citeproc-json-ish text ris bibtex
|
34
|
+
crossref-xml datacite-xml bibentry
|
35
|
+
crossref-tdm].freeze
|
36
36
|
|
37
37
|
def initialize(ids, format, style, locale)
|
38
38
|
self.ids = ids
|
@@ -43,10 +43,10 @@ module Serrano
|
|
43
43
|
|
44
44
|
def perform
|
45
45
|
unless CN_FORMATS.include? format
|
46
|
-
raise
|
46
|
+
raise "format not one of accepted types"
|
47
47
|
end
|
48
48
|
|
49
|
-
conn = Faraday.new
|
49
|
+
conn = Faraday.new "https://doi.org/" do |c|
|
50
50
|
c.use FaradayMiddleware::FollowRedirects
|
51
51
|
c.adapter :net_http
|
52
52
|
end
|
@@ -68,23 +68,23 @@ end
|
|
68
68
|
def make_request(conn, ids, format, style, locale)
|
69
69
|
type = CN_FORMAT_HEADERS.select { |x, _| x.include? format }.values[0]
|
70
70
|
|
71
|
-
if format ==
|
72
|
-
endpt =
|
71
|
+
if format == "citeproc-json"
|
72
|
+
endpt = "https://api.crossref.org/works/" + ids + "/" + type
|
73
73
|
cr_works = Faraday.new(url: endpt)
|
74
74
|
cr_works.headers[:user_agent] = make_ua
|
75
|
-
cr_works.headers[
|
75
|
+
cr_works.headers["X-USER-AGENT"] = make_ua
|
76
76
|
res = cr_works.get
|
77
77
|
else
|
78
|
-
if format ==
|
79
|
-
type = type +
|
78
|
+
if format == "text"
|
79
|
+
type = type + "; style = " + style + "; locale = " + locale
|
80
80
|
end
|
81
81
|
|
82
|
-
res = conn.get
|
82
|
+
res = conn.get { |req|
|
83
83
|
req.url ids
|
84
|
-
req.headers[
|
84
|
+
req.headers["Accept"] = type
|
85
85
|
req.headers[:user_agent] = make_ua
|
86
|
-
req.headers[
|
87
|
-
|
86
|
+
req.headers["X-USER-AGENT"] = make_ua
|
87
|
+
}
|
88
88
|
end
|
89
89
|
|
90
90
|
res.body
|