rbook 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +340 -0
- data/LICENSE +13 -0
- data/README +16 -0
- data/Rakefile +206 -0
- data/examples/titlepage.rb +14 -0
- data/examples/www/find_all.rb +23 -0
- data/examples/www/find_cover_from_amazon.rb +12 -0
- data/examples/www/find_url_from_rainbow.rb +12 -0
- data/examples/www/list.rb +13 -0
- data/lib/rbook/bisac.rb +175 -0
- data/lib/rbook/errors.rb +7 -0
- data/lib/rbook/isbn.rb +249 -0
- data/lib/rbook/onix.rb +68 -0
- data/lib/rbook/onix/contributor.rb +60 -0
- data/lib/rbook/onix/lists.rb +2 -0
- data/lib/rbook/onix/lists/contributor_role.rb +10 -0
- data/lib/rbook/onix/lists/product_form.rb +100 -0
- data/lib/rbook/onix/message.rb +101 -0
- data/lib/rbook/onix/product.rb +188 -0
- data/lib/rbook/onix/sales_restriction.rb +51 -0
- data/lib/rbook/onix/supply_detail.rb +68 -0
- data/lib/rbook/onix/xchar.rb +98 -0
- data/lib/rbook/titlepage.rb +96 -0
- data/lib/rbook/titlepage/TitleQueryClient.rb +62 -0
- data/lib/rbook/titlepage/titlepage_driver.rb +134 -0
- data/lib/rbook/titlepage/titlepage_utils.rb +374 -0
- data/lib/rbook/www.rb +172 -0
- data/lib/rbook/www/aau_scraper.rb +76 -0
- data/lib/rbook/www/amazon_uk_scraper.rb +44 -0
- data/lib/rbook/www/base.rb +87 -0
- data/lib/rbook/www/harper_au_scraper.rb +56 -0
- data/lib/rbook/www/harper_us_scraper.rb +55 -0
- data/lib/rbook/www/hha_scraper.rb +50 -0
- data/lib/rbook/www/macmillan_scraper.rb +62 -0
- data/lib/rbook/www/orbis_scraper.rb +48 -0
- data/lib/rbook/www/oup_scraper.rb +64 -0
- data/lib/rbook/www/paulist_scraper.rb +53 -0
- data/lib/rbook/www/pearson_au_scraper.rb +52 -0
- data/lib/rbook/www/penguin_scraper.rb +45 -0
- data/lib/rbook/www/random_au_scraper.rb +90 -0
- data/lib/rbook/www/random_us_scraper.rb +59 -0
- data/lib/rbook/www/sas_scraper.rb +54 -0
- data/lib/rbook/www/unireps_scraper.rb +58 -0
- data/lib/rbook/www/wiley_us_scraper.rb +54 -0
- data/test/data/abingdon.xml +38931 -0
- data/test/data/augsburg.xml +39009 -0
- data/test/data/chalice.xml +10851 -0
- data/test/data/eerdsman.xml +36942 -0
- data/test/data/invalid_no_product.xml +9 -0
- data/test/data/not_xml.csv +1 -0
- data/test/data/single_product.xml +50 -0
- data/test/data/xml_not_onix.xml +7 -0
- data/test/mocks/titlepage_driver.rb +107 -0
- data/test/unit/bisac_test.rb +57 -0
- data/test/unit/isbn_test.rb +149 -0
- data/test/unit/onix/contributor_test.rb +50 -0
- data/test/unit/onix/message_test.rb +119 -0
- data/test/unit/onix/product_test.rb +101 -0
- data/test/unit/onix/sales_restriction_test.rb +48 -0
- data/test/unit/onix/supply_detail_test.rb +53 -0
- data/test/unit/onix/xchar_test.rb +37 -0
- data/test/unit/titlepage_test.rb +127 -0
- metadata +130 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
module RBook
|
5
|
+
module Onix
|
6
|
+
|
7
|
+
class SalesRestriction
|
8
|
+
attr_accessor :type, :detail
|
9
|
+
|
10
|
+
# Attempts to create a contributor object using the supplied xml element
|
11
|
+
def SalesRestriction.load_from_element(element)
|
12
|
+
raise ArgumentError, 'load_from_element expects a REXML element object' unless element.class == REXML::Element
|
13
|
+
|
14
|
+
if REXML::XPath.first(element, '//SalesRestriction').nil?
|
15
|
+
raise LoadError, 'supplied REXML document object does not appear contain a valid SalesRestriction fragment'
|
16
|
+
end
|
17
|
+
|
18
|
+
restriction = SalesRestriction.new
|
19
|
+
|
20
|
+
tmp = REXML::XPath.first(element, '//SalesRestriction/SalesRestrictionType')
|
21
|
+
restriction.type = tmp.text if tmp != nil
|
22
|
+
|
23
|
+
tmp = REXML::XPath.first(element, '//SalesRestriction/SalesRestrictionDetail')
|
24
|
+
restriction.detail = tmp.text if tmp != nil
|
25
|
+
|
26
|
+
return restriction
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return an xml element representing this contributor
|
31
|
+
def to_element
|
32
|
+
raise 'SalesRestriction must have a type to create an element' if self.type.nil?
|
33
|
+
raise 'Contributor must have a detail to create an element' if self.detail.nil?
|
34
|
+
|
35
|
+
restriction = REXML::Element.new('SalesRestriction')
|
36
|
+
restriction.add_element('SalesRestrictionType').text = self.type.to_xs
|
37
|
+
restriction.add_element('SalesRestrictionDetail').text = self.detail.to_xs
|
38
|
+
|
39
|
+
return restriction
|
40
|
+
end
|
41
|
+
|
42
|
+
# Return an XML string representing this contributor
|
43
|
+
def to_s
|
44
|
+
tmp = to_element
|
45
|
+
output = ''
|
46
|
+
tmp.write(output, 0)
|
47
|
+
return output
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
require 'bigdecimal'
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
module RBook
|
6
|
+
module Onix
|
7
|
+
|
8
|
+
class SupplyDetail
|
9
|
+
attr_accessor :supplier_name, :availability_code, :intermediary_availability_code, :price
|
10
|
+
|
11
|
+
# Attempts to create a contributor object using the supplied xml element
|
12
|
+
def self.load_from_element(element)
|
13
|
+
raise ArgumentError, 'load_from_element expects a REXML element object' unless element.class == REXML::Element
|
14
|
+
|
15
|
+
if REXML::XPath.first(element, '//SupplyDetail').nil?
|
16
|
+
raise LoadError, 'supplied REXML document object does not appear contain a valid SupplyDetail fragment'
|
17
|
+
end
|
18
|
+
|
19
|
+
supply_detail = SupplyDetail.new
|
20
|
+
|
21
|
+
tmp = REXML::XPath.first(element, '//SupplyDetail/SupplierName')
|
22
|
+
supply_detail.supplier_name = tmp.text if tmp != nil
|
23
|
+
|
24
|
+
tmp = REXML::XPath.first(element, '//SupplyDetail/AvailabilityCode')
|
25
|
+
supply_detail.availability_code = tmp.text if tmp != nil
|
26
|
+
|
27
|
+
tmp = REXML::XPath.first(element, '//SupplyDetail/IntermediaryAvailabilityCode')
|
28
|
+
supply_detail.intermediary_availability_code = tmp.text if tmp != nil
|
29
|
+
|
30
|
+
tmp = REXML::XPath.first(element, '//SupplyDetail/Price/PriceAmount')
|
31
|
+
supply_detail.price = BigDecimal(tmp.text) if tmp != nil
|
32
|
+
|
33
|
+
return supply_detail
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return an xml element representing this contributor
|
38
|
+
def to_element
|
39
|
+
raise 'SupplyDetail must have a supplier name to create an element' if self.supplier_name.nil?
|
40
|
+
raise 'SupplyDetail must have a availability code to create an element' if self.availability_code.nil?
|
41
|
+
|
42
|
+
supply_detail = REXML::Element.new('SupplyDetail')
|
43
|
+
supply_detail.add_element('SupplierName').text = self.supplier_name.to_xs
|
44
|
+
supply_detail.add_element('AvailabilityCode').text = self.availability_code.to_xs unless self.availability_code.nil?
|
45
|
+
supply_detail.add_element('IntermediaryAvailabilityCode').text = self.intermediary_availability_code_to_xs unless self.intermediary_availability_code.nil?
|
46
|
+
unless self.price.nil?
|
47
|
+
tmp = REXML::Element.new('Price')
|
48
|
+
if self.price.kind_of?(BigDecimal)
|
49
|
+
tmp.add_element('PriceAmount').text = self.price.to_s("F")
|
50
|
+
else
|
51
|
+
tmp.add_element('PriceAmount').text = self.price.to_s
|
52
|
+
end
|
53
|
+
supply_detail.add_element(tmp)
|
54
|
+
end
|
55
|
+
|
56
|
+
return supply_detail
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return an XML string representing this contributor
|
60
|
+
def to_s
|
61
|
+
tmp = to_element
|
62
|
+
output = ''
|
63
|
+
tmp.write(output, 0)
|
64
|
+
return output
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# sourced from http://www.intertwingly.net/blog/2005/09/28/XML-Cleansing
|
2
|
+
|
3
|
+
module XChar
|
4
|
+
# http://intertwingly.net/stories/2004/04/14/i18n.html#CleaningWindows
|
5
|
+
CP1252 = {
|
6
|
+
128 => 8364, # euro sign
|
7
|
+
130 => 8218, # single low-9 quotation mark
|
8
|
+
131 => 402, # latin small letter f with hook
|
9
|
+
132 => 8222, # double low-9 quotation mark
|
10
|
+
133 => 8230, # horizontal ellipsis
|
11
|
+
134 => 8224, # dagger
|
12
|
+
135 => 8225, # double dagger
|
13
|
+
136 => 710, # modifier letter circumflex accent
|
14
|
+
137 => 8240, # per mille sign
|
15
|
+
138 => 352, # latin capital letter s with caron
|
16
|
+
139 => 8249, # single left-pointing angle quotation mark
|
17
|
+
140 => 338, # latin capital ligature oe
|
18
|
+
142 => 381, # latin capital letter z with caron
|
19
|
+
145 => 8216, # left single quotation mark
|
20
|
+
146 => 8217, # right single quotation mark
|
21
|
+
147 => 8220, # left double quotation mark
|
22
|
+
148 => 8221, # right double quotation mark
|
23
|
+
149 => 8226, # bullet
|
24
|
+
150 => 8211, # en dash
|
25
|
+
151 => 8212, # em dash
|
26
|
+
152 => 732, # small tilde
|
27
|
+
153 => 8482, # trade mark sign
|
28
|
+
154 => 353, # latin small letter s with caron
|
29
|
+
155 => 8250, # single right-pointing angle quotation mark
|
30
|
+
156 => 339, # latin small ligature oe
|
31
|
+
158 => 382, # latin small letter z with caron
|
32
|
+
159 => 376} # latin capital letter y with diaeresis
|
33
|
+
|
34
|
+
# http://www.w3.org/TR/REC-xml/#dt-chardata
|
35
|
+
PREDEFINED = {
|
36
|
+
38 => '&', # ampersand
|
37
|
+
60 => '<', # left angle bracket
|
38
|
+
62 => '>'} # right angle bracket
|
39
|
+
|
40
|
+
# http://www.w3.org/TR/REC-xml/#charsets
|
41
|
+
VALID = [[0x9, 0xA, 0xD], (0x20..0xD7FF),
|
42
|
+
(0xE000..0xFFFD), (0x10000..0x10FFFF)]
|
43
|
+
end
|
44
|
+
|
45
|
+
class Fixnum
|
46
|
+
# xml escaped version of chr
|
47
|
+
def xchr
|
48
|
+
n = XChar::CP1252[self] || self
|
49
|
+
n = 42 unless XChar::VALID.find {|range| range.include? n}
|
50
|
+
XChar::PREDEFINED[n] or (n<128 ? n.chr : "&##{n};")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class String
|
55
|
+
# xml escaped version of to_s
|
56
|
+
def to_xs
|
57
|
+
unpack('U*').map {|n| n.xchr}.join # ASCII, UTF-8
|
58
|
+
rescue
|
59
|
+
unpack('C*').map {|n| n.xchr}.join # ISO-8859-1, WIN-1252
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
=begin
|
64
|
+
require 'test/unit'
|
65
|
+
|
66
|
+
class TestXmlEscaping < Test::Unit::TestCase
|
67
|
+
def test_ascii
|
68
|
+
assert_equal 'abc', 'abc'.to_xs
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_predefined
|
72
|
+
assert_equal '&', '&'.to_xs # ampersand
|
73
|
+
assert_equal '<', '<'.to_xs # left angle bracket
|
74
|
+
assert_equal '>', '>'.to_xs # right angle bracket
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_invalid
|
78
|
+
assert_equal '*', "\x00".to_xs # null
|
79
|
+
assert_equal '*', "\x0C".to_xs # form feed
|
80
|
+
assert_equal '*', "\xEF\xBF\xBF".to_xs # U+FFFF
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_iso_8859_1
|
84
|
+
assert_equal 'ç', "\xE7".to_xs # small c cedilla
|
85
|
+
assert_equal '©', "\xA9".to_xs # copyright symbol
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_win_1252
|
89
|
+
assert_equal '’', "\x92".to_xs # smart quote
|
90
|
+
assert_equal '€', "\x80".to_xs # euro
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_utf8
|
94
|
+
assert_equal '’', "\xE2\x80\x99".to_xs # right single quote
|
95
|
+
assert_equal '©', "\xC2\xA9".to_xs # copy
|
96
|
+
end
|
97
|
+
end
|
98
|
+
=end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + "/../")
|
2
|
+
|
3
|
+
require 'rbook/isbn'
|
4
|
+
require 'rbook/errors'
|
5
|
+
require 'rbook/titlepage/titlepage_driver'
|
6
|
+
|
7
|
+
module RBook
|
8
|
+
|
9
|
+
# a convenience class for accessing the SOAP API for http://www.titlepage.com.
|
10
|
+
# Uses boilerplate code generated by soap4r.
|
11
|
+
#
|
12
|
+
# You should be aware of any limits of query volume imposed by the provider - currently a
|
13
|
+
# maximum of 30 queries per minute is permitted.
|
14
|
+
#
|
15
|
+
# All examples require the following two lines at the top of your file:
|
16
|
+
# require 'rubygems'
|
17
|
+
# require 'rbook/titlepage'
|
18
|
+
#
|
19
|
+
# Basic usage:
|
20
|
+
# tp = Book::TitlePage.new
|
21
|
+
# tp.login('someuser','topsecret')
|
22
|
+
# puts tp.find("0091835135").inspect
|
23
|
+
# sleep 3
|
24
|
+
# puts tp.find("9780672327568").inspect
|
25
|
+
# tp.logout
|
26
|
+
#
|
27
|
+
# Alternative Usage:
|
28
|
+
# RBook::TitlePage.open("username","password") do |tp|
|
29
|
+
# puts tp.find("0091835135").inspect
|
30
|
+
# sleep 3
|
31
|
+
# puts tp.find("9780672327568").inspect
|
32
|
+
# end
|
33
|
+
class TitlePage
|
34
|
+
|
35
|
+
# Optional driver parameter allows an alternative SOAP driver to the default to be specified.
|
36
|
+
# This is primarily for testing purposes and probably isn't useful to anyone in the real world.
|
37
|
+
def initialize(driver = nil)
|
38
|
+
@driver = driver || TitleQueryPortType.new
|
39
|
+
@token = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# login to the titlepage API.
|
43
|
+
def login(username, password)
|
44
|
+
raise InvalidRubyVersionError, 'Ruby 1.8.3 or higher is required to use this class' unless RUBY_VERSION >= "1.8.3"
|
45
|
+
logout if @token
|
46
|
+
@token = @driver.login(username, password)
|
47
|
+
return true if @token
|
48
|
+
end
|
49
|
+
|
50
|
+
# logout from the titlepage API
|
51
|
+
def logout
|
52
|
+
if @token
|
53
|
+
@driver.logout(@token)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# retrieve information on a specified ISBN
|
58
|
+
def find(isbn)
|
59
|
+
return NotLoggedInError, 'You must login to titlepage API before performing a search' unless @token
|
60
|
+
isbn = ISBN::convert_to_isbn13(isbn)
|
61
|
+
return nil if isbn.nil?
|
62
|
+
begin
|
63
|
+
result = @driver.SearchByEAN(@token, isbn)
|
64
|
+
if result.Product.nil?
|
65
|
+
return nil
|
66
|
+
else
|
67
|
+
return result
|
68
|
+
end
|
69
|
+
rescue
|
70
|
+
return nil
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
# a convenience method to make queries to title page a little cleaner. This function
|
76
|
+
# essentially calls the login and logout functions for you automatically.
|
77
|
+
#
|
78
|
+
# RBook::TitlePage.open("username","password") do |tp|
|
79
|
+
# result = tp.find("9780091835132")
|
80
|
+
# end
|
81
|
+
def TitlePage.open(username, password, driver = nil)
|
82
|
+
|
83
|
+
tp = TitlePage.new(driver || TitleQueryPortType.new)
|
84
|
+
|
85
|
+
begin
|
86
|
+
tp.login(username, password)
|
87
|
+
|
88
|
+
yield(tp)
|
89
|
+
|
90
|
+
ensure
|
91
|
+
tp.logout
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'defaultDriver.rb'
|
3
|
+
|
4
|
+
endpoint_url = ARGV.shift
|
5
|
+
obj = TitleQueryPortType.new(endpoint_url)
|
6
|
+
|
7
|
+
# run ruby with -d to see SOAP wiredumps.
|
8
|
+
obj.wiredump_dev = STDERR if $DEBUG
|
9
|
+
|
10
|
+
# SYNOPSIS
|
11
|
+
# Login(userName, password)
|
12
|
+
#
|
13
|
+
# ARGS
|
14
|
+
# userName String - {http://www.w3.org/2001/XMLSchema}string
|
15
|
+
# password String - {http://www.w3.org/2001/XMLSchema}string
|
16
|
+
#
|
17
|
+
# RETURNS
|
18
|
+
# token String - {http://www.w3.org/2001/XMLSchema}string
|
19
|
+
#
|
20
|
+
userName = "rba303"
|
21
|
+
password = "ra1nb0Wb"
|
22
|
+
puts obj.login(userName, password)
|
23
|
+
|
24
|
+
# SYNOPSIS
|
25
|
+
# SearchByISBN(token, iSBN)
|
26
|
+
#
|
27
|
+
# ARGS
|
28
|
+
# token String - {http://www.w3.org/2001/XMLSchema}string
|
29
|
+
# iSBN String - {http://www.w3.org/2001/XMLSchema}string
|
30
|
+
#
|
31
|
+
# RETURNS
|
32
|
+
# searchResults SearchResults - {urn:TitleQuery}SearchResults
|
33
|
+
#
|
34
|
+
token = iSBN = nil
|
35
|
+
puts obj.searchByISBN(token, iSBN)
|
36
|
+
|
37
|
+
# SYNOPSIS
|
38
|
+
# SearchByEAN(token, eAN)
|
39
|
+
#
|
40
|
+
# ARGS
|
41
|
+
# token String - {http://www.w3.org/2001/XMLSchema}string
|
42
|
+
# eAN String - {http://www.w3.org/2001/XMLSchema}string
|
43
|
+
#
|
44
|
+
# RETURNS
|
45
|
+
# searchResults SearchResults - {urn:TitleQuery}SearchResults
|
46
|
+
#
|
47
|
+
token = eAN = nil
|
48
|
+
puts obj.searchByEAN(token, eAN)
|
49
|
+
|
50
|
+
# SYNOPSIS
|
51
|
+
# Logout(token)
|
52
|
+
#
|
53
|
+
# ARGS
|
54
|
+
# token String - {http://www.w3.org/2001/XMLSchema}string
|
55
|
+
#
|
56
|
+
# RETURNS
|
57
|
+
# N/A
|
58
|
+
#
|
59
|
+
token = nil
|
60
|
+
puts obj.logout(token)
|
61
|
+
|
62
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/titlepage_utils.rb'
|
2
|
+
|
3
|
+
require 'soap/rpc/driver'
|
4
|
+
|
5
|
+
class TitleQueryPortType < ::SOAP::RPC::Driver
|
6
|
+
DefaultEndpointUrl = "http://www.titlepage.com.au/ws/TitleQuery.php"
|
7
|
+
MappingRegistry = ::SOAP::Mapping::Registry.new
|
8
|
+
|
9
|
+
MappingRegistry.set(
|
10
|
+
SearchResults,
|
11
|
+
::SOAP::SOAPStruct,
|
12
|
+
::SOAP::Mapping::Registry::TypedStructFactory,
|
13
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "SearchResults") }
|
14
|
+
)
|
15
|
+
MappingRegistry.set(
|
16
|
+
Product,
|
17
|
+
::SOAP::SOAPStruct,
|
18
|
+
::SOAP::Mapping::Registry::TypedStructFactory,
|
19
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "Product") }
|
20
|
+
)
|
21
|
+
MappingRegistry.set(
|
22
|
+
ArrayOfProductIdentifier,
|
23
|
+
::SOAP::SOAPArray,
|
24
|
+
::SOAP::Mapping::Registry::TypedArrayFactory,
|
25
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "ProductIdentifier") }
|
26
|
+
)
|
27
|
+
MappingRegistry.set(
|
28
|
+
Title,
|
29
|
+
::SOAP::SOAPStruct,
|
30
|
+
::SOAP::Mapping::Registry::TypedStructFactory,
|
31
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "Title") }
|
32
|
+
)
|
33
|
+
MappingRegistry.set(
|
34
|
+
ArrayOfContributor,
|
35
|
+
::SOAP::SOAPArray,
|
36
|
+
::SOAP::Mapping::Registry::TypedArrayFactory,
|
37
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "Contributor") }
|
38
|
+
)
|
39
|
+
MappingRegistry.set(
|
40
|
+
SupplyDetail,
|
41
|
+
::SOAP::SOAPStruct,
|
42
|
+
::SOAP::Mapping::Registry::TypedStructFactory,
|
43
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "SupplyDetail") }
|
44
|
+
)
|
45
|
+
MappingRegistry.set(
|
46
|
+
Stock,
|
47
|
+
::SOAP::SOAPStruct,
|
48
|
+
::SOAP::Mapping::Registry::TypedStructFactory,
|
49
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "Stock") }
|
50
|
+
)
|
51
|
+
MappingRegistry.set(
|
52
|
+
Price,
|
53
|
+
::SOAP::SOAPStruct,
|
54
|
+
::SOAP::Mapping::Registry::TypedStructFactory,
|
55
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "Price") }
|
56
|
+
)
|
57
|
+
MappingRegistry.set(
|
58
|
+
ProductIdentifier,
|
59
|
+
::SOAP::SOAPStruct,
|
60
|
+
::SOAP::Mapping::Registry::TypedStructFactory,
|
61
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "ProductIdentifier") }
|
62
|
+
)
|
63
|
+
MappingRegistry.set(
|
64
|
+
Contributor,
|
65
|
+
::SOAP::SOAPStruct,
|
66
|
+
::SOAP::Mapping::Registry::TypedStructFactory,
|
67
|
+
{ :type => XSD::QName.new("urn:TitleQuery", "Contributor") }
|
68
|
+
)
|
69
|
+
|
70
|
+
Methods = [
|
71
|
+
[ XSD::QName.new("http://www.titlepage.com/ws", "Login"),
|
72
|
+
"http://www.titlepage.com.au/ws/TitleQuery.php/Login",
|
73
|
+
"login",
|
74
|
+
[ ["in", "UserName", ["::SOAP::SOAPString"]],
|
75
|
+
["in", "Password", ["::SOAP::SOAPString"]],
|
76
|
+
["retval", "Token", ["::SOAP::SOAPString"]] ],
|
77
|
+
{ :request_style => :rpc, :request_use => :encoded,
|
78
|
+
:response_style => :rpc, :response_use => :encoded }
|
79
|
+
],
|
80
|
+
[ XSD::QName.new("http://www.titlepage.com/ws", "SearchByISBN"),
|
81
|
+
"http://www.titlepage.com.au/ws/TitleQuery.php/SearchByISBN",
|
82
|
+
"searchByISBN",
|
83
|
+
[ ["in", "Token", ["::SOAP::SOAPString"]],
|
84
|
+
["in", "ISBN", ["::SOAP::SOAPString"]],
|
85
|
+
["retval", "SearchResults", ["SearchResults", "urn:TitleQuery", "SearchResults"]] ],
|
86
|
+
{ :request_style => :rpc, :request_use => :encoded,
|
87
|
+
:response_style => :rpc, :response_use => :encoded }
|
88
|
+
],
|
89
|
+
[ XSD::QName.new("http://www.titlepage.com/ws", "SearchByEAN"),
|
90
|
+
"http://www.titlepage.com.au/ws/TitleQuery.php/SearchByEAN",
|
91
|
+
"searchByEAN",
|
92
|
+
[ ["in", "Token", ["::SOAP::SOAPString"]],
|
93
|
+
["in", "EAN", ["::SOAP::SOAPString"]],
|
94
|
+
["retval", "SearchResults", ["SearchResults", "urn:TitleQuery", "SearchResults"]] ],
|
95
|
+
{ :request_style => :rpc, :request_use => :encoded,
|
96
|
+
:response_style => :rpc, :response_use => :encoded }
|
97
|
+
],
|
98
|
+
[ XSD::QName.new("http://www.titlepage.com/ws", "Logout"),
|
99
|
+
"http://www.titlepage.com.au/ws/TitleQuery.php/Logout",
|
100
|
+
"logout",
|
101
|
+
[ ["in", "token", ["::SOAP::SOAPString"]] ],
|
102
|
+
{ :request_style => :rpc, :request_use => :encoded,
|
103
|
+
:response_style => :rpc, :response_use => :encoded }
|
104
|
+
]
|
105
|
+
]
|
106
|
+
|
107
|
+
def initialize(endpoint_url = nil)
|
108
|
+
endpoint_url ||= DefaultEndpointUrl
|
109
|
+
super(endpoint_url, nil)
|
110
|
+
self.mapping_registry = MappingRegistry
|
111
|
+
init_methods
|
112
|
+
end
|
113
|
+
|
114
|
+
private
|
115
|
+
|
116
|
+
def init_methods
|
117
|
+
Methods.each do |definitions|
|
118
|
+
opt = definitions.last
|
119
|
+
if opt[:request_style] == :document
|
120
|
+
add_document_operation(*definitions)
|
121
|
+
else
|
122
|
+
add_rpc_operation(*definitions)
|
123
|
+
qname = definitions[0]
|
124
|
+
name = definitions[2]
|
125
|
+
if qname.name != name and qname.name.capitalize == name.capitalize
|
126
|
+
::SOAP::Mapping.define_singleton_method(self, qname.name) do |*arg|
|
127
|
+
__send__(name, *arg)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|