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 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