moving zebra to zebra-broken
[zcc.git] / lib / zcc / cli_display.rb
blob6a82a3f02cbdea675f40b131df1f3b934916a59f
1 module ZCC
2   HighLine.track_eof = false
3   def zcc_select_good_marc(results, take_how_many)
4     #puts self[0]
5     unless results.is_a? ZCC::ResultSet
6       raise ArgumentError, "This Array doesn't have a MARC::Record!" 
7     end
8     
9     
10     clear = %x{clear}
11     #print clear
12     
13     # Help statements:
14     #change default help?
16     help_help = "help_help"
17     
18     help_n = "#".bold + "Next Z39.50 server/group of zservers.\n>  n"
19     
20     help_num = "View that record by typing in the index number\n> 16." # this represents the '#'
21     
22     help_p = "Pick the record at that index position into the result set to work on and save."
24     help_s = <<-E_O_F
25       Sort.
26       Hit 's' to get a menu of sort possibilities. 
27       Possible sorts include: title, date, subfield, content standard.
28       sort by title:   s -> t
29       sort by date:    s -> d
30       sort by content: s -> c
31       Paths to sort by subfield:
32       sort -> s 260a
33       sort -> subfield -> 260a
34       sort -> subfield -> 260    which equals 260a
35       s    -> s 260a
36       s    -> s        -> 260a
37       Sorting reindexes the result set and removes nil values.
38       E_O_F
40     help_r = "Remove the record from the result set. This is a way to narrow the result set.\n> r4\nRemoves record 4 from the result set.\n
41     Alternately, just enter 'r' and you will have the chance to enter a range to remove."
43     help_c = "Compare two records. Compares the records line by line. Lines with an 'm' match each other. Lines with a plus sign are in the first record but not the second. Lines with a minus sign '-'"
45     help_l = "Lint the record."
47     help_d = "Done selecting records. If at least one record has been selected you continue on. If no records have been selected you are presented with a search prompt again."
49     help_f = "Forwards through the result set"
50     help_b = "backwards through the result set"
51     help_all = "Select all the records in the result set to work on and save."
52     help_none = "Select none of the records from the final set."
53     help_u = "Unselect a record from the result set."
54     not_implemented = "This feature is not yet implemented."
56     #take_how_many = 'multi' #'one' # 'multi'
58     recs_to_return = []
60     loop do
61       rec_copy = results.records
62       choose do |menu|
63         print $clear_code
64         
65         menu.layout = :one_line
66         menu.readline = true
67         menu.shell  = true
68         menu.prompt = "Enter "
69         menu.select_by = :name
70         menu.update_responses
71         menu.help("help", help_help)
72         
73         rec_copy.each_index do |index|
74           ZCC.display_menu(rec_copy, index)
75           #puts "\n\n"
76         end
77         
78         recs_length = rec_copy.length
79         index_range = (0..recs_length - 1)
81         menu.hidden("help", help_help) do |cmd, d| 
82           if d == ''
83             say_help(help_help)
84           else
85             say_help("not completed: #{d}")
86           end
87         end
88         
89         # # => view
90               menu.choice('#'.intern, help_num) do |command, details|
91           say_help(help_num)
92         end
93         for x in index_range
94                 menu.hidden("#{x}".intern, help_num) do |cmd, details|
95             print "\a"
96                   say("#{ZCC.zcc_marc_str_bold(rec_copy[cmd.to_s.to_i].to_s, 'record')}")
97             ask("Hit ENTER to continue...".headlinez)
98             
99           end
100         end
102         # next
103               if take_how_many == 'multi'
104           menu.choice(:n, help_n) do |command, details|
105             return 'next'
106           end
107         end
109         # pick
110               menu.choice("p#".intern, help_p) { |cmd, d|  say_help(help_p) }
111               menu.hidden(:pick, help_p) { |cmd, d|  say_help(help_p) }
112         for x in index_range
113                 menu.hidden("p#{x}") do |cmd, d|
114             num_picked = cmd[1,99]
115                   rec_copy[num_picked.to_i].selected = true
116             if take_how_many == 'one'
117               return results
118             end
119           end
120         end
121         
122         
123         
124         # remove
125         #menu.hidden("r#".intern, help_r) { |cmd, d|  say_help(help_r) }
126         menu.hidden(:remove, help_r) { |cmd, d|  say_help(help_r) }
127         menu.choice(:r, help_r) do |cmd, d|  
128           say(help_r)
129           range = ask("Enter range to remove like '2-5' remove records 2, 3, 4 and 5.".boldz)
130           range_a = range.split('-').collect{|i| i.to_i}
131           if range_a[1]
132             for r in range_a[0]..range_a[1]
133               rec_copy[r] = nil
134             end
135           else
136             rec_copy[range_a[0]] = nil
137           end          
138         end
139               menu.hidden(:remove, help_r) { |cmd, d|  say_help(help_r) }
140         
141         for x in index_range
142                 menu.hidden("r#{x}", help_r) do |cmd, d|
143             num_picked = cmd[1,99]
144             rec_copy[num_picked.to_i] = nil
145             #return
146           end
147         end
148         
149         
150         
151         #unselect
152         menu.choice("u#".intern, help_u) { |cmd, d|  say_help(help_u) }
153               menu.hidden(:unselect, help_u) { |cmd, d|  say_help(help_u) }
154         for x in index_range
155                 menu.hidden("u#{x}", help_u) do |cmd, d|
156             num_picked = cmd[1,99]
157                   rec_copy[num_picked.to_i].selected = false
158             #return
159           end
160         end
162         # sort
163         menu.hidden(:sort, help_s){|cmd, d| say(help_s)}
164               menu.choice(:s, help_s) do |command, details|
165           say(help_s)
166           choose do |sort_menu|
167             
168             sort_menu.layout = :one_line
169             sort_menu.readline = true
170             sort_menu.shell  = true
171             sort_menu.prompt = "Enter "
172             sort_menu.select_by = :name
173             
174             sort_menu.choice(:title, help_s){|cmd, d| results.sort_by_title!}
175             sort_menu.choice(:date, help_s){|cmd, d| results.sort_by_date!}
176             sort_menu.choice(:content, help_s){|cmd, d| results.sort_by_standard!}
177             sort_menu.choice(:subfield, help_s){|cmd, d|
178               puts "|" + d + "|"
179               if d == ''
180                 field_subfield = ask("Enter field and subfield like so: 245c > ")
181                 results.sort_by_subfield!(field_subfield)                
182               else
183                 results.sort_by_subfield!(d)
184               end
185             }
186           end
187           #sort_menu(rec_copy)
188         end
189               
190         
191         
192         
193         # compare
194               menu.choice('c#-#', help_c) do |command, details|
195           say_help(help_c)
196         end
197         comparison = []
198         for x in (0..recs_length-1)
199           for y in (0..recs_length-1)
200             unless x == y
201               comparison << 'c' + x.to_s + '-' + y.to_s
202             end
203           end
204         end
205         comparison.each do |compare|
206           menu.hidden(compare, help_c) do |cmd, details|
207             say("comparison:".headline)
208             cmd = cmd[1,99]
209             compare_nums = cmd.split('-')
210             compare_marc(rec_copy[compare_nums[0].to_i], rec_copy[compare_nums[1].to_i])
211             ask("Hit ENTER to continue...".headlinez)
212             
213             next
214           end
215         end
217         # lint
218               menu.choice('l#', help_l) do |cmd, d|
219           say_help(help_l)
220           #ask("Which record do you want to lint? ")
221         end
222               menu.hidden(:lint) {|cmd, d| say(help_l)}
223         for x in (0..recs_length - 1)
224                 menu.hidden("l#{x}") do |cmd, d| 
225             rec_copy[cmd[1,99].to_i].linter
226             ask("Hit ENTER to continue...".headlinez)
227             
228           end
229         end
231         # done => selected as many 
232               unless take_how_many == 'one'
233           menu.choice(:d, help_d) do |cmd, d|
234             #say("You will not search any more z-servers!".headline)
235             #recs_to_return << "done"
236             return 'done'
237           end
238         end
240         # none -- only for final record taking
241               if take_how_many == 'one'    
242                 menu.choice(:none, help_none) do |cmd, d| 
243             say("Since you cannot decide on a good record, please refer the book to a cataloger.".headline)
244             return "none"       
245           end
246         end
247         
248         # forwards
249         menu.hidden(:f, help_f) {|cmd, d| say(not_implemented)}
250   
251         # backwards
252         menu.hidden(:b, help_b) {|cmd, d| say(not_implemented)}
253         
254         # quit
255               menu.choice(:quit, "Exit program.") { |cmd, d| exit}
256         
257       end
258     end
259   end
261   def display_menu(rec_copy, index)
262     field_width = $term_width - 8
263     if rec_copy[index].nil?
264       #say("<%= color(\"#{index}\") %> ")
265       #say("\tYou deleted this record from the set!")
266     else
267       if rec_copy[index].selected
268         say(index.to_s.headlinez)
269       else
270         say(index.to_s.red.boldz)
271       end
272     
273       say("\t\t" + rec_copy[index].zserver.to_s)
274       ['245', '260', '300'].each do |field|
275         string = rec_copy[index].marc[field].to_s
276         string.rstrip!
277         string.lstrip!
278         begin
279           if string.length < field_width
280             say("\t" + ZCC.zcc_marc_str_bold(string, field))
281           else
282             better_string = ZCC.wrap_field(string, field_width)
283             #puts better_string
284             say("\t" + ZCC.zcc_marc_str_bold(better_string, field))
285           end
286         rescue
287           #The dp here stands for display problem.
288           puts "  dp\t#{rec_copy[index].marc[field].to_s}"
289           next
290         end
291       end
292       puts "\n"
293     end        
294   end
295   
296   #currently this goes word by word. how difficult to go field by subfield?
297   def wrap_field(s, width)
298     lines = []
299     line = ""
300     smaller_width = width - 7
301     s.split(/\s+/).each do |word|
302             if (line.size + word.size) >= (width - 3)
303         lines << line 
304         line = word
305         width = smaller_width
306             elsif line.empty?
307         line = word
308             else
309         line << " " << word
310       end
311           end
312           lines << line if line
313     return lines.join("\n\t\t")
314   end
315   
316   
317   def zcc_marc_str_bold(string, field)
318     #puts field
319     #string.gsub!("'", "\'")
320     #unless field == 'record'
321     #  string.gsub!('"', '\"')
322     #end
323     #string.gsub!("(", "\(")
324     #string.gsub!(")", "\)")
325     if field == '245'
326       string.gsub!(/(\$a\s)(.*?)(\$.|$)/, "\\1" + "\\2".blue + "\\3")
327     elsif field == '260'
328       #puts 'gets here'
329       string.gsub!(/(\$c\s)([\[0-9A-Za-z\]]*)(.|$)/,  "\\1" + "\\2".blue + "\\3")
330       #string.gsub!(/(\$c)(.*)(\$\s)/,  "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
331       #string.gsub!(/(\$c)(.*)(\.|$)/,  "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
332     elsif field == '300'
333       string.gsub!(/(\$a)(.*?)(\$|$)/, "\\1" + "\\2".blue + "\\3")
334     elsif field == 'record'
335       string.sub!(/(LEADER.{19})(.{1})/, "\\1" + "\\2".bold.blue) #colorizes the value of the standard (AACR2, ISBD, or none)
336       string.sub!(/(LEADER.{10})(.{1})/, "\\1" + "\\2".bold.blue) #colorizes the
337     end
338     string.gsub!( /(\$.)/, "\\1".bold )
339     string.gsub!( /^(\d\d\d)\s/, "\\1 ".bold)
340     string
341   end
342   
343   def not_valid_value
344     print $clear_code
345     say("\aThat's not a valid value. Try again.".headline)
346     sleep 1
347     print "\a"
348   end
351   def say_help h
352     say(h)
353     ask("Hit enter to continue.".boldz)
354    
355   end
356   
357   def sort_menu records
358     loop do
359       choose do |menu|
360         menu.layout = :menu_only
361         menu.readline = true
362         menu.shell  = true
363         #menu.prompt = "> "
364         menu.select_by = :index_or_name
365         menu.choice(:author){|cmd, d| say("not implemented yet") }
366         menu.choice(:date){|cmd, d| say("not implemented yet")}
367         menu.choice(:subfield, "in the form of 245a"){|cmd, d| say("not implemented yet")}
368         menu.choice(:relevancy){|cmd, d| say("not implemented yet")}
369       end
370     end
371   end
373   
374   
375   
379 # Override HighLine's own defaults so that our large menu options do not display.
380 # This needs work to have better help for these error messages.
382 class Highline
383   class Menu
384     def update_responses(  )
385       append_default unless default.nil?
386     @responses = { :ambiguous_completion =>                       "Ambiguous choice.  ",                     :ask_on_error         =>                       "?  ",                     :invalid_type         =>                       "You must enter a valid option.",                     :no_completion        =>                       "You must choose a valid option.",                     :not_in_range         =>                       "Your answer isn't within the expected range " ,                     :not_valid            =>                       "Your answer isn't valid." }.merge(@responses)
387     end
388     
389     
390   end