titlepage 1.3.0 → 1.4.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.
- data/Rakefile +6 -8
- data/lib/titlepage.rb +3 -2
- data/lib/titlepage/client.rb +1 -2
- data/lib/titlepage/rest.rb +89 -0
- data/lib/titlepage/utils.rb +3 -3
- metadata +68 -27
- data/examples/titlepage_www.rb +0 -10
- data/lib/titlepage/wwwclient.rb +0 -100
data/Rakefile
CHANGED
@@ -6,11 +6,9 @@ require 'rake/testtask'
|
|
6
6
|
require "rake/gempackagetask"
|
7
7
|
require 'spec/rake/spectask'
|
8
8
|
|
9
|
-
PKG_VERSION = "1.
|
9
|
+
PKG_VERSION = "1.4.0"
|
10
10
|
PKG_NAME = "titlepage"
|
11
11
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
12
|
-
RUBYFORGE_PROJECT = 'rbook'
|
13
|
-
RUBYFORGE_USER = 'yob'
|
14
12
|
|
15
13
|
CLEAN.include "**/.*.sw*"
|
16
14
|
|
@@ -69,13 +67,13 @@ spec = Gem::Specification.new do |spec|
|
|
69
67
|
spec.has_rdoc = true
|
70
68
|
spec.extra_rdoc_files = %w{README COPYING LICENSE}
|
71
69
|
spec.rdoc_options << '--title' << 'titlepage Documentation' << '--main' << 'README' << '-q'
|
72
|
-
spec.add_dependency('
|
73
|
-
spec.add_dependency('andand', '1.3
|
74
|
-
spec.add_dependency('handsoap', '
|
70
|
+
spec.add_dependency('isbn10', '~>1.1')
|
71
|
+
spec.add_dependency('andand', '~>1.3')
|
72
|
+
spec.add_dependency('handsoap', '~>1.0')
|
73
|
+
spec.add_dependency('ean13', '~>1.4')
|
75
74
|
spec.author = "James Healy"
|
76
75
|
spec.email = "jimmy@deefa.com"
|
77
|
-
spec.
|
78
|
-
spec.homepage = "http://rbook.rubyforge.org/"
|
76
|
+
spec.homepage = "http://github.com/yob/titlepage"
|
79
77
|
spec.description = "This library is designed to assist with using the titlepage.com SOAP API."
|
80
78
|
end
|
81
79
|
|
data/lib/titlepage.rb
CHANGED
@@ -3,7 +3,8 @@
|
|
3
3
|
require "bigdecimal"
|
4
4
|
require "handsoap"
|
5
5
|
require "andand"
|
6
|
-
require "
|
6
|
+
require "isbn10"
|
7
|
+
require "ean13"
|
7
8
|
|
8
9
|
# a convenience module for accessing the SOAP API for http://www.titlepage.com.
|
9
10
|
# Uses boilerplate code generated by soap4r.
|
@@ -40,4 +41,4 @@ end
|
|
40
41
|
require File.dirname(__FILE__) + '/titlepage/driver'
|
41
42
|
require File.dirname(__FILE__) + '/titlepage/utils'
|
42
43
|
require File.dirname(__FILE__) + '/titlepage/client'
|
43
|
-
require File.dirname(__FILE__) + '/titlepage/
|
44
|
+
require File.dirname(__FILE__) + '/titlepage/rest'
|
data/lib/titlepage/client.rb
CHANGED
@@ -54,8 +54,7 @@ module TitlePage
|
|
54
54
|
|
55
55
|
def all(isbn)
|
56
56
|
return NotLoggedInError, 'You must login to titlepage API before performing a search' unless @token
|
57
|
-
isbn =
|
58
|
-
return nil if isbn.nil?
|
57
|
+
isbn = ISBN10.new(isbn).to_ean || isbn
|
59
58
|
@driver.search_by_isbn13(@token, isbn)
|
60
59
|
end
|
61
60
|
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
###################################################################
|
4
|
+
# A proxy REST web service for the titlepage SOAP API.
|
5
|
+
#
|
6
|
+
# Requires no state and exists to serialise requests to the authoritive
|
7
|
+
# API so that an organisation can avoid exceeding the API usage limits.
|
8
|
+
#
|
9
|
+
# To use this REST wrapper, run the following:
|
10
|
+
#
|
11
|
+
# thin -R config.ru -p 4567 start
|
12
|
+
#
|
13
|
+
# This make the following request:
|
14
|
+
#
|
15
|
+
# curl http://127.0.0.1:4567/username/password/ean
|
16
|
+
#
|
17
|
+
# Returns 400 if the requested EAN is invalid
|
18
|
+
# Returns 401 if the titlepage API returned an error, often an authentication issue
|
19
|
+
# Returns 404 if the requested EAN wasn't found on titlepage
|
20
|
+
# Returns 408 if the titlepage API didn't respond in time
|
21
|
+
# Returns 200 and a YAML serialised hash of results if the query was successful
|
22
|
+
#
|
23
|
+
###################################################################
|
24
|
+
|
25
|
+
require 'rubygems'
|
26
|
+
require 'sinatra/base'
|
27
|
+
require 'ean13'
|
28
|
+
require 'yaml'
|
29
|
+
require 'timeout'
|
30
|
+
|
31
|
+
module TitlePage
|
32
|
+
class Rest < Sinatra::Base
|
33
|
+
|
34
|
+
TIMESTAMP_FILE = "/tmp/titlepage.dat"
|
35
|
+
|
36
|
+
# We only respond to 1 URI
|
37
|
+
get '/:username/:password/:ean' do |username, password, ean|
|
38
|
+
status(400) and return unless EAN13.valid?(ean)
|
39
|
+
|
40
|
+
while (!update_file)
|
41
|
+
sleep 0.5
|
42
|
+
end
|
43
|
+
|
44
|
+
result = nil
|
45
|
+
|
46
|
+
begin
|
47
|
+
TitlePage::Client.open(username, password) do |tp|
|
48
|
+
Timeout::timeout(6) do
|
49
|
+
result = tp.first(ean)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
rescue Timeout::Error
|
53
|
+
status(408) and return
|
54
|
+
rescue Handsoap::Fault
|
55
|
+
status(401) and return
|
56
|
+
end
|
57
|
+
|
58
|
+
if result
|
59
|
+
YAML.dump(result.to_hash)
|
60
|
+
else
|
61
|
+
status(404)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# update a lock file that we use to track when the last query was proxied
|
68
|
+
# through to the authoritive Titlepage API.
|
69
|
+
#
|
70
|
+
# Updates the file and returns true if no query was made in the previous 3
|
71
|
+
# seconds, otherwise doesn't update the file and returns false.
|
72
|
+
#
|
73
|
+
# Used to ensure we don't exceed the query limit.
|
74
|
+
#
|
75
|
+
def update_file
|
76
|
+
if File.file?(TIMESTAMP_FILE)
|
77
|
+
if Time.now.to_i - File.mtime(TIMESTAMP_FILE).to_i > 3
|
78
|
+
File.open(TIMESTAMP_FILE, "w") { |of| of.write "titlepage timestamp"}
|
79
|
+
true
|
80
|
+
else
|
81
|
+
false
|
82
|
+
end
|
83
|
+
else
|
84
|
+
File.open(TIMESTAMP_FILE, "w") { |of| of.write "titlepage timestamp"}
|
85
|
+
true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/titlepage/utils.rb
CHANGED
@@ -131,6 +131,7 @@ module TitlePage
|
|
131
131
|
price = self.new
|
132
132
|
price.price_type_code = node.xpath("//Price/PriceTypeCode/text()").first.andand.to_s
|
133
133
|
val = node.xpath("//Price/PriceAmount/text()").first.andand.to_s
|
134
|
+
val = val.gsub(/[^\d\.]/,"") # strip any extra chars (like commas)
|
134
135
|
price.price_amount = BigDecimal.new(val) if val.size > 0
|
135
136
|
price
|
136
137
|
end
|
@@ -218,9 +219,8 @@ module TitlePage
|
|
218
219
|
:availability => self.supply_detail.product_availability,
|
219
220
|
:on_hand => self.supply_detail.stock.on_hand,
|
220
221
|
:on_order => self.supply_detail.stock.on_order,
|
221
|
-
:
|
222
|
-
:pack_quantity => self.supply_detail.pack_quantity
|
223
|
-
|
222
|
+
:expected_ship_date => self.supply_detail.expected_ship_date,
|
223
|
+
:pack_quantity => self.supply_detail.pack_quantity
|
224
224
|
}
|
225
225
|
end
|
226
226
|
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: titlepage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 7
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 1.4.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- James Healy
|
@@ -9,39 +15,69 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2010-09-03 00:00:00 +10:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
name: isbn10
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
|
-
- -
|
27
|
+
- - ~>
|
22
28
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
29
|
+
hash: 13
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 1
|
33
|
+
version: "1.1"
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
25
36
|
- !ruby/object:Gem::Dependency
|
26
37
|
name: andand
|
27
|
-
|
28
|
-
|
29
|
-
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
30
41
|
requirements:
|
31
|
-
- -
|
42
|
+
- - ~>
|
32
43
|
- !ruby/object:Gem::Version
|
33
|
-
|
34
|
-
|
44
|
+
hash: 9
|
45
|
+
segments:
|
46
|
+
- 1
|
47
|
+
- 3
|
48
|
+
version: "1.3"
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
35
51
|
- !ruby/object:Gem::Dependency
|
36
52
|
name: handsoap
|
37
|
-
|
38
|
-
|
39
|
-
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
40
56
|
requirements:
|
41
|
-
- -
|
57
|
+
- - ~>
|
42
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 15
|
60
|
+
segments:
|
61
|
+
- 1
|
62
|
+
- 0
|
43
63
|
version: "1.0"
|
44
|
-
|
64
|
+
type: :runtime
|
65
|
+
version_requirements: *id003
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: ean13
|
68
|
+
prerelease: false
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 7
|
75
|
+
segments:
|
76
|
+
- 1
|
77
|
+
- 4
|
78
|
+
version: "1.4"
|
79
|
+
type: :runtime
|
80
|
+
version_requirements: *id004
|
45
81
|
description: This library is designed to assist with using the titlepage.com SOAP API.
|
46
82
|
email: jimmy@deefa.com
|
47
83
|
executables: []
|
@@ -53,19 +89,18 @@ extra_rdoc_files:
|
|
53
89
|
- COPYING
|
54
90
|
- LICENSE
|
55
91
|
files:
|
56
|
-
- examples/titlepage_www.rb
|
57
92
|
- examples/titlepage.rb
|
58
93
|
- lib/titlepage.rb
|
59
94
|
- lib/titlepage/utils.rb
|
95
|
+
- lib/titlepage/rest.rb
|
60
96
|
- lib/titlepage/client.rb
|
61
|
-
- lib/titlepage/wwwclient.rb
|
62
97
|
- lib/titlepage/driver.rb
|
63
98
|
- Rakefile
|
64
99
|
- README
|
65
100
|
- COPYING
|
66
101
|
- LICENSE
|
67
102
|
has_rdoc: true
|
68
|
-
homepage: http://
|
103
|
+
homepage: http://github.com/yob/titlepage
|
69
104
|
licenses: []
|
70
105
|
|
71
106
|
post_install_message:
|
@@ -78,21 +113,27 @@ rdoc_options:
|
|
78
113
|
require_paths:
|
79
114
|
- lib
|
80
115
|
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
none: false
|
81
117
|
requirements:
|
82
118
|
- - ">="
|
83
119
|
- !ruby/object:Gem::Version
|
120
|
+
hash: 3
|
121
|
+
segments:
|
122
|
+
- 0
|
84
123
|
version: "0"
|
85
|
-
version:
|
86
124
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
87
126
|
requirements:
|
88
127
|
- - ">="
|
89
128
|
- !ruby/object:Gem::Version
|
129
|
+
hash: 3
|
130
|
+
segments:
|
131
|
+
- 0
|
90
132
|
version: "0"
|
91
|
-
version:
|
92
133
|
requirements: []
|
93
134
|
|
94
|
-
rubyforge_project:
|
95
|
-
rubygems_version: 1.3.
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 1.3.7
|
96
137
|
signing_key:
|
97
138
|
specification_version: 3
|
98
139
|
summary: A library for using the titlepage.com API
|
data/examples/titlepage_www.rb
DELETED
@@ -1,10 +0,0 @@
|
|
1
|
-
# assuming you have titlepage installed via rubygems,
|
2
|
-
# in a regular script, replace the following require
|
3
|
-
# line with these 2 lines:
|
4
|
-
# require 'rubygems'
|
5
|
-
# require 'titlepage'
|
6
|
-
require File.dirname(__FILE__) + '/../lib/titlepage'
|
7
|
-
|
8
|
-
TitlePage::WWWClient.open("username","password") do |client|
|
9
|
-
puts client.get_onix_file("9780060000707")
|
10
|
-
end
|
data/lib/titlepage/wwwclient.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module TitlePage
|
4
|
-
|
5
|
-
# A helper class for grabbing ONIX files from titlepage.com
|
6
|
-
#
|
7
|
-
# A valid login is required, see the site for information on applying
|
8
|
-
# for access.
|
9
|
-
#
|
10
|
-
# You should be aware of any limits of query volume imposed by the provider - currently a
|
11
|
-
# maximum of 30 queries per minute is permitted.
|
12
|
-
#
|
13
|
-
# = Usage
|
14
|
-
#
|
15
|
-
# TitlePage::WWWClient.open("username","password") do |tp|
|
16
|
-
# puts tp.get_onix_file("9780091835132")
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
class WWWClient
|
20
|
-
|
21
|
-
TITLEPAGE_DOMAIN = "www.titlepage.com"
|
22
|
-
|
23
|
-
def get_onix_file(isbn)
|
24
|
-
isbn = RBook::ISBN.convert_to_isbn13(isbn)
|
25
|
-
raise ArgumentError, 'Invalid ISBN supplied' if isbn.nil?
|
26
|
-
|
27
|
-
headers = { 'Cookie' => @cookie }
|
28
|
-
|
29
|
-
login_response = Net::HTTP.start(TITLEPAGE_DOMAIN, 80) do |http|
|
30
|
-
data = [
|
31
|
-
"posted=yes",
|
32
|
-
"quicksearch=#{isbn}",
|
33
|
-
"qsrchby=isbn13",
|
34
|
-
"detailed=Search"
|
35
|
-
].join("&")
|
36
|
-
http.post('/results.php', data, headers)
|
37
|
-
end
|
38
|
-
regex = /onclick=\"bookPopUp\(\'(.+)\'\);\"/
|
39
|
-
code = login_response.body.match(regex)
|
40
|
-
if code.nil?
|
41
|
-
return nil
|
42
|
-
else
|
43
|
-
code = code[1]
|
44
|
-
end
|
45
|
-
onix_file = Net::HTTP.start(TITLEPAGE_DOMAIN, 80) do |http|
|
46
|
-
data = [
|
47
|
-
"download=Download",
|
48
|
-
"rr=#{code}"
|
49
|
-
].join("&")
|
50
|
-
http.post('/detail.php', data, headers)
|
51
|
-
end
|
52
|
-
return onix_file.body
|
53
|
-
end
|
54
|
-
|
55
|
-
# login to the titlepage website.
|
56
|
-
def login(username, password)
|
57
|
-
login_response = Net::HTTP.start(TITLEPAGE_DOMAIN, 80) do |http|
|
58
|
-
data = [
|
59
|
-
"usr=#{username}",
|
60
|
-
"pwd=#{password}",
|
61
|
-
"login=Login"
|
62
|
-
].join("&")
|
63
|
-
headers = { 'Referer' => 'http://www.titlepage.com/index.php' }
|
64
|
-
http.post('/index.php', data, headers)
|
65
|
-
end
|
66
|
-
@cookie = login_response['set-cookie']
|
67
|
-
end
|
68
|
-
|
69
|
-
# logout from the titlepage API
|
70
|
-
def logout
|
71
|
-
if @cookie
|
72
|
-
login_response = Net::HTTP.start(TITLEPAGE_DOMAIN, 80) do |http|
|
73
|
-
http.get("/logout.php")
|
74
|
-
end
|
75
|
-
@cookie = nil
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
# a convenience method to make queries to title page a little cleaner. This function
|
80
|
-
# essentially calls the login and logout functions for you automatically.
|
81
|
-
#
|
82
|
-
# TitlePage::WWWClient.open("username","password") do |tp|
|
83
|
-
# result = tp.get_onix_file("9780091835132")
|
84
|
-
# end
|
85
|
-
def self.open(username, password)
|
86
|
-
|
87
|
-
tp = self.new
|
88
|
-
|
89
|
-
begin
|
90
|
-
tp.login(username, password)
|
91
|
-
|
92
|
-
yield(tp)
|
93
|
-
|
94
|
-
ensure
|
95
|
-
tp.logout
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
end
|
100
|
-
end
|