rbook-bisac 0.5
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 +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
|