europeana-api 0.5.2 → 1.0.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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +4 -2
  4. data/Gemfile +1 -8
  5. data/README.md +103 -21
  6. data/Rakefile +2 -1
  7. data/bin/console +21 -0
  8. data/europeana-api.gemspec +12 -1
  9. data/lib/europeana/api.rb +44 -68
  10. data/lib/europeana/api/annotation.rb +20 -0
  11. data/lib/europeana/api/client.rb +51 -0
  12. data/lib/europeana/api/entity.rb +16 -0
  13. data/lib/europeana/api/errors.rb +25 -41
  14. data/lib/europeana/api/faraday_middleware.rb +26 -0
  15. data/lib/europeana/api/faraday_middleware/request/authenticated_request.rb +25 -0
  16. data/lib/europeana/api/faraday_middleware/request/parameter_repetition.rb +25 -0
  17. data/lib/europeana/api/faraday_middleware/response/handle_text.rb +19 -0
  18. data/lib/europeana/api/faraday_middleware/response/parse_json_to_various.rb +52 -0
  19. data/lib/europeana/api/logger.rb +10 -0
  20. data/lib/europeana/api/queue.rb +47 -0
  21. data/lib/europeana/api/record.rb +29 -83
  22. data/lib/europeana/api/request.rb +77 -38
  23. data/lib/europeana/api/resource.rb +30 -0
  24. data/lib/europeana/api/response.rb +47 -0
  25. data/lib/europeana/api/version.rb +2 -1
  26. data/spec/europeana/api/annotation_spec.rb +77 -0
  27. data/spec/europeana/api/client_spec.rb +46 -0
  28. data/spec/europeana/api/entity_spec.rb +6 -0
  29. data/spec/europeana/api/faraday_middleware/request/authenticated_request_spec.rb +22 -0
  30. data/spec/europeana/api/queue_spec.rb +4 -0
  31. data/spec/europeana/api/record_spec.rb +54 -104
  32. data/spec/europeana/api/request_spec.rb +3 -0
  33. data/spec/europeana/api/resource_spec.rb +47 -0
  34. data/spec/europeana/api/response_spec.rb +10 -0
  35. data/spec/europeana/api_spec.rb +34 -84
  36. data/spec/spec_helper.rb +8 -0
  37. data/spec/support/shared_examples/resource_endpoint.rb +11 -0
  38. metadata +158 -34
  39. data/lib/europeana/api/record/hierarchy.rb +0 -48
  40. data/lib/europeana/api/record/hierarchy/ancestor_self_siblings.rb +0 -12
  41. data/lib/europeana/api/record/hierarchy/base.rb +0 -30
  42. data/lib/europeana/api/record/hierarchy/children.rb +0 -12
  43. data/lib/europeana/api/record/hierarchy/following_siblings.rb +0 -12
  44. data/lib/europeana/api/record/hierarchy/parent.rb +0 -12
  45. data/lib/europeana/api/record/hierarchy/preceding_siblings.rb +0 -15
  46. data/lib/europeana/api/record/hierarchy/self.rb +0 -12
  47. data/lib/europeana/api/requestable.rb +0 -118
  48. data/lib/europeana/api/search.rb +0 -64
  49. data/lib/europeana/api/search/fields.rb +0 -112
  50. data/spec/europeana/api/errors_spec.rb +0 -23
  51. data/spec/europeana/api/record/hierarchy_spec.rb +0 -15
  52. data/spec/europeana/api/search_spec.rb +0 -97
  53. data/spec/support/shared_examples/api_request.rb +0 -65
  54. data/spec/support/shared_examples/record_request.rb +0 -26
  55. data/spec/support/shared_examples/search_request.rb +0 -42
  56. data/spec/support/webmock.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 330985d53a6b1fb63021e3144d271c09b518deab
4
- data.tar.gz: 7d8c128ff306ba05a4f7a2a4e041c08fbce564b3
3
+ metadata.gz: a0b2c092e5307dddee16a30424d9f095d1881006
4
+ data.tar.gz: 9e55b99b93b151cf461c3ddf297329c163a7a3df
5
5
  SHA512:
