rbook 0.1

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.
Files changed (63) hide show
  1. data/COPYING +340 -0
  2. data/LICENSE +13 -0
  3. data/README +16 -0
  4. data/Rakefile +206 -0
  5. data/examples/titlepage.rb +14 -0
  6. data/examples/www/find_all.rb +23 -0
  7. data/examples/www/find_cover_from_amazon.rb +12 -0
  8. data/examples/www/find_url_from_rainbow.rb +12 -0
  9. data/examples/www/list.rb +13 -0
  10. data/lib/rbook/bisac.rb +175 -0
  11. data/lib/rbook/errors.rb +7 -0
  12. data/lib/rbook/isbn.rb +249 -0
  13. data/lib/rbook/onix.rb +68 -0
  14. data/lib/rbook/onix/contributor.rb +60 -0
  15. data/lib/rbook/onix/lists.rb +2 -0
  16. data/lib/rbook/onix/lists/contributor_role.rb +10 -0
  17. data/lib/rbook/onix/lists/product_form.rb +100 -0
  18. data/lib/rbook/onix/message.rb +101 -0
  19. data/lib/rbook/onix/product.rb +188 -0
  20. data/lib/rbook/onix/sales_restriction.rb +51 -0
  21. data/lib/rbook/onix/supply_detail.rb +68 -0
  22. data/lib/rbook/onix/xchar.rb +98 -0
  23. data/lib/rbook/titlepage.rb +96 -0
  24. data/lib/rbook/titlepage/TitleQueryClient.rb +62 -0
  25. data/lib/rbook/titlepage/titlepage_driver.rb +134 -0
  26. data/lib/rbook/titlepage/titlepage_utils.rb +374 -0
  27. data/lib/rbook/www.rb +172 -0
  28. data/lib/rbook/www/aau_scraper.rb +76 -0
  29. data/lib/rbook/www/amazon_uk_scraper.rb +44 -0
  30. data/lib/rbook/www/base.rb +87 -0
  31. data/lib/rbook/www/harper_au_scraper.rb +56 -0
  32. data/lib/rbook/www/harper_us_scraper.rb +55 -0
  33. data/lib/rbook/www/hha_scraper.rb +50 -0
  34. data/lib/rbook/www/macmillan_scraper.rb +62 -0
  35. data/lib/rbook/www/orbis_scraper.rb +48 -0
  36. data/lib/rbook/www/oup_scraper.rb +64 -0
  37. data/lib/rbook/www/paulist_scraper.rb +53 -0
  38. data/lib/rbook/www/pearson_au_scraper.rb +52 -0
  39. data/lib/rbook/www/penguin_scraper.rb +45 -0
  40. data/lib/rbook/www/random_au_scraper.rb +90 -0
  41. data/lib/rbook/www/random_us_scraper.rb +59 -0
  42. data/lib/rbook/www/sas_scraper.rb +54 -0
  43. data/lib/rbook/www/unireps_scraper.rb +58 -0
  44. data/lib/rbook/www/wiley_us_scraper.rb +54 -0
  45. data/test/data/abingdon.xml +38931 -0
  46. data/test/data/augsburg.xml +39009 -0
  47. data/test/data/chalice.xml +10851 -0
  48. data/test/data/eerdsman.xml +36942 -0
  49. data/test/data/invalid_no_product.xml +9 -0
  50. data/test/data/not_xml.csv +1 -0
  51. data/test/data/single_product.xml +50 -0
  52. data/test/data/xml_not_onix.xml +7 -0
  53. data/test/mocks/titlepage_driver.rb +107 -0
  54. data/test/unit/bisac_test.rb +57 -0
  55. data/test/unit/isbn_test.rb +149 -0
  56. data/test/unit/onix/contributor_test.rb +50 -0
  57. data/test/unit/onix/message_test.rb +119 -0
  58. data/test/unit/onix/product_test.rb +101 -0
  59. data/test/unit/onix/sales_restriction_test.rb +48 -0
  60. data/test/unit/onix/supply_detail_test.rb +53 -0
  61. data/test/unit/onix/xchar_test.rb +37 -0
  62. data/test/unit/titlepage_test.rb +127 -0
  63. metadata +130 -0
