serrano 1.0.0 → 1.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 75729f32a4cfabb79a33d78638a91c253fb76a8ec3abc8d9ecc743056464d38d
4
- data.tar.gz: 8e47227794125651a8c35450a8f7f5aaa5c377ac461ea2433836d00b76fdb699
3
+ metadata.gz: 8b5e125bb4a2745b6dbf520ad692df6817c0e2dc7d6db1ed307bdee243e9c501
4
+ data.tar.gz: 680c37e478abc9c5213ea7a6db288a3afa9e9f71140e796a7fc5cdb88ef27517
5
5
  SHA512:
6
- metadata.gz: a1be1549ce95a4fa7bac8d417f28f9c2d70e800b48f1f7b8c4471cf8461ca37288dd9a2f06c5c15376364e3af4f8d4e61589ad0b4e0f8cdbbd6c1bf46fc170db
7
- data.tar.gz: d21603574250c471ea20c3fe7f433d5ef56715307442d8067814757b522306afdca717bbcd612eda4055c1e1b41fc2a8a3f9d340d45dd57127c9a3950b24f70a
6
+ metadata.gz: 82e9496fa1a0737ef3f491f199792c9b8e99a7c90d285a340108014e4a877ab8e38f79bde1d9a95f9999cef262e642a099f433a1ec2441537d677c6ec4ab1b58
7
+ data.tar.gz: 5ab1e3c2900d546894d0798014cd649b6b5d35e07c69b16565158fa7a4492c8dbdc13be81a7414517395be42b409875b309e232e95d80571398e7f0c0e597873
@@ -0,0 +1,22 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ time: "13:00"
8
+ open-pull-requests-limit: 10
9
+ ignore:
10
+ - dependency-name: codecov
11
+ versions:
12
+ - "> 0.1.17, < 0.2"
13
+ - dependency-name: codecov
14
+ versions:
15
+ - "> 0.2.1, < 0.3"
16
+ - dependency-name: codecov
17
+ versions:
18
+ - 0.4.2
19
+ - 0.4.3
20
+ - dependency-name: simplecov
21
+ versions:
22
+ - 0.20.0
@@ -2,29 +2,29 @@ name: Ruby
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [ master ]
5
+ branches: [main]
6
6
  pull_request:
7
- branches: [ master ]
7
+ branches: [main]
8
8
 
9
9
  jobs:
10
10
  test:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
14
- os: [ ubuntu-latest, macos-latest ]
15
- ruby: [ 2.5, 2.6, 2.7 ]
16
- runs-on: ${{ matrix.os }}
14
+ ruby: [3.0, 3.1, 3.2, 3.3, 3.4]
15
+ runs-on: ubuntu-latest
17
16
  env:
18
17
  CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
19
18
  steps:
