zcc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+