elsevier_api 0.1.0
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 +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: []
|