titlepage 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
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.3.0"
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('rbook-isbn', '>= 1.0')
73
- spec.add_dependency('andand', '1.3.1')
74
- spec.add_dependency('handsoap', '>= 1.0')
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.rubyforge_project = "rbook"
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
 
@@ -3,7 +3,8 @@
3
3
  require "bigdecimal"
4
4
  require "handsoap"
5
5
  require "andand"
6
- require "rbook/isbn"
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/wwwclient'
44
+ require File.dirname(__FILE__) + '/titlepage/rest'
@@ -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 = RBook::ISBN::convert_to_isbn13(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
@@ -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
- :expected_shop_date => self.supply_detail.expected_ship_date,
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
- version: 1.3.0
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: 2009-11-14 00:00:00 +11:00
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: rbook-isbn
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
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
- version: "1.0"
24
- version:
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
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
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
- version: 1.3.1
34
- version:
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
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
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
- version:
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://rbook.rubyforge.org/
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: rbook
95
- rubygems_version: 1.3.5
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
@@ -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
@@ -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