zcc 0.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.
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/perl
2
+
3
+ use strict;
4
+ ##
5
+ use MARC::Record;
6
+ use MARC::File::XML;
7
+ use MARC::File::USMARC;
8
+ use MARC::Lint;
9
+
10
+
11
+ #print @ARGV[0];
12
+ print "\n";
13
+
14
+ my $lint = MARC::Lint->new();
15
+
16
+
17
+ my $file = MARC::Record->new_from_xml( @ARGV[0] );
18
+
19
+ #print $file->as_formatted;
20
+ #my $file = MARC::File::USMARC->in( 'temp_lint.mrc' );
21
+ #print $record->as_formatted;
22
+
23
+ #print "title: ", $title;
24
+ #print $record->as_formatted;
25
+
26
+ $lint->check_record($file);
27
+ my @warnings = $lint->warnings();
28
+
29
+
30
+ foreach my $warning ( @warnings ) {
31
+ print $warning . "\n";
32
+ }
33
+
34
+
35
+
36
+ #while ( my $marc = $file->next() ) {
37
+ # $lint->check_record( $marc );
38
+ #
39
+ # Print the title tag
40
+ # print $marc->title, "\n";
41
+
42
+ # Print the errors that were found
43
+ # print join( "\n", $lint->warnings ), "\n";
44
+ # } # while
45
+
46
+
47
+ #print "Hello, world!\n";
48
+ #@input = @ARGV;
49
+ #print "\nthis\n";
50
+ #print "\ninput[0]", $input[0], "\n\n";
data/bin/zcc ADDED
@@ -0,0 +1,240 @@
1
+ #!/usr/bin/ruby -w
2
+ ## Jason Ronallo
3
+ # April, 2007
4
+
5
+ require 'rubygems'
6
+ require 'zoom'
7
+ require 'marc'
8
+ require 'stringio'
9
+ require 'yaml'
10
+
11
+ $KCODE = 'u'
12
+ require 'jcode'
13
+ require 'unicode'
14
+
15
+ #--my modules
16
+ require 'zcc/marcadditions'
17
+ require 'zcc/pickers'
18
+
19
+ class Array
20
+ include Pickers
21
+ end
22
+
23
+ class Object #MARC::Record
24
+ include MARCAdditions
25
+ end
26
+
27
+
28
+
29
+
30
+ class String
31
+ def usubstr(a, b)
32
+ i = 0
33
+ buff = ''
34
+ each_char do
35
+ | c |
36
+ i += 1
37
+ if i >= a: buff += c end
38
+ if i == b: return buff end
39
+ end
40
+ end
41
+ end
42
+
43
+
44
+ #--############ BEGIN CONFIGURATION ####################
45
+ ## Basic configuration below. To complete full configuration, including picking z39.50 servers please see zcc.yaml
46
+ TO_SHOW = 10
47
+ #HOW_TO_SAVE = 'search_term'
48
+ HOW_TO_SAVE = 'timestamp' #with 'timestamp' all records are saved to the same date stamped file of the time the program starts. The other valid value is 'search_term' in which case each record is saved according to the search term appending on to files which have the same search term
49
+
50
+ TIMESTAMP = Time.now.strftime("%Y%m%d%H%M%S")
51
+ SCRIPTING = 'yes' #if you want scripting enabled for each record
52
+ CSV = 'yes' #would you like to run the csv creation?
53
+ LINTER = 'yes' #If you do not have the Perl MARC::Lint module installed, probably from cpan, change this value to 'no'
54
+ FORMAT_TO_SAVE = 'marc' #other value that works is 'xml' which saves in marcxml
55
+ ###### END OF CONFIGURATION ###########
56
+
57
+ $testing = ARGV[0]
58
+ $testing = nil unless $testing == 'v' or $testing == 't'
59
+ puts "We're testing " if $testing
60
+ STDIN.gets if $testing
61
+
62
+ yamlfile = YAML.load_file( "#{File.expand_path("~")}/.zcc/zcc.yaml" )
63
+ zservers = yamlfile['zservers']
64
+ labels = yamlfile['labels']
65
+ scripting = yamlfile['scripting']
66
+ $procs = yamlfile['procs']
67
+
68
+ #class String
69
+ # def to_proc
70
+ # eval "Proc.new #{self} " # or "Proc.new #{self}" in my case
71
+ # end
72
+ #end
73
+
74
+ def continue?
75
+ loop {
76
+ print "Enter to search again. q to quit: "
77
+ enter_quit = STDIN.gets.chomp
78
+ if enter_quit == ''
79
+ puts "Again!\n"
80
+ return "again"
81
+ elsif enter_quit == 'q'
82
+ puts "Please! No more!"
83
+ exit
84
+ end
85
+ }
86
+ end
87
+
88
+ def zoomer (search_term, server, port, database )
89
+ puts "\n-------------------------------------\n#{server} #{port} #{database} \n"
90
+ conn = ZOOM::Connection.new
91
+
92
+ conn.connect(server, port) #do |conn|
93
+ conn.set_option('charset', 'UTF-8')
94
+ conn.preferred_record_syntax = 'MARC21'
95
+ #STDIN.gets
96
+ conn.database_name = database
97
+ #conn.preferred_record_syntax = 'MARC21'#'USMARC' #was 'XML'
98
+ #conn.set_option('charset', 'UTF-8')
99
+ full_search = ''
100
+ if search_term =~ /\d+[X||\d]/ and !(search_term.match( /[a-wyz]/i ))
101
+ puts "Searching for ISBN: #{search_term}"
102
+ if server == 'z3950.loc.gov'
103
+ full_search = "@attr 1=1007 #{search_term}"
104
+ else
105
+ full_search = "@attr 1=7 #{search_term}"
106
+ end
107
+ elsif ( search_term[/[a-z]/i] ) #-- This check for a string could be better!
108
+ puts "searching for title:#{search_term}"
109
+ search_term = "\'#{search_term}\'"
110
+ full_search = "@attr 1=4 \"#{search_term}\""
111
+ else
112
+ puts "What is this search? Does not compute."
113
+ exit
114
+ end
115
+
116
+ rset = conn.search(full_search)
117
+ if ( rset.length == 0)
118
+ return nil
119
+ end
120
+
121
+ rset_recs = rset[0,TO_SHOW]
122
+
123
+ #puts rset_recs
124
+ #STDIN.gets
125
+
126
+ puts "rset.length #{rset.length}"
127
+ #puts rset.get_option('charset')
128
+ #STDIN.gets
129
+ xmlsrecs = ''
130
+ #--xmlsrecs = rset.records
131
+ rset_recs.each do |rsetrec|
132
+ #--puts "moving record into array"
133
+ #puts rsetrec.syntax
134
+ #puts rsetrec
135
+ #STDIN.gets
136
+ xmlsrecs += rsetrec.xml('MARC-8', 'UTF-8') #change this to detect character encoding before assuming marc8 to utf8
137
+ #puts xmlsrecs
138
+ end
139
+ #puts xmlsrecs
140
+ return records = MARC::XMLReader.new(StringIO.new(string=xmlsrecs))
141
+ #end
142
+ rescue Exception => except
143
+ puts "Error! #{except}"
144
+ return nil
145
+
146
+
147
+ end
148
+
149
+ #++# All the main logic of the program is just one simple big loop.
150
+ puts "Zcc, Copyright (C) 2007 Jason Ronallo\nZcc comes with ABSOLUTELY NO WARRANTY.\nZcc is released under the terms of the GPL v.2 or later. See LICENSE for full information."
151
+ loop {
152
+ taken = []
153
+ print "Enter a title or ISBN to search for: "
154
+ search_term = STDIN.gets.chomp
155
+
156
+
157
+ zservers.each do |zserver|
158
+ records = zoomer(search_term, zserver[0], zserver[1], zserver[2])
159
+ puts "\n"
160
+
161
+ if records.nil?: print "nil records returned"; next; end
162
+
163
+ recs_array = records.to_a
164
+ taker = []
165
+ taker = recs_array.select_good_marc('multi')
166
+ #--puts taker.inspect
167
+ another_zserver = taker.pop if taker[-1] == 'done'
168
+
169
+ next if taker == nil
170
+ taker.each do |taker|
171
+ puts "\ntaker: #{taker['245']}\n\n"
172
+ taken << taker
173
+ end
174
+ break if another_zserver == 'done'
175
+ end
176
+
177
+ taken.flatten!
178
+ taken.compact!
179
+ puts "taken.length #{taken.length}"
180
+ if taken.length > 1
181
+ puts "\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nWe only need one record per book, so make your choice now!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n"
182
+ taken = taken.select_good_marc('one')
183
+ next if taken == 'none'
184
+ puts "after selecting final record taken.length = #{taken.length}"
185
+ puts taken[0]['245'] , "\n\n"
186
+ elsif taken.length == 0
187
+ print "You didn't get any records!\n"
188
+ next if continue? == 'again'
189
+ end
190
+
191
+ final_taken = taken[0]
192
+ puts final_taken
193
+ final_taken.local_script(scripting) if SCRIPTING == 'yes'
194
+
195
+ puts "--------------FINAL RECORD----------------------------"
196
+ puts final_taken
197
+ puts "--------------FINAL RECORD----------------------------\a"
198
+ puts "Above is how your final record looks. Are you happy with it? (anything or n)"
199
+
200
+ to_save_or_not_to_save = STDIN.gets.chomp
201
+
202
+ if to_save_or_not_to_save == 'n'
203
+ next if continue? == 'again'
204
+ end
205
+
206
+ csv = final_taken.marc_to_csv(labels) if CSV == 'yes'
207
+
208
+ print "\n#{csv}\n"
209
+
210
+ if HOW_TO_SAVE == 'search_term'
211
+ filename = search_term.gsub(' ','_')
212
+ elsif HOW_TO_SAVE == 'timestamp'
213
+ filename = TIMESTAMP
214
+ end
215
+ #puts Dir.getwd
216
+ #STDIN.gets
217
+ #Dir.chdir("./saved") do
218
+ if FORMAT_TO_SAVE == 'marc'
219
+ aFile = File.new("#{filename}\.mrc","a+")
220
+ aFile.write(final_taken.to_marc)
221
+ puts "#{final_taken['245']['a']} saved in #{filename}\.mrc"
222
+ aFile.close
223
+ elsif FORMAT_TO_SAVE == 'xml'
224
+ puts final_taken.to_xml
225
+ aFile = File.new("#{filename}\.xml","a+")
226
+ aFile.write(final_taken.to_xml)
227
+ puts "#{final_taken['245']['a']} saved in #{filename}\.xml"
228
+ aFile.close
229
+ end
230
+
231
+ if CSV == 'yes'
232
+ csvFile = File.new("csv-#{filename}\.txt","a+")
233
+ csvFile.write(csv)
234
+ puts "csv for #{taken[0]['245']['a']} saved in csv-#{filename}\.txt"
235
+ csvFile.close
236
+ end
237
+ #end
238
+
239
+ next if continue? == 'again'
240
+ }
@@ -0,0 +1,238 @@
1
+ # ZOOMER CONFIG FILE
2
+ # This is in YAML format
3
+ # Configure this file if you want:
4
+ # 1. to search multiple Z39.50 servers
5
+ # 2. the added functionality of scripting
6
+ # 3. creation of csv files.
7
+ # See below in each section for more information.
8
+
9
+
10
+ ###########################
11
+ # Z39.50 servers
12
+ # Place zservers in the order of your preferences for records.
13
+ # The current zservers are preceded with a minus sign and a space.
14
+ # Each server is enclosed in brackets and values are separated by commas.
15
+ # Columns and tabs are not important and are only done for readability.
16
+ # For a list of other servers see: http://targettest.indexdata.com/
17
+ #
18
+ ##########################
19
+ zservers:
20
+ # server port service
21
+
22
+ # [128.148.19.6, 210, INNOPAC ] #bad server, for testing
23
+ #-[81.144.245.7, 210, INNOPAC] #wellcome.ac.uk latin1 charset
24
+ #- [142.51.8.7, 2200, unicorn]
25
+ - [z3950.loc.gov, 7090, Voyager ] # Library of Congress
26
+ # [bobcat.nyu.edu, 210, ADVANCE] #New York University Libraries | 98%
27
+ # [128.197.130.200, 210, INNOPAC] #Boston U. | 100%
28
+
29
+
30
+ #######################################################
31
+ # CSV files
32
+ # Follows is the template for creating csv files.
33
+ # Saving information to a csv file might be useful for print labels in
34
+ # a program like glabels or for statistics.
35
+ #######################################################
36
+ labels:
37
+ - [245, a, 30]
38
+ - [1XX, a, 30]
39
+ - [952, c]
40
+ - [942, k]
41
+ - [942, j]
42
+ - [942, l]
43
+ - [952, m]
44
+ - [952, t]
45
+ - [952, p]
46
+
47
+
48
+ #################################################
49
+ # Scripting
50
+ # Scripting allows you to change the record before saving it.
51
+ # Below is where you make changes to the scripting
52
+ # that will be run on each record. This feature is
53
+ # turned on in the main script with the value of the
54
+ # constant SCRIPTING at the head of the file.
55
+ #################################################
56
+ scripting:
57
+ - [remove, 9XX]
58
+ - [create-field, 942, " ", " "] #create new field with empty indicators
59
+ - [create-field, 952, " ", " "]
60
+ - [append-subfield, 952, 2, DLC]
61
+ - [append-subfield, 952, b, MRML]
62
+ #- [append-subfield, 952, c, BIO] # BIO, Fic
63
+ - [append-subfield, 942, c, BOOK]
64
+ - [append-subfield, 942, k, proc get_dewey] # "proc name" is the way to get
65
+ # the script to evaluate a block
66
+ # of code. See below. comment out for BIO
67
+ - [append-subfield, 942, j, proc get_decimal] #comment out for BIO
68
+ #- [append-subfield, 942, l, proc prompt_cutter] #BIO
69
+ - [append-subfield, 942, l, proc get_cutter] #comment out for BIO
70
+ - [append-subfield, 952, k, proc get_combined_callnum]
71
+ - [prompt, 942, x, IS THERE A CIP]
72
+ - [append-subfield, 942, y, proc get_cip_callnum]
73
+ - [prompt, 942, z, OLD CALL NUMBER]
74
+ - [prompt, 952, z, PUBLIC NOTE FOR ITEM]
75
+ - [prompt, 952, x, INTERNAL NOTE]
76
+ - [proc barcode_and_itemnum]
77
+ # [sort-tags] #This currently doesn't work.
78
+
79
+
80
+ #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
81
+ # This is where the procs go for added scripting power.
82
+ # If you know some Ruby you can try to create one of these.
83
+ # If the block of code is placed in the last position,
84
+ # the last value evaluated will be returned and entered in the field.
85
+ # If the block of code is the only value within barckets,
86
+ # then you need to do the work yourself. For instance, if you want
87
+ # to create a field you need to do that yourself.
88
+ # The word variable record refers to the record the script is
89
+ # being run on.
90
+ # All blocks of code below must begin the this way:
91
+ # 1. Indent.
92
+ # 2. Name of the block exactly as you enter it above.
93
+ # 3. Colon, space, pipe.
94
+ # 4. The block of code starts on the next line with two indentations.
95
+ # 5. The block of code ends with a line between it and the next
96
+ #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
97
+ procs:
98
+ prompt_cutter: |
99
+ print "What do you want the cutter to be?"
100
+ cutter = STDIN.gets.chomp
101
+ cutter
102
+
103
+ get_dewey: |
104
+ puts "in the get dewey proc" if $testing
105
+ if record['082']
106
+ dewey = record['082']['a']
107
+ callnum = dewey.gsub(/\//, '')
108
+ callnum = callnum.split(/\./)
109
+ callnum[0]
110
+ else
111
+ print "What is the dewey (just the part before the decimal!)? "
112
+ dewey = STDIN.gets.chomp
113
+ dewey
114
+ end
115
+
116
+
117
+ get_decimal: |
118
+ puts "in the get decimal proc" if $testing
119
+ if record['082']
120
+ dewey = record['082']['a']
121
+ dewey = dewey.gsub(/\//, '')
122
+ puts "dewey: #{dewey} #{dewey.class}" if $testing
123
+ puts "#{record['082']['a']}"
124
+ #STDIN.gets if $testing
125
+ #exit
126
+ decimal = dewey.split(/\./)
127
+ next if decimal[1] == nil
128
+ decimal = decimal[1].slice(0, 3)
129
+ decimal = decimal.gsub(/[0]+$/, '')
130
+ decimal = "." + decimal
131
+ #puts decimal
132
+ decimal = nil if decimal == '.'
133
+ #puts decimal
134
+
135
+ decimal
136
+ else
137
+ print "What is the decimal (leaving off the decimal point!)? "
138
+ decimal = STDIN.gets.chomp
139
+ decimal = "." + decimal
140
+ decimal = nil if decimal == '.'
141
+ decimal
142
+ end
143
+
144
+
145
+
146
+ get_cutter: |
147
+ #puts "|" , record , "|"
148
+ #puts "in the cutter proc"
149
+ if (record['952']) and (record['952']['c'] == ('BIO' or 'F'))
150
+ print "This is a |#{record['952']['c']}|, so choose your cutter accordingly: "
151
+ cutter = STDIN.gets.chomp
152
+ cutter.upcase!
153
+ return cutter
154
+ elsif record['100']
155
+ cutter = record['100']['a'].dup
156
+ elsif record['110']
157
+ cutter = record['110']['a'].dup
158
+ elsif record['111']
159
+ cutter = record['111']['a'].dup
160
+ elsif record['130']
161
+ cutter = record['130']['a'].dup
162
+ elsif record['245'].indicator1 == '0'
163
+ cutter = record['245']['a']
164
+ i = record['245'].indicator2.to_i
165
+ cutter = cutter[i,99]
166
+ else
167
+ print "What is the cutter for this book? "
168
+ cutter = STDIN.gets.chomp
169
+ end
170
+ #puts cutter
171
+ #puts cutter.length
172
+ #puts cutter.jlength
173
+ #STDIN.gets
174
+ #puts cutter.usubstr(0, 3)
175
+
176
+ #STDIN.gets
177
+ if cutter.length == cutter.jlength
178
+ cutter = cutter[0,4]
179
+ #puts "cutter after slice", cutter
180
+ cutter.gsub!("'", '')
181
+ cutter.gsub!(" ", '')
182
+ cutter = cutter[0,3]
183
+ else
184
+ puts "This cutter appears to have multi-byte characters."
185
+ print "What is the cutter for this book? "
186
+ cutter = STDIN.gets.chomp
187
+ end
188
+ cutter.upcase!
189
+ puts "|#{cutter}|"
190
+ puts cutter.jlength
191
+
192
+ cutter
193
+
194
+
195
+ get_cip_callnum: |
196
+ if record['942']['x'] == 'y'
197
+ print "What is the CIP call number? "
198
+ cipcall = STDIN.gets.chomp
199
+ cipcall
200
+ else
201
+ puts "value is nil"
202
+ end
203
+
204
+
205
+ get_combined_callnum: |
206
+ #puts "into get_combined_callnum"
207
+ #puts record
208
+ #puts "**942 #{record['942']}"
209
+ #puts "**942k #{record['942']['k']}"
210
+ combined_callnum = record['942']['k'] if record['942']['k']
211
+ combined_callnum = combined_callnum + record['942']['j'] if record['942']['j']
212
+ if record['942']['k']
213
+ combined_callnum = combined_callnum.to_s + " " + record['942']['l']
214
+ else
215
+ combined_callnum = record['942']['l']
216
+ end
217
+
218
+ barcode_and_itemnum: |
219
+ puts "BARCODE AND ITEMNUM!!!\a" if $testing
220
+ #STDIN.gets
221
+ #Dir.chdir("..") if Dir.pwd.include?('zoomer/saved')
222
+ #puts Dir.pwd
223
+ if $testing == 't'
224
+ iterator = File.new("~/.zcc/test-zoomer-iterator.txt", "r").gets
225
+ else
226
+ iterator = File.new("#{File.expand_path("~")}/.zcc/zoomer-iterator.txt", "r").gets
227
+ end
228
+ #iterator = File.new("test-zoomer-iterator.txt").gets if $testing == 't'
229
+ puts iterator
230
+ iterator = iterator.chomp
231
+ barcode = "MRML-%05d" % iterator
232
+ new_iterator = iterator.to_i + 1
233
+ File.open("#{File.expand_path("~")}/.zcc/zoomer-iterator.txt", "w+") do |myfile|
234
+ myfile.write(new_iterator) unless $testing == 't'
235
+ end
236
+ record['952'].append(MARC::Subfield.new('p', barcode))
237
+ record['952'].append(MARC::Subfield.new('u', iterator))
238
+