4 attr_reader :term, :zservers, :type, :zsearch
6 def initialize(term, zservers)
7 self.term = term #=> string of original query post any filtering
8 #puts "term: " + self.term
10 @zservers << zservers #=>array of Zserver objects
11 self.zservers.compact!
12 self.zservers.flatten!
14 #puts self.zservers[0].to_s
19 @term = lccn_conversion(term)
21 #puts "converted lccn to #{@term}"
22 @zsearch = "@attr 1=9 #{@term}"
23 elsif term =~ /\d+[X||\d]/ and !(term.match( /[a-wyz]/i ))
24 #puts "Searching for ISBN: #{term}"
27 @zsearch = "@attr 1=7 #{@term}"
28 else ( term[/[a-z]/i] ) #-- This check for a string could be better!
29 #puts "searching for title:#{term}"
30 if term.match(/ :au /)
31 term = term.split(" :au ")
32 puts "Author and title then"
34 @zsearch = "@and @attr 1=4 \"#{@term}\" @attr 1=1 \"#{term[1]} \"" #was: "@attr 1=4 \"'#{@term}'\""
37 @zsearch = "@attr 1=4 \"#{@term}\"" #was: "@attr 1=4 \"'#{@term}'\""
48 #This is the main search logic of the whole shebang. Aliased as 'search'.
49 #The method on a query object and is passed the number of records from each host to present to the user. Default number of records is 10.
50 #Still need to work on a way to get options in so this might change.
51 #Currently only MARC21 is supported.
53 result_set = ResultSet.new(self)
54 #puts zservers.inspect
56 puts zservers.size.to_s + " z-servers in group " + zservers[0].group.to_s
58 self.zservers.each do |server|
60 #zservers are made up of...
62 search_threads << Thread.new(server, z) do |myserver, myz|
64 conn = ZOOM::Connection.new
65 conn.connect(myserver.host, server.port) #do |conn
66 conn.set_option('charset', 'UTF-8')
67 conn.preferred_record_syntax = 'MARC21'
68 conn.database_name = myserver.database
69 puts "#{myz} Searching: #{myserver.to_s} | #{self.zsearch}"
70 rset = conn.search(self.zsearch)
71 say(myz.to_s.headline + " Finished searching: #{myserver.to_s} | rset.size: " + "#{rset.size}".red.bold)
72 rset_recs = rset[0, show]
73 #puts "rset_recs in query.search: "
76 rset_recs.each do |rec|
80 marc_record = ZCC.convert_char(rec)
81 #puts "gets past character conversion"
82 #puts "-------------\n"
84 #puts "---------------\n"
85 zcc_record = Record.new(marc_record, myserver)
86 result_set.ingest(zcc_record)
87 puts "#{myz} record #{i} from #{myserver}..."
91 zerror_log("dead thread: " + myserver.to_s + " | " + e)
92 puts "\a#{myz}!!!!!!!! Thread died #{myserver} !!!!!"
94 #puts "end: #{Thread.list}"
95 #puts "Results processed from: #{myserver.to_s}"
99 search_threads.each{|thread| thread.join}
105 File.open("#{File.expand_path("~")}/.zcc/zerror_log", "a+") do |f|
113 def convert_char rsetrec
114 rec = MARC::Record.new_from_marc(rsetrec.raw)
115 #puts "initial rec" + rec.to_s
116 ldr9 = rec.leader[9, 1]
118 #puts "gets to creating dummy record."
120 #return_rec = MARC::Record.new_from_marc(rsetrec.raw('MARC-8', 'UTF-8')) #This does NOT work
121 return_rec = MARC::XMLReader.new(StringIO.new(rsetrec.xml('MARC-8', 'UTF-8'))).to_a
122 return_rec = return_rec[0]
123 return_rec.leader[9,1] = 'a'
124 #puts "return_rec" + return_rec.to_s
126 #puts "already unicode"
129 raise "Invalid value in leader 9 for MARC21"
134 def lccn_conversion lccn
135 split_lccn = lccn.split('-')
136 year_len = split_lccn[0].length
137 serial_len = split_lccn[1].length
138 start_length = year_len + serial_len
140 final_lccn = lccn.gsub('-', "#{'0' * (8 - start_length)}")
142 final_lccn = lccn.gsub('-', "#{'0' * (10 - start_length)}")
147 #++ compare() is a method to print out a comparison of two MARC records tag by tag (not by subfields).
148 # A match between lines is denoted with a 'm'. If there are differences between the records,
149 # the object that recieves the compare call is denoted with a '+' and the object passed in
150 # parens is denoted with '-'.
151 def compare_marc(orig, rec2)
152 puts "+ = #{orig.zserver.to_s}".bold
153 puts "- = #{rec2.zserver.to_s}".bold
157 for ft in ('000'..'999')
158 fields_original = orig.find_all {|f| f.tag == ft}
159 fields_record2 = rec2.find_all {|f| f.tag == ft}
163 fields_original.each {|f| fields_orig << f.to_s}
164 fields_record2.each {|f| fields_rec2 << f.to_s}
166 matches = fields_orig & fields_rec2
167 matches.each { |f| puts "m".bold + " #{f}" } if matches
169 fields_orig -= matches
170 fields_orig.each {|f| puts "+".bold + " #{f}"} if fields_orig
172 fields_rec2 -= matches
173 fields_rec2.each {|f| puts "-".bold + " #{f}"} if fields_rec2
177 def blank_field_prompt(field, subfield)
178 #puts "subfield: #{subfield}"
179 value = ask("\nYour MARC record does not contain #{field}#{subfield}.\nEnter the intended value for #{field}#{subfield} or hit ENTER to leave blank\n#{field}#{subfield} > ")