rbook-bisac 0.5
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/COPYING +340 -0
- data/LICENSE +13 -0
- data/README +0 -0
- data/Rakefile +90 -0
- data/lib/rbook/bisac.rb +35 -0
- data/lib/rbook/bisac/message.rb +99 -0
- data/lib/rbook/bisac/po.rb +96 -0
- data/lib/rbook/bisac/po_line_item.rb +36 -0
- data/lib/rbook/bisac/product.rb +176 -0
- data/lib/rbook/errors.rb +9 -0
- data/specs/data/bisac_po.bsc +112 -0
- data/specs/data/bisac_po.txt +112 -0
- data/specs/data/bisac_po_no_footer.txt +111 -0
- data/specs/data/bisac_po_no_header.txt +111 -0
- data/specs/data/valid_bisac.txt +213 -0
- data/specs/new_bisac_spec.rb +68 -0
- data/specs/new_po_line_item_spec.rb +31 -0
- data/specs/new_po_spec.rb +66 -0
- metadata +82 -0
@@ -0,0 +1,99 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module RBook
|
4
|
+
module Bisac
|
5
|
+
|
6
|
+
# Represents a single Bisac File. See RBook::Bisac for a basic
|
7
|
+
# usage example.
|
8
|
+
class Message
|
9
|
+
|
10
|
+
attr_accessor :company, :san, :batch, :code, :products
|
11
|
+
|
12
|
+
# creates a new bisac file in memory
|
13
|
+
# params:
|
14
|
+
# - company = company name (10 chars)
|
15
|
+
# - san = company SAN number (12 chars)
|
16
|
+
# - batch = batch name for this file (6 chars)
|
17
|
+
# - code = 1 for new titles, 2 for updated titles (1 char)
|
18
|
+
def initialize(company, san, batch, code)
|
19
|
+
@company = company
|
20
|
+
@san = san
|
21
|
+
@batch = batch
|
22
|
+
@code = code
|
23
|
+
@products = []
|
24
|
+
end
|
25
|
+
|
26
|
+
# loads the requested BISAC file into memory.
|
27
|
+
# returns a Message object or nil if the file is not
|
28
|
+
# a BISAC file
|
29
|
+
def self.load(filename)
|
30
|
+
msg = self.new(nil,nil,nil,nil)
|
31
|
+
|
32
|
+
File.open(filename, "r") do |f|
|
33
|
+
f.each_line do |l|
|
34
|
+
if l[0,10].eql?("**HEADER**")
|
35
|
+
msg.company = l[16,10].strip
|
36
|
+
msg.san = l[26,12].strip
|
37
|
+
msg.batch = l[38,6].strip
|
38
|
+
msg.code = l[44,1].strip
|
39
|
+
elsif !l[0,11].eql?("**TRAILER**")
|
40
|
+
product = RBook::Bisac::Product.from_string(l)
|
41
|
+
msg << product unless product.nil?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
if msg.company.nil? || msg.san.nil? || msg.batch.nil? || msg.code.nil?
|
47
|
+
return nil
|
48
|
+
else
|
49
|
+
return msg
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# adds a new title to the bisic file. Expects a Rbook::Bisac::Product object.
|
54
|
+
def << (item)
|
55
|
+
unless item.class == RBook::Bisac::Product
|
56
|
+
raise ArgumentError, 'item must be a RBook::Bisac::Product object'
|
57
|
+
end
|
58
|
+
@products << item
|
59
|
+
end
|
60
|
+
|
61
|
+
# converts this bisac file into a string
|
62
|
+
def to_s
|
63
|
+
# File Header
|
64
|
+
content = "**HEADER**"
|
65
|
+
content << Time.now.strftime("%y%m%d")
|
66
|
+
content << @company[0,10].ljust(10)
|
67
|
+
content << @san[0,12].ljust(12)
|
68
|
+
content << @batch[0,6].ljust(6)
|
69
|
+
content << @code[0,1].ljust(1)
|
70
|
+
content << "**PUBSTAT*"
|
71
|
+
content << "040"
|
72
|
+
content << "".ljust(201)
|
73
|
+
content << "\n"
|
74
|
+
|
75
|
+
# File Content
|
76
|
+
counter = 0
|
77
|
+
@products.each do |item|
|
78
|
+
content << item.to_s + "\n"
|
79
|
+
counter = counter + 1
|
80
|
+
end
|
81
|
+
|
82
|
+
# File Footer
|
83
|
+
content << "**TRAILER*"
|
84
|
+
content << Time.now.strftime("%y%m%d")
|
85
|
+
content << @batch[0,6].ljust(6)
|
86
|
+
content << counter.to_s[0,6].ljust(6)
|
87
|
+
content << "**PUBSTAT*"
|
88
|
+
content << "".ljust(221)
|
89
|
+
|
90
|
+
return content
|
91
|
+
end
|
92
|
+
|
93
|
+
# writes the content of this bisac file out to the specified file
|
94
|
+
def write(filename)
|
95
|
+
File.open(filename, "w") { |f| f.puts to_s }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/po_line_item'
|
2
|
+
|
3
|
+
module RBook
|
4
|
+
module Bisac
|
5
|
+
|
6
|
+
# Represents a single BISAC purchase order
|
7
|
+
class PO
|
8
|
+
|
9
|
+
attr_accessor :source_san, :source_suffix, :source_name
|
10
|
+
attr_accessor :date, :filename, :format_version
|
11
|
+
attr_accessor :destination_san, :destination_suffix
|
12
|
+
attr_accessor :po_number, :cancellation_date, :backorder
|
13
|
+
attr_accessor :do_not_exceed_action, :do_not_exceed_amount
|
14
|
+
attr_accessor :invoice_copies, :special_instructions
|
15
|
+
attr_accessor :do_not_ship_before
|
16
|
+
attr_accessor :items
|
17
|
+
|
18
|
+
# creates a new RBook::Bisac::PO object
|
19
|
+
def initialize
|
20
|
+
@items = []
|
21
|
+
end
|
22
|
+
|
23
|
+
# reads a bisac text file into memory. input should be a string
|
24
|
+
# that specifies the file path
|
25
|
+
def self.load_from_file(input)
|
26
|
+
raise RBook::InvalidFileError, 'Invalid file' unless File.exist?(input)
|
27
|
+
data = []
|
28
|
+
File.open(input) do |f|
|
29
|
+
f.each_line { |l| data << l }
|
30
|
+
end
|
31
|
+
return self.build_message(data)
|
32
|
+
end
|
33
|
+
|
34
|
+
# creates a RBook::Bisac::PO object from a string. Input should
|
35
|
+
# be a complete bisac file as a string
|
36
|
+
def self.load_from_string(input)
|
37
|
+
data = input.split("\n")
|
38
|
+
return self.build_message(data)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def self.build_message(data)
|
44
|
+
raise RBook::InvalidFileError, 'File appears to be too short' unless data.size >= 3
|
45
|
+
raise RBook::InvalidFileError, 'Missing header information' unless data[0][0,2].eql?("00")
|
46
|
+
raise RBook::InvalidFileError, 'Missing footer information' unless data[-1][0,2].eql?("90")
|
47
|
+
|
48
|
+
msg = PO.new
|
49
|
+
|
50
|
+
data.each do |line|
|
51
|
+
|
52
|
+
case line[0,2]
|
53
|
+
when "00" # first header
|
54
|
+
msg.source_san = line[7,7].strip
|
55
|
+
msg.source_suffix = line[14,5].strip
|
56
|
+
msg.source_name = line[19,13].strip
|
57
|
+
msg.date = line[32,6].strip
|
58
|
+
msg.filename = line[38,20].strip
|
59
|
+
msg.format_version = line[60,3].strip
|
60
|
+
msg.destination_san = line[63,7].strip
|
61
|
+
msg.destination_suffix = line[70,5].strip
|
62
|
+
when "10" # second header
|
63
|
+
msg.po_number = line[7, 12].strip
|
64
|
+
msg.cancellation_date = line[50,6].strip
|
65
|
+
msg.backorder = line[56,1].eql?("Y") ? true : false
|
66
|
+
msg.do_not_exceed_action = line[57,1].strip
|
67
|
+
msg.do_not_exceed_amount = line[58,7].strip
|
68
|
+
msg.invoice_copies = line[65,2].strip
|
69
|
+
msg.special_instructions = line[67,1].eql?("Y") ? true : false
|
70
|
+
msg.do_not_ship_before = line[73,6].strip
|
71
|
+
when "40" # line item
|
72
|
+
# load each lineitem into the message
|
73
|
+
item = RBook::Bisac::POLineItem.load_from_string(line)
|
74
|
+
msg.items << item
|
75
|
+
when "41"
|
76
|
+
if line.length > 21
|
77
|
+
title = line[21, line.length - 21]
|
78
|
+
msg.items.last.title = title.strip unless title.nil?
|
79
|
+
end
|
80
|
+
when "42"
|
81
|
+
if line.length > 21
|
82
|
+
author = line[21, line.length - 21]
|
83
|
+
msg.items.last.author = author.strip unless author.nil?
|
84
|
+
end
|
85
|
+
when "90" # footer
|
86
|
+
# check the built objects match the file
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
# return the results
|
92
|
+
return msg
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
#require 'rbook/errors'
|
3
|
+
|
4
|
+
module RBook
|
5
|
+
module Bisac
|
6
|
+
|
7
|
+
# represents a single line on the purchase order. Has attributes like
|
8
|
+
# price, qty and description
|
9
|
+
class POLineItem
|
10
|
+
|
11
|
+
attr_accessor :sequence_number, :po_number, :line_item_number
|
12
|
+
attr_accessor :isbn, :qty, :catalogue_code, :price
|
13
|
+
attr_accessor :author, :title
|
14
|
+
|
15
|
+
# returns a new RBook::Bisac::POLineItem object using the data passed in as a string
|
16
|
+
# refer to the bisac spec for the expected format of the string
|
17
|
+
def self.load_from_string(data)
|
18
|
+
raise RBook::InvalidArgumentError, 'data must be a string' unless data.kind_of? String
|
19
|
+
|
20
|
+
item = self.new
|
21
|
+
|
22
|
+
item.sequence_number = data[2,5].to_i
|
23
|
+
item.po_number = data[7,13].strip
|
24
|
+
item.line_item_number = data[21,10].strip
|
25
|
+
item.isbn = data[31,10].strip
|
26
|
+
item.qty = data[41,5].to_i
|
27
|
+
item.catalogue_code = data[46,1].strip
|
28
|
+
item.price = BigDecimal.new(data[47,6])
|
29
|
+
|
30
|
+
return item
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module RBook
|
2
|
+
module Bisac
|
3
|
+
|
4
|
+
# Class to represent a single product line in a Bisac File. See
|
5
|
+
# RBook::Bisac for basic usage instructions.
|
6
|
+
class Product
|
7
|
+
|
8
|
+
attr_reader :isbn, :title, :author, :price, :pubdate, :publisher
|
9
|
+
attr_reader :imprint, :volumes, :edition, :binding, :volume, :status
|
10
|
+
|
11
|
+
# Creates a new product object with the requested ISBN. Must be a 10 digit ISBN.
|
12
|
+
def initialize(isbn)
|
13
|
+
raise ArgumentError, 'isbn must 10 chars or less' if isbn.to_s.length > 10
|
14
|
+
|
15
|
+
@isbn = isbn.to_s
|
16
|
+
@title = ""
|
17
|
+
@author = ""
|
18
|
+
@price = ""
|
19
|
+
@pubdate = ""
|
20
|
+
@publisher = ""
|
21
|
+
@imprint = ""
|
22
|
+
@volumes = ""
|
23
|
+
@edition = ""
|
24
|
+
@binding = ""
|
25
|
+
@volume = ""
|
26
|
+
@status = ""
|
27
|
+
end
|
28
|
+
|
29
|
+
# sets the products author. Maximum of 30 chars.
|
30
|
+
def author=(author)
|
31
|
+
@author = author.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
# sets the products binding. Maximum of 2 chars.
|
35
|
+
def binding=(binding)
|
36
|
+
@binding = binding.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
# sets the products edition number. Maximum of 3 chars.
|
40
|
+
def edition=(edition)
|
41
|
+
@edition = edition.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
# takes a single line from a BISAC file and attempts to convert
|
45
|
+
# it to a Product object
|
46
|
+
def self.from_string(s)
|
47
|
+
s = s.to_s
|
48
|
+
return nil if s.length < 259
|
49
|
+
product = self.new(s[0,10])
|
50
|
+
product.title = s[15,30].strip
|
51
|
+
product.author = s[46,30].strip
|
52
|
+
product.price = s[79,7].strip if s[79,7].strip.match(/\A\d{0,7}\Z/)
|
53
|
+
product.pubdate = s[87,6].strip if s[87,6].strip.match(/\A\d{6}\Z/)
|
54
|
+
product.publisher = s[94,10].strip
|
55
|
+
product.imprint = s[105,14].strip
|
56
|
+
product.volumes = s[120,3].strip
|
57
|
+
product.edition = s[124,2].strip
|
58
|
+
product.binding = s[127,2].strip
|
59
|
+
product.volume = s[130,3].strip
|
60
|
+
product.status = s[153,3].strip
|
61
|
+
return product
|
62
|
+
end
|
63
|
+
|
64
|
+
# Sets the products imprint. Maximum of 14 chars.
|
65
|
+
def imprint=(imprint)
|
66
|
+
@imprint = imprint.to_s
|
67
|
+
end
|
68
|
+
|
69
|
+
# Sets the price imprint. Maximum of 7 chars. Must by a whole
|
70
|
+
# number (represent price in cents).
|
71
|
+
def price=(price)
|
72
|
+
unless price.to_s.match(/\A\d{0,7}\Z/)
|
73
|
+
raise ArgumentError, 'price should be a whole number with no more than 7 digits. (price in cents)'
|
74
|
+
end
|
75
|
+
@price = price.to_s
|
76
|
+
end
|
77
|
+
|
78
|
+
# Sets the products pubdate. Must be in the form YYMMDD
|
79
|
+
def pubdate=(pubdate)
|
80
|
+
unless pubdate.to_s.match(/\A\d{6}\Z/)
|
81
|
+
raise ArgumentError, 'pubdate should be a date in the form YYMMDD.'
|
82
|
+
end
|
83
|
+
@pubdate = pubdate.to_s
|
84
|
+
end
|
85
|
+
|
86
|
+
# sets the products publisher. Maximum of 10 chars.
|
87
|
+
def publisher=(publisher)
|
88
|
+
@publisher = publisher.to_s
|
89
|
+
end
|
90
|
+
|
91
|
+
# sets the products status code. Maximum of 3 chars.
|
92
|
+
def status=(status)
|
93
|
+
@status = status.to_s
|
94
|
+
end
|
95
|
+
|
96
|
+
# sets the products title. Maximum of 30 chars.
|
97
|
+
def title=(title)
|
98
|
+
@title = title.to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns the product as a single line ready for inserting into a BISAC file.
|
102
|
+
# Doesn't have a \n on the end
|
103
|
+
def to_s
|
104
|
+
content = ""
|
105
|
+
content << @isbn[0,10].ljust(10) # 10 digit isbn
|
106
|
+
content << "1"
|
107
|
+
content << "N"
|
108
|
+
content << "N"
|
109
|
+
content << "B"
|
110
|
+
content << "N"
|
111
|
+
content << @title[0,30].ljust(30)
|
112
|
+
content << "N"
|
113
|
+
content << @author[0,30].ljust(30)
|
114
|
+
content << "N"
|
115
|
+
content << "A" # author role
|
116
|
+
content << "N"
|
117
|
+
content << @price[0,7].rjust(7,"0") # current price
|
118
|
+
content << "N"
|
119
|
+
content << @pubdate[0,6].ljust(6) # published date
|
120
|
+
content << "N"
|
121
|
+
content << @publisher[0,10].ljust(10) # publisher
|
122
|
+
content << "N"
|
123
|
+
content << @imprint[0,14].ljust(14) #imprint
|
124
|
+
content << "N"
|
125
|
+
content << @volumes[0,3].rjust(3,"0") # volumes included in this isbn
|
126
|
+
content << "N"
|
127
|
+
content << @edition[0,2].rjust(2,"0") # edition
|
128
|
+
content << "N"
|
129
|
+
content << @binding[0,2].rjust(2,"0") # binding
|
130
|
+
content << "N"
|
131
|
+
content << @volume[0,3].rjust(3,"0") # volume number
|
132
|
+
content << "N"
|
133
|
+
content << "0000000" # new price
|
134
|
+
content << "N"
|
135
|
+
content << "000000" # new price effective date
|
136
|
+
content << "N"
|
137
|
+
content << " " # audience type
|
138
|
+
content << "N"
|
139
|
+
content << @status[0,3].rjust(3) # status
|
140
|
+
content << "N"
|
141
|
+
content << " " # available date. only use for status' like NYP
|
142
|
+
content << "N"
|
143
|
+
content << " " # alternate isbn
|
144
|
+
content << "N"
|
145
|
+
content << "999999" # out of print date. only use for status == OP
|
146
|
+
content << "N"
|
147
|
+
content << " " # geographic restrictions
|
148
|
+
content << "N"
|
149
|
+
content << " " # library of congress catalogue number
|
150
|
+
content << "N"
|
151
|
+
content << "".ljust(40) # series title
|
152
|
+
content << "N"
|
153
|
+
content << "0" # price code for current price
|
154
|
+
content << "N"
|
155
|
+
content << "0" # price code for new price
|
156
|
+
content << "N"
|
157
|
+
content << "0000000" # freight pass through price
|
158
|
+
content << "N"
|
159
|
+
content << "000000" # new freight pass through price
|
160
|
+
content << "00000" # last changed date
|
161
|
+
|
162
|
+
return content
|
163
|
+
end
|
164
|
+
|
165
|
+
# sets the products volume number. Maximum of 3 chars.
|
166
|
+
def volume=(volume)
|
167
|
+
@volume = volume.to_s
|
168
|
+
end
|
169
|
+
|
170
|
+
# sets the number of volumes in the set this product belongs to. Maximum of 3 chars.
|
171
|
+
def volumes=(volumes)
|
172
|
+
@volumes = volumes.to_s
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
data/lib/rbook/errors.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
00000019013725 Rainbow Book 061112INTERNET.BSC F03901375X
|
2
|
+
1000002 14976 9013725 901375X 061112000000Y 000000001N00020000000
|
3
|
+
4000003 14976 Y000000000102978513220000100000000000000000000550000000
|
4
|
+
4100004 14976 Finding Sanctuary :Monastic St
|
5
|
+
4200005 14976 JAMISON ABBOT CHRISTOPH
|
6
|
+
4000006 14976 Y000000000203407855780000100000000000000000000550000000
|
7
|
+
4100007 14976 In My Own Words: Padre Pio
|
8
|
+
4200008 14976 CHIFFOLO ANTHONY
|
9
|
+
4000009 14976 Y000000000303408635440000100000000000000000000550000000
|
10
|
+
4100010 14976 Knowing God New Edn.With Study
|
11
|
+
4200011 14976 PACKER J I
|
12
|
+
4000012 14976 Y000000000403409111580000100000000000000000000550000000
|
13
|
+
4100013 14976 Everyone I See Is Luckier Than
|
14
|
+
4200014 14976 BEVAN CLARE
|
15
|
+
4000015 14976 Y000000000503409111740000100000000000000000000550000000
|
16
|
+
4100016 14976 I Want To Shout And Stamp Abou
|
17
|
+
4200017 14976 MITTON TONY
|
18
|
+
4000018 14976 Y000000000605670406230000100000000000000000000550000000
|
19
|
+
4100019 14976 Gnostics :Identifying an Ancie
|
20
|
+
4200020 14976 LOGAN, ALASTAIR
|
21
|
+
4000021 14976 Y000000000705670875140000100000000000000000000550000000
|
22
|
+
4100022 14976 Mary For All Christians
|
23
|
+
4200023 14976 MACQUARRIE J
|
24
|
+
4000024 14976 Y000000000806425620750000100000000000000000000550000000
|
25
|
+
4100025 14976 Forgiveness and Other Acts of
|
26
|
+
4200026 14976 DOWRICK STEPHANIE
|
27
|
+
4000027 14976 Y000000000907333174560000100000000000000000000550000000
|
28
|
+
4100028 14976 Honey and The Fires: Ancient s
|
29
|
+
4200029 14976 PULVERS ROGER & ALICE
|
30
|
+
4000030 14976 Y000000001007333179600000100000000000000000000550000000
|
31
|
+
4100031 14976 Mummy Book
|
32
|
+
4200032 14976 PARR TODD
|
33
|
+
4000033 14976 Y000000001107333198230000100000000000000000000550000000
|
34
|
+
4100034 14976 So Many Selves
|
35
|
+
4200035 14976 CAREY GABRIELLE
|
36
|
+
4000036 14976 Y000000001207336159880000100000000000000000000550000000
|
37
|
+
4100037 14976 New Glucose Revolution Pocket
|
38
|
+
4200038 14976 MILLET ET AL
|
39
|
+
4000039 14976 Y000000001307475413530000100000000000000000000550000000
|
40
|
+
4100040 14976 Achieving Emotional Literacy
|
41
|
+
4200041 14976 STEINER CLAUDE
|
42
|
+
4000042 14976 Y000000001407499210990000100000000000000000000550000000
|
43
|
+
4100043 14976 How Meditation Heals
|
44
|
+
4200044 14976 HARRISON ERIC
|
45
|
+
4000045 14976 Y000000001507499242170000100000000000000000000550000000
|
46
|
+
4100046 14976 Other Side and Back :A Psychic
|
47
|
+
4200047 14976 BROWNE SYLVIA
|
48
|
+
4000048 14976 Y000000001607502213130000100000000000000000000550000000
|
49
|
+
4100049 14976 I'm Worried :Your Emotions Pb
|
50
|
+
4200050 14976 MOSES BRIAN
|
51
|
+
4000051 14976 Y000000001707502213210000100000000000000000000550000000
|
52
|
+
4100052 14976 It's Not Fair :Your Feelings P
|
53
|
+
4200053 14976 MOSES BRIAN
|
54
|
+
4000054 14976 Y000000001807538205440000100000000000000000000550000000
|
55
|
+
4100055 14976 Memory and Identity :Personal
|
56
|
+
4200056 14976 PAUL JOHN II
|
57
|
+
4000057 14976 Y000000001908192198190000100000000000000000000550000000
|
58
|
+
4100058 14976 Gift of Faith (Morehouse) :Sho
|
59
|
+
4200059 14976 NEFF LAVONNE
|
60
|
+
4000060 14976 Y0000000020082646520X0000200000000000000000000550000000
|
61
|
+
4100061 14976 Pastoral Prayers
|
62
|
+
4200062 14976 DEADMAN R
|
63
|
+
4000063 14976 Y000000002108264685000000200000000000000000000550000000
|
64
|
+
4100064 14976 Dignity of Difference P/B: How
|
65
|
+
4200065 14976 SACKS JONATHAN
|
66
|
+
4000066 14976 Y000000002208264733770000100000000000000000000550000000
|
67
|
+
4100067 14976 Celebrating Life :Finding happ
|
68
|
+
4200068 14976 SACKS JONATHAN
|
69
|
+
4000069 14976 Y000000002308264748100000100000000000000000000550000000
|
70
|
+
4100070 14976 From Optimism to Hope
|
71
|
+
4200071 14976 SACKS JONATHAN
|
72
|
+
4000072 14976 Y000000002408264785570000100000000000000000000550000000
|
73
|
+
4100073 14976 Persistence of Faith :Religion
|
74
|
+
4200074 14976 JONATHAN SACKS
|
75
|
+
4000075 14976 Y000000002508264794210000100000000000000000000550000000
|
76
|
+
4100076 14976 Shape of the Liturgy New Ed.
|
77
|
+
4200077 14976 DIX GREGORY
|
78
|
+
4000078 14976 Y000000002608601242580000200000000000000000000550000000
|
79
|
+
4100079 14976 Essence of Prayer
|
80
|
+
4200080 14976 BURROWS RUTH
|
81
|
+
4000081 14976 Y000000002715633841400000100000000000000000000550000000
|
82
|
+
4100082 14976 Theological Perspectives On Go
|
83
|
+
4200083 14976 MILBANK & WRD
|
84
|
+
4000084 14976 Y000000002817411479210000200000000000000000000550000000
|
85
|
+
4100085 14976 David Suzuki
|
86
|
+
4200086 14976 SUZUKI DAVID
|
87
|
+
4000087 14976 Y000000002917411484640000100000000000000000000550000000
|
88
|
+
4100088 14976 Holism and Complementary Medic
|
89
|
+
4200089 14976 DI STEFANO VINCENT
|
90
|
+
4000090 14976 Y000000003018418129270000100000000000000000000550000000
|
91
|
+
4100091 14976 Personal power animals :for gu
|
92
|
+
4200092 14976 GAUDING MADONNA
|
93
|
+
4000093 14976 Y000000003118644894130000100000000000000000000550000000
|
94
|
+
4100094 14976 Earth Time
|
95
|
+
4200095 14976 SUZUKI DAVID
|
96
|
+
4000096 14976 Y000000003218650838440000100000000000000000000550000000
|
97
|
+
4100097 14976 Facing The Fifties
|
98
|
+
4200098 14976 O'CONNOR PETER
|
99
|
+
4000099 14976 Y000000003318650891760000100000000000000000000550000000
|
100
|
+
4100100 14976 Long Way from Rome A: Why the
|
101
|
+
4200101 14976 MCGILLION CHRIS (ED)
|
102
|
+
4000102 14976 Y000000003418891089600000100000000000000000000550000000
|
103
|
+
4100103 14976 14 Presentations for Fall (God
|
104
|
+
4200104 14976 BERRYMAN JEROME W
|
105
|
+
4000105 14976 Y000000003518891089790000100000000000000000000550000000
|
106
|
+
4100106 14976 20 Presentations for Winter (G
|
107
|
+
4200107 14976 BERRYMAN JEROME W
|
108
|
+
4000108 14976 Y000000003618891089870000100000000000000000000550000000
|
109
|
+
4100109 14976 20 Presentations for Spring (G
|
110
|
+
4200110 14976 BERRYMAN JEROME W
|
111
|
+
5000111 14976 0011000000000360000000040
|
112
|
+
90001120000000000036000010000000040000010000100000000000003600001000000000000000
|