serrano 0.5.0 → 0.5.2
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 +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +14 -0
- data/.rubocop_todo.yml +122 -0
- data/.travis.yml +7 -3
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +42 -26
- data/LICENSE +1 -1
- data/README.md +5 -0
- data/Rakefile +25 -18
- data/bin/serrano +96 -98
- data/lib/serrano.rb +112 -85
- data/lib/serrano/cn.rb +6 -8
- data/lib/serrano/cnrequest.rb +41 -27
- data/lib/serrano/error.rb +2 -0
- data/lib/serrano/faraday.rb +15 -14
- data/lib/serrano/filterhandler.rb +13 -15
- data/lib/serrano/filters.rb +72 -70
- data/lib/serrano/helpers/configuration.rb +2 -2
- data/lib/serrano/request.rb +41 -39
- data/lib/serrano/request_cursor.rb +62 -61
- data/lib/serrano/styles.rb +14 -9
- data/lib/serrano/utils.rb +16 -13
- data/lib/serrano/version.rb +3 -1
- data/serrano.gemspec +19 -17
- metadata +77 -52
- data/lib/serrano/constants.rb +0 -36
- data/lib/serrano/cursor_testing.rb +0 -52
data/lib/serrano.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
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'
|
8
11
|
|
9
12
|
require 'rexml/document'
|
10
13
|
require 'rexml/xpath'
|
@@ -19,10 +22,10 @@ require 'rexml/xpath'
|
|
19
22
|
# @param sort [String] Field to sort on, one of score, relevance,
|
20
23
|
# updated (date of most recent change to metadata - currently the same as deposited),
|
21
24
|
# deposited (time of most recent deposit), indexed (time of most recent index),
|
22
|
-
# published (publication date), published-print (print publication date),
|
23
|
-
# published-online (online publication date), issued (issued date (earliest known publication date)),
|
24
|
-
# is-referenced-by-count (number of times this DOI is referenced by other Crossref DOIs), or
|
25
|
-
# references-count (number of references included in the references section of the document
|
25
|
+
# published (publication date), published-print (print publication date),
|
26
|
+
# published-online (online publication date), issued (issued date (earliest known publication date)),
|
27
|
+
# is-referenced-by-count (number of times this DOI is referenced by other Crossref DOIs), or
|
28
|
+
# references-count (number of references included in the references section of the document
|
26
29
|
# identified by this DOI). Note: If the API call includes a query, then the sort
|
27
30
|
# order will be by the relevance score. If no query is included, then the sort order
|
28
31
|
# will be by DOI update date.
|
@@ -32,7 +35,7 @@ require 'rexml/xpath'
|
|
32
35
|
# @param select [String/Array(String)] Crossref metadata records can be
|
33
36
|
# quite large. Sometimes you just want a few elements from the schema. You can "select"
|
34
37
|
# a subset of elements to return. This can make your API calls much more efficient. Not
|
35
|
-
# clear yet which fields are allowed here.
|
38
|
+
# clear yet which fields are allowed here.
|
36
39
|
# @param verbose [Boolean] Print request headers to stdout. Default: false
|
37
40
|
|
38
41
|
# @!macro cursor_params
|
@@ -60,7 +63,7 @@ require 'rexml/xpath'
|
|
60
63
|
# - oauth [Hash] A hash with OAuth details
|
61
64
|
|
62
65
|
# @!macro field_queries
|
63
|
-
# @param [Hash<Object>] args Field queries, as named parameters. See
|
66
|
+
# @param [Hash<Object>] args Field queries, as named parameters. See
|
64
67
|
# https://github.com/CrossRef/rest-api-doc/blob/master/rest_api.md#field-queries
|
65
68
|
# Field query parameters mut be named, and must start with `query_`. Any dashes or
|
66
69
|
# periods should be replaced with underscores. The options include:
|
@@ -119,13 +122,13 @@ require 'rexml/xpath'
|
|
119
122
|
# information, then they will send you to a separate pool of machines,
|
120
123
|
# with better control the performance of these machines because they can
|
121
124
|
# block abusive users.
|
122
|
-
#
|
125
|
+
#
|
123
126
|
# We have been using `https` in `serrano` for a while now, so that's good
|
124
127
|
# to go. To get into the Polite Pool, also set your `mailto` email address
|
125
128
|
# with `Serrano.configuration` (example below), or set as an environment
|
126
129
|
# variable with the name `CROSSREF_EMAIL` and your mailto will be set
|
127
|
-
# for each request automatically.
|
128
|
-
#
|
130
|
+
# for each request automatically.
|
131
|
+
#
|
129
132
|
# require 'serrano'
|
130
133
|
# Serrano.configuration do |config|
|
131
134
|
# config.mailto = "foo@bar.com"
|
@@ -138,14 +141,20 @@ require 'rexml/xpath'
|
|
138
141
|
# limit is 50 requests per second. Look for the headers `X-Rate-Limit-Limit`
|
139
142
|
# and `X-Rate-Limit-Interval` in requests to see what the current rate
|
140
143
|
# limits are.
|
144
|
+
#
|
145
|
+
#
|
146
|
+
# URL Encoding
|
147
|
+
# We do URL encoding of DOIs for you for all methods except `Serrano.citation_count`
|
148
|
+
# which doesn't work if you encode DOIs beforehand. We use `ERB::Util.url_encode`
|
149
|
+
# to encode.
|
141
150
|
|
142
151
|
module Serrano
|
143
152
|
extend Configuration
|
144
153
|
|
145
154
|
define_setting :access_token
|
146
155
|
define_setting :access_secret
|
147
|
-
define_setting :mailto, ENV[
|
148
|
-
define_setting :base_url,
|
156
|
+
define_setting :mailto, ENV['CROSSREF_EMAIL']
|
157
|
+
define_setting :base_url, 'https://api.crossref.org/'
|
149
158
|
|
150
159
|
##
|
151
160
|
# Search the works route
|
@@ -193,7 +202,7 @@ module Serrano
|
|
193
202
|
#
|
194
203
|
# # sample
|
195
204
|
# Serrano.works(sample: 2)
|
196
|
-
#
|
205
|
+
#
|
197
206
|
# # select - pass an array or a comma separated string
|
198
207
|
# Serrano.works(query: "ecology", select: "DOI,title", limit: 30)
|
199
208
|
# Serrano.works(query: "ecology", select: ["DOI","title"], limit: 30)
|
@@ -221,13 +230,13 @@ module Serrano
|
|
221
230
|
# # select certain fields
|
222
231
|
# Serrano.works(select: ['DOI', 'title'], limit: 3)
|
223
232
|
def self.works(ids: nil, query: nil, filter: nil, offset: nil,
|
224
|
-
|
225
|
-
|
226
|
-
|
233
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
234
|
+
select: nil, options: nil, verbose: false, cursor: nil,
|
235
|
+
cursor_max: 5000, **args)
|
227
236
|
|
228
237
|
RequestCursor.new('works', ids, query, filter, offset,
|
229
|
-
|
230
|
-
|
238
|
+
limit, sample, sort, order, facet, select, nil, nil, options,
|
239
|
+
verbose, cursor, cursor_max, args).perform
|
231
240
|
end
|
232
241
|
|
233
242
|
##
|
@@ -277,13 +286,13 @@ module Serrano
|
|
277
286
|
# # select certain fields
|
278
287
|
# Serrano.members(ids: 340, works: true, select: ['DOI', 'title'], limit: 3)
|
279
288
|
def self.members(ids: nil, query: nil, filter: nil, offset: nil,
|
280
|
-
|
281
|
-
|
282
|
-
|
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)
|
283
292
|
|
284
293
|
RequestCursor.new('members', ids, query, filter, offset,
|
285
|
-
|
286
|
-
|
294
|
+
limit, sample, sort, order, facet, select, works, nil,
|
295
|
+
options, verbose, cursor, cursor_max, args).perform
|
287
296
|
end
|
288
297
|
|
289
298
|
##
|
@@ -322,15 +331,15 @@ module Serrano
|
|
322
331
|
# res[0]['message']['items'].collect { |x| x['title'] }
|
323
332
|
#
|
324
333
|
# # select certain fields
|
325
|
-
# Serrano.prefixes(ids: "10.1016", works: true, select: ['DOI', 'title'], limit: 3)
|
334
|
+
# Serrano.prefixes(ids: "10.1016", works: true, select: ['DOI', 'title'], limit: 3)
|
326
335
|
def self.prefixes(ids:, filter: nil, offset: nil,
|
327
|
-
|
328
|
-
|
329
|
-
|
336
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
337
|
+
select: nil, works: false, options: nil, verbose: false,
|
338
|
+
cursor: nil, cursor_max: 5000, **args)
|
330
339
|
|
331
340
|
RequestCursor.new('prefixes', ids, nil, filter, offset,
|
332
|
-
|
333
|
-
|
341
|
+
limit, sample, sort, order, facet, select, works, nil,
|
342
|
+
options, verbose, cursor, cursor_max, args).perform
|
334
343
|
end
|
335
344
|
|
336
345
|
##
|
@@ -374,15 +383,15 @@ module Serrano
|
|
374
383
|
# res[0]['message']['items'].collect { |x| x['author'][0]['family'] }
|
375
384
|
#
|
376
385
|
# # select certain fields
|
377
|
-
# Serrano.funders(ids: "10.13039/100000001", works: true, select: ['DOI', 'title'], limit: 3)
|
386
|
+
# Serrano.funders(ids: "10.13039/100000001", works: true, select: ['DOI', 'title'], limit: 3)
|
378
387
|
def self.funders(ids: nil, query: nil, filter: nil, offset: nil,
|
379
|
-
|
380
|
-
|
381
|
-
|
388
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
389
|
+
select: nil, works: false, options: nil, verbose: false,
|
390
|
+
cursor: nil, cursor_max: 5000, **args)
|
382
391
|
|
383
392
|
RequestCursor.new('funders', ids, query, filter, offset,
|
384
|
-
|
385
|
-
|
393
|
+
limit, sample, sort, order, facet, select, works, nil, options,
|
394
|
+
verbose, cursor, cursor_max, args).perform
|
386
395
|
end
|
387
396
|
|
388
397
|
##
|
@@ -426,15 +435,15 @@ module Serrano
|
|
426
435
|
# res[0]['message']['items'].collect { |x| x['container-title'] }
|
427
436
|
#
|
428
437
|
# # select certain fields
|
429
|
-
# Serrano.journals(ids: "2167-8359", works: true, select: ['DOI', 'title'], limit: 3)
|
438
|
+
# Serrano.journals(ids: "2167-8359", works: true, select: ['DOI', 'title'], limit: 3)
|
430
439
|
def self.journals(ids: nil, query: nil, filter: nil, offset: nil,
|
431
|
-
|
432
|
-
|
433
|
-
|
440
|
+
limit: nil, sample: nil, sort: nil, order: nil, facet: nil,
|
441
|
+
select: nil, works: false, options: nil, verbose: false,
|
442
|
+
cursor: nil, cursor_max: 5000, **args)
|
434
443
|
|
435
444
|
RequestCursor.new('journals', ids, query, filter, offset,
|
436
|
-
|
437
|
-
|
445
|
+
limit, sample, sort, order, facet, select, works, nil, options,
|
446
|
+
verbose, cursor, cursor_max, args).perform
|
438
447
|
end
|
439
448
|
|
440
449
|
##
|
@@ -448,7 +457,7 @@ module Serrano
|
|
448
457
|
# @param select [String/Array(String)] Crossref metadata records can be
|
449
458
|
# quite large. Sometimes you just want a few elements from the schema. You can "select"
|
450
459
|
# a subset of elements to return. This can make your API calls much more efficient. Not
|
451
|
-
# clear yet which fields are allowed here.
|
460
|
+
# clear yet which fields are allowed here.
|
452
461
|
# @return [Array] An array of hashes
|
453
462
|
#
|
454
463
|
# @example
|
@@ -470,21 +479,40 @@ module Serrano
|
|
470
479
|
# res[0]['message']['items'].collect { |x| x['container-title'] }
|
471
480
|
#
|
472
481
|
# # select certain fields
|
473
|
-
# Serrano.types(ids: "journal", works: true, select: ['DOI', 'title'], limit: 3)
|
482
|
+
# Serrano.types(ids: "journal", works: true, select: ['DOI', 'title'], limit: 3)
|
474
483
|
def self.types(ids: nil, offset: nil, limit: nil, select: nil, works: false,
|
475
|
-
|
484
|
+
options: nil, verbose: false, cursor: nil, cursor_max: 5000, **args)
|
476
485
|
|
477
486
|
RequestCursor.new('types', ids, nil, nil, offset,
|
478
|
-
|
479
|
-
|
487
|
+
limit, nil, nil, nil, nil, select, works, nil, options,
|
488
|
+
verbose, cursor, cursor_max, args).perform
|
480
489
|
end
|
481
490
|
|
482
491
|
##
|
483
492
|
# Search the licenses route
|
484
493
|
#
|
485
|
-
# @!macro serrano_params
|
486
494
|
# @!macro serrano_options
|
487
495
|
# @param query [String] A query string
|
496
|
+
# @param offset [Fixnum] Number of record to start at, any non-negative integer up to 10,000
|
497
|
+
# @param limit [Fixnum] Number of results to return. Not relavant when searching with specific dois.
|
498
|
+
# Default: 20. Max: 1000
|
499
|
+
# @param sample [Fixnum] Number of random results to return. when you use the sample parameter,
|
500
|
+
# the limit and offset parameters are ignored. This parameter only used when works requested.
|
501
|
+
# Max: 100.
|
502
|
+
# @param sort [String] Field to sort on, one of score, relevance,
|
503
|
+
# updated (date of most recent change to metadata - currently the same as deposited),
|
504
|
+
# deposited (time of most recent deposit), indexed (time of most recent index),
|
505
|
+
# published (publication date), published-print (print publication date),
|
506
|
+
# published-online (online publication date), issued (issued date (earliest known publication date)),
|
507
|
+
# is-referenced-by-count (number of times this DOI is referenced by other Crossref DOIs), or
|
508
|
+
# references-count (number of references included in the references section of the document
|
509
|
+
# identified by this DOI). Note: If the API call includes a query, then the sort
|
510
|
+
# order will be by the relevance score. If no query is included, then the sort order
|
511
|
+
# will be by DOI update date.
|
512
|
+
# @param order [String] Sort order, one of 'asc' or 'desc'
|
513
|
+
# @param facet [Boolean/String] Include facet results OR a query (e.g., `license:*`) to facet by
|
514
|
+
# license. Default: false
|
515
|
+
# @param verbose [Boolean] Print request headers to stdout. Default: false
|
488
516
|
# @return [Array] An array of hashes
|
489
517
|
#
|
490
518
|
# @example
|
@@ -493,11 +521,11 @@ module Serrano
|
|
493
521
|
# Serrano.licenses()
|
494
522
|
# Serrano.licenses(limit: 3)
|
495
523
|
def self.licenses(query: nil, offset: nil,
|
496
|
-
|
497
|
-
|
524
|
+
limit: nil, sample: nil, sort: nil, order: nil,
|
525
|
+
facet: nil, options: nil, verbose: false)
|
498
526
|
|
499
527
|
Request.new('licenses', nil, query, nil, offset,
|
500
|
-
|
528
|
+
limit, sample, sort, order, facet, nil, nil, nil, options, verbose).perform
|
501
529
|
end
|
502
530
|
|
503
531
|
##
|
@@ -512,9 +540,8 @@ module Serrano
|
|
512
540
|
# Serrano.registration_agency(ids: '10.1371/journal.pone.0033693')
|
513
541
|
# Serrano.registration_agency(ids: ['10.1007/12080.1874-1746','10.1007/10452.1573-5125', '10.1111/(issn)1442-9993'])
|
514
542
|
def self.registration_agency(ids:, options: nil, verbose: false)
|
515
|
-
|
516
543
|
Request.new('works', ids, nil, nil, nil,
|
517
|
-
|
544
|
+
nil, nil, nil, nil, nil, false, true, options, verbose).perform
|
518
545
|
end
|
519
546
|
|
520
547
|
##
|
@@ -535,9 +562,8 @@ module Serrano
|
|
535
562
|
# Serrano.random_dois(sample: 10)
|
536
563
|
# Serrano.random_dois(sample: 100)
|
537
564
|
def self.random_dois(sample: 10, options: nil, verbose: false)
|
538
|
-
|
539
565
|
tmp = Request.new('works', nil, nil, nil, nil,
|
540
|
-
|
566
|
+
nil, sample, nil, nil, nil, nil, false, nil, options, verbose).perform
|
541
567
|
tmp['message']['items'].collect { |x| x['DOI'] }
|
542
568
|
end
|
543
569
|
|
@@ -564,7 +590,7 @@ module Serrano
|
|
564
590
|
# Serrano.content_negotiation(ids: "10.1126/science.169.3946.635", format: "crossref-xml")
|
565
591
|
# Serrano.content_negotiation(ids: "10.1126/science.169.3946.635", format: "text")
|
566
592
|
#
|
567
|
-
# # return
|
593
|
+
# # return a bibentry type
|
568
594
|
# Serrano.content_negotiation(ids: "10.1126/science.169.3946.635", format: "bibentry")
|
569
595
|
# Serrano.content_negotiation(ids: "10.6084/m9.figshare.97218", format: "bibentry")
|
570
596
|
#
|
@@ -577,30 +603,32 @@ module Serrano
|
|
577
603
|
# Serrano.content_negotiation(ids: "10.1126/science.169.3946.635", format: "text", style: "oikos")
|
578
604
|
#
|
579
605
|
# # example with many DOIs
|
580
|
-
# dois =
|
581
|
-
# Serrano.content_negotiation(dois, format: "text", style: "apa")
|
606
|
+
# dois = Serrano.random_dois(sample: 2)
|
607
|
+
# Serrano.content_negotiation(ids: dois, format: "text", style: "apa")
|
582
608
|
#
|
583
609
|
# # Using DataCite DOIs
|
584
|
-
#
|
585
|
-
#
|
586
|
-
#
|
587
|
-
#
|
610
|
+
# doi = "10.1126/science.169.3946.635"
|
611
|
+
# Serrano.content_negotiation(ids: doi, format: "text")
|
612
|
+
# Serrano.content_negotiation(ids: doi, format: "crossref-xml")
|
613
|
+
# Serrano.content_negotiation(ids: doi, format: "crossref-tdm")
|
588
614
|
#
|
589
615
|
# ## But most do work
|
590
|
-
# Serrano.content_negotiation(ids:
|
591
|
-
# Serrano.content_negotiation(ids:
|
592
|
-
# Serrano.content_negotiation(ids:
|
593
|
-
# Serrano.content_negotiation(ids:
|
594
|
-
# Serrano.content_negotiation(ids:
|
595
|
-
# Serrano.content_negotiation(ids:
|
596
|
-
# Serrano.content_negotiation(ids:
|
597
|
-
# Serrano.content_negotiation(ids:
|
616
|
+
# Serrano.content_negotiation(ids: doi, format: "datacite-xml")
|
617
|
+
# Serrano.content_negotiation(ids: doi, format: "rdf-xml")
|
618
|
+
# Serrano.content_negotiation(ids: doi, format: "turtle")
|
619
|
+
# Serrano.content_negotiation(ids: doi, format: "citeproc-json")
|
620
|
+
# Serrano.content_negotiation(ids: doi, format: "ris")
|
621
|
+
# Serrano.content_negotiation(ids: doi, format: "bibtex")
|
622
|
+
# Serrano.content_negotiation(ids: doi, format: "bibentry")
|
623
|
+
# Serrano.content_negotiation(ids: doi, format: "bibtex")
|
598
624
|
#
|
599
625
|
# # many DOIs
|
600
|
-
# dois = ['10.5167/UZH-30455','10.5167/UZH-49216','10.5167/UZH-503',
|
626
|
+
# dois = ['10.5167/UZH-30455','10.5167/UZH-49216','10.5167/UZH-503',
|
627
|
+
# '10.5167/UZH-38402','10.5167/UZH-41217']
|
601
628
|
# x = Serrano.content_negotiation(ids: dois)
|
602
629
|
# puts x
|
603
|
-
def self.content_negotiation(ids:, format:
|
630
|
+
def self.content_negotiation(ids:, format: 'bibtex', style: 'apa', locale: 'en-US')
|
631
|
+
ids = Array(ids).map { |x| ERB::Util.url_encode(x) }
|
604
632
|
CNRequest.new(ids, format, style, locale).perform
|
605
633
|
end
|
606
634
|
|
@@ -619,17 +647,17 @@ module Serrano
|
|
619
647
|
# Serrano.citation_count(doi: "10.1016/j.fbr.2012.01.001")
|
620
648
|
# # DOI not found
|
621
649
|
# Serrano.citation_count(doi: "10.1016/j.fbr.2012")
|
622
|
-
def self.citation_count(doi:, url:
|
623
|
-
|
650
|
+
def self.citation_count(doi:, url: 'http://www.crossref.org/openurl/',
|
651
|
+
key: 'cboettig@ropensci.org', options: nil)
|
624
652
|
|
625
|
-
args = { id:
|
626
|
-
opts = args.delete_if { |
|
627
|
-
conn = Faraday.new(:
|
653
|
+
args = { id: 'doi:' + doi, pid: key, noredirect: true }
|
654
|
+
opts = args.delete_if { |_k, v| v.nil? }
|
655
|
+
conn = Faraday.new(url: url, request: options)
|
628
656
|
res = conn.get '', opts
|
629
657
|
x = res.body
|
630
658
|
oc = REXML::Document.new("<doc>#{x}</doc>")
|
631
659
|
value = REXML::XPath.first(oc, '//query').attributes['fl_count'].to_i
|
632
|
-
|
660
|
+
value
|
633
661
|
end
|
634
662
|
|
635
663
|
# Get csl styles
|
@@ -639,7 +667,6 @@ module Serrano
|
|
639
667
|
# @example
|
640
668
|
# Serrano.csl_styles
|
641
669
|
def self.csl_styles
|
642
|
-
|
670
|
+
fetch_styles
|
643
671
|
end
|
644
|
-
|
645
672
|
end
|
data/lib/serrano/cn.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'serrano/version'
|
4
|
+
require 'serrano/cnrequest'
|
3
5
|
|
4
6
|
##
|
5
7
|
# ContentNegotiation - Content Negotiation class
|
6
8
|
#
|
7
9
|
# @see http://www.crosscite.org/cn/ for details
|
8
10
|
module Serrano
|
9
|
-
|
10
11
|
class ContentNegotiation
|
11
|
-
|
12
12
|
attr_accessor :ids
|
13
13
|
attr_accessor :format
|
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
|
@@ -22,9 +22,7 @@ module Serrano
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def cn
|
25
|
-
CNRequest.new(
|
25
|
+
CNRequest.new(ids, format, style, locale).perform
|
26
26
|
end
|
27
|
-
|
28
27
|
end
|
29
|
-
|
30
28
|
end
|
data/lib/serrano/cnrequest.rb
CHANGED
@@ -1,23 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
require 'faraday_middleware'
|
5
|
+
require 'multi_json'
|
6
|
+
require 'serrano/error'
|
6
7
|
require 'serrano/utils'
|
7
8
|
require 'serrano/helpers/configuration'
|
8
9
|
|
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
|
+
|
9
21
|
##
|
10
22
|
# Serrano::CNRequest
|
11
23
|
#
|
12
24
|
# Class to perform HTTP requests to the Crossref API
|
13
25
|
module Serrano
|
14
26
|
class CNRequest #:nodoc:
|
15
|
-
|
16
27
|
attr_accessor :ids
|
17
28
|
attr_accessor :format
|
18
29
|
attr_accessor :style
|
19
30
|
attr_accessor :locale
|
20
31
|
|
32
|
+
CN_FORMATS = %w[rdf-xml turtle citeproc-json
|
33
|
+
citeproc-json-ish text ris bibtex
|
34
|
+
crossref-xml datacite-xml bibentry
|
35
|
+
crossref-tdm].freeze
|
36
|
+
|
21
37
|
def initialize(ids, format, style, locale)
|
22
38
|
self.ids = ids
|
23
39
|
self.format = format
|
@@ -26,24 +42,22 @@ module Serrano
|
|
26
42
|
end
|
27
43
|
|
28
44
|
def perform
|
29
|
-
|
30
|
-
raise
|
45
|
+
unless CN_FORMATS.include? format
|
46
|
+
raise 'format not one of accepted types'
|
31
47
|
end
|
32
48
|
|
33
|
-
|
49
|
+
conn = Faraday.new 'https://doi.org/' do |c|
|
34
50
|
c.use FaradayMiddleware::FollowRedirects
|
35
51
|
c.adapter :net_http
|
36
52
|
end
|
37
53
|
|
38
|
-
if
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
return make_request(self.ids, self.format, self.style, self.locale)
|
54
|
+
if ids.length == 1
|
55
|
+
self.ids = ids[0] if ids.class == Array
|
56
|
+
return make_request(conn, ids, format, style, locale)
|
43
57
|
else
|
44
58
|
coll = []
|
45
|
-
Array(
|
46
|
-
coll << make_request(x,
|
59
|
+
Array(ids).each do |x|
|
60
|
+
coll << make_request(conn, x, format, style, locale)
|
47
61
|
end
|
48
62
|
return coll
|
49
63
|
end
|
@@ -51,29 +65,29 @@ module Serrano
|
|
51
65
|
end
|
52
66
|
end
|
53
67
|
|
54
|
-
def make_request(ids, format, style, locale)
|
55
|
-
type =
|
68
|
+
def make_request(conn, ids, format, style, locale)
|
69
|
+
type = CN_FORMAT_HEADERS.select { |x, _| x.include? format }.values[0]
|
56
70
|
|
57
|
-
if format ==
|
58
|
-
endpt =
|
59
|
-
cr_works = Faraday.new(:
|
71
|
+
if format == 'citeproc-json'
|
72
|
+
endpt = 'http://api.crossref.org/works/' + ids + '/' + type
|
73
|
+
cr_works = Faraday.new(url: endpt)
|
60
74
|
cr_works.headers[:user_agent] = make_ua
|
61
|
-
cr_works.headers[
|
75
|
+
cr_works.headers['X-USER-AGENT'] = make_ua
|
62
76
|
res = cr_works.get
|
63
77
|
else
|
64
|
-
if format ==
|
65
|
-
type = type +
|
78
|
+
if format == 'text'
|
79
|
+
type = type + '; style = ' + style + '; locale = ' + locale
|
66
80
|
end
|
67
81
|
|
68
|
-
res =
|
82
|
+
res = conn.get do |req|
|
69
83
|
req.url ids
|
70
84
|
req.headers['Accept'] = type
|
71
85
|
req.headers[:user_agent] = make_ua
|
72
|
-
req.headers[
|
86
|
+
req.headers['X-USER-AGENT'] = make_ua
|
73
87
|
end
|
74
88
|
end
|
75
89
|
|
76
|
-
|
90
|
+
res.body
|
77
91
|
end
|
78
92
|
|
79
93
|
# parser <- cn_types[[self.format]]
|