20
- - uses: actions/checkout@v2
21
- - name: Setup Ruby
22
- uses: ruby/setup-ruby@v1
23
- with:
24
- ruby-version: ${{ matrix.ruby }}
25
- - name: Install dependencies
26
- run: bundle install
27
- - name: Run tests
28
- run: |
29
- bundle exec rake install
30
- bundle exec rake test TESTOPTS="-v"
19
+ - uses: actions/checkout@v4
20
+ - name: Setup Ruby
21
+ uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: ${{ matrix.ruby }}
24
+ bundler-cache: true
25
+ - name: Install dependencies
26
+ run: bundle install
27
+ - name: Run tests
28
+ run: |
29
+ bundle exec rake install
30
+ bundle exec rake test TESTOPTS="-v"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 1.6 (2025-06-17)
2
+
3
+ * Fixed filter handling so that the same filter can be used multiple times (#176)
4
+
5
+ ## 1.4 (2022-03-26)
6
+
7
+ * Moved to faraday > v2. There's no user facing changes here, but let me know if any issues arise (#172)
8
+ * PR by @LocoDelAssembly fixes `Serrano.content_negotiation(format: "citeproc-json")` by having it return `nil` instead of `Resource not found` when no DOI is found, so that the output is more compatible with flows that use serrano to create JSON (#169)
9
+ * PR by @xuanxu adds `REXML` as a runtime dependency (#159)
10
+
1
11
  ## 1.0.0 (2020-10-19)
2
12
 
3
13
  * updated dependency versions
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (C) 2020 Scott Chamberlain
1
+ Copyright (C) 2025 Scott Chamberlain
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
data/README.md CHANGED
@@ -2,21 +2,21 @@ serrano
2
2
  =========
3
3
 
4
4
  [![gem version](https://img.shields.io/gem/v/serrano.svg)](https://rubygems.org/gems/serrano)
5
- [![Ruby](https://github.com/sckott/serrano/workflows/Ruby/badge.svg)](https://github.com/sckott/serrano/actions)
6
- [![codecov.io](https://codecov.io/github/sckott/serrano/coverage.svg?branch=master)](https://codecov.io/github/sckott/serrano?branch=master)
7
- [![DOI](https://zenodo.org/badge/2600/sckott/serrano.svg)](https://zenodo.org/badge/latestdoi/2600/sckott/serrano)
5
+ [![Ruby](https://github.com/sckott/serrano/actions/workflows/ruby.yml/badge.svg)](https://github.com/sckott/serrano/actions/workflows/ruby.yml)
6
+ [![codecov.io](https://codecov.io/github/sckott/serrano/coverage.svg?branch=main)](https://codecov.io/github/sckott/serrano?branch=main)
7
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6386581.svg)](https://zenodo.org/badge/latestdoi/2600/sckott/serrano)
8
8
  [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
9
9
 
10
10
  `serrano` is a low level client for Crossref APIs
11
11
 
12
- Docs: https://www.rubydoc.info/gems/serrano
12
+ Docs: <https://www.rubydoc.info/gems/serrano>
13
13
 
14
14
  Other Crossref API clients:
15
15
 
16
16
  - Python: [habanero](https://github.com/sckott/habanero)
17
17
  - R: [rcrossref](https://github.com/ropensci/rcrossref)
18
18
 
19
- Crossref's API issue tracker: https://gitlab.com/crossref/issues
19
+ Crossref's API issue tracker: <https://crossref.atlassian.net/jira/software/c/projects/CR/issues>
20
20
 
21
21
  ## Changes
22
22
 
@@ -47,7 +47,7 @@ Other methods:
47
47
 
48
48
  Note about searching:
49
49
 
50
- You are using the Crossref search API described at https://github.com/CrossRef/rest-api-doc When you search with query terms, on Crossref servers they are not searching full text, or even abstracts of articles, but only what is available in the data that is returned to you. That is, they search article titles, authors, etc. For some discussion on this, see https://gitlab.com/crossref/issues/issues/101
50
+ You are using the Crossref search API described at https://api.crossref.org When you search with query terms, on Crossref servers they are not searching full text, or even abstracts of articles, but only what is available in the data that is returned to you. That is, they search article titles, authors, etc. For some discussion on this, see https://gitlab.com/crossref/issues/issues/101
51
51
 
52
52
  Rate limits:
53
53
 
@@ -184,6 +184,8 @@ Commands:
184
184
 
185
185
  # Many DOIs
186
186
  ~$ serrano works "10.1007/12080.1874-1746,10.1007/10452.1573-5125"
187
+ ## if above two dois in a file called dois.txt
188
+ ~$ cat dois.txt | xargs -I{} serrano works {}
187
189
 
188
190
  # output JSON, then parse with e.g., jq
189
191
  ~$ serrano works --filter=has_orcid:true --json --limit=2 | jq '.message.items[].author[].ORCID | select(. != null)'
@@ -194,9 +196,8 @@ Commands:
194
196
  * Please note that this project is released with a [Contributor Code of Conduct](CONDUCT.md). By participating in this project you agree to abide by its terms.
195
197
  * License: MIT
196
198
 
197
- [crapi]: https://github.com/CrossRef/rest-api-doc/blob/master/rest_api.md
199
+ [crapi]: https://api.crossref.org/
198
200
  [cn]: https://citation.crosscite.org/docs.html
199
- [tdm]: https://www.crossref.org/education/retrieve-metadata/rest-api/text-and-data-mining/
200
- [ccount]: https://labs.crossref.org/openurl/
201
+ [ccount]: https://www.crossref.org/documentation/retrieve-metadata/openurl/
201
202
  [csl]: https://github.com/citation-style-language/styles
202
- [changelog]: https://github.com/sckott/serrano/blob/master/CHANGELOG.md
203
+ [changelog]: https://github.com/sckott/serrano/blob/main/CHANGELOG.md
data/Rakefile CHANGED
@@ -44,3 +44,8 @@ desc "Release to Rubygems"
44
44
  task release: :build do
45
45
  system "gem push serrano-#{Serrano::VERSION}.gem"
46
46
  end
47
+
48
+ desc "open an irb session preloaded with this gem"
49
+ task :console do
50
+ sh "irb -r pp -r ./lib/serrano.rb"
51
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "faraday"
4
- require "faraday_middleware"
4
+ require "faraday/follow_redirects"
5
5
  require "multi_json"
6
6
  require "serrano/error"
7
7
  require "serrano/utils"
@@ -23,7 +23,7 @@ CN_FORMAT_HEADERS = {"rdf-xml" => "application/rdf+xml",
23
23
  #
24
24
  # Class to perform HTTP requests to the Crossref API
25
25
  module Serrano
26
- class CNRequest #:nodoc:
26
+ class CNRequest # :nodoc:
27
27
  attr_accessor :ids
28
28
  attr_accessor :format
29
29
  attr_accessor :style
@@ -47,12 +47,12 @@ module Serrano
47
47
  end
48
48
 
49
49
  conn = Faraday.new "https://doi.org/" do |c|
50
- c.use FaradayMiddleware::FollowRedirects
50
+ c.use Faraday::FollowRedirects::Middleware
51
51
  c.adapter :net_http
52
52
  end
53
53
 
54
54
  if ids.length == 1
55
- self.ids = ids[0] if ids.class == Array
55
+ self.ids = ids[0] if ids.instance_of?(Array)
56
56
  make_request(conn, ids, format, style, locale)
57
57
  else
58
58
  coll = []
@@ -87,19 +87,5 @@ def make_request(conn, ids, format, style, locale)
87
87
  }
88
88
  end
89
89
 
90
- res.body
90
+ res.body if res.success?
91
91
  end
92
-
93
- # parser <- cn_types[[self.format]]
94
- # if (raw) {
95
- # content(response, "text")
96
- # } else {
97
- # out <- content(response, "parsed", parser, "UTF-8")
98
- # if (format == "text") {
99
- # out <- gsub("\n", "", out)
100
- # }
101
- # if (format == "bibentry") {
102
- # out <- parse_bibtex(out)
103
- # }
104
- # out
105
- # }
@@ -4,69 +4,71 @@ require "faraday"
4
4
  require "multi_json"
5
5
 
6
6
  # @private
7
- module FaradayMiddleware
8
- # @private
9
- class RaiseHttpException < Faraday::Middleware
10
- def call(env)
11
- @app.call(env).on_complete do |response|
12
- case response[:status].to_i
13
- when 400
14
- raise Serrano::BadRequest, error_message_400(response)
15
- when 404
16
- raise Serrano::NotFound, error_message_400(response)
17
- when 500
18
- raise Serrano::InternalServerError, error_message_500(response, "Something is technically wrong.")
19
- when 502
20
- raise Serrano::BadGateway, error_message_500(response, "The server returned an invalid or incomplete response.")
21
- when 503
22
- raise Serrano::ServiceUnavailable, error_message_500(response, "Crossref is rate limiting your requests.")
23
- when 504
24
- raise Serrano::GatewayTimeout, error_message_500(response, "504 Gateway Time-out")
7
+ module Faraday
8
+ module SerranoErrors
9
+ # @private
10
+ class Middleware < Faraday::Middleware
11
+ def call(env)
12
+ @app.call(env).on_complete do |response|
13
+ case response[:status].to_i
14
+ when 400
15
+ raise Serrano::BadRequest, error_message_400(response)
16
+ when 404
17
+ raise Serrano::NotFound, error_message_400(response)
18
+ when 500
19
+ raise Serrano::InternalServerError, error_message_500(response, "Something is technically wrong.")
20
+ when 502
21
+ raise Serrano::BadGateway, error_message_500(response, "The server returned an invalid or incomplete response.")
22
+ when 503
23
+ raise Serrano::ServiceUnavailable, error_message_500(response, "Crossref is rate limiting your requests.")
24
+ when 504
25
+ raise Serrano::GatewayTimeout, error_message_500(response, "504 Gateway Time-out")
26
+ end
25
27
  end
26
28
  end
27
- end
28
29
 
29
- def initialize(app)
30
- super app
31
- @parser = nil
32
- end
30
+ def initialize(app)
31
+ super
32
+ @parser = nil
33
+ end
33
34
 
34
- private
35
+ private
35
36
 
36
- def error_message_400(response)
37
- "\n #{response[:method].to_s.upcase} #{response[:url]}\n Status #{response[:status]}#{error_body(response[:body])}"
38
- end
37
+ def error_message_400(response)
38
+ "\n #{response[:method].to_s.upcase} #{response[:url]}\n Status #{response[:status]}#{error_body(response[:body])}"
39
+ end
39
40
 
40
- def error_body(body)
41
- if !body.nil? && !body.empty? && body.is_a?(String)
42
- if json?(body)
43
- body = ::MultiJson.load(body)
44
- if body["message"].nil?
45
- body = nil
46
- elseif body["message"].length == 1
47
- body = body["message"]
48
- else
49
- body = body["message"].collect { |x| x["message"] }.join("; ")
41
+ def error_body(body)
42
+ if !body.nil? && !body.empty? && body.is_a?(String)
43
+ if json?(body)
44
+ body = ::MultiJson.load(body)
45
+ if body["message"].nil?
46
+ body = nil
47
+ elseif body["message"].length == 1
48
+ body = body["message"]
49
+ else
50
+ body = body["message"].collect { |x| x["message"] }.join("; ")
51
+ end
50
52
  end
51
53
  end
52
- end
53
54
 
54
- if body.nil?
55
- nil
56
- else
57
- ": #{body}"
55
+ if body.nil?
56
+ nil
57
+ else
58
+ ": #{body}"
59
+ end
58
60
  end
59
- end
60
61
 
61
- def error_message_500(response, body = nil)
62
- "#{response[:method].to_s.upcase} #{response[:url]}: #{[response[:status].to_s + ":", body].compact.join(" ")}"
63
- end
62
+ def error_message_500(response, body = nil)
63
+ "#{response[:method].to_s.upcase} #{response[:url]}: #{[response[:status].to_s + ":", body].compact.join(" ")}"
64
+ end
64
65
 
65
- def json?(string)
66
- MultiJson.load(string)
67
- true
68
- rescue MultiJson::ParseError
69
- false
66
+ def json?(string)
67
+ MultiJson.load(string)
68
+ true
69
+ rescue MultiJson::ParseError
70
+ false
71
+ end
70
72
  end
71
73
  end
72
74
  end
@@ -37,8 +37,13 @@ module Helpers
37
37
 
38
38
  newnn = nn.collect { |m| m.tr("_", "-") }
39
39
  x = rename_keys(x, newnn)
40
- x.collect { |k, v| [k, v].join(":") }.join(",")
41
-
40
+ x.collect { |k, v|
41
+ if v.is_a?(Array)
42
+ v.map { |val| [k, val].join(":") }
43
+ else
44
+ [k, v].join(":")
45
+ end
46
+ }.join(",")
42
47
  end
43
48
  end
44
49
 
@@ -52,11 +57,11 @@ module Helpers
52
57
  end
53
58
 
54
59
  module Serrano
55
- class Request #:nodoc:
60
+ class Request # :nodoc:
56
61
  include Helpers
57
62
  end
58
63
 
59
- class RequestCursor #:nodoc:
64
+ class RequestCursor # :nodoc:
60
65
  include Helpers
61
66
  end
62
67
  end
@@ -12,7 +12,7 @@ require "serrano/helpers/configuration"
12
12
  #
13
13
  # Class to perform HTTP requests to the Crossref API
14
14
  module Serrano
15
- class Request #:nodoc:
15
+ class Request # :nodoc:
16
16
  attr_accessor :endpt
17
17
  attr_accessor :id
18
18
  attr_accessor :query
@@ -32,7 +32,6 @@ module Serrano
32
32
  def initialize(endpt, id, query, filter, offset,
33
33
  limit, sample, sort, order, facet, select,
34
34
  works, agency, options, verbose)
35
-
36
35
  self.endpt = endpt
37
36
  self.id = id
38
37
  self.query = query
@@ -53,24 +52,21 @@ module Serrano
53
52
  def perform
54
53
  filt = filter_handler(filter)
55
54
 
56
- self.select = select.join(",") if select && select.class == Array
55
+ self.select = select&.instance_of?(Array) ? select.join(",") : select
57
56
 
58
- args = {query: query, filter: filt, offset: offset,
59
- rows: limit, sample: sample, sort: sort,
60
- order: order, facet: facet,
57
+ args = {query: query, filter: filt, offset: offset, rows: limit,
58
+ sample: sample, sort: sort, order: order, facet: facet,
61
59
  select: select}
62
60
  opts = args.delete_if { |_k, v| v.nil? }
63
61
 
64
62
  conn = if verbose
65
- Faraday.new(url: Serrano.base_url, request: options || []) do |f|
63
+ Faraday.new(url: Serrano.base_url, request: options || {}) do |f|
66
64
  f.response :logger
67
- f.use FaradayMiddleware::RaiseHttpException
68
- f.adapter Faraday.default_adapter
65
+ f.use Faraday::SerranoErrors::Middleware
69
66
  end
70
67
  else
71
- Faraday.new(url: Serrano.base_url, request: options || []) do |f|
72
- f.use FaradayMiddleware::RaiseHttpException
73
- f.adapter Faraday.default_adapter
68
+ Faraday.new(url: Serrano.base_url, request: options || {}) do |f|
69
+ f.use Faraday::SerranoErrors::Middleware
74
70
  end
75
71
  end
76
72
 
@@ -2,12 +2,10 @@
2
2
 
3
3
  require "erb"
4
4
  require "faraday"
5
- require "faraday_middleware"
6
5
  require "multi_json"
7
6
  require "serrano/error"
8
7
  require "serrano/helpers/configuration"
9
8
  require "serrano/filterhandler"
10
- require "serrano/error"
11
9
  require "serrano/faraday"
12
10
  require "serrano/utils"
13
11
 
@@ -16,7 +14,7 @@ require "serrano/utils"
16
14
  #
17
15
  # Class to perform HTTP requests to the Crossref API
18
16
  module Serrano
19
- class RequestCursor #:nodoc:
17
+ class RequestCursor # :nodoc:
20
18
  attr_accessor :endpt
21
19
  attr_accessor :id
22
20
  attr_accessor :query
@@ -40,7 +38,6 @@ module Serrano
40
38
  limit, sample, sort, order, facet, select,
41
39
  works, agency, options, verbose, cursor,
42
40
  cursor_max, args)
43
-
44
41
  self.endpt = endpt
45
42
  self.id = id
46
43
  self.query = query
@@ -64,7 +61,7 @@ module Serrano
64
61
  def perform
65
62
  filt = filter_handler(filter)
66
63
  fieldqueries = field_query_handler(args)
67
- self.select = select.join(",") if select && select.class == Array
64
+ self.select = select&.instance_of?(Array) ? select.join(",") : select
68
65
 
69
66
  unless cursor_max.class.nil?
70
67
  raise "cursor_max must be of class int" unless cursor_max.is_a?(Integer)
@@ -78,15 +75,13 @@ module Serrano
78
75
  opts = arguments.delete_if { |_k, v| v.nil? }
79
76
 
80
77
  conn = if verbose
81
- Faraday.new(url: Serrano.base_url, request: options || []) do |f|
78
+ Faraday.new(url: Serrano.base_url, request: options || {}) do |f|
82
79
  f.response :logger
83
- f.use FaradayMiddleware::RaiseHttpException
84
- f.adapter Faraday.default_adapter
80
+ f.use Faraday::SerranoErrors::Middleware
85
81
  end
86
82
  else
87
- Faraday.new(url: Serrano.base_url, request: options || []) do |f|
88
- f.use FaradayMiddleware::RaiseHttpException
89
- f.adapter Faraday.default_adapter
83
+ Faraday.new(url: Serrano.base_url, request: options || {}) do |f|
84
+ f.use Faraday::SerranoErrors::Middleware
90
85
  end
91
86
  end
92
87
 
@@ -98,7 +93,7 @@ module Serrano
98
93
  js = _req(conn, endpt, opts)
99
94
  cu = js["message"]["next-cursor"]
100
95
  max_avail = js["message"]["total-results"]
101
- _redo_req(conn, js, opts, cu, max_avail)
96
+ _redo_req(conn, js, opts, cu, max_avail, endpt2)
102
97
 
103
98
  else
104
99
  self.id = Array(id)
@@ -119,13 +114,13 @@ module Serrano
119
114
  js = _req(conn, endpt2, opts)
120
115
  cu = js["message"]["next-cursor"]
121
116
  max_avail = js["message"]["total-results"]
122
- coll << _redo_req(conn, js, opts, cu, max_avail)
117
+ coll << _redo_req(conn, js, opts, cu, max_avail, endpt2)
123
118
  end
124
119
  coll
125
120
  end
126
121
  end
127
122
 
128
- def _redo_req(conn, js, opts, cu, max_avail)
123
+ def _redo_req(conn, js, opts, cu, max_avail, endpt2)
129
124
  if !cu.nil? && (cursor_max > js["message"]["items"].length)
130
125
  res = [js]
131
126
  total = js["message"]["items"].length
@@ -6,8 +6,8 @@ require "multi_json"
6
6
  def fetch_styles
7
7
  base = "https://api.github.com/repos/citation-style-language/styles"
8
8
  conn = Faraday.new(url: base) { |f|
9
- f.use FaradayMiddleware::RaiseHttpException
10
- f.adapter Faraday.default_adapter
9
+ f.use Faraday::Response::RaiseError
10
+ # f.adapter Faraday.default_adapter
11
11
  }
12
12
  args = {per_page: 1}
13
13
  tt = conn.get "commits", args
data/lib/serrano/utils.rb CHANGED
@@ -24,12 +24,12 @@ end
24
24
 
25
25
  class Hash
26
26
  def tostrings
27
- Hash[map { |(k, v)| [k.to_s, v] }]
27
+ map { |(k, v)| [k.to_s, v] }.to_h
28
28
  end
29
29
  end
30
30
 
31
31
  class Hash
32
32
  def tosymbols
33
- Hash[map { |(k, v)| [k.to_sym, v] }]
33
+ map { |(k, v)| [k.to_sym, v] }.to_h
34
34
  end
35
35
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Serrano
4
- VERSION = "1.0.0"
4
+ VERSION = "1.6"
5
5
  end
data/lib/serrano.rb CHANGED
@@ -42,8 +42,7 @@ require "rexml/xpath"
42
42
  # @param cursor [String] Cursor character string to do deep paging. Default is `nil`.
43
43
  # Pass in '*' to start deep paging. Any combination of query, filters and facets may be
44
44
  # used with deep paging cursors. While limit may be specified along with cursor, offset
45
- # and sample cannot be used. See
46
- # https://github.com/CrossRef/rest-api-doc/blob/master/rest_api.md#deep-paging-with-cursors
45
+ # and sample cannot be used. See https://api.crossref.org/
47
46
  # @param cursor_max [Fixnum] Max records to retrieve. Only used when cursor
48
47
  # param used. Because deep paging can result in continuous requests until all
49
48
  # are retrieved, use this parameter to set a maximum number of records. Of course,
@@ -63,8 +62,7 @@ require "rexml/xpath"
63
62
  # - oauth [Hash] A hash with OAuth details
64
63
 
65
64
  # @!macro field_queries
66
- # @param [Hash<Object>] args Field queries, as named parameters. See
67
- # https://github.com/CrossRef/rest-api-doc/blob/master/rest_api.md#field-queries
65
+ # @param [Hash<Object>] args Field queries, as named parameters. See https://api.crossref.org/
68
66
  # Field query parameters mut be named, and must start with `query_`. Any dashes or
69
67
  # periods should be replaced with underscores. The options include:
70
68
  # - query_container_title: Query container-title aka. publication name
@@ -99,18 +97,16 @@ require "rexml/xpath"
99
97
  # For example, if you want to inspect headers returned from the HTTP request,
100
98
  # and parse the raw result in any way you wish.
101
99
  #
102
- # @see https://github.com/CrossRef/rest-api-doc/blob/master/rest_api.md for
103
- # detailed description of the Crossref API
100
+ # @see https://api.crossref.org for detailed description of the Crossref API
104
101
  #
105
102
  # What am I actually searching when using the Crossref search API?
106
103
  #
107
- # You are using the Crossref search API described at
108
- # https://github.com/CrossRef/rest-api-doc/blob/master/rest_api.md.
104
+ # You are using the Crossref search API described at https://api.crossref.org
109
105
  # When you search with query terms, on Crossref servers they are not
110
106
  # searching full text, or even abstracts of articles, but only what is
111
107
  # available in the data that is returned to you. That is, they search
112
108
  # article titles, authors, etc. For some discussion on this, see
113
- # https://gitlab.com/crossref/issues/issues/101
109
+ # https://gitlab.com/crossref/issues/-/issues/101
114
110
  #
115
111
  #
116
112
  # The Polite Pool
@@ -232,7 +228,6 @@ module Serrano
232
228
  limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
233
229
  select: nil, options: nil, verbose: false, cursor: nil,
234
230
  cursor_max: 5000, **args)
235
-
236
231
  assert_valid_filters(filter) if filter
237
232
  RequestCursor.new("works", ids, query, filter, offset,
238
233
  limit, sample, sort, order, facet, select, nil, nil, options,
@@ -289,7 +284,6 @@ module Serrano
289
284
  limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
290
285
  select: nil, works: false, options: nil, verbose: false,
291
286
  cursor: nil, cursor_max: 5000, **args)
292
-
293
287
  assert_valid_filters(filter) if filter
294
288
  RequestCursor.new("members", ids, query, filter, offset,
295
289
  limit, sample, sort, order, facet, select, works, nil,
@@ -337,7 +331,6 @@ module Serrano
337
331
  limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
338
332
  select: nil, works: false, options: nil, verbose: false,
339
333
  cursor: nil, cursor_max: 5000, **args)
340
-
341
334
  assert_valid_filters(filter) if filter
342
335
  RequestCursor.new("prefixes", ids, nil, filter, offset,
343
336
  limit, sample, sort, order, facet, select, works, nil,
@@ -390,7 +383,6 @@ module Serrano
390
383
  limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
391
384
  select: nil, works: false, options: nil, verbose: false,
392
385
  cursor: nil, cursor_max: 5000, **args)
393
-
394
386
  assert_valid_filters(filter) if filter
395
387
  RequestCursor.new("funders", ids, query, filter, offset,
396
388
  limit, sample, sort, order, facet, select, works, nil, options,
@@ -443,7 +435,6 @@ module Serrano
443
435
  limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
444
436
  select: nil, works: false, options: nil, verbose: false,
445
437
  cursor: nil, cursor_max: 5000, **args)
446
-
447
438
  assert_valid_filters(filter) if filter
448
439
  RequestCursor.new("journals", ids, query, filter, offset,
449
440
  limit, sample, sort, order, facet, select, works, nil, options,
@@ -486,7 +477,6 @@ module Serrano
486
477
  # Serrano.types(ids: "journal", works: true, select: ['DOI', 'title'], limit: 3)
487
478
  def self.types(ids: nil, offset: nil, limit: nil, select: nil, works: false,
488
479
  options: nil, verbose: false, cursor: nil, cursor_max: 5000, **args)
489
-
490
480
  RequestCursor.new("types", ids, nil, nil, offset,
491
481
  limit, nil, nil, nil, nil, select, works, nil, options,
492
482
  verbose, cursor, cursor_max, args).perform
@@ -527,7 +517,6 @@ module Serrano
527
517
  def self.licenses(query: nil, offset: nil,
528
518
  limit: nil, sample: nil, sort: nil, order: nil,
529
519
  facet: nil, options: nil, verbose: false)
530
-
531
520
  Request.new("licenses", nil, query, nil, offset,
532
521
  limit, sample, sort, order, facet, nil, nil, nil, options, verbose).perform
533
522
  end
@@ -643,7 +632,8 @@ module Serrano
643
632
  # @param url [String] the API url for the function (should be left to default)
644
633
  # @param key [String] your API key
645
634
  #
646
- # @see http://labs.crossref.org/openurl/ for more info on this Crossref API service.
635
+ # @see https://www.crossref.org/documentation/retrieve-metadata/openurl/ for
636
+ # more info on this Crossref API service.
647
637
  #
648
638
  # @example
649
639
  # require 'serrano'
@@ -653,7 +643,6 @@ module Serrano
653
643
  # Serrano.citation_count(doi: "10.1016/j.fbr.2012")
654
644
  def self.citation_count(doi:, url: "https://www.crossref.org/openurl/",
655
645
  key: "cboettig@ropensci.org", options: nil)
656
-
657
646
  args = {id: "doi:" + doi, pid: key, noredirect: true}
658
647
  opts = args.delete_if { |_k, v| v.nil? }
659
648
  conn = Faraday.new(url: url, request: options)
data/serrano.gemspec CHANGED
@@ -8,8 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.name = "serrano"
9
9
  s.version = Serrano::VERSION
10
10
  s.platform = Gem::Platform::RUBY
11
- s.required_ruby_version = ">= 2.1"
12
- s.date = "2020-10-19"
11
+ s.required_ruby_version = ">= 3.0"
13
12
  s.summary = "Crossref Client"
14
13
  s.description = "Low Level Ruby Client for the Crossref Search API"
15
14
  s.authors = "Scott Chamberlain"
@@ -25,20 +24,21 @@ Gem::Specification.new do |s|
25
24
  s.bindir = "bin"
26
25
  s.executables = ["serrano"]
27
26
 
28
- s.add_development_dependency "bundler", '~> 2.1', '>= 2.1.4'
29
- s.add_development_dependency "codecov", "~> 0.2.0"
30
- s.add_development_dependency "json", '~> 2.3', '>= 2.3.1'
31
- s.add_development_dependency "rake", '~> 13.0', '>= 13.0.1'
32
- s.add_development_dependency "standard", "~> 0.7"
33
- s.add_development_dependency "simplecov", "~> 0.19.0"
34
- s.add_development_dependency "test-unit", '~> 3.3', '>= 3.3.6'
35
- s.add_development_dependency "vcr", "~> 6.0"
36
- s.add_development_dependency "webmock", '~> 3.9', '>= 3.9.3'
27
+ s.add_development_dependency "bundler", "~> 2.1", ">= 2.1.4"
28
+ s.add_development_dependency "codecov", "~> 0.5.0"
29
+ s.add_development_dependency "json", "~> 2.3", ">= 2.3.1"
30
+ s.add_development_dependency "rake", "~> 13.0", ">= 13.0.1"
31
+ s.add_development_dependency "standard", "~> 1.0"
32
+ s.add_development_dependency "simplecov", "~> 0.21.2"
33
+ s.add_development_dependency "test-unit", "~> 3.3", ">= 3.3.6"
34
+ s.add_development_dependency "vcr", "~> 6.3", ">= 6.3.1"
35
+ s.add_development_dependency "webmock", "~> 3.25", ">= 3.25.1"
37
36
 
38
- s.add_runtime_dependency "faraday", "~> 1.1"
39
- s.add_runtime_dependency "faraday_middleware", "~> 1.0"
40
- s.add_runtime_dependency "multi_json", '~> 1.15'
41
- s.add_runtime_dependency 'thor', '~> 1.0', '>= 1.0.1'
37
+ s.add_runtime_dependency "faraday", "~> 2.13", ">= 2.13.1"
38
+ s.add_runtime_dependency "faraday-follow_redirects", ">= 0.1", "< 0.4"
39
+ s.add_runtime_dependency "multi_json", "~> 1.15"
40
+ s.add_runtime_dependency "rexml", "~> 3.2", ">= 3.2.5"
41
+ s.add_runtime_dependency "thor", "~> 1.2", ">= 1.2.1"
42
42
 
43
43
  s.metadata = {
44
44
  "homepage_uri" => "https://github.com/sckott/serrano",
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: '1.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chamberlain
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2020-10-19 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: bundler
@@ -36,14 +35,14 @@ dependencies:
36
35
  requirements:
37
36
  - - "~>"
38
37
  - !ruby/object:Gem::Version
39
- version: 0.2.0
38
+ version: 0.5.0
40
39
  type: :development
41
40
  prerelease: false
42
41
  version_requirements: !ruby/object:Gem::Requirement
43
42
  requirements:
44
43
  - - "~>"
45
44
  - !ruby/object:Gem::Version
46
- version: 0.2.0
45
+ version: 0.5.0
47
46
  - !ruby/object:Gem::Dependency
48
47
  name: json
49
48
  requirement: !ruby/object:Gem::Requirement
@@ -90,28 +89,28 @@ dependencies:
90
89
  requirements:
91
90
  - - "~>"
92
91
  - !ruby/object:Gem::Version
93
- version: '0.7'
92
+ version: '1.0'
94
93
  type: :development
95
94
  prerelease: false
96
95
  version_requirements: !ruby/object:Gem::Requirement
97
96
  requirements:
98
97
  - - "~>"
99
98
  - !ruby/object:Gem::Version
100
- version: '0.7'
99
+ version: '1.0'
101
100
  - !ruby/object:Gem::Dependency
102
101
  name: simplecov
103
102
  requirement: !ruby/object:Gem::Requirement
104
103
  requirements:
105
104
  - - "~>"
106
105
  - !ruby/object:Gem::Version
107
- version: 0.19.0
106
+ version: 0.21.2
108
107
  type: :development
109
108
  prerelease: false
110
109
  version_requirements: !ruby/object:Gem::Requirement
111
110
  requirements:
112
111
  - - "~>"
113
112
  - !ruby/object:Gem::Version
114
- version: 0.19.0
113
+ version: 0.21.2
115
114
  - !ruby/object:Gem::Dependency
116
115
  name: test-unit
117
116
  requirement: !ruby/object:Gem::Requirement
@@ -138,62 +137,80 @@ dependencies:
138
137
  requirements:
139
138
  - - "~>"
140
139
  - !ruby/object:Gem::Version
141
- version: '6.0'
140
+ version: '6.3'
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: 6.3.1
142
144
  type: :development
143
145
  prerelease: false
144
146
  version_requirements: !ruby/object:Gem::Requirement
145
147
  requirements:
146
148
  - - "~>"
147
149
  - !ruby/object:Gem::Version
148
- version: '6.0'
150
+ version: '6.3'
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: 6.3.1
149
154
  - !ruby/object:Gem::Dependency
150
155
  name: webmock
151
156
  requirement: !ruby/object:Gem::Requirement
152
157
  requirements:
153
158
  - - "~>"
154
159
  - !ruby/object:Gem::Version
155
- version: '3.9'
160
+ version: '3.25'
156
161
  - - ">="
157
162
  - !ruby/object:Gem::Version
158
- version: 3.9.3
163
+ version: 3.25.1
159
164
  type: :development
160
165
  prerelease: false
161
166
  version_requirements: !ruby/object:Gem::Requirement
162
167
  requirements:
163
168
  - - "~>"
164
169
  - !ruby/object:Gem::Version
165
- version: '3.9'
170
+ version: '3.25'
166
171
  - - ">="
167
172
  - !ruby/object:Gem::Version
168
- version: 3.9.3
173
+ version: 3.25.1
169
174
  - !ruby/object:Gem::Dependency
170
175
  name: faraday
171
176
  requirement: !ruby/object:Gem::Requirement
172
177
  requirements:
173
178
  - - "~>"
174
179
  - !ruby/object:Gem::Version
175
- version: '1.1'
180
+ version: '2.13'
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: 2.13.1
176
184
  type: :runtime
177
185
  prerelease: false
178
186
  version_requirements: !ruby/object:Gem::Requirement
179
187
  requirements:
180
188
  - - "~>"
181
189
  - !ruby/object:Gem::Version
182
- version: '1.1'
190
+ version: '2.13'
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: 2.13.1
183
194
  - !ruby/object:Gem::Dependency
184
- name: faraday_middleware
195
+ name: faraday-follow_redirects
185
196
  requirement: !ruby/object:Gem::Requirement
186
197
  requirements:
187
- - - "~>"
198
+ - - ">="
188
199
  - !ruby/object:Gem::Version
189
- version: '1.0'
200
+ version: '0.1'
201
+ - - "<"
202
+ - !ruby/object:Gem::Version
203
+ version: '0.4'
190
204
  type: :runtime
191
205
  prerelease: false
192
206
  version_requirements: !ruby/object:Gem::Requirement
193
207
  requirements:
194
- - - "~>"
208
+ - - ">="
195
209
  - !ruby/object:Gem::Version
196
- version: '1.0'
210
+ version: '0.1'
211
+ - - "<"
212
+ - !ruby/object:Gem::Version
213
+ version: '0.4'
197
214
  - !ruby/object:Gem::Dependency
198
215
  name: multi_json
199
216
  requirement: !ruby/object:Gem::Requirement
@@ -208,26 +225,46 @@ dependencies:
208
225
  - - "~>"
209
226
  - !ruby/object:Gem::Version
210
227
  version: '1.15'
228
+ - !ruby/object:Gem::Dependency
229
+ name: rexml
230
+ requirement: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - "~>"
233
+ - !ruby/object:Gem::Version
234
+ version: '3.2'
235
+ - - ">="
236
+ - !ruby/object:Gem::Version
237
+ version: 3.2.5
238
+ type: :runtime
239
+ prerelease: false
240
+ version_requirements: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - "~>"
243
+ - !ruby/object:Gem::Version
244
+ version: '3.2'
245
+ - - ">="
246
+ - !ruby/object:Gem::Version
247
+ version: 3.2.5
211
248
  - !ruby/object:Gem::Dependency
212
249
  name: thor
213
250
  requirement: !ruby/object:Gem::Requirement
214
251
  requirements:
215
252
  - - "~>"
216
253
  - !ruby/object:Gem::Version
217
- version: '1.0'
254
+ version: '1.2'
218
255
  - - ">="
219
256
  - !ruby/object:Gem::Version
220
- version: 1.0.1
257
+ version: 1.2.1
221
258
  type: :runtime
222
259
  prerelease: false
223
260
  version_requirements: !ruby/object:Gem::Requirement
224
261
  requirements:
225
262
  - - "~>"
226
263
  - !ruby/object:Gem::Version
227
- version: '1.0'
264
+ version: '1.2'
228
265
  - - ">="
229
266
  - !ruby/object:Gem::Version
230
- version: 1.0.1
267
+ version: 1.2.1
231
268
  description: Low Level Ruby Client for the Crossref Search API
232
269
  email: myrmecocystus@gmail.com
233
270
  executables:
@@ -235,6 +272,7 @@ executables:
235
272
  extensions: []
236
273
  extra_rdoc_files: []
237
274
  files:
275
+ - ".github/dependabot.yml"
238
276
  - ".github/workflows/ruby.yml"
239
277
  - ".gitignore"
240
278
  - CHANGELOG.md
@@ -264,10 +302,9 @@ licenses:
264
302
  metadata:
265
303
  homepage_uri: https://github.com/sckott/serrano
266
304
  documentation_uri: https://www.rubydoc.info/gems/serrano
267
- changelog_uri: https://github.com/sckott/serrano/releases/tag/v1.0.0
305
+ changelog_uri: https://github.com/sckott/serrano/releases/tag/v1.6
268
306
  source_code_uri: https://github.com/sckott/serrano
269
307
  bug_tracker_uri: https://github.com/sckott/serrano/issues
270
- post_install_message:
271
308
  rdoc_options: []
272
309
  require_paths:
273
310
  - lib
@@ -275,15 +312,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
275
312
  requirements:
276
313
  - - ">="
277
314
  - !ruby/object:Gem::Version
278
- version: '2.1'
315
+ version: '3.0'
279
316
  required_rubygems_version: !ruby/object:Gem::Requirement
280
317
  requirements:
281
318
  - - ">="
282
319
  - !ruby/object:Gem::Version
283
320
  version: '0'
284
321
  requirements: []
285
- rubygems_version: 3.1.2
286
- signing_key:
322
+ rubygems_version: 3.6.9
287
323
  specification_version: 4
288
324
  summary: Crossref Client
289
325
  test_files: []