olibrary 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/.gitignore +9 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/README.rdoc +238 -0
- data/Rakefile +4 -0
- data/lib/olibrary/client/authors.rb +10 -0
- data/lib/olibrary/client/books.rb +31 -0
- data/lib/olibrary/client/editions.rb +10 -0
- data/lib/olibrary/client/history.rb +9 -0
- data/lib/olibrary/client/login.rb +10 -0
- data/lib/olibrary/client/recent.rb +9 -0
- data/lib/olibrary/client/save.rb +18 -0
- data/lib/olibrary/client/search.rb +50 -0
- data/lib/olibrary/client.rb +31 -0
- data/lib/olibrary/data.rb +76 -0
- data/lib/olibrary/details.rb +53 -0
- data/lib/olibrary/errors.rb +6 -0
- data/lib/olibrary/request.rb +109 -0
- data/lib/olibrary/version.rb +3 -0
- data/lib/olibrary/view.rb +51 -0
- data/lib/olibrary.rb +21 -0
- data/openlibrary.gemspec +29 -0
- data/spec/client_spec.rb +256 -0
- data/spec/fixtures/author.json +12 -0
- data/spec/fixtures/book.json +59 -0
- data/spec/fixtures/book_by_isbn.json +1 -0
- data/spec/fixtures/book_by_lccn.json +1 -0
- data/spec/fixtures/book_by_oclc.json +1 -0
- data/spec/fixtures/editions.json +354 -0
- data/spec/fixtures/free_search.json +7841 -0
- data/spec/fixtures/history.json +261 -0
- data/spec/fixtures/recent.json +16807 -0
- data/spec/fixtures/save_after_change.json +42 -0
- data/spec/fixtures/save_before_change.json +42 -0
- data/spec/fixtures/search.json +7933 -0
- data/spec/openlibrary_spec.rb +69 -0
- data/spec/spec_helper.rb +56 -0
- metadata +179 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require 'rest-client'
|
|
2
|
+
require 'active_support'
|
|
3
|
+
require 'active_support/core_ext'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'uri'
|
|
6
|
+
require 'hashie'
|
|
7
|
+
|
|
8
|
+
module Olibrary
|
|
9
|
+
module Request
|
|
10
|
+
API_URL = 'https://openlibrary.org'
|
|
11
|
+
|
|
12
|
+
protected
|
|
13
|
+
|
|
14
|
+
HANDLE_REST_CLIENT_RESPONSE = lambda do |response, request, result, &block|
|
|
15
|
+
case response.code
|
|
16
|
+
when 200
|
|
17
|
+
response.return!(&block)
|
|
18
|
+
when 401
|
|
19
|
+
raise Olibrary::Unauthorized
|
|
20
|
+
when 404
|
|
21
|
+
raise Olibrary::NotFound
|
|
22
|
+
when 302
|
|
23
|
+
raise Olibrary::Redirect
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Perform a GET request
|
|
28
|
+
#
|
|
29
|
+
# path - Request path
|
|
30
|
+
#
|
|
31
|
+
def request(path, params={})
|
|
32
|
+
request_url = "#{API_URL}#{path}"
|
|
33
|
+
perform_get_request(request_url, params)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# Get the history of an object in Open Library
|
|
38
|
+
#
|
|
39
|
+
# object - Object key, e.g., '/books/OL1M'
|
|
40
|
+
#
|
|
41
|
+
def history(object, params={})
|
|
42
|
+
history_url = "#{API_URL}#{object}.json?m=history"
|
|
43
|
+
perform_get_request(history_url, params)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Perform a query using the Query API
|
|
47
|
+
#
|
|
48
|
+
# query - Query path, e.g. "type=/type/edition&isbn_10=XXXXXXXXXX"
|
|
49
|
+
#
|
|
50
|
+
def query(query, params={})
|
|
51
|
+
query_url = "#{API_URL}/query.json?#{query}"
|
|
52
|
+
perform_get_request(query_url, params)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def protected_login(username, password, params={})
|
|
56
|
+
params.merge!(content_type: :json, accept: :json)
|
|
57
|
+
url = "#{API_URL}/account/login"
|
|
58
|
+
login = { 'username' => username, 'password' => password }.to_json
|
|
59
|
+
|
|
60
|
+
resp = RestClient.post(url, login, params) do |response|
|
|
61
|
+
case response.code
|
|
62
|
+
when 200
|
|
63
|
+
session = response.cookies
|
|
64
|
+
session
|
|
65
|
+
when 401
|
|
66
|
+
raise Olibrary::Unauthorized
|
|
67
|
+
when 404
|
|
68
|
+
raise Olibrary::NotFound
|
|
69
|
+
when 302
|
|
70
|
+
raise Olibrary::Redirect
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Update an Open Library object
|
|
76
|
+
#
|
|
77
|
+
# key - Object key the Open Library resource
|
|
78
|
+
# cookie - Cookie retrieved by the login method
|
|
79
|
+
# update - Complete updated Open Library object in JSON format
|
|
80
|
+
# comment - Comment describing the change(s) to the object
|
|
81
|
+
#
|
|
82
|
+
def update(key, cookie, update, comment, params={})
|
|
83
|
+
cookie_header = { 'Cookie' => cookie }
|
|
84
|
+
comment_header = {
|
|
85
|
+
'Opt' => '"http://openlibrary.org/dev/docs/api"; ns=42',
|
|
86
|
+
'42-comment' => comment
|
|
87
|
+
}
|
|
88
|
+
params.merge!(cookie_header)
|
|
89
|
+
params.merge!(comment_header)
|
|
90
|
+
params.merge!(content_type: :json, accept: :json)
|
|
91
|
+
update_url = "#{API_URL}#{key}"
|
|
92
|
+
|
|
93
|
+
response = RestClient.put(update_url, update, params, &HANDLE_REST_CLIENT_RESPONSE)
|
|
94
|
+
parse(response)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def parse(response)
|
|
98
|
+
JSON.parse(response.body)
|
|
99
|
+
end
|
|
100
|
+
private :parse
|
|
101
|
+
|
|
102
|
+
def perform_get_request(url, params)
|
|
103
|
+
params.merge!(accept: :json)
|
|
104
|
+
response = RestClient.get(url, params, &HANDLE_REST_CLIENT_RESPONSE)
|
|
105
|
+
parse(response)
|
|
106
|
+
end
|
|
107
|
+
private :perform_get_request
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Olibrary
|
|
2
|
+
|
|
3
|
+
class View
|
|
4
|
+
attr_accessor :bib_key
|
|
5
|
+
attr_accessor :info_url
|
|
6
|
+
attr_accessor :preview
|
|
7
|
+
attr_accessor :preview_url
|
|
8
|
+
attr_accessor :thumbnail_url
|
|
9
|
+
|
|
10
|
+
def self.find_by_isbn(key)
|
|
11
|
+
find("ISBN",key)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.find_by_lccn(key)
|
|
15
|
+
find("LCCN",key)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.find_by_oclc(key)
|
|
19
|
+
find("OCLC",key)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.find_by_olid(key)
|
|
23
|
+
find("OLID",key)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.find(type,key)
|
|
27
|
+
type_for_uri = URI.encode_www_form_component(type)
|
|
28
|
+
key_for_uri = URI.encode_www_form_component(key)
|
|
29
|
+
|
|
30
|
+
response = RestClient.get "http://openlibrary.org/api/books" +
|
|
31
|
+
"?bibkeys=#{type_for_uri}:#{key_for_uri}&format=json&jscmd=viewapi"
|
|
32
|
+
response_data = JSON.parse(response)
|
|
33
|
+
view = response_data["#{type}:#{key}"]
|
|
34
|
+
|
|
35
|
+
if view
|
|
36
|
+
view_meta = new
|
|
37
|
+
|
|
38
|
+
view_meta.bib_key = view["bib_key"]
|
|
39
|
+
view_meta.info_url = view["info_url"]
|
|
40
|
+
view_meta.preview = view["preview"]
|
|
41
|
+
view_meta.preview_url = view["preview_url"]
|
|
42
|
+
view_meta.thumbnail_url = view["thumbnail_url"]
|
|
43
|
+
|
|
44
|
+
view_meta
|
|
45
|
+
else
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
data/lib/olibrary.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'olibrary/version'
|
|
2
|
+
require_relative 'olibrary/data'
|
|
3
|
+
require_relative 'olibrary/view'
|
|
4
|
+
require_relative 'olibrary/client'
|
|
5
|
+
require_relative 'olibrary/errors'
|
|
6
|
+
require_relative 'olibrary/request'
|
|
7
|
+
require_relative 'olibrary/details'
|
|
8
|
+
|
|
9
|
+
module Olibrary
|
|
10
|
+
# Create a new Olibrary::Client instance
|
|
11
|
+
#
|
|
12
|
+
def self.new(options={})
|
|
13
|
+
Olibrary::Client.new(options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Return the openlibrary gem version
|
|
17
|
+
#
|
|
18
|
+
def self.version
|
|
19
|
+
"Olibrary version #{Olibrary::VERSION}"
|
|
20
|
+
end
|
|
21
|
+
end
|
data/openlibrary.gemspec
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
|
3
|
+
require "olibrary/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |s|
|
|
6
|
+
s.name = "olibrary"
|
|
7
|
+
s.version = Olibrary::VERSION
|
|
8
|
+
s.authors = ["Yosef Serkez"]
|
|
9
|
+
s.email = ["yosefserkez@gmail.com"]
|
|
10
|
+
s.homepage = "https://github.com/4till2/olibrary"
|
|
11
|
+
s.summary = %q{Ruby Interface for the openlibrary.org API}
|
|
12
|
+
s.description = %q{openlibrary.org API Interface}
|
|
13
|
+
|
|
14
|
+
s.rubyforge_project = "olibrary"
|
|
15
|
+
|
|
16
|
+
s.files = `git ls-files`.split("\n")
|
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
|
19
|
+
s.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
s.add_development_dependency 'rspec', '~> 3.11.0'
|
|
22
|
+
s.add_development_dependency 'webmock', '~> 3.14.0'
|
|
23
|
+
|
|
24
|
+
s.add_runtime_dependency 'hashie', '~> 5.0.0'
|
|
25
|
+
s.add_runtime_dependency 'json', '>= 2.6.1'
|
|
26
|
+
s.add_runtime_dependency 'rest-client', '~> 2.1.0'
|
|
27
|
+
|
|
28
|
+
s.add_runtime_dependency 'activesupport', '~> 7.0.2.3'
|
|
29
|
+
end
|
data/spec/client_spec.rb
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe 'Client' do
|
|
4
|
+
let(:client) { Olibrary::Client.new }
|
|
5
|
+
|
|
6
|
+
describe '#new' do
|
|
7
|
+
it 'requires an argument' do
|
|
8
|
+
expect { Olibrary::Client.new(nil) }.
|
|
9
|
+
to raise_error ArgumentError, "Options hash required."
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'requires a hash argument' do
|
|
13
|
+
expect { Olibrary::Client.new('foo') }.
|
|
14
|
+
to raise_error ArgumentError, "Options hash required."
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe '#book' do
|
|
19
|
+
before do
|
|
20
|
+
olid = 'OL23109860M'
|
|
21
|
+
stub_get("/books/#{olid}", 'book.json')
|
|
22
|
+
end
|
|
23
|
+
it 'returns book details' do
|
|
24
|
+
expect { client.book('OL23109860M') }.not_to raise_error
|
|
25
|
+
|
|
26
|
+
book = client.book('OL23109860M')
|
|
27
|
+
|
|
28
|
+
expect(book).to be_a Hashie::Mash
|
|
29
|
+
expect(book.contributors).to be_a Array
|
|
30
|
+
expect(book.covers).to be_a Array
|
|
31
|
+
expect(book.works).to be_a Array
|
|
32
|
+
|
|
33
|
+
expect(book.title).to eq 'The Great Gatsby'
|
|
34
|
+
expect(book.by_statement).to eq 'F. Scott Fitzgerald.'
|
|
35
|
+
expect(book.number_of_pages).to eq 180
|
|
36
|
+
expect(book.contributors[0].name).to eq 'Francis Cugat'
|
|
37
|
+
expect(book.contributors[0].role).to eq 'Cover Art'
|
|
38
|
+
expect(book.copyright_date).to eq '1925'
|
|
39
|
+
expect(book.isbn_10[0]).to eq '0743273567'
|
|
40
|
+
expect(book.identifiers.goodreads[0]).to eq '4671'
|
|
41
|
+
expect(book.identifiers.google[0]).to eq 'iXn5U2IzVH0C'
|
|
42
|
+
expect(book.physical_format).to eq 'Trade Paperback'
|
|
43
|
+
expect(book.publishers[0]).to eq 'Scribner'
|
|
44
|
+
expect(book.subjects[1]).to eq 'First loves -- Fiction'
|
|
45
|
+
expect(book.subjects[0]).to eq 'Traffic accidents -- Fiction'
|
|
46
|
+
|
|
47
|
+
# Because of a conflict with the internal `key?` method of
|
|
48
|
+
# Hashie::Mash, any key actually named 'key' must be referenced
|
|
49
|
+
# with a bang (!) to get the value.
|
|
50
|
+
expect(book.key!).to eq '/books/OL23109860M'
|
|
51
|
+
expect(book.languages[0].key!).to eq '/languages/eng'
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe '#book_by_isbn' do
|
|
56
|
+
before do
|
|
57
|
+
isbn_10 = '046503912X'
|
|
58
|
+
type = '/type/edition'
|
|
59
|
+
stub_get("/query.json?type=#{type}&isbn_10=#{isbn_10}",
|
|
60
|
+
'book_by_isbn.json')
|
|
61
|
+
end
|
|
62
|
+
it 'returns array of books' do
|
|
63
|
+
expect { client.book_by_isbn('046503912X').not_to raise_error }
|
|
64
|
+
expect { client.book_by_isbn('123').
|
|
65
|
+
to raise_error ArgumentError, "ISBN must be 10 or 13 characters." }
|
|
66
|
+
|
|
67
|
+
books = client.book_by_isbn('046503912X')
|
|
68
|
+
|
|
69
|
+
expect(books).to be_a Array
|
|
70
|
+
expect(books[0]).to be_a Hash
|
|
71
|
+
|
|
72
|
+
expect(books[0]['key']).to eq '/books/OL6807502M'
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe '#book_by_lccn' do
|
|
77
|
+
before do
|
|
78
|
+
lccn = '00271772'
|
|
79
|
+
type = '/type/edition'
|
|
80
|
+
stub_get("/query.json?type=#{type}&lccn=#{lccn}",
|
|
81
|
+
'book_by_lccn.json')
|
|
82
|
+
end
|
|
83
|
+
it 'returns array of books' do
|
|
84
|
+
expect { client.book_by_lccn('00271772').not_to raise_error }
|
|
85
|
+
|
|
86
|
+
books = client.book_by_lccn('00271772')
|
|
87
|
+
|
|
88
|
+
expect(books).to be_a Array
|
|
89
|
+
expect(books[0]).to be_a Hash
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe '#book_by_oclc' do
|
|
94
|
+
before do
|
|
95
|
+
oclc = '42860053'
|
|
96
|
+
type = '/type/edition'
|
|
97
|
+
stub_get("/query.json?type=#{type}&oclc_numbers=#{42860053}",
|
|
98
|
+
'book_by_oclc.json')
|
|
99
|
+
end
|
|
100
|
+
it 'returns array of books' do
|
|
101
|
+
expect { client.book_by_oclc('42860053').not_to raise_error }
|
|
102
|
+
|
|
103
|
+
books = client.book_by_oclc('42860053')
|
|
104
|
+
|
|
105
|
+
expect(books).to be_a Array
|
|
106
|
+
expect(books[0]).to be_a Hash
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe '#author' do
|
|
111
|
+
before do
|
|
112
|
+
key = 'OL1A'
|
|
113
|
+
stub_get("/authors/#{key}", 'author.json')
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
it 'returns author details' do
|
|
117
|
+
expect { client.author('OL1A') }.not_to raise_error
|
|
118
|
+
|
|
119
|
+
author = client.author('OL1A')
|
|
120
|
+
|
|
121
|
+
expect(author).to be_a Hashie::Mash
|
|
122
|
+
expect(author.name).to eq 'Sachi Rautroy'
|
|
123
|
+
expect(author.personal_name).to eq 'Sachi Rautroy'
|
|
124
|
+
expect(author.death_date).to eq '2004'
|
|
125
|
+
expect(author.birth_date).to eq '1916'
|
|
126
|
+
expect(author.last_modified.type).to eq '/type/datetime'
|
|
127
|
+
expect(author.last_modified.value).to eq '2008-11-16T07:25:54.131674'
|
|
128
|
+
expect(author.id).to eq 97
|
|
129
|
+
expect(author.revision).to eq 6
|
|
130
|
+
|
|
131
|
+
# Because of a conflict with the internal `key?` method of
|
|
132
|
+
# Hashie::Mash, any key actually named 'key' must be referenced
|
|
133
|
+
# with a bang (!) to get the value.
|
|
134
|
+
expect(author.key!).to eq '/authors/OL1A'
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
describe '#rev_history' do
|
|
139
|
+
before do
|
|
140
|
+
key = '/books/OL1M'
|
|
141
|
+
stub_get("#{key}.json?m=history", 'history.json')
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'returns the revision history of an object' do
|
|
145
|
+
expect { client.rev_history('/books/OL1M') }.not_to raise_error
|
|
146
|
+
|
|
147
|
+
history = client.rev_history('/books/OL1M')
|
|
148
|
+
|
|
149
|
+
expect(history).to be_a Array
|
|
150
|
+
expect(history[0]).to be_a Hash
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
describe '#recent' do
|
|
155
|
+
before do
|
|
156
|
+
stub_get("/recentchanges", 'recent.json')
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it 'returns recent changes to Open Library' do
|
|
160
|
+
expect { client.recent.not_to raise_error }
|
|
161
|
+
|
|
162
|
+
changes = client.recent
|
|
163
|
+
|
|
164
|
+
expect(changes).to be_a Array
|
|
165
|
+
expect(changes[0]).to be_a Hash
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe '#editions' do
|
|
170
|
+
before do
|
|
171
|
+
work = 'OL27258W'
|
|
172
|
+
stub_get("/works/#{work}/editions.json?limit=10&offset=0", 'editions.json')
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it 'returns the editions of a work' do
|
|
176
|
+
expect { client.editions('OL27258W') }.not_to raise_error
|
|
177
|
+
|
|
178
|
+
editions = client.editions('OL27258W', 10, 0)
|
|
179
|
+
|
|
180
|
+
expect(editions).to be_a Hashie::Mash
|
|
181
|
+
expect(editions.entries).to be_a Array
|
|
182
|
+
|
|
183
|
+
expect(editions.size!).to eq 19
|
|
184
|
+
expect(editions.links.next).to eq '/works/OL27258W/editions.json?limit=10&offset=10'
|
|
185
|
+
expect(editions.links.self).to eq '/works/OL27258W/editions.json?limit=10&offset=0'
|
|
186
|
+
expect(editions.links.work).to eq '/works/OL27258W'
|
|
187
|
+
|
|
188
|
+
# Failing tests for iteration through entries
|
|
189
|
+
#
|
|
190
|
+
# editions.entries[0].should be_a Hashie::Mash
|
|
191
|
+
# editions.entries[0].number_of_pages.should eq 322
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
describe '#search' do
|
|
196
|
+
before do
|
|
197
|
+
stub_get("/search.json?author=tolkien&title=lord%20of%20the%20rings", 'search.json')
|
|
198
|
+
stub_get("/search.json?q=capitalism%20and%20freedom", 'free_search.json')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it 'returns book search results' do
|
|
202
|
+
search = {title: "lord of the rings", author: "tolkien"}
|
|
203
|
+
expect {client.search(search)}.not_to raise_error
|
|
204
|
+
|
|
205
|
+
search = client.search(search, 5, 10)
|
|
206
|
+
|
|
207
|
+
expect(search.size).to eq 5
|
|
208
|
+
expect(search[0].key!).to eq 'OL14926051W'
|
|
209
|
+
expect(search[0].title).to eq 'The Lord of Rings'
|
|
210
|
+
|
|
211
|
+
expect {client.search("capitalism and freedom")}.not_to raise_error
|
|
212
|
+
free_search = client.search("capitalism and freedom")
|
|
213
|
+
|
|
214
|
+
expect(free_search.size).to eq 10
|
|
215
|
+
expect(free_search[0].key!).to eq 'OL2747782W'
|
|
216
|
+
expect(free_search[0].author_name[0]).to eq 'Milton Friedman'
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
describe '#login' do
|
|
221
|
+
before do
|
|
222
|
+
stub_http_request(:post, "https://openlibrary.org/account/login").
|
|
223
|
+
with( body: "{\"username\":\"username\",\"password\":\"password\"}" ).
|
|
224
|
+
to_return( status: 200, headers: {'Set-Cookie' => 'session=cookie'} )
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
it 'logs in to Open Library' do
|
|
228
|
+
expect { client.login('username', 'password') }.not_to raise_error
|
|
229
|
+
|
|
230
|
+
cookie = client.login('username', 'password')
|
|
231
|
+
expect(cookie).to eq "cookie"
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
describe '#after_save' do
|
|
236
|
+
before do
|
|
237
|
+
key = "/books/OL9674499M"
|
|
238
|
+
comment = 'update weight and number of pages'
|
|
239
|
+
stub_put(key, 'save_after_change.json', comment)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'PUTs the updated object, and receives the updated object as a response' do
|
|
243
|
+
key = "/books/OL9674499M"
|
|
244
|
+
cookie = 'cookie'
|
|
245
|
+
update = fixture('save_after_change.json')
|
|
246
|
+
comment = 'update weight and number of pages'
|
|
247
|
+
|
|
248
|
+
expect { client.save(key, cookie, update, comment) }.not_to raise_error
|
|
249
|
+
|
|
250
|
+
object = client.save(key, cookie, update, comment)
|
|
251
|
+
|
|
252
|
+
expect(object.weight).to eq '1.5 pounds'
|
|
253
|
+
expect(object.number_of_pages).to eq 1103
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{ "birth_date" : "1916",
|
|
2
|
+
"death_date" : "2004",
|
|
3
|
+
"id" : 97,
|
|
4
|
+
"key" : "/authors/OL1A",
|
|
5
|
+
"last_modified" : { "type" : "/type/datetime",
|
|
6
|
+
"value" : "2008-11-16T07:25:54.131674"
|
|
7
|
+
},
|
|
8
|
+
"name" : "Sachi Rautroy",
|
|
9
|
+
"personal_name" : "Sachi Rautroy",
|
|
10
|
+
"revision" : 6,
|
|
11
|
+
"type" : { "key" : "/type/author" }
|
|
12
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{ "authors" : [ { "key" : "/authors/OL27349A" } ],
|
|
2
|
+
"by_statement" : "F. Scott Fitzgerald.",
|
|
3
|
+
"classifications" : { },
|
|
4
|
+
"contributors" : [ { "name" : "Francis Cugat",
|
|
5
|
+
"role" : "Cover Art"
|
|
6
|
+
} ],
|
|
7
|
+
"copyright_date" : "1925",
|
|
8
|
+
"covers" : [ 6776207,
|
|
9
|
+
6725316,
|
|
10
|
+
6390463
|
|
11
|
+
],
|
|
12
|
+
"created" : { "type" : "/type/datetime",
|
|
13
|
+
"value" : "2009-02-18T18:42:07.162489"
|
|
14
|
+
},
|
|
15
|
+
"dewey_decimal_class" : [ "813" ],
|
|
16
|
+
"genres" : [ "Fiction." ],
|
|
17
|
+
"ia_box_id" : [ "IA119605" ],
|
|
18
|
+
"identifiers" : { "goodreads" : [ "4671" ],
|
|
19
|
+
"google" : [ "iXn5U2IzVH0C" ],
|
|
20
|
+
"librarything" : [ "2964" ]
|
|
21
|
+
},
|
|
22
|
+
"isbn_10" : [ "0743273567" ],
|
|
23
|
+
"isbn_13" : [ "9780743273565" ],
|
|
24
|
+
"key" : "/books/OL23109860M",
|
|
25
|
+
"languages" : [ { "key" : "/languages/eng" } ],
|
|
26
|
+
"last_modified" : { "type" : "/type/datetime",
|
|
27
|
+
"value" : "2011-08-12T01:22:25.394416"
|
|
28
|
+
},
|
|
29
|
+
"latest_revision" : 12,
|
|
30
|
+
"lc_classifications" : [ "PS3511.I9 G7 2004" ],
|
|
31
|
+
"lccn" : [ "25010468" ],
|
|
32
|
+
"notes" : { "type" : "/type/text",
|
|
33
|
+
"value" : "* [Publisher's Website for this edition][1]\r\n\r\n\r\n [1]: http://books.simonandschuster.com/Great-Gatsby/F-Scott-Fitzgerald/9780743273565"
|
|
34
|
+
},
|
|
35
|
+
"number_of_pages" : 180,
|
|
36
|
+
"ocaid" : "greatgat00fitz",
|
|
37
|
+
"oclc_number" : [ "57215622" ],
|
|
38
|
+
"oclc_numbers" : [ "57215622" ],
|
|
39
|
+
"pagination" : "180 p. ;",
|
|
40
|
+
"physical_format" : "Trade Paperback",
|
|
41
|
+
"publish_country" : "nyu",
|
|
42
|
+
"publish_date" : "2004",
|
|
43
|
+
"publish_places" : [ "New York, New York, USA" ],
|
|
44
|
+
"publishers" : [ "Scribner" ],
|
|
45
|
+
"revision" : 12,
|
|
46
|
+
"source_records" : [ "marc:SanFranPL14/SanFranPL14.out:71962031:12930",
|
|
47
|
+
"ia:greatgat00fitz"
|
|
48
|
+
],
|
|
49
|
+
"subjects" : [ "Traffic accidents -- Fiction",
|
|
50
|
+
"First loves -- Fiction",
|
|
51
|
+
"Rich people -- Fiction",
|
|
52
|
+
"Mistresses -- Fiction",
|
|
53
|
+
"Revenge -- Fiction",
|
|
54
|
+
"Long Island (N.Y.) -- Fiction"
|
|
55
|
+
],
|
|
56
|
+
"title" : "The Great Gatsby",
|
|
57
|
+
"type" : { "key" : "/type/edition" },
|
|
58
|
+
"works" : [ { "key" : "/works/OL468431W" } ]
|
|
59
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"key": "/books/OL6807502M"}]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"key": "/books/OL6807502M"}]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"key": "/books/OL6807502M"}]
|