6
- metadata.gz: 66111e036999c9cabcbd0ce2bbccccf507cccca8ca6d963c8ca68deeb66d7af01588be958c7fc984aad2a88c56538e95ca6e5301562adb236d229b1517c7a393
7
- data.tar.gz: 2d243b1d9e517e5b95a11d28e7853092421005541de037dfa824bc4b215113694d11e1e83cbfb88f2eb19fa9cae6f325646db3433f489b8c5faee1c216f2d3ec
6
+ metadata.gz: 57332276a79ed9680b91d31ed8439c67adef397fea3377062eb48797118796722d40e5506dd5fc829e13ea5e375ad81b0460495d1c8c125f3b0d1659756b003f
7
+ data.tar.gz: bfa182f373f3df742b5db95b3bb14ed9014b0c8ea99545e69ae5c37e1f52a02a9ef14c1104bd76f42e74185ef69a2f96e51cb174dfc74030335828b821eb43ee
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ /.ruby-version
5
6
  .yardoc
6
7
  Gemfile.lock
7
8
  InstalledFiles
@@ -15,3 +16,5 @@ spec/reports
15
16
  test/tmp
16
17
  test/version_tmp
17
18
  tmp
19
+ /.env
20
+ /.env.*
@@ -1,12 +1,14 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
4
- - 2.1.7
5
3
  - 2.2.2
6
4
  - 2.2.3
7
5
  - 2.3.1
6
+ - 2.3.3
7
+ - 2.4.0
8
8
  notifications:
9
9
  email: false
10
10
  sudo: false
11
11
  cache:
12
12
  bundler: true
13
+ before_install:
14
+ - gem update --system
data/Gemfile CHANGED
@@ -1,12 +1,5 @@
1
+ # frozen_string_literal: true
1
2
  source 'https://rubygems.org'
2
3
 
3
4
  # Specify your gem's dependencies in europeana.gemspec
4
5
  gemspec
5
-
6
- group :test do
7
- gem 'coveralls', require: false
8
- end
9
-
10
- group :test, :develop do
11
- gem 'rubocop', '0.39.0', require: false # only update when Hound does
12
- end
data/README.md CHANGED
@@ -1,15 +1,13 @@
1
- # Europeana
1
+ # Europeana API
2
2
 
