module ZCC class Record attr_accessor :selected, :marc, :authorities, :rank attr_reader :zserver def initialize(marc, zserver, selected = false) @marc = marc @zserver = zserver @selected = selected @rank = 0 end #def authorities<< (authority) #end def to_s full_string = "\n---------------RECORD----------------\nzserver: " + zserver.to_s + "\n" + marc.to_s + "---------------RECORD----------------\n" full_string end def title self.marc['245']['a'] end def author end #1XX? def extent self.marc['260']['a'] end def year_260 if self.marc['260'] && self.marc['260']['c'] date = self.marc['260']['c'].dup date.gsub!('[', '') date.gsub!(']', '') date.gsub!('c','') date else date = '0' date end end def years_fixed end def save(format) end #save MARC record to file in proper format (MARC, MARCXML) # linter depends on Perl's MARC::Lint and hence Perl's MARC::Record # Use cpan to install them. def linter rec = self.marc xml_rec = (rec.to_xml).to_s if LINTER == false puts 'You do not have the Perl MARC::Lint module installed or have disabled this feature.' return end contents = `perl "#{ROOT}"/linter.pl "#{xml_rec}"` if contents.empty? puts "there were no errors detected by the linter." else puts contents end if rec.leader[18,1] == 'a' puts "Leader indicates: AACR" elsif rec.leader[18,1] == 'i' puts "Leader indicates: ISBD" else puts "Leader indicates NOT AACR nor ISBD." end end #++ The local_script method is for automating changes to the record before saving it. See the main script to turn on this feature. See zoomer.yaml for instructions on creating a script for your purposes. def local_script(script) #print $clear_code record = self.marc #--creating my procs for creating fields and appending subfields # these two should probably be moved to methods create_datafield = proc{|record, field, i1, i2| puts "Creating datafield: #{field}"; record.append(MARC::DataField.new(field.to_s, i1.to_s, i2.to_s)); puts "****", record, "***" if $testing;} append_subfield = proc{|record, field, subfield, val| field = field.to_s subfield = subfield.to_s value = val.dup value = value.to_s if value.include?('proc ') #I've had problems with this bit but it seems to work now value = value.sub(/^proc /, '') real_value = eval("#{$procs[value]}") next if real_value == nil record[field].append(MARC::Subfield.new(subfield, real_value)) elsif record[field].append(MARC::Subfield.new(subfield, value)) end } script.each do |single_script| puts "--------------------------------------" if $testing puts single_script.join(', ') if $testing op, field, subfield, filler= single_script field = field.to_s subfield = subfield.to_s operation = op.dup if operation.include?('proc ') operation = operation.dup.sub(/^proc /, '') eval("#{$procs[operation]}") elsif operation == 'create-field' create_datafield.call(record, field, subfield, filler) elsif operation == 'append-subfield' append_subfield.call(record, field, subfield, filler) elsif operation == 'prompt' field_data = ask("What do you want to go into the #{field}#{subfield} #{filler}? ") next if field_data.empty? m_fields = record.find_all{|x| x.tag == field} if m_fields.empty? puts "m_fields is empty!!" create_datafield.call(record, field, ' ', ' ') m_fields = record.find_all{|x| x.tag == field} end m_fields.each {|field| field.append(MARC::Subfield.new(subfield, field_data))} elsif operation == 'remove' to_remove = record.find_all {|f| f.tag =~ Regexp.new( field.gsub('X','.'))} to_remove.each do |remove| record.fields.delete(remove) end elsif operation == 'sort-tags' ##This doesn't work right now puts "sorting by tag" puts record , "################" record = record.sort_by{| field | field.tag} puts record STDIN.gets else puts "there's nothing for that yet in local_script" end puts record if $testing end record end def edit puts "Subfield Editing" puts "To denote which subfield you want to edit put it in the form of 245a.\nIn the case of repeating fields or subfields you will be prompted\nto choose the one you wish to edit. " continue = true while continue fs = ask("What field and subfield would you like to edit (in form 245a) or quit?\n> "){|q| q.readline = true} if fs == 'q' || fs == 'quit' continue = false next end if !(fs =~/\d\d\d\w/ ) puts "That's not a valid value" next end self.change_subfield(fs) end end #edit_subfield is passed to a MARC::Record object and give a subfield def change_subfield(fs) field_subfield = subfield_parse(fs) field = field_subfield[0] subfield = field_subfield[1] fields = self.marc.find_all {|f| f.tag == field} subfields = [] for field in fields subfields << field.find_all {|s| s.code == subfield} end subfields.flatten! if subfields.length > 1 i = 0 for subfield in subfields puts "#{i}\t#{subfield}" i += 1 end num_to_change = ask("Which subfield do you want to change?"){|q| q.readline = true} subfield_to_change = subfields[num_to_change.to_i] elsif subfields.length == 1 subfield_to_change = subfields[0] elsif subfields.empty? puts "No such subfield!" return nil end puts self.marc; puts print "Currently:\t" puts subfield_to_change.value edit = ask("Your edit:\t"){|q| q.readline = true} subfield_to_change.value = edit puts; puts self.marc; puts end #subfield_parse method for getting from '245a' to ['245','a'] def subfield_parse(combined) field_subfield = [] field_subfield << combined[0, 3] field_subfield << combined[3,1] end def full_edit #puts self.class orig_marc = Tempfile.new("orig_marc-") orig_marc << self.marc.to_marc orig_marc.close line_format = `yaz-marcdump #{orig_marc.path}` out = Tempfile.new("full_edit-") out << line_format out.close system("#{TEXT_EDITOR} #{out.path}") final = Tempfile.new("final-") final.close `yaz-marcdump -i line -o marc #{out.path} > #{final.path}` record = MARC::Reader.new(final.path) for rec in record puts rec self.marc = rec puts rec.class end puts self.marc.inspect end # To use marc_to_csv it must be passed a csv template in the order of the fields. # See the zoomer.yaml file for instructions on creating a template. # See the main script for turning this feature on. def marc_to_csv(template) values = [] template.each do |template| field, subfield, leng = template field = field.to_s subfield = subfield.to_s if field == 'prompt' value = ask("prompt: please enter the #{field} #{subfield}") #--subfield here is a label for the prompt value = "\"#{value}\"," values << value elsif field.length == 3 and field.match('\d') fields = self.marc.find_all { | f | f.tag =~ Regexp.new( field.gsub('X','.'))} value = '' if fields.empty? #puts "oh, no!" value = blank_field_prompt(field, subfield) #eval(blank_field_prompt) else fields.each do |f| if f[subfield] value += f[subfield] + "|" else value = blank_field_prompt(field, subfield) end end end value.sub!(/\|$/, '') if leng if value.length == value.jlength value = value[0, leng] else puts "This value seems to have multibyte characters. If a byte gets dropped off the end that spells trouble." leng = ask("How many bytes would you like to take?") value = value[0, leng.to_s] end end #puts "value: #{value}" value = "\"#{value}\"," values << value else puts "this is not a valid value for marc_to_csv" end end #puts values values[-1].sub!(/\,$/, '') values = values.to_s values += "\n" end end end