elsevier_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.idea/vcs.xml +6 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +43 -0
- data/LICENSE +29 -0
- data/README.md +136 -0
- data/Rakefile +6 -0
- data/bin/elsevier-api-console +14 -0
- data/elsevier_api.gemspec +24 -0
- data/lib/elsevier_api/connection.rb +147 -0
- data/lib/elsevier_api/uri_request.rb +73 -0
- data/lib/elsevier_api/version.rb +3 -0
- data/lib/elsevier_api/xml_response/abstract_citation_response.rb +97 -0
- data/lib/elsevier_api/xml_response/abstract_retrieval_response.rb +333 -0
- data/lib/elsevier_api/xml_response/author_retrieval_response.rb +36 -0
- data/lib/elsevier_api/xml_response/author_retrieval_response_list.rb +38 -0
- data/lib/elsevier_api/xml_response/search_results.rb +54 -0
- data/lib/elsevier_api/xml_response/service_error.rb +34 -0
- data/lib/elsevier_api/xml_response.rb +61 -0
- data/lib/elsevier_api.rb +66 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2d54cf0dc5287b82d77c1eb3bfaa84aa274535f7ede5e168e8d3766dda3de4be
|
4
|
+
data.tar.gz: 591553769d5a31753c3d1a8ef4d3b24a2d8737ef178d5efdf0cde251264d0518
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7359e8f97afc750f9b703206d41a468530c2249856c45783bb9d239158cdcaaca82ffbb4ae553c223934b529b74d7d9366c5655cd46dbea3f0a1f0388d5dad98
|
7
|
+
data.tar.gz: bc767d36f271fd430d5221e7163989fc9f8e36084823a302ccec36ed1bb8902c49d6a5cc8c9ff5544d6591b5283cf7b36d2e98e189d8dea1beb27d5ca1ad2924
|
data/.idea/vcs.xml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
curb (0.9.10)
|
5
|
+
diff-lcs (1.3)
|
6
|
+
docile (1.3.2)
|
7
|
+
mini_portile2 (2.4.0)
|
8
|
+
nokogiri (1.10.8)
|
9
|
+
mini_portile2 (~> 2.4.0)
|
10
|
+
openssl (2.1.2)
|
11
|
+
rake (13.0.1)
|
12
|
+
rspec (3.9.0)
|
13
|
+
rspec-core (~> 3.9.0)
|
14
|
+
rspec-expectations (~> 3.9.0)
|
15
|
+
rspec-mocks (~> 3.9.0)
|
16
|
+
rspec-core (3.9.1)
|
17
|
+
rspec-support (~> 3.9.1)
|
18
|
+
rspec-expectations (3.9.0)
|
19
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
20
|
+
rspec-support (~> 3.9.0)
|
21
|
+
rspec-mocks (3.9.1)
|
22
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
23
|
+
rspec-support (~> 3.9.0)
|
24
|
+
rspec-support (3.9.2)
|
25
|
+
simplecov (0.18.2)
|
26
|
+
docile (~> 1.1)
|
27
|
+
simplecov-html (~> 0.11)
|
28
|
+
simplecov-html (0.12.0)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
bundler!
|
35
|
+
curb!
|
36
|
+
nokogiri!
|
37
|
+
openssl (~> 2.1.2)!
|
38
|
+
rake!
|
39
|
+
rspec!
|
40
|
+
simplecov!
|
41
|
+
|
42
|
+
BUNDLED WITH
|
43
|
+
2.1.4
|
data/LICENSE
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
10
|
+
list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
14
|
+
and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
17
|
+
contributors may be used to endorse or promote products derived from
|
18
|
+
this software without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
# elsevier_api
|
2
|
+
|
3
|
+
Provides access to Elsevier dev services for Ruby. You require an API from https://dev.elsevier.com/apikey/ first.
|
4
|
+
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem 'elsevier_api'
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install elservier_api
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
First, you should create a connection to Elsevier server using your Elsevier API key
|
25
|
+
```ruby
|
26
|
+
require 'elsevier_api'
|
27
|
+
@conn=ElsevierApi::Connection.new(api_key)
|
28
|
+
```
|
29
|
+
|
30
|
+
If you need to use a proxy, just add the information after the key.
|
31
|
+
```ruby
|
32
|
+
@conn=ElsevierApi::Connection.new(api_key,
|
33
|
+
proxy_host: proxy_host,
|
34
|
+
|
35
|
+
proxy_port: proxy_port,
|
36
|
+
proxy_user: proxy_user,
|
37
|
+
proxy_pass: proxy_password
|
38
|
+
)
|
39
|
+
```
|
40
|
+
|
41
|
+
The basic method is *retrieve_response*, that requires an URI and retrieves a parsed response. ElsevierApi retrieves the XML responde from Elsevier, and parse it using a class of type ElsevierApi::XMLResponse based on the first node of XML.
|
42
|
+
|
43
|
+
For example, we could retrieve the information about the developer of this gem
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
|
47
|
+
info = @conn.retrieve_response("https://api.elsevier.com/content/author?author_id=56609918400")
|
48
|
+
info.class
|
49
|
+
=> ElsevierApi::XMLResponse::Authorretrievalresponse
|
50
|
+
```
|
51
|
+
|
52
|
+
We could operate directly on the XML
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
info.xml.xpath("//document-count").text
|
56
|
+
=> 26
|
57
|
+
```
|
58
|
+
|
59
|
+
A more interesting XMLResponse object is provided if we use a search
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
query_encoded=URI::encode("(ruby language) and api")
|
63
|
+
|
64
|
+
search = @conn.retrieve_response("https://api.elsevier.com/content/search/scopus?query=#{query_encoded}&count=2")
|
65
|
+
search.class
|
66
|
+
=> ElsevierApi::XMLResponse::Searchresults
|
67
|
+
|
68
|
+
search.entries_to_ary
|
69
|
+
=> [{:scopus_id=>"SCOPUS_ID:85077509321",
|
70
|
+
:title=>"Energy-Delay investigation of Remote Inter-Process communication technologies",
|
71
|
+
:journal=>"Journal of Systems and Software",
|
72
|
+
:creator=>"Georgiou S.",
|
73
|
+
:doi=>"10.1016/j.jss.2019.110506"},
|
74
|
+
{:scopus_id=>"SCOPUS_ID:85079458224",
|
75
|
+
:title=>"A mechanized formalization of GraphQL",
|
76
|
+
:journal=>
|
77
|
+
"CPP 2020 - Proceedings of the 9th ACM SIGPLAN International Conference on Certified Programs and Proofs, co-located with POPL 2020",
|
78
|
+
:creator=>"Diaz T.",
|
79
|
+
:doi=>"10.1145/3372885.3373822"}]
|
80
|
+
|
81
|
+
```
|
82
|
+
|
83
|
+
The most complete parsing procedure was developed for abstracts, to retrieve complete information about authors and affiliations.
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
abstract = @conn.retrieve_response("https://api.elsevier.com/content/abstract/scopus_id/85079458224")
|
87
|
+
=> #<ElsevierApi::XMLResponse::Abstractsretrievalresponse:27496700 @title=A mechanized formalization of GraphQL @journal=CPP 2020 - Proceedings of the 9th ACM SIGPLAN International Conference on Certified Programs and Proofs, co-located with POPL 2020 @authors=[56940212100,35174987700,13104010300]>
|
88
|
+
|
89
|
+
abstract.scopus_id
|
90
|
+
=> "SCOPUS_ID:85079458224"
|
91
|
+
|
92
|
+
abstract.authors.first
|
93
|
+
=> ["56940212100",
|
94
|
+
{:auid=>"56940212100",
|
95
|
+
:seq=>"1",
|
96
|
+
:initials=>"T.",
|
97
|
+
:indexed_name=>"Diaz T.",
|
98
|
+
:given_name=>"Tomas",
|
99
|
+
:surname=>"Diaz",
|
100
|
+
:email=>nil,
|
101
|
+
:affiliation=>"123888358"}]
|
102
|
+
|
103
|
+
abstract.affiliations
|
104
|
+
=> {"60012464"=>
|
105
|
+
{:id=>"60012464",
|
106
|
+
:name=>"Universidad de Chile",
|
107
|
+
:city=>"Santiago",
|
108
|
+
:country=>"Chile",
|
109
|
+
:type=>:scopus},
|
110
|
+
"123888358"=>
|
111
|
+
{:id=>"123888358", :name=>"IMFD Chile", :city=>"", :country=>"Chile", :type=>:scopus},
|
112
|
+
"123888173"=>
|
113
|
+
{:id=>"123888173",
|
114
|
+
:name=>"U. of Chile and IMFD Chile and Inria Paris",
|
115
|
+
:city=>"Paris",
|
116
|
+
:country=>"France",
|
117
|
+
:type=>:scopus}}
|
118
|
+
```
|
119
|
+
|
120
|
+
Some methods to create URIs for Elsevier API are located in ElsevierApi::URIRequest module, that is included on connection.
|
121
|
+
|
122
|
+
|
123
|
+
## Development
|
124
|
+
|
125
|
+
After checking out the repository, use
|
126
|
+
|
127
|
+
$ bundle install
|
128
|
+
|
129
|
+
to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
130
|
+
|
131
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
132
|
+
|
133
|
+
## Contributing
|
134
|
+
|
135
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/clbustos/elsevier-api.
|
136
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require_relative "../lib/elsevier_api"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'elsevier_api/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "elsevier_api"
|
8
|
+
spec.version = ElsevierApi::VERSION
|
9
|
+
spec.authors = ["Claudio Bustos"]
|
10
|
+
spec.email = ["clbustos@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Ruby gem to interact with Elsevier's APIs}
|
13
|
+
spec.description = %q{A Ruby gem for use with Elsevier's APIs: Scopus, ScienceDirect, others. }
|
14
|
+
spec.homepage = "https://github.com/clbustos/elsevier_api"
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
spec.bindir = "exe"
|
17
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
spec.licenses = ['BSD-3-Clause']
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
21
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
22
|
+
spec.add_development_dependency "nokogiri", "~> 1.6"
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
require 'uri'
|
29
|
+
require 'net/http'
|
30
|
+
require 'curb'
|
31
|
+
module ElsevierApi
|
32
|
+
class Connection
|
33
|
+
extend ElsevierApi::URIRequest
|
34
|
+
include ElsevierApi::URIRequest
|
35
|
+
attr_reader :key, :error, :error_msg, :xml_response, :raw_xml
|
36
|
+
attr_accessor :use_proxy
|
37
|
+
attr_accessor :proxy_host, :proxy_post, :proxy_user, :proxy_pass
|
38
|
+
def initialize(key, opts={})
|
39
|
+
@key=key
|
40
|
+
@use_proxy=false
|
41
|
+
@error=false
|
42
|
+
@error_msg=nil
|
43
|
+
if opts[:proxy_host]
|
44
|
+
@use_proxy=true
|
45
|
+
@proxy_host=opts[:proxy_host]
|
46
|
+
@proxy_port=opts[:proxy_port]
|
47
|
+
@proxy_user=opts[:proxy_user]
|
48
|
+
@proxy_pass=opts[:proxy_pass]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def connection
|
52
|
+
@connection||=get_connection
|
53
|
+
end
|
54
|
+
def close
|
55
|
+
@connection.close if @connection
|
56
|
+
end
|
57
|
+
|
58
|
+
# Connect to api and retrieve a response based on URI
|
59
|
+
def retrieve_response(uri_string)
|
60
|
+
@xml_response=nil
|
61
|
+
begin
|
62
|
+
Curl::Easy.new(uri_string) do |curl|
|
63
|
+
if @use_proxy
|
64
|
+
curl.proxy_tunnel = true
|
65
|
+
curl.proxy_url = "http://#{@proxy_host}:#{@proxy_port}/"
|
66
|
+
curl.proxypwd = "#{@proxy_user}:#{proxy_pass}"
|
67
|
+
end
|
68
|
+
curl.follow_location = true
|
69
|
+
curl.ssl_verify_peer = false
|
70
|
+
curl.max_redirects = 3
|
71
|
+
curl.headers=['Accept: application/xml', "X-ELS-APIKey: #{@key}"]
|
72
|
+
curl.perform
|
73
|
+
#p curl.body_str
|
74
|
+
xml=Nokogiri::XML(curl.body_str)
|
75
|
+
if xml.xpath("//service-error").length>0
|
76
|
+
@error=true
|
77
|
+
@error_msg=xml.xpath("//statusText").text
|
78
|
+
elsif xml.xpath("//atom:error",'atom'=>'http://www.w3.org/2005/Atom').length>0
|
79
|
+
@error=true
|
80
|
+
@error_msg=xml.xpath("//atom:error").text
|
81
|
+
elsif xml.children.length==0
|
82
|
+
@error=true
|
83
|
+
@error_msg="Empty_XML"
|
84
|
+
else
|
85
|
+
@error=false
|
86
|
+
@error_msg=nil
|
87
|
+
end
|
88
|
+
@xml_response=ElsevierApi.process_xml(xml)
|
89
|
+
end
|
90
|
+
rescue Exception=>e
|
91
|
+
#$log.info(e.message)
|
92
|
+
@error=true
|
93
|
+
@error_msg=e.message
|
94
|
+
end
|
95
|
+
|
96
|
+
@xml_response
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
def get_articles_from_uri(uri)
|
101
|
+
completo=false
|
102
|
+
acumulado=[]
|
103
|
+
pagina=1
|
104
|
+
until completo do
|
105
|
+
#puts "Page:#{pagina}"
|
106
|
+
xml_response=retrieve_response(uri)
|
107
|
+
if @error
|
108
|
+
break
|
109
|
+
else
|
110
|
+
acumulado=acumulado+xml_response.entries_to_hash
|
111
|
+
next_page=xml_response.next_page
|
112
|
+
if next_page
|
113
|
+
pagina+=1
|
114
|
+
uri=next_page.attribute("href").value
|
115
|
+
else
|
116
|
+
# puts "completo"
|
117
|
+
completo=true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
acumulado
|
122
|
+
end
|
123
|
+
|
124
|
+
def get_journal_articles(journal,year=nil)
|
125
|
+
uri=get_uri_journal_articles(journal,year)
|
126
|
+
completo=false
|
127
|
+
acumulado=[]
|
128
|
+
until completo do
|
129
|
+
xml_response=retrieve_response(uri)
|
130
|
+
if @error
|
131
|
+
break
|
132
|
+
else
|
133
|
+
acumulado=acumulado+xml_response.entries_to_ary
|
134
|
+
next_page=xml_response.next_page
|
135
|
+
if next_page
|
136
|
+
uri=next_page.attribute("href").value
|
137
|
+
#puts "siguiente pagina"
|
138
|
+
else
|
139
|
+
#puts "completo"
|
140
|
+
completo=true
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
acumulado
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
module ElsevierApi
|
29
|
+
module URIRequest
|
30
|
+
|
31
|
+
def get_uri_author(author_id,view=:light,opts={})
|
32
|
+
if author_id.is_a? (Array)
|
33
|
+
author_id=author_id.join(",")
|
34
|
+
end
|
35
|
+
opts={:view=>view.to_s.upcase}.merge(opts)
|
36
|
+
opts_s=opts.map {|v| "#{v[0].to_s}=#{v[1]}"}.join("&")
|
37
|
+
res=::URI.encode("https://api.elsevier.com/content/author?author_id=#{author_id}&#{opts_s}")
|
38
|
+
res
|
39
|
+
end
|
40
|
+
def get_uri_citation_overview(scopus_id,date,opts={})
|
41
|
+
if scopus_id.is_a? (Array)
|
42
|
+
scopus_id=scopus_id.join(",")
|
43
|
+
end
|
44
|
+
opts={:date=>date,:field=>"h-index,dc:identifier,scopus_id,pcc,cc,lcc,rangeCount,rowTotal,sort-year,prevColumnHeading,columnHeading,laterColumnHeading,prevColumnTotal,columnTotal,laterColumnTotal,rangeColumnTotal,grandTotal"}.merge(opts)
|
45
|
+
opts_s=opts.map {|v| "#{v[0].to_s}=#{v[1]}"}.join("&")
|
46
|
+
res=::URI.encode("https://api.elsevier.com/content/abstract/citations?scopus_id=#{scopus_id}&#{opts_s}")
|
47
|
+
|
48
|
+
res
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_uri_articles_country_year_area(country,year,area)
|
52
|
+
query="AFFILCOUNTRY ( #{country} ) AND PUBYEAR = #{year} AND SUBJAREA ( \"#{area}\" )"
|
53
|
+
::URI.encode("https://api.elsevier.com/content/search/scopus?sort=artnum&query=#{query}")
|
54
|
+
end
|
55
|
+
# Get URI to obtain list of articles from a specific
|
56
|
+
# journal. You could specify year
|
57
|
+
def get_uri_journal_articles(journal,year=nil)
|
58
|
+
query="EXACTSRCTITLE(\"#{journal}\")"
|
59
|
+
query+=" AND PUBYEAR IS #{year}" if year
|
60
|
+
::URI.encode("https://api.elsevier.com/content/search/scopus?apiKey=#{key}&query=#{query}")
|
61
|
+
end
|
62
|
+
def get_uri_abstract(id,type="scopus_id",opts={:view=>"FULL"})
|
63
|
+
raise "Type should be a string" unless type.is_a? String
|
64
|
+
if opts[:view]
|
65
|
+
opts_s="view=#{opts[:view]}"
|
66
|
+
elsif opts[:field]
|
67
|
+
opts_s="field=#{opts[:field]}"
|
68
|
+
end
|
69
|
+
::URI.encode("https://api.elsevier.com/content/abstract/#{type}/#{id}?#{opts_s}")
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
module ElsevierApi
|
29
|
+
module XMLResponse
|
30
|
+
|
31
|
+
class ElsevierApi::XMLResponse::Abstractcitationsresponse < XMLResponseGeneric
|
32
|
+
attr_reader :h_index # How many records are in the xml
|
33
|
+
attr_reader :year_range
|
34
|
+
attr_reader :prev_total
|
35
|
+
attr_reader :later_total
|
36
|
+
attr_reader :column_total
|
37
|
+
attr_reader :range_total
|
38
|
+
attr_reader :grand_total
|
39
|
+
attr_reader :records
|
40
|
+
attr_reader :n_records
|
41
|
+
def process
|
42
|
+
#p @xml
|
43
|
+
@h_index=process_path(@xml,"//h-index").to_i
|
44
|
+
@year_range=@xml.xpath("//columnHeading").map {|xx| xx.text.to_i}
|
45
|
+
@prev_total=process_path(@xml,"//prevColumnTotal").to_i
|
46
|
+
@later_total=process_path(@xml,"//laterColumnTotal").to_i
|
47
|
+
@column_total=@xml.xpath("//columnTotal").map {|xx| xx.text.to_i}
|
48
|
+
@range_total=process_path(@xml,"//rangeColumnTotal").to_i
|
49
|
+
@grand_total=process_path(@xml,"//grandTotal").to_i
|
50
|
+
|
51
|
+
|
52
|
+
@records=xml.xpath("//citeInfo").map do |x|
|
53
|
+
scopus_id=process_path(x,".//dc:identifier")
|
54
|
+
|
55
|
+
pcc=process_path(x,".//pcc").to_i
|
56
|
+
cc=x.xpath(".//cc").map {|xx| xx.text.to_i}
|
57
|
+
|
58
|
+
lcc=process_path(x,".//lcc").to_i
|
59
|
+
#if scopus_id=="SCOPUS_ID:84866769122"
|
60
|
+
# p x
|
61
|
+
# p({:scopus_id=>scopus_id,:pcc=>pcc,:lcc=>lcc,:cc=>cc})
|
62
|
+
#end
|
63
|
+
{:scopus_id=>scopus_id,:pcc=>pcc,:lcc=>lcc,:cc=>cc}
|
64
|
+
end
|
65
|
+
#p @records
|
66
|
+
end
|
67
|
+
def n_records
|
68
|
+
@records.length
|
69
|
+
end
|
70
|
+
|
71
|
+
def scopus_id_a
|
72
|
+
@records.map {|r| r[:scopus_id]}
|
73
|
+
end
|
74
|
+
def get_record(scopus_id)
|
75
|
+
record=@records.find {|r| r[:scopus_id]==scopus_id}
|
76
|
+
raise("Record doesn't exists") unless record
|
77
|
+
record
|
78
|
+
end
|
79
|
+
def empty_record?(scopus_id)
|
80
|
+
record=get_record(scopus_id)
|
81
|
+
record[:cc]==[]
|
82
|
+
end
|
83
|
+
def citations_by_year(scopus_id)
|
84
|
+
record=get_record(scopus_id)
|
85
|
+
return nil if record[:cc].length==0
|
86
|
+
year_range.each_index.inject({}) {|ac,i|
|
87
|
+
ac[@year_range[i]]=record[:cc][i]
|
88
|
+
ac
|
89
|
+
}
|
90
|
+
end
|
91
|
+
def citations_outside_range?(scopus_id)
|
92
|
+
@grand_total!=@range_total
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,333 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
|
29
|
+
require 'digest'
|
30
|
+
|
31
|
+
#
|
32
|
+
module ElsevierApi
|
33
|
+
module XMLResponse
|
34
|
+
class Abstractsretrievalresponse < XMLResponseGeneric
|
35
|
+
NA_AFFILIATION="NAFD:**NA**"
|
36
|
+
NA_AFFILIATION_NAME="__No affiliation__"
|
37
|
+
attr_reader :scopus_id
|
38
|
+
attr_reader :cited_by_count
|
39
|
+
attr_reader :title
|
40
|
+
attr_reader :eid
|
41
|
+
attr_reader :type_code
|
42
|
+
attr_reader :type
|
43
|
+
attr_reader :year
|
44
|
+
attr_reader :journal
|
45
|
+
attr_reader :authors
|
46
|
+
attr_reader :volume
|
47
|
+
attr_reader :issue
|
48
|
+
attr_reader :starting_page
|
49
|
+
attr_reader :ending_page
|
50
|
+
attr_reader :doi
|
51
|
+
attr_reader :affiliations
|
52
|
+
attr_reader :abstract
|
53
|
+
attr_reader :subject_areas
|
54
|
+
attr_reader :author_keywords
|
55
|
+
attr_reader :book_title
|
56
|
+
attr_reader :author_groups
|
57
|
+
def inspect
|
58
|
+
"#<#{self.class}:#{self.object_id} @title=#{@title} @journal=#{@journal} @authors=[#{@authors.keys.join(",")}]>"
|
59
|
+
end
|
60
|
+
def process
|
61
|
+
|
62
|
+
@authors={}
|
63
|
+
@affiliations={}
|
64
|
+
@author_keywords=[]
|
65
|
+
@subject_areas=[]
|
66
|
+
@author_groups=[]
|
67
|
+
process_basic_metadata
|
68
|
+
process_taxonomy
|
69
|
+
process_affiliations
|
70
|
+
process_author_groups
|
71
|
+
process_authors
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# We can't find the affiliation the ussual way
|
76
|
+
# we have to improvise
|
77
|
+
# Given the afid, we search on every <affiliation> tag until
|
78
|
+
# we find the desired one
|
79
|
+
def search_affiliation(afid)
|
80
|
+
x=xml.at_xpath("//affiliation[@afid=\"#{afid}\"]")
|
81
|
+
if !x
|
82
|
+
raise "I can't find affiliation #{afid}"
|
83
|
+
else
|
84
|
+
name=x.xpath("organization").map { |e| e.text }.join(";")
|
85
|
+
city=process_path(xml, "//affiliation[@afid=\"#{afid}\"]/city-group")
|
86
|
+
country=process_path(xml, "//affiliation[@afid=\"#{afid}\"]/country")
|
87
|
+
country||=x.attribute("country").value
|
88
|
+
end
|
89
|
+
{:id => afid, :name => name, :city => city, :country => country,:type=>:scopus}
|
90
|
+
end
|
91
|
+
|
92
|
+
# We have to find doi on
|
93
|
+
def search_doi
|
94
|
+
if xml.at_xpath("//source").text=~/^\s*http:\/\/dx\.doi\.org\/([^\s]+)/
|
95
|
+
return $1
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def get_affiliation_id(aff)
|
101
|
+
if aff.nil?
|
102
|
+
nil
|
103
|
+
elsif id=aff.attribute('afid')
|
104
|
+
id.value
|
105
|
+
else
|
106
|
+
city, country, id, name = get_affiliation_data(aff)
|
107
|
+
id
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def search_affiliation_country(id)
|
112
|
+
return nil if id.nil?
|
113
|
+
process_path(xml, "//affiliation[@afid='#{id}']/country")
|
114
|
+
end
|
115
|
+
def process_affiliations
|
116
|
+
xml.xpath("/xmlns:abstracts-retrieval-response/xmlns:affiliation").each do |x|
|
117
|
+
id=x.attribute("id").nil? ? "" : x.attribute("id").value
|
118
|
+
next if id==""
|
119
|
+
name=process_path(x, "xmlns:affilname")
|
120
|
+
city=process_path(x, "xmlns:affiliation-city")
|
121
|
+
country=process_path(x, "xmlns:affiliation-country")
|
122
|
+
country=search_affiliation_country(id) if (country=="")
|
123
|
+
@affiliations[id]={
|
124
|
+
:id => id,
|
125
|
+
:name => name,
|
126
|
+
:city => city,
|
127
|
+
:country => country,
|
128
|
+
:type=>:scopus
|
129
|
+
}
|
130
|
+
end
|
131
|
+
add_unidentified_affilitations
|
132
|
+
end
|
133
|
+
|
134
|
+
# Some affiliations doesn't have an id. We could create it
|
135
|
+
# hashing the name and the country on unidentified filliations on
|
136
|
+
# head tag
|
137
|
+
# The process only add the affiliation if name is not nil
|
138
|
+
|
139
|
+
def get_id_affiliation(name,city,country)
|
140
|
+
"NS:"+Digest::MD5.hexdigest("#{name}|#{city}|#{country}")
|
141
|
+
end
|
142
|
+
def add_unidentified_affilitations
|
143
|
+
xml.xpath("//bibrecord/head/author-group/affiliation").each do |aff|
|
144
|
+
next if aff.attribute("afid")
|
145
|
+
city, country, id, name = get_affiliation_data(aff)
|
146
|
+
next if (name=="" and city=="" and country=="")
|
147
|
+
|
148
|
+
|
149
|
+
@affiliations[id]={
|
150
|
+
:id => id,
|
151
|
+
:name => name,
|
152
|
+
:city => city,
|
153
|
+
:country => country,
|
154
|
+
:type=>:non_scopus
|
155
|
+
}
|
156
|
+
end
|
157
|
+
end
|
158
|
+
def add_no_affiliation_case(auid)
|
159
|
+
id=NA_AFFILIATION+":"+Digest::MD5.hexdigest("#{@scopus_id}|#{auid}")
|
160
|
+
@affiliations[id]={
|
161
|
+
:id => id,
|
162
|
+
:name => "#{@scopus_id}|#{auid}",
|
163
|
+
:city => "",
|
164
|
+
:country => "NO_COUNTRY",
|
165
|
+
:type=>:non_scopus
|
166
|
+
}
|
167
|
+
id
|
168
|
+
end
|
169
|
+
def get_affiliation_data(aff)
|
170
|
+
organization=aff.xpath("organization").map { |e| e.text }.join(";")
|
171
|
+
address=aff.xpath("address-part").map { |e| e.text }.join(";")
|
172
|
+
name= organization!="" ? organization : address
|
173
|
+
city_only=aff.xpath("city").text
|
174
|
+
city_part=aff.xpath("city-group").text
|
175
|
+
city= city_only!="" ? city_only : city_part
|
176
|
+
country=aff.xpath("country").text
|
177
|
+
|
178
|
+
name="UNKOWN ORG FOR #{@scopus_id} ARTICLE" if name==""
|
179
|
+
country="NO_COUNTRY" if country==""
|
180
|
+
|
181
|
+
|
182
|
+
id=get_id_affiliation(name,city,country)
|
183
|
+
return city, country, id, name
|
184
|
+
end
|
185
|
+
|
186
|
+
# Author groups gives us information about the authors
|
187
|
+
# groups as appears on the head. Could be useful to retrieve
|
188
|
+
# information about missing affilitations
|
189
|
+
# Author-groups with authors duplicated are eliminated
|
190
|
+
def process_author_groups
|
191
|
+
author_groups_temp=xml.xpath("//bibrecord/head/author-group").map do |ag|
|
192
|
+
process_one_author_group(ag)
|
193
|
+
end
|
194
|
+
|
195
|
+
#authors_list= []
|
196
|
+
@author_groups=author_groups_temp
|
197
|
+
# @author_groups=[]
|
198
|
+
# author_groups_temp.each do |ag|
|
199
|
+
# @author_groups.push(ag) unless ag[:authors].any? {|author| authors_list.include? author}
|
200
|
+
# authors_list=authors_list | ag[:authors]
|
201
|
+
# end
|
202
|
+
|
203
|
+
end
|
204
|
+
|
205
|
+
|
206
|
+
def process_one_author_group(ag)
|
207
|
+
if aff_node = ag.at_xpath("affiliation")
|
208
|
+
city, country, afid1, name = get_affiliation_data(aff_node)
|
209
|
+
aff_id2 = get_affiliation_id(ag.at_xpath("affiliation"))
|
210
|
+
if (name == "" and city == "" and country == "")
|
211
|
+
aff_id = nil
|
212
|
+
else
|
213
|
+
aff_id = aff_id2
|
214
|
+
end
|
215
|
+
else
|
216
|
+
aff_id = nil
|
217
|
+
end
|
218
|
+
{:authors => ag.xpath("author").map {|auth|
|
219
|
+
a = auth.attribute('auid')
|
220
|
+
a ? a.value : nil},
|
221
|
+
:affiliation => aff_id
|
222
|
+
}
|
223
|
+
end
|
224
|
+
|
225
|
+
private :process_one_author_group
|
226
|
+
|
227
|
+
|
228
|
+
def process_authors
|
229
|
+
xml.xpath("//xmlns:authors/xmlns:author").each do |x|
|
230
|
+
auid=x.attribute("auid").value
|
231
|
+
seq=x.attribute("seq").value
|
232
|
+
initials =process_path(x, "xmlns:preferred-name/ce:initials")
|
233
|
+
indexed_name = process_path(x, "xmlns:preferred-name/ce:indexed-name")
|
234
|
+
given_name =process_path(x, "xmlns:preferred-name/ce:given-name")
|
235
|
+
surname=process_path(x, "xmlns:preferred-name/ce:surname")
|
236
|
+
affiliation=nil
|
237
|
+
affiliation_node=x.xpath("xmlns:affiliation")
|
238
|
+
|
239
|
+
if affiliation_node.length==1
|
240
|
+
affiliation=affiliation_node[0].attribute("id").text
|
241
|
+
if !affiliation.nil? and @affiliations[affiliation].nil?
|
242
|
+
@affiliations[affiliation]=search_affiliation(affiliation)
|
243
|
+
end
|
244
|
+
elsif affiliation_node.length>1
|
245
|
+
affiliation=affiliation_node.map{|af|
|
246
|
+
af.attribute("id").text
|
247
|
+
}.uniq
|
248
|
+
affiliation.each do |af|
|
249
|
+
if !af.nil? and @affiliations[af].nil?
|
250
|
+
@affiliations[af]=search_affiliation(af)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
else
|
254
|
+
# Must search in author-groups for affilitation
|
255
|
+
res=@author_groups.find{|ag|
|
256
|
+
ag[:authors].include? auid
|
257
|
+
}
|
258
|
+
|
259
|
+
if res
|
260
|
+
affiliation=res[:affiliation]
|
261
|
+
end
|
262
|
+
if affiliation.nil?
|
263
|
+
# Affiliation shouldn't be nil. We create a custom affiliation for this cases
|
264
|
+
affiliation=add_no_affiliation_case(auid)
|
265
|
+
end
|
266
|
+
|
267
|
+
#
|
268
|
+
end
|
269
|
+
|
270
|
+
#p "#{name} #{apellido}"
|
271
|
+
@authors[auid]={
|
272
|
+
:auid => auid,
|
273
|
+
:seq => seq,
|
274
|
+
:initials => initials,
|
275
|
+
:indexed_name => indexed_name,
|
276
|
+
:given_name => given_name,
|
277
|
+
:surname => surname,
|
278
|
+
:email => nil,
|
279
|
+
:affiliation => affiliation
|
280
|
+
}
|
281
|
+
|
282
|
+
|
283
|
+
end
|
284
|
+
# Searching for authors e-mails
|
285
|
+
|
286
|
+
xml.xpath("//bibrecord//head//author-group/author//ce:e-address[@type='email']").each do |email|
|
287
|
+
auid=email.parent.attribute("auid").value
|
288
|
+
@authors[auid][:email]=email.text
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
|
293
|
+
def process_taxonomy
|
294
|
+
xml.xpath("//xmlns:authkeywords/xmlns:author-keyword").each do |x|
|
295
|
+
@author_keywords.push(x.text)
|
296
|
+
end
|
297
|
+
xml.xpath("//xmlns:subject-areas/xmlns:subject-area").each do |x|
|
298
|
+
@subject_areas.push(
|
299
|
+
{:abbrev => x.attribute("abbrev").value,
|
300
|
+
:code => x.attribute("code").value.to_i,
|
301
|
+
:name => x.text
|
302
|
+
}
|
303
|
+
)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def process_basic_metadata
|
308
|
+
@scopus_id = process_path(xml, "//dc:identifier")
|
309
|
+
@title = process_path(xml, "//dc:title")
|
310
|
+
@doi = process_path(xml, "//prism:doi")
|
311
|
+
@doi||=search_doi
|
312
|
+
@eid = process_path(xml, "//xmlns:eid")
|
313
|
+
@type_code = process_path(xml, "//xmlns:srctype")
|
314
|
+
@cited_by_count = process_path(xml,"//xmlns:citedby-count").to_i
|
315
|
+
@type = process_path(xml, "//prism:aggregationType").downcase.to_sym
|
316
|
+
if @type_code=="j" or @type_code=="p"
|
317
|
+
@journal =process_path(xml, "//prism:publicationName")
|
318
|
+
@volume =process_path(xml, "//prism:volume")
|
319
|
+
@issue =process_path(xml, "//prism:issueIdentifier")
|
320
|
+
elsif @type_code=="b"
|
321
|
+
@book_title =process_path(xml, "//prism:publicationName")
|
322
|
+
end
|
323
|
+
@starting_page =process_path(xml, "//prism:startingPage")
|
324
|
+
@ending_page =process_path(xml, "//prism:endingPage")
|
325
|
+
@year =process_path(xml, "//year")
|
326
|
+
@abstract =process_path(xml, "//dc:description/xmlns:abstract[@xml:lang='eng']/ce:para")
|
327
|
+
@abstract ||=process_path(xml, "//abstract/ce:para")
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
module ElsevierApi
|
29
|
+
module XMLResponse
|
30
|
+
class ElsevierApi::XMLResponse::Authorretrievalresponse < XMLResponseGeneric
|
31
|
+
def proccess
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
|
29
|
+
# PENDING
|
30
|
+
module ElsevierApi
|
31
|
+
module XMLResponse
|
32
|
+
class ElsevierApi::XMLResponse::Authorretrievalresponselist < XMLResponseGeneric
|
33
|
+
def proccess
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
module ElsevierApi
|
29
|
+
module XMLResponse
|
30
|
+
|
31
|
+
class ElsevierApi::XMLResponse::Searchresults < XMLResponseGeneric
|
32
|
+
def next_page
|
33
|
+
@xml.at_xpath("//atom:link[@ref='next']")
|
34
|
+
end
|
35
|
+
def entries_to_ary
|
36
|
+
@xml.xpath("//atom:entry").map {|v|
|
37
|
+
title=v.at_xpath("dc:title").nil? ? nil : v.at_xpath("dc:title").text
|
38
|
+
journal=v.at_xpath("prism:publicationName").nil? ? nil : v.at_xpath("prism:publicationName").text
|
39
|
+
h={
|
40
|
+
:scopus_id=>v.at_xpath("dc:identifier").text,
|
41
|
+
:title=>title,
|
42
|
+
:journal=>journal
|
43
|
+
}
|
44
|
+
{:creator=>"dc:creator",:doi=>"prism:doi"}.each_pair {|key,xv|
|
45
|
+
h[key]=v.at_xpath(xv).text unless v.at_xpath(xv).nil?
|
46
|
+
}
|
47
|
+
h
|
48
|
+
}
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
module ElsevierApi
|
29
|
+
module XMLResponse
|
30
|
+
|
31
|
+
class ElsevierApi::XMLResponse::Serviceerror < XMLResponseGeneric
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
module ElsevierApi
|
29
|
+
module XMLResponse
|
30
|
+
class XMLEmpty
|
31
|
+
def error
|
32
|
+
true
|
33
|
+
end
|
34
|
+
def error_msg
|
35
|
+
I18n::t(:empty_xml_file)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
class XMLResponseGeneric
|
39
|
+
attr_reader :xml
|
40
|
+
def initialize(xml)
|
41
|
+
@xml=xml
|
42
|
+
process()
|
43
|
+
end
|
44
|
+
# Just put anything you want here
|
45
|
+
def process
|
46
|
+
end
|
47
|
+
def process_path(x, path)
|
48
|
+
node=x.at_xpath(path)
|
49
|
+
(node.nil?) ? nil : node.text
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
require_relative "xml_response/abstract_retrieval_response"
|
57
|
+
require_relative "xml_response/search_results"
|
58
|
+
require_relative "xml_response/service_error"
|
59
|
+
require_relative "xml_response/abstract_citation_response"
|
60
|
+
require_relative "xml_response/author_retrieval_response"
|
61
|
+
require_relative "xml_response/author_retrieval_response_list"
|
data/lib/elsevier_api.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Copyright (c) 2016-2020, Claudio Bustos Navarrete
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# * Redistributions of source code must retain the above copyright notice, this
|
8
|
+
# list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# * Neither the name of the copyright holder nor the names of its
|
15
|
+
# contributors may be used to endorse or promote products derived from
|
16
|
+
# this software without specific prior written permission.
|
17
|
+
#
|
18
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
19
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
20
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
21
|
+
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
22
|
+
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
23
|
+
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
24
|
+
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
25
|
+
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
26
|
+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
27
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
28
|
+
|
29
|
+
require 'nokogiri'
|
30
|
+
# Module ElsevierApi
|
31
|
+
#
|
32
|
+
# Provides access to ElsevierApi dev services
|
33
|
+
module ElsevierApi
|
34
|
+
# Factory method
|
35
|
+
def self.process_xml(xml)
|
36
|
+
|
37
|
+
xml=Nokogiri::XML(xml) if xml.is_a? String
|
38
|
+
if xml.children.length==0
|
39
|
+
# Error
|
40
|
+
ElsevierApi::XMLResponse::XMLEmpty.new
|
41
|
+
else
|
42
|
+
name=xml.children[0].name.gsub("-","").capitalize
|
43
|
+
ElsevierApi::XMLResponse.const_get(name.to_sym).new(xml)
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.entries_to_csv(entries,csv_file)
|
49
|
+
require 'csv'
|
50
|
+
d=Date.today.to_s
|
51
|
+
header=["scopus_id","title","journal","creator","doi","date"]
|
52
|
+
CSV.open(csv_file,"wb") {|csv|
|
53
|
+
csv << header
|
54
|
+
entries.each {|e|
|
55
|
+
csv << [e[:scopus_id],e[:title],e[:journal], e[:creator],e[:doi],d]
|
56
|
+
}
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
require_relative "elsevier_api/uri_request"
|
63
|
+
require_relative "elsevier_api/connection"
|
64
|
+
require_relative "elsevier_api/xml_response"
|
65
|
+
|
66
|
+
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: elsevier_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Claudio Bustos
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-02-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.12'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.12'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: nokogiri
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.6'
|
55
|
+
description: 'A Ruby gem for use with Elsevier''s APIs: Scopus, ScienceDirect, others. '
|
56
|
+
email:
|
57
|
+
- clbustos@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- ".idea/vcs.xml"
|
63
|
+
- Gemfile
|
64
|
+
- Gemfile.lock
|
65
|
+
- LICENSE
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- bin/elsevier-api-console
|
69
|
+
- elsevier_api.gemspec
|
70
|
+
- lib/elsevier_api.rb
|
71
|
+
- lib/elsevier_api/connection.rb
|
72
|
+
- lib/elsevier_api/uri_request.rb
|
73
|
+
- lib/elsevier_api/version.rb
|
74
|
+
- lib/elsevier_api/xml_response.rb
|
75
|
+
- lib/elsevier_api/xml_response/abstract_citation_response.rb
|
76
|
+
- lib/elsevier_api/xml_response/abstract_retrieval_response.rb
|
77
|
+
- lib/elsevier_api/xml_response/author_retrieval_response.rb
|
78
|
+
- lib/elsevier_api/xml_response/author_retrieval_response_list.rb
|
79
|
+
- lib/elsevier_api/xml_response/search_results.rb
|
80
|
+
- lib/elsevier_api/xml_response/service_error.rb
|
81
|
+
homepage: https://github.com/clbustos/elsevier_api
|
82
|
+
licenses:
|
83
|
+
- BSD-3-Clause
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubygems_version: 3.1.2
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Ruby gem to interact with Elsevier's APIs
|
104
|
+
test_files: []
|