@@ -0,0 +1,14 @@
1
+ # assuming you have rbook installed via rubygems,
2
+ # in a regular script, replace the following require
3
+ # line with these 2 lines:
4
+ # require 'rubygems'
5
+ # require 'rbook/titlepage'
6
+ require File.dirname(__FILE__) + '/../lib/rbook/titlepage'
7
+
8
+ RBook::TitlePage.open("username", "password") do |tp|
9
+
10
+ puts tp.find("0091835135").inspect
11
+ sleep 3
12
+ puts tp.find("1741146712").inspect
13
+
14
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/ruby1.8
2
+
3
+ # assuming you have rbook installed via rubygems,
4
+ # in a regular script, replace the following require
5
+ # line with these 2 lines:
6
+ # require 'rubygems'
7
+ # require 'rbook/www'
8
+ require File.dirname(__FILE__) + '/../../lib/rbook/www'
9
+
10
+ results = RBook::WWW.find_info(:all, ARGV[0], :rba)
11
+
12
+ if results.nil?
13
+ puts "No matches found"
14
+ else
15
+ results.each do |result|
16
+ puts
17
+ result.each do |key, value|
18
+ puts key.to_s + " : " + value.to_s
19
+ end
20
+ end
21
+ end
22
+
23
+ puts
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/ruby1.8
2
+
3
+ # assuming you have rbook installed via rubygems,
4
+ # in a regular script, replace the following require
5
+ # line with these 2 lines:
6
+ # require 'rubygems'
7
+ # require 'rbook/www'
8
+ require File.dirname(__FILE__) + '/../../lib/rbook/www'
9
+
10
+
11
+ puts RBook::WWW.find_cover(ARGV[0], :amazon_uk).inspect
12
+
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/ruby1.8
2
+
3
+ # assuming you have rbook installed via rubygems,
4
+ # in a regular script, replace the following require
5
+ # line with these 2 lines:
6
+ # require 'rubygems'
7
+ # require 'rbook/www'
8
+ require File.dirname(__FILE__) + '/../../lib/rbook/www'
9
+
10
+
11
+ puts RBook::WWW.find_url(ARGV[0], :rba).inspect
12
+
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/ruby1.8
2
+
3
+ # assuming you have rbook installed via rubygems,
4
+ # in a regular script, replace the following require
5
+ # line with these 2 lines:
6
+ # require 'rubygems'
7
+ # require 'rbook/www'
8
+ require File.dirname(__FILE__) + '/../../lib/rbook/www'
9
+
10
+ RBook::WWW.scrapers.each do |scraper|
11
+ puts scraper::SCRAPER_NAME + " @ " + scraper::SCRAPER_SITE
12
+ end
13
+
@@ -0,0 +1,175 @@
1
+ module RBook
2
+
3
+ # Ruby class for reading and writing BISAC files.
4
+ # BISAC is a really bad format for electronic exchange of data - ONIX should be
5
+ # used where possible. Here be dragons.
6
+ #
7
+ # Basic Usage:
8
+ # require 'rubygems'
9
+ # require 'rbook/bisac'
10
+ # bisac = RBook::Bisac.new("Rainbow", "0000000000", "jan06", "1")
11
+ # item = {:isbn => "020161622X",
12
+ # :title => "Pragmatic Programmer",
13
+ # :author => "Hunt Thomas",
14
+ # :price => "2995",
15
+ # :binding => "PB",
16
+ # :pubdate => "061223",
17
+ # :publihser => "Pearson Education",
18
+ # :imprint => "Addison-Wesley",
19
+ # :edition => "1",
20
+ # :volume => "1",
21
+ # :volumes => "1",
22
+ # :status => "O/O"
23
+ # }
24
+ # bisac.add_item(item)
25
+ # bisac.write("/tmp/jan06.txt")
26
+ class Bisac
27
+
28
+ # creates a new bisac file in memory
29
+ # company = company name (10 chars)
30
+ # san = company SAN number (12 chars)
31
+ # batch = batch name for this file (6 chars)
32
+ # code = 1 for new titles, 2 for updated titles (1 char)
33
+ def initialize(company, san, batch, code)
34
+ @company = company
35
+ @san = san
36
+ @batch = batch
37
+ @code = code
38
+ @data = []
39
+ end
40
+
41
+ # TODO: Not Yet Implemented.
42
+ # loads the requested BISAC file into memory. Returns an array of hashes
43
+ def self.load(filename)
44
+
45
+ end
46
+
47
+ # adds a new title to the bisic file. Expects a hash with the required data.
48
+ #
49
+ # Required hash indexes:
50
+ # - :isbn
51
+ # - :title
52
+ # - :author
53
+ # - :price
54
+ # - :pubdate
55
+ # - :publisher
56
+ # - :imprint
57
+ # - :edition
58
+ # - :binding
59
+ # - :volume
60
+ # - :volumes
61
+ # - :status
62
+ def add_item(item)
63
+ raise ArgumentError, 'item must be a hash' unless item.kind_of?(Hash)
64
+ raise ArgumentError, 'Hash needs an :isbn index' if item[:isbn].nil?
65
+ raise ArgumentError, 'Hash needs an :title index' if item[:title].nil?
66
+ raise ArgumentError, 'Hash needs an :author index' if item[:author].nil?
67
+ raise ArgumentError, 'Hash needs an :price index' if item[:price].nil?
68
+ raise ArgumentError, 'Hash needs an :pubdate index' if item[:pubdate].nil?
69
+ raise ArgumentError, 'Hash needs an :publisher index' if item[:publisher].nil?
70
+ raise ArgumentError, 'Hash needs an :imprint index' if item[:imprint].nil?
71
+ raise ArgumentError, 'Hash needs an :volumes index' if item[:volumes].nil?
72
+ raise ArgumentError, 'Hash needs an :edition index' if item[:edition].nil?
73
+ raise ArgumentError, 'Hash needs an :binding index' if item[:binding].nil?
74
+ raise ArgumentError, 'Hash needs an :volume index' if item[:volume].nil?
75
+ raise ArgumentError, 'Hash needs an :status index' if item[:status].nil?
76
+ @data << item
77
+ end
78
+
79
+ # converts this bisac file into a string
80
+ def to_s
81
+ # File Header
82
+ content = "**HEADER**"
83
+ content << Time.now.strftime("%y%m%d")
84
+ content << @company[0,10].ljust(10)
85
+ content << @san[0,12].ljust(12)
86
+ content << @batch[0,6].ljust(6)
87
+ content << @code[0,1].ljust(1)
88
+ content << "**PUBSTAT*"
89
+ content << "040"
90
+ content << "".ljust(201)
91
+ content << "\n"
92
+
93
+ # File Content
94
+ counter = 0
95
+ @data.each do |item|
96
+ content << item[:isbn][0,10].ljust(10) # 10 digit isbn
97
+ content << "1"
98
+ content << "N"
99
+ content << "N"
100
+ content << "B"
101
+ content << "N"
102
+ content << item[:title][0,30].ljust(30)
103
+ content << "N"
104
+ content << item[:author][0,30].ljust(30)
105
+ content << "N"
106
+ content << "A" # author role
107
+ content << "N"
108
+ content << item[:price][0,7].rjust(7,"0") # current price
109
+ content << "N"
110
+ content << item[:pubdate][0,6].ljust(6) # published date
111
+ content << "N"
112
+ content << item[:publisher][0,10].ljust(10) # publisher
113
+ content << "N"
114
+ content << item[:imprint][0,14].ljust(14) #imprint
115
+ content << "N"
116
+ content << item[:volumes][0,3].rjust(3,"0") # volumes included in this isbn
117
+ content << "N"
118
+ content << item[:edition][0,2].rjust(2,"0") # edition
119
+ content << "N"
120
+ content << item[:binding][0,2].rjust(2) # binding
121
+ content << "N"
122
+ content << item[:volume][0,3].rjust(3,"0") # volume number
123
+ content << "N"
124
+ content << "0000000" # new price
125
+ content << "N"
126
+ content << "000000" # new price effective date
127
+ content << "N"
128
+ content << " " # audience type
129
+ content << "N"
130
+ content << item[:status][0,3].rjust(3) # status
131
+ content << "N"
132
+ content << " " # available date. only use for status' like NYP
133
+ content << "N"
134
+ content << " " # alternate isbn
135
+ content << "N"
136
+ content << "999999" # out of print date. only use for status == OP
137
+ content << "N"
138
+ content << " " # geographic restrictions
139
+ content << "N"
140
+ content << " " # library of congress catalogue number
141
+ content << "N"
142
+ content << "".ljust(40) # series title
143
+ content << "N"
144
+ content << "0" # price code for current price
145
+ content << "N"
146
+ content << "0" # price code for new price
147
+ content << "N"
148
+ content << "0000000" # freight pass through price
149
+ content << "N"
150
+ content << "000000" # new freight pass through price
151
+ content << "00000" # last changed date
152
+ content << "\n"
153
+
154
+
155
+ counter = counter + 1
156
+ end
157
+
158
+ # File Footer
159
+ content << "**TRAILER*"
160
+ content << Time.now.strftime("%y%m%d")
161
+ content << @batch[0,6].ljust(6)
162
+ content << counter.to_s[0,6].ljust(6)
163
+ content << "**PUBSTAT*"
164
+ content << "".ljust(221)
165
+
166
+
167
+ return content
168
+ end
169
+
170
+ # writes the content of this bisac file out to the specified file
171
+ def write(filename)
172
+ File.open(filename, "w") { |f| f.puts to_s }
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,7 @@
1
+
2
+ module RBook
3
+
4
+ class InvalidRubyVersionError < RuntimeError; end
5
+ class NotLoggedInError < RuntimeError; end
6
+
7
+ end
data/lib/rbook/isbn.rb ADDED
@@ -0,0 +1,249 @@
1
+ module RBook
2
+ # A collection of useful functions for dealing with ISBNs. Each
3
+ # function can be used directly - examples listed below.
4
+ # To use these examples you will need the following 2 lines
5
+ # at the top of your script:
6
+ # require 'rubygems'
7
+ # require 'rbook/isbn'
8
+ module ISBN
9
+
10
+ # adds hyphens to a valid isbn in the appropriate spots
11
+ #
12
+ # ISBN::add_groups("020161622X")
13
+ # #=> 0-201-61622-X
14
+ # ISBN::add_groups("9780201616224")
15
+ # #=> 978-0-201-61622-4
16
+ def ISBN::add_groups(isbn)
17
+
18
+ if !valid_isbn?(isbn)
19
+ isbn
20
+ elsif isbn.length == 10
21
+ calc = isbn * 1
22
+ calc = calc.insert(1, "-")
23
+ calc = calc.insert(7, "-")
24
+ calc = calc.insert(11, "-")
25
+ return calc
26
+ elsif isbn.length == 13
27
+ calc = isbn * 1
28
+ calc = calc.insert(3, "-")
29
+ calc = calc.insert(5, "-")
30
+ calc = calc.insert(11, "-")
31
+ calc = calc.insert(15, "-")
32
+ return calc
33
+ end
34
+
35
+ end
36
+
37
+ # Returns true if the supplied string is a valid isbn10 or isbn13
38
+ #
39
+ # ISBN::valid_isbn?("020161622X")
40
+ # #=> true
41
+ # ISBN::valid_isbn?("9780201616224")
42
+ # #=> true
43
+ # ISBN::valid_isbn?("9780201616223")
44
+ # #=> false
45
+ # ISBN::valid_isbn?("not an isbn")
46
+ # #=> false
47
+ def ISBN::valid_isbn?(isbn)
48
+ valid_isbn10?(isbn) || valid_isbn13?(isbn)
49
+ end
50
+
51
+ # returns true if the supplied string is a valid isbn10
52
+ #
53
+ # ISBN::valid_isbn10?("020161622X")
54
+ # #=> true
55
+ # ISBN::valid_isbn10?("9780201616224")
56
+ # #=> false
57
+ # ISBN::valid_isbn10?("9780201616223")
58
+ # #=> false
59
+ # ISBN::valid_isbn10?("not an isbn")
60
+ # #=> false
61
+ def ISBN::valid_isbn10?(isbn)
62
+ if isbn.nil?
63
+ false
64
+ elsif isbn.class != String
65
+ false
66
+ elsif isbn.length != 10
67
+ false
68
+ elsif isbn[/[^\dxX]/]
69
+ false
70
+ else
71
+ isbn == isbn[0,9] + ISBN::calc_isbn10_check(isbn.to_s[0,9])
72
+ end
73
+ end
74
+
75
+ # returns true if the supplied string is a valid isbn13
76
+ #
77
+ # ISBN::valid_isbn13?("020161622X")
78
+ # #=> false
79
+ # ISBN::valid_isbn13?("9780201616224")
80
+ # #=> true
81
+ # ISBN::valid_isbn13?("9780201616223")
82
+ # #=> false
83
+ # ISBN::valid_isbn13?("not an isbn")
84
+ # #=> false
85
+ def ISBN::valid_isbn13?(isbn)
86
+ if isbn.nil?
87
+ false
88
+ elsif isbn.class != String
89
+ false
90
+ elsif isbn.length != 13
91
+ false
92
+ elsif isbn[/[^\dxX]/]
93
+ false
94
+ else
95
+ isbn == isbn[0,12] + ISBN::calc_isbn13_check(isbn[0,12])
96
+ end
97
+ end
98
+
99
+ # Attempts to calculate the check digit on a supplied 9 digit string.
100
+ #
101
+ # If passed nil or a non string, nil is returned.
102
+ #
103
+ # If the supplied string length isn't chars 9 long, nil is returned.
104
+ #
105
+ # If the supplied string is 9 chars long, the check digit is calculated and returned
106
+ #
107
+ # ISBN::calc_isbn10_check("020161622")
108
+ # #=> X
109
+ # ISBN::calc_isbn10_check("020161622X")
110
+ # #=> nil
111
+ # ISBN::calc_isbn10_check("9780201616224")
112
+ # #=> nil
113
+ # ISBN::calc_isbn10_check("9780201616223")
114
+ # #=> nil
115
+ # ISBN::calc_isbn10_check("not an isbn")
116
+ # #=> nil
117
+ def ISBN::calc_isbn10_check(isbn)
118
+ if isbn.nil? || isbn.class != String || isbn.length != 9
119
+ return nil
120
+ else
121
+ check = isbn[0,1].to_i
122
+ check = check + isbn[1,1].to_i * 2
123
+ check = check + isbn[2,1].to_i * 3
124
+ check = check + isbn[3,1].to_i * 4
125
+ check = check + isbn[4,1].to_i * 5
126
+ check = check + isbn[5,1].to_i * 6
127
+ check = check + isbn[6,1].to_i * 7
128
+ check = check + isbn[7,1].to_i * 8
129
+ check = check + isbn[8,1].to_i * 9
130
+ check = check % 11
131
+
132
+ if check == 10
133
+ return "X"
134
+ else
135
+ return check.to_s
136
+ end
137
+ end
138
+ end
139
+
140
+ # Attempts to calculate the check digit on a supplied 12 digit string.
141
+ #
142
+ # If passed nil or a non String, nil is returned.
143
+ #
144
+ # If the supplied string isn't 12 digits long, nil is returned.
145
+ #
146
+ # For all other strings the check digit will be returned
147
+ #
148
+ # ISBN::calc_isbn13_check("978020161622")
149
+ # #=> 4
150
+ # ISBN::calc_isbn13_check("9780201616224")
151
+ # #=> nil
152
+ # ISBN::calc_isbn13_check("020161622X")
153
+ # #=> nil
154
+ # ISBN::calc_isbn13_check("9780201616223")
155
+ # #=> nil
156
+ # ISBN::calc_isbn13_check("not an isbn")
157
+ # #=> nil
158
+ def ISBN::calc_isbn13_check(isbn)
159
+ if isbn.nil? || isbn.class != String || isbn.length != 12
160
+ return nil
161
+ else
162
+ checkdigit = isbn[0,1].to_i * 1
163
+ checkdigit = checkdigit + isbn[1,1].to_i * 3
164
+ checkdigit = checkdigit + isbn[2,1].to_i * 1
165
+ checkdigit = checkdigit + isbn[3,1].to_i * 3
166
+ checkdigit = checkdigit + isbn[4,1].to_i * 1
167
+ checkdigit = checkdigit + isbn[5,1].to_i * 3
168
+ checkdigit = checkdigit + isbn[6,1].to_i * 1
169
+ checkdigit = checkdigit + isbn[7,1].to_i * 3
170
+ checkdigit = checkdigit + isbn[8,1].to_i * 1
171
+ checkdigit = checkdigit + isbn[9,1].to_i * 3
172
+ checkdigit = checkdigit + isbn[10,1].to_i * 1
173
+ checkdigit = checkdigit + isbn[11,1].to_i * 3
174
+
175
+ remainder = checkdigit % 10
176
+
177
+ if remainder == 0
178
+ checkdigit = 0
179
+ else
180
+ checkdigit = (10 - remainder)
181
+ end
182
+
183
+ if checkdigit == 10
184
+ return "X"
185
+ else
186
+ return checkdigit.to_s
187
+ end
188
+
189
+ end
190
+ end
191
+
192
+ # Attempts to convert a valid isbn13 into an isbn10.
193
+ #
194
+ # If supplied string is a valid isbn10, it is returned unchanged.
195
+ #
196
+ # If if the string is a valid isbn13 and starts with 978, it is converted to an isbn10.
197
+ #
198
+ # All other strings return nil.
199
+ #
200
+ # ISBN::convert_to_isbn10("9780201616224")
201
+ # #=> 020161622X
202
+ # ISBN::convert_to_isbn10("020161622X")
203
+ # #=> 020161622X
204
+ # ISBN::convert_to_isbn10("9793472834833")
205
+ # #=> nil
206
+ # ISBN::convert_to_isbn10("not an isbn")
207
+ # #=> nil
208
+ def ISBN::convert_to_isbn10(convert_me)
209
+ if convert_me.nil? || convert_me.class != String
210
+ nil
211
+ elsif ISBN::valid_isbn10?(convert_me)
212
+ convert_me
213
+ elsif ISBN::valid_isbn13?(convert_me) && convert_me[0,3] == '978'
214
+ convert_me[3,9] + ISBN::calc_isbn10_check(convert_me[3,9])
215
+ else
216
+ nil
217
+ end
218
+ end
219
+
220
+ # Attempts to convert the supplied string into an ISBN13.
221
+ #
222
+ # If the string is a valid isbn13, it is returned unchanged.
223
+ #
224
+ # If the string is a valid isbn10, it will be converted to isbn13.
225
+ #
226
+ # All other strings will return nil.
227
+ #
228
+ # ISBN::convert_to_isbn13("020161622X")
229
+ # #=> 9780201616224
230
+ # ISBN::convert_to_isbn13("9780201616224")
231
+ # #=> 9780201616224
232
+ # ISBN::convert_to_isbn13("9793472834833")
233
+ # #=> nil
234
+ # ISBN::convert_to_isbn13("not an isbn")
235
+ # #=> nil
236
+ def ISBN::convert_to_isbn13(convert_me)
237
+ if convert_me.nil? || convert_me.class != String
238
+ nil
239
+ elsif ISBN::valid_isbn13?(convert_me)
240
+ convert_me
241
+ elsif ISBN::valid_isbn10?(convert_me)
242
+ '978'+convert_me[0,9] + ISBN::calc_isbn13_check('978'+convert_me[0,9])
243
+ else
244
+ nil
245
+ end
246
+ end
247
+
248
+ end
249
+ end