3
- [![Build Status](https://travis-ci.org/europeana/europeana-api-client-ruby.svg?branch=master)](https://travis-ci.org/europeana/europeana-api-client-ruby) [![Coverage Status](https://coveralls.io/repos/europeana/europeana-api-client-ruby/badge.svg?branch=master&service=github)](https://coveralls.io/github/europeana/europeana-api-client-ruby?branch=master) [![security](https://hakiri.io/github/europeana/europeana-api-client-ruby/master.svg)](https://hakiri.io/github/europeana/europeana-api-client-ruby/master) [![Dependency Status](https://gemnasium.com/europeana/europeana-api-client-ruby.svg)](https://gemnasium.com/europeana/europeana-api-client-ruby)
3
+ [![Build Status](https://travis-ci.org/europeana/europeana-api-client-ruby.svg?branch=develop)](https://travis-ci.org/europeana/europeana-api-client-ruby) [![Coverage Status](https://coveralls.io/repos/europeana/europeana-api-client-ruby/badge.svg?branch=develop&service=github)](https://coveralls.io/github/europeana/europeana-api-client-ruby?branch=develop) [![security](https://hakiri.io/github/europeana/europeana-api-client-ruby/develop.svg)](https://hakiri.io/github/europeana/europeana-api-client-ruby/develop) [![Dependency Status](https://gemnasium.com/europeana/europeana-api-client-ruby.svg)](https://gemnasium.com/europeana/europeana-api-client-ruby)
4
4
 
5
5
  Ruby client library for the search and retrieval of records from the [Europeana
6
6
  REST API](http://labs.europeana.eu/api/introduction/).
7
7
 
8
- ## License
9
-
10
- Licensed under the EUPL V.1.1.
8
+ ## Requirements
11
9
 
12
- For full details, see [LICENSE.md](LICENSE.md).
10
+ * Ruby >= 2.2.2
13
11
 
14
12
  ## Installation
15
13
 
@@ -21,19 +19,21 @@ gem 'europeana-api'
21
19
 
22
20
  And then execute:
23
21
 
24
- $ bundle
22
+ ```
23
+ bundle
24
+ ```
25
25
 
26
26
  Or install it yourself as:
27
27
 
28
- $ gem install europeana-api
28
+ ```
29
+ gem install europeana-api
30
+ ```
29
31
 
30
32
  ## Usage
31
33
 
32
34
  ### Authentication
33
35
 
34
- Authentication is *required* for all requests to the Europeana API.
35
-
36
- Only Basic Authentication (by API key) is supported.
36
+ Authentication by API key is *required* for all requests to the Europeana API.
37
37
 
38
38
  Sign up for an API key at: http://labs.europeana.eu/api/registration/
39
39
 
@@ -41,26 +41,108 @@ Configure your application with the API key:
41
41
 
42
42
  ```ruby
43
43
  require 'europeana/api'
44
- Europeana::API.api_key = 'xyz'
44
+ Europeana::API.key = 'xyz'
45
+ ```
46
+
47
+ ### Response format
48
+
49
+ Responses from the API methods described below will by default be hashes with
50
+ indifferent access, i.e. values can be retrieved by string or symbol keys.
51
+
52
+ To have API methods return objects instead:
53
+ ```ruby
54
+ Europeana::API.configure do |config|
55
+ config.parse_json_to = OpenStruct
56
+ end
45
57
  ```
46
58
 
47
- ### Search
59
+ ### Records
60
+
61
+ #### Search
48
62
 
49
63
  ```ruby
50
- search = Europeana::API.search(query: '"first world war"') # => { "success" => true, "items" => [ ... ], "totalResults" => 1234, ... }
51
- search['items'] # => [ item1, item2, ... ]
52
- search['totalResults'] # => 1234
64
+ search = Europeana::API.record.search(query: '"first world war"')
65
+ search[:items] # => [ item1, item2, ... ]
66
+ search[:totalResults] # => 81530
53
67
  ```
54
68
 
55
- See http://labs.europeana.eu/api/search/ for details of the data returned in
56
- the search response.
69
+ See http://labs.europeana.eu/api/search/ for details of the available request
70
+ parameters, and of the data returned in the search response.
57
71
 
58
- ### Record
72
+ #### Fetch
59
73
 
60
74
  ```ruby
61
- record = Europeana::API.record('/abc/1234') # => { "success" => true, "object" => { ... }, ... }
62
- record['object'] # => { "title" => "...", "proxies" => [ ... ], "aggregations" => [ ... ], ... }
75
+ record = Europeana::API.record.fetch(id: '/92070/BibliographicResource_1000126223918')
76
+ record[:object][:title] # => ["Panorama des Schafberges in Ober-Österreich. Blatt 1"]
77
+ record[:object][:proxies].first[:dcCreator][:def] # => ["Simony, Friedrich"]
63
78
  ```
64
79
 
65
80
  See http://labs.europeana.eu/api/record/ for details of the data returned in
66
81
  the record response.
82
+
83
+ #### Hierarchies
84
+
85
+ ```ruby
86
+ hierarchy = Europeana::API.record.parent(id: '/2048604/data_item_onb_abo__2BZ17084070X')
87
+ hierarchy[:parent][:id] # => "/2048604/data_item_onb_abo_AC10352829"
88
+ ```
89
+
90
+ Methods available for hierarchy retrieval:
91
+ ```ruby
92
+ Europeana::API.record.self
93
+ Europeana::API.record.parent
94
+ Europeana::API.record.children
95
+ Europeana::API.record.preceding_siblings
96
+ Europeana::API.record.following_siblings
97
+ Europeana::API.record.ancestor_self_siblings
98
+ ```
99
+
100
+ See http://labs.europeana.eu/api/hierarchical-records for details of the various
101
+ hierarchy methods and their responses.
102
+
103
+ ### Annotations
104
+
105
+ See http://labs.europeana.eu/api/annotations-methods for details of the responses
106
+ received from the Annotations API methods.
107
+
108
+ #### Search
109
+
110
+ ```ruby
111
+ search = Europeana::API.annotation.search(query: 'music')
112
+ search[:items].first # => "http://data.europeana.eu/annotation/collections/8"
113
+ ```
114
+
115
+ #### Fetch
116
+
117
+ ```ruby
118
+ annotation = Europeana::API.annotation.fetch(provider: 'collections', id: 8)
119
+ annotation[:body] # => "Sheet music"
120
+ ```
121
+
122
+ #### Create
123
+
124
+ ```ruby
125
+ body = { bodyValue: 'Trombones', motivation: 'tagging', target: 'http://data.europeana.eu/item/09102/_UEDIN_214' }
126
+ annotation = Europeana::API.annotation.create(userToken: 'secret-token', body: body.to_json)
127
+ annotation[:id] # => "http://www.europeana.eu/api/annotations/myname/1234"
128
+ ```
129
+
130
+ #### Update
131
+
132
+ ```ruby
133
+ body = { bodyValue: 'Trombones', motivation: 'tagging' }
134
+ annotation = Europeana::API.annotation.update(provider: 'myname', id: '1234', userToken: 'secret-token', body: body.to_json)
135
+ annotation[:body][:value] # => "Trombones"
136
+ ```
137
+
138
+ #### Delete
139
+
140
+ ```ruby
141
+ Europeana::API.annotation.delete(provider: 'myname', id: '1234', userToken: 'secret-token') # => ""
142
+ ```
143
+
144
+ ## License
145
+
146
+ Licensed under the EUPL V.1.1.
147
+
148
+ For full details, see [LICENSE.md](LICENSE.md).
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
1
2
  require 'bundler/gem_tasks'
2
3
  require 'rspec/core/rake_task'
3
- task :default => :spec
4
+ task default: :spec
4
5
  RSpec::Core::RakeTask.new
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'dotenv'
5
+ Dotenv.load
6
+
7
+ require 'bundler/setup'
8
+ require 'europeana/api'
9
+
10
+ # You can add fixtures and/or initialization code here to make experimenting
11
+ # with your gem easier. You can also use a different console, if you like.
12
+
13
+ # (If you use this, don't forget to add pry to your Gemfile!)
14
+ # require 'pry'
15
+ # Pry.start
16
+
17
+ Europeana::API.key = ENV['EUROPEANA_API_KEY']
18
+ Europeana::API.url = ENV['EUROPEANA_API_URL'] if ENV['EUROPEANA_API_URL']
19
+
20
+ require 'irb'
21
+ IRB.start
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ # frozen_string_literal: true
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'europeana/api/version'
@@ -20,11 +21,21 @@ Gem::Specification.new do |spec|
20
21
 
21
22
  spec.required_ruby_version = '>= 2.0.0'
22
23
 
23
- spec.add_dependency 'activesupport', '>= 3.0', '< 5'
24
+ spec.add_dependency 'activesupport', '>= 4.2', '< 6.0'
25
+ # Locked to < v0.12.2 due to incompatibility with v0.12.2
26
+ # TODO: resolve incompatibility and unlock
27
+ spec.add_dependency 'faraday', '~> 0.9', '< 0.12.2'
28
+ spec.add_dependency 'faraday_middleware'
24
29
  spec.add_dependency 'multi_json', '~> 1.0'
30
+ spec.add_dependency 'rack', '> 1.6.2'
31
+ spec.add_dependency 'typhoeus', '~> 1.1'
25
32
 
26
33
  spec.add_development_dependency 'bundler', '~> 1.3'
34
+ spec.add_development_dependency 'coveralls'
35
+ spec.add_development_dependency 'dotenv'
27
36
  spec.add_development_dependency 'rake'
28
37
  spec.add_development_dependency 'rspec', '~> 3.0'
38
+ spec.add_development_dependency 'rubocop', '0.39.0' # only update when Hound does
39
+ spec.add_development_dependency 'shoulda-matchers', '~> 3.1'
29
40
  spec.add_development_dependency 'webmock', '~> 1.18.0'
30
41
  end
@@ -1,112 +1,88 @@
1
- require 'active_support/cache'
2
- require 'active_support/core_ext/object'
1
+ # frozen_string_literal: true
2
+ require 'active_support/concern'
3
+ require 'active_support/core_ext/class/attribute'
3
4
  require 'active_support/core_ext/hash/indifferent_access'
4
5
  require 'active_support/core_ext/hash/slice'
6
+ require 'active_support/core_ext/module/delegation'
7
+ require 'active_support/core_ext/object'
5
8
  require 'active_support/hash_with_indifferent_access'
6
9
  require 'active_support/inflector/methods'
10
+ require 'active_support/json'
7
11
  require 'europeana/api/version'
12
+ require 'europeana/api/logger'
8
13
  require 'logger'
9
14
  require 'uri'
10
15
 
11
16
  module Europeana
12
17
  ##
13
- # Europeana REST API client
18
+ # Interface to Europeana's RESTful API(s)
14
19
  module API
20
+ autoload :Annotation, 'europeana/api/annotation'
21
+ autoload :Client, 'europeana/api/client'
22
+ autoload :Entity, 'europeana/api/entity'
15
23
  autoload :Errors, 'europeana/api/errors'
24
+ autoload :FaradayMiddleware, 'europeana/api/faraday_middleware'
25
+ autoload :Queue, 'europeana/api/queue'
16
26
  autoload :Record, 'europeana/api/record'
17
27
  autoload :Request, 'europeana/api/request'
18
- autoload :Requestable, 'europeana/api/requestable'
19
- autoload :Search, 'europeana/api/search'
28
+ autoload :Resource, 'europeana/api/resource'
29
+ autoload :Response, 'europeana/api/response'
30
+
31
+ @url = 'https://www.europeana.eu/api'
20
32
 
21
33
  class << self
22
34
  ##
23
35
  # The Europeana API key, required for authentication
24
36
  #
25
37
  # @return [String]
26
- attr_accessor :api_key
38
+ attr_accessor :key
27
39
 
28
40
  ##
29
41
  # The API's base URL
30
42
  #
31
43
  # @return [String]
32
44
  attr_accessor :url
33
-
34
- ##
35
- # The maximum number of retries permitted
36
- #
37
- # Retries occur when a network request to the API fails. The default is 5
38
- # retries before giving up.
39
- #
40
- # @return [Integer]
41
- attr_accessor :max_retries
42
-
43
- ##
44
- # The number of seconds to wait between retries
45
- #
46
- # The default is 10 seconds.
47
- #
48
- # @return [Integer]
49
- attr_accessor :retry_delay
50
45
 
51
46
  # @return [Logger]
52
47
  attr_writer :logger
53
48
 
54
- attr_accessor :cache_store
49
+ def configuration
50
+ @configuration ||= Configuration.new
51
+ end
55
52
 
56
- attr_accessor :cache_expires_in
53
+ def logger
54
+ @logger ||= defined?(Rails) && Rails.logger ? Rails.logger : Logger.new(STDOUT)
55
+ end
57
56
 
58
- ##
59
- # Sets configuration values to their defaults
60
- def defaults!
61
- self.url = 'https://www.europeana.eu/api/v2'
62
- self.max_retries = 5
63
- self.retry_delay = 10
64
- self.cache_store = ActiveSupport::Cache::NullStore.new
65
- self.cache_expires_in = 24.hours
57
+ def configure
58
+ yield(configuration)
66
59
  end
67
60
 
68
- ##
69
- # Sends a Search request to the Europeana API
70
- #
71
- # Equivalent to:
72
- # search = Europeana::API::Search.new(params)
73
- # search.execute
74
- #
75
- # @param [Hash] params Query parameters
76
- # @return [Hash] search response
77
- # @see Europeana::API::Search#execute
78
- def search(params = {})
79
- Search.new(params).execute
61
+ def in_parallel(&block)
62
+ client = Client.new
63
+ yield client.queue
64
+ client.queue.run
80
65
  end
81
66
 
82
- ##
83
- # Sends a Record request to the Europeana API
84
- #
85
- # Equivalent to:
86
- # record = Europeana::API::Record.new(record_id, params)
87
- # record.get(options)
88
- #
89
- # @param [String] Record ID
90
- # @param [Hash] params Query parameters
91
- # @param [Hash] options (see Europeana::API::Record#get)
92
- # @return [Hash] search response
93
- # @see Europeana::API::Record#get
94
- def record(record_id, params = {}, options = {})
95
- Record.new(record_id, params).get(options)
67
+ def annotation
68
+ Annotation
96
69
  end
97
70
 
98
- def logger
99
- return @logger unless @logger.nil?
71
+ def record
72
+ Record
73
+ end
100
74
 
101
- @logger = case
102
- when defined?(Rails) && Rails.logger
103
- Rails.logger
104
- else
105
- Logger.new(STDOUT)
106
- end
75
+ def entity
76
+ Entity
107
77
  end
108
78
  end
109
79
 
110
- self.defaults!
80
+ class Configuration
81
+ attr_accessor :parse_json_to
82
+
83
+ def initialize
84
+ @parse_json_to = Hash
85
+ end
86
+ end
111
87
  end
112
88
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ module Europeana
3
+ module API
4
+ ##
5
+ # An annotation of a Europeana object
6
+ #
7
+ # @see http://labs.europeana.eu/api/annotations
8
+ class Annotation
9
+ include Resource
10
+
11
+ has_api_endpoint :search, method: :get, path: '/annotations/search'
12
+ has_api_endpoint :fetch, method: :get, path: '/annotations/%{provider}/%{id}'
13
+ has_api_endpoint :create, method: :post, path: '/annotations/',
14
+ headers: { 'Content-Type' => 'application/ld+json' }
15
+ has_api_endpoint :update, method: :put, path: '/annotations/%{provider}/%{id}',
16
+ headers: { 'Content-Type' => 'application/ld+json' }
17
+ has_api_endpoint :delete, method: :delete, path: '/annotations/%{provider}/%{id}'
18
+ end
19
+ end
20
+ end