zcc 0.0.3 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/History.txt +15 -0
  2. data/Manifest.txt +12 -19
  3. data/Rakefile +2 -1
  4. data/bin/zcc +228 -202
  5. data/examples/zcc.yaml +21 -12
  6. data/examples/zebra/{register/empty → key/remove_me} +1 -1
  7. data/examples/zebra/{key/empty → lock/remove_me} +1 -1
  8. data/examples/zebra/records/0.mrc +1 -0
  9. data/examples/zebra/{lock/empty → register/remove_me} +1 -1
  10. data/examples/zebra/tab/marc21.abs +67 -0
  11. data/examples/zebra/tab/record.abs +1 -0
  12. data/examples/zebra/zebra.cfg +2 -2
  13. data/examples/zservers.yaml +869 -0
  14. data/lib/zcc.rb +8 -0
  15. data/lib/zcc/ansicolorz.rb +26 -0
  16. data/lib/zcc/cli_display.rb +461 -0
  17. data/lib/zcc/query.rb +183 -0
  18. data/lib/zcc/record.rb +265 -0
  19. data/lib/zcc/resultset.rb +169 -0
  20. data/lib/zcc/version.rb +2 -2
  21. data/lib/zcc/zoomer.rb +16 -2
  22. data/lib/zcc/zserver.rb +38 -0
  23. data/website/index.html +1 -1
  24. data/website/koha.html +18 -10
  25. data/website/koha.txt +13 -8
  26. data/website/zcc.html +35 -33
  27. data/website/zcc.txt +30 -32
  28. data/website/zebra.html +57 -15
  29. data/website/zebra.txt +56 -15
  30. metadata +23 -21
  31. data/examples/zebra/README +0 -2
  32. data/examples/zebra/records/examples/0.xml +0 -1
  33. data/examples/zebra/records/examples/1.xml +0 -1
  34. data/examples/zebra/records/examples/2.xml +0 -1
  35. data/examples/zebra/records/examples/3.xml +0 -1
  36. data/examples/zebra/records/examples/4.xml +0 -1
  37. data/examples/zebra/records/examples/5.xml +0 -1
  38. data/examples/zebra/records/examples/6.xml +0 -1
  39. data/examples/zebra/records/examples/7.xml +0 -1
  40. data/examples/zebra/records/examples/8.xml +0 -1
  41. data/examples/zebra/records/examples/9.xml +0 -1
  42. data/examples/zebra/shadow/empty +0 -1
  43. data/examples/zebra/tab/kohalis +0 -1
  44. data/examples/zebra/tmp/empty +0 -1
  45. data/lib/zcc/marcadditions.rb +0 -221
  46. data/lib/zcc/pickers.rb +0 -176
data/lib/zcc.rb CHANGED
@@ -2,3 +2,11 @@ module Zcc
2
2
  end
3
3
 
4
4
  require 'zcc/version'
5
+ #require 'zcc/marcadditions'
6
+ require 'zcc/cli_display'
7
+ #require 'zcc/subfieldeditor'
8
+ require 'zcc/query'
9
+ require 'zcc/resultset'
10
+ require 'zcc/zserver'
11
+ require 'zcc/record'
12
+ require 'zcc/ansicolorz'
@@ -0,0 +1,26 @@
1
+ # HighLine has a lot of Erb junk in its colorizing that makes the text difficult to read.
2
+ # Term::ANSIColor is much simpler. Other colorising
3
+ class String
4
+ include Term::ANSIColor
5
+ end
6
+
7
+ module Term
8
+ module ANSIColor
9
+ attributez = [:clear, :reset, :bold, :dark, :italic, :underline, :underscore, :blink, :rapid_blink, :negative, :concealed, :strikethrough, :black, :red, :green, :yellow, :blue, :magenta, :cyan, :white, :on_black, :on_red, :on_green, :on_yellow, :on_blue, :on_magenta, :on_cyan, :on_white ]
10
+ attributez.each do |c|
11
+ eval %Q{
12
+ def #{c}z
13
+ #{c} + " "
14
+ end
15
+ }
16
+ end
17
+ def headline
18
+ white.bold.on_black
19
+ end
20
+ def headlinez
21
+ headline + " "
22
+ end
23
+
24
+
25
+ end
26
+ end
@@ -0,0 +1,461 @@
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
+ clear = %x{clear}
10
+
11
+ # Help statements:
12
+ help_help = <<-EOF
13
+ HELP
14
+ For help on a particular topic:
15
+ help [topic]
16
+ topics include:
17
+ # view a record
18
+ p pick a record
19
+ u unselect a record
20
+ r remove a record
21
+
22
+ s sort
23
+
24
+ c compare two records
25
+ l lint a record
26
+
27
+ f forwards
28
+ b backwards
29
+ n next
30
+ d done searching
31
+ q quit
32
+ EOF
33
+
34
+ help_num = "View a record by typing in the index number\n> 16."
35
+ help_p = "Pick the record at that index position into the result set to work on and save.\n> p3"
36
+ help_u = "Unselect a record.\nIf you have chosen to pick a record and no longer want it,\nyou can unselect it.\n> u2"
37
+ 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 and unclutter the screen some.\n
38
+ Alternately, just enter 'r' and you will have the chance to enter a range to remove."
39
+
40
+ help_s = <<-E_O_F
41
+ Sort.
42
+ Hit 's' to get a menu of sort possibilities.
43
+ Possible sorts include: title, date, subfield, content standard.
44
+ sort by title: s -> t
45
+ sort by date: s -> d
46
+ sort by content: s -> c
47
+ Paths to sort by subfield:
48
+ sort -> s 260a
49
+ sort -> subfield -> 260a
50
+ sort -> subfield -> 260 which equals 260a
51
+ s -> s 260a
52
+ s -> s -> 260a
53
+ Sorting reindexes the result set and removes nil values.
54
+ E_O_F
55
+
56
+ help_c = "Compare two records.\nCompares the records line by line.\nLines with an 'm' match each other.\nLines with a plus sign are in the first record but not the second. Lines with a minus sign '-' are from the second record but not the first.\nEven the difference of a period matters here.\n> c4-2"
57
+ help_l = "Lint the record.\nCheck for errors such as wrong indicator values or poor punctuation.\n> l5"
58
+
59
+ help_f = "Forwards through the result set.\nThe number of results shown per page is configured in zcc.yaml."
60
+ help_b = "backwards through the result set.\nThe number of results shown per page is configured in zcc.yaml."
61
+ help_n = "Next Z39.50 server/group of zservers.\nIf there are no more zservers to search, you are presented with you combined picks or a new search prompt.\n> n"
62
+ help_d = "Done selecting records.\nIf at least one record has been selected you continue on to final selection.\nIf no records have been selected you are presented with a search prompt again."
63
+ help_d = "Quit the program."
64
+
65
+ #the following are not implemented
66
+ help_all = "Select all the records in the result set to work on and save."
67
+ help_none = "Select none of the records from the final set."
68
+
69
+ not_implemented = "This feature is not yet implemented."
70
+
71
+ #take_how_many = 'multi' #'one' # 'multi'
72
+
73
+
74
+
75
+ loop do
76
+ rec_copy = results.records
77
+ choose do |menu|
78
+ print $clear_code
79
+
80
+ menu.layout = :one_line
81
+ menu.readline = true
82
+ menu.shell = true
83
+ menu.prompt = "Enter "
84
+ menu.select_by = :name
85
+ menu.update_responses
86
+ menu.help("help", help_help)
87
+
88
+ rec_copy.each_index do |index|
89
+ showings = results.index_start + results.index_pos
90
+ #puts showings
91
+ if index >= results.index_start && index <= showings
92
+ ZCC.display_menu(rec_copy, index)
93
+ end
94
+ #puts "\n\n"
95
+ end
96
+ puts "Highest position: " + (results.size - 1).to_s
97
+
98
+
99
+ recs_length = rec_copy.length
100
+ index_range = (0..recs_length - 1)
101
+
102
+ menu.hidden("help", help_help) do |cmd, d|
103
+ if d == ''
104
+ say_help(help_help)
105
+ elsif d == '#'
106
+ say_help(help_num)
107
+ elsif d == 'p'
108
+ say_help(help_p)
109
+ elsif d == 's'
110
+ say_help(help_s)
111
+ elsif d == 'r'
112
+ say_help(help_r)
113
+ elsif d == 'c'
114
+ say_help(help_c)
115
+ elsif d == 'l'
116
+ say_help(help_l)
117
+ elsif d == 'f'
118
+ say_help(help_f)
119
+ elsif d == 'b'
120
+ say_help(help_b)
121
+ elsif d == 'n'
122
+ say_help(help_n)
123
+ elsif d == 'u'
124
+ say_help(help_u)
125
+ elsif d == 'd'
126
+ say_help(help_d)
127
+ end
128
+ end
129
+
130
+ # # => view
131
+ menu.choice('#'.intern, help_num) do |command, details|
132
+ say_help(help_num)
133
+ end
134
+ for x in index_range
135
+ menu.hidden("#{x}".intern, help_num) do |cmd, details|
136
+ if rec_copy[cmd.to_s.to_i] == nil
137
+ say("You removed that record!")
138
+ else
139
+ print "\a"
140
+ say("#{ZCC.zcc_marc_str_bold(rec_copy[cmd.to_s.to_i].to_s, 'record')}")
141
+ end
142
+ ask("Hit ENTER to continue...".headlinez)
143
+ end
144
+ end
145
+
146
+ # pick
147
+ menu.choice("p#".intern, help_p) { |cmd, d| say_help(help_p) }
148
+ menu.hidden(:p, help_p){|cmd, d| say_help(help_p)}
149
+ menu.hidden(:pick, help_p) { |cmd, d| say_help(help_p) }
150
+ for x in index_range
151
+ menu.hidden("p#{x}") do |cmd, d|
152
+ num_picked = cmd[1,99]
153
+ rec_copy[num_picked.to_i].selected = true if rec_copy[num_picked.to_i] != nil
154
+ if take_how_many == 'one'
155
+ return results
156
+ end
157
+ end
158
+ end
159
+
160
+ #unselect
161
+ menu.choice("u#".intern, help_u) { |cmd, d| say_help(help_u) }
162
+ menu.hidden(:u, help_u) { |cmd, d| say_help(help_u) }
163
+ menu.hidden(:unselect, help_u) { |cmd, d| say_help(help_u) }
164
+ for x in index_range
165
+ menu.hidden("u#{x}", help_u) do |cmd, d|
166
+ num_picked = cmd[1,99]
167
+ if rec_copy[num_picked.to_i] != nil
168
+ rec_copy[num_picked.to_i].selected = false
169
+ #return
170
+ end
171
+ end
172
+ end
173
+
174
+ # remove
175
+ #menu.hidden("r#".intern, help_r) { |cmd, d| say_help(help_r) }
176
+ menu.hidden(:remove, help_r) { |cmd, d| say_help(help_r) }
177
+ menu.choice(:r, help_r) do |cmd, d|
178
+ say(help_r)
179
+ range = ask("Enter range to remove like '2-5' remove records 2, 3, 4 and 5.".boldz)
180
+ range_a = range.split('-').collect{|i| i.to_i}
181
+ if range_a[1]
182
+ for r in range_a[0]..range_a[1]
183
+ rec_copy[r] = nil if rec_copy[r]
184
+ end
185
+ else
186
+ rec_copy[range_a[0]] = nil
187
+ end
188
+ end
189
+ menu.hidden(:remove, help_r) { |cmd, d| say_help(help_r) }
190
+
191
+ for x in index_range
192
+ menu.hidden("r#{x}", help_r) do |cmd, d|
193
+ num_picked = cmd[1,99]
194
+ rec_copy[num_picked.to_i] = nil
195
+ #return
196
+ end
197
+ end
198
+
199
+ # sort
200
+ menu.hidden(:sort, help_s){|cmd, d| say(help_s)}
201
+ menu.choice(:s, help_s) do |command, details|
202
+ say(help_s)
203
+ choose do |sort_menu|
204
+
205
+ sort_menu.layout = :one_line
206
+ sort_menu.readline = true
207
+ sort_menu.shell = true
208
+ sort_menu.prompt = "Enter "
209
+ sort_menu.select_by = :name
210
+
211
+ sort_menu.choice(:title, help_s){|cmd, d| results.sort_by_title!}
212
+ sort_menu.choice(:date, help_s){|cmd, d| results.sort_by_date!}
213
+ sort_menu.choice(:content, help_s){|cmd, d| results.sort_by_standard!}
214
+ sort_menu.choice(:subfield, help_s){|cmd, d|
215
+ puts "|" + d + "|"
216
+ if d == ''
217
+ field_subfield = ask("Enter field and subfield like so: 245c > ")
218
+ results.sort_by_subfield!(field_subfield)
219
+ else
220
+ results.sort_by_subfield!(d)
221
+ end
222
+ }
223
+ end
224
+ #sort_menu(rec_copy)
225
+ end
226
+
227
+ # compare
228
+ menu.hidden(:c, help_c){|c,d| say_help(help_c)}
229
+ menu.choice('c#-#', help_c) do |command, details|
230
+ say_help(help_c)
231
+ end
232
+ comparison = []
233
+ for x in (0..recs_length-1)
234
+ for y in (0..recs_length-1)
235
+ unless x == y
236
+ comparison << 'c' + x.to_s + '-' + y.to_s
237
+ end
238
+ end
239
+ end
240
+ comparison.each do |compare|
241
+ menu.hidden(compare, help_c) do |cmd, details|
242
+ cmd = cmd[1,99]
243
+ compare_nums = cmd.split('-')
244
+ if rec_copy[compare_nums[0].to_i] == nil || rec_copy[compare_nums[1].to_i] == nil
245
+ say_help("One of the records has been removed!")
246
+ else
247
+ say("comparison:".headline)
248
+ compare_marc(rec_copy[compare_nums[0].to_i], rec_copy[compare_nums[1].to_i])
249
+ ask("Hit ENTER to continue...".headlinez)
250
+ next
251
+ end
252
+ end
253
+ end
254
+
255
+ # lint
256
+ menu.hidden(:l, help_l){|c,d| say_help(help_l)}
257
+ menu.choice('l#', help_l) do |cmd, d|
258
+ say_help(help_l)
259
+ #ask("Which record do you want to lint? ")
260
+ end
261
+ menu.hidden(:lint) {|cmd, d| say(help_l)}
262
+ for x in (0..recs_length - 1)
263
+ menu.hidden("l#{x}") do |cmd, d|
264
+ if rec_copy[cmd[1,99].to_i] != nil
265
+ rec_copy[cmd[1,99].to_i].linter
266
+ ask("Hit ENTER to continue...".headlinez)
267
+ end
268
+ end
269
+ end
270
+
271
+ # forwards
272
+ menu.choice(:f, help_f) do |cmd, d|
273
+ unless results.index_start + results.index_pos + 1 >= results.size
274
+ results.index_start += results.index_pos + 1
275
+ else
276
+ puts "\a"
277
+ end
278
+ end
279
+
280
+ # backwards
281
+ menu.choice(:b, help_b) do |cmd, d|
282
+ unless results.index_start == 0
283
+ results.index_start -= (results.index_pos + 1)
284
+ else
285
+ puts "\a"
286
+ end
287
+ end
288
+
289
+ # next
290
+ if take_how_many == 'multi'
291
+ menu.choice(:n, help_n) do |command, details|
292
+ return 'next'
293
+ end
294
+ end
295
+
296
+ # done => selected as many
297
+ unless take_how_many == 'one'
298
+ menu.choice(:d, help_d) do |cmd, d|
299
+ return 'done'
300
+ end
301
+ end
302
+
303
+ # quit
304
+ menu.choice(:quit, "Exit program.") { |cmd, d| exit}
305
+
306
+ # none -- only for final record taking. not currently used
307
+ if take_how_many == 'one'
308
+ menu.choice(:none, help_none) do |cmd, d|
309
+ say("Since you cannot decide on a good record, please refer the book to a cataloger.".headline)
310
+ return "none"
311
+ end
312
+ end
313
+
314
+ end
315
+ end
316
+ end
317
+
318
+ def display_menu(rec_copy, index)
319
+ field_width = $term_width - 8
320
+ if rec_copy[index].nil?
321
+ say(index.to_s + " Removed from set.")
322
+ else
323
+ if rec_copy[index].selected
324
+ say(index.to_s.headlinez)
325
+ else
326
+ say(index.to_s.red.boldz)
327
+ end
328
+
329
+ # print rank
330
+ if rec_copy[index].rank >= 10
331
+ print " **".boldz
332
+ elsif rec_copy[index].rank >= 5
333
+ print " *".boldz
334
+ else
335
+ #nothing
336
+ end
337
+ say("\t\t" + rec_copy[index].zserver.to_s)
338
+ #['245', '260', '300'].each do |field|
339
+ FIELDS_TO_SHOW.each do |field|
340
+ field = field.to_s
341
+ string = rec_copy[index].marc[field].to_s
342
+ string.rstrip!
343
+ string.lstrip!
344
+ begin
345
+ if string.length < field_width
346
+ say("\t" + ZCC.zcc_marc_str_bold(string, field))
347
+ else
348
+ better_string = ZCC.wrap_field(string, field_width)
349
+ say("\t" + ZCC.zcc_marc_str_bold(better_string, field))
350
+ end
351
+ rescue
352
+ #The dp here stands for display problem.
353
+ puts " dp\t#{rec_copy[index].marc[field].to_s}"
354
+ next
355
+ end
356
+ end
357
+ puts "\n"
358
+ end
359
+ end
360
+
361
+ #currently this goes word by word. how difficult to go field by subfield?
362
+ def wrap_field(s, width)
363
+ lines = []
364
+ line = ""
365
+ smaller_width = width - 7
366
+ s.split(/\s+/).each do |word|
367
+ if (line.size + word.size) >= (width - 3)
368
+ lines << line
369
+ line = word
370
+ width = smaller_width
371
+ elsif line.empty?
372
+ line = word
373
+ else
374
+ line << " " << word
375
+ end
376
+ end
377
+ lines << line if line
378
+ return lines.join("\n\t\t")
379
+ end
380
+
381
+
382
+ def zcc_marc_str_bold(string, field)
383
+ #puts field
384
+ #string.gsub!("'", "\'")
385
+ #unless field == 'record'
386
+ # string.gsub!('"', '\"')
387
+ #end
388
+ #string.gsub!("(", "\(")
389
+ #string.gsub!(")", "\)")
390
+ if field == '245'
391
+ string.gsub!(/(\$a\s)(.*?)(\$.|$)/, "\\1" + "\\2".blue + "\\3")
392
+ elsif field == '260'
393
+ #puts 'gets here'
394
+ string.gsub!(/(\$c\s)([\[0-9A-Za-z\]]*)(.|$)/, "\\1" + "\\2".blue + "\\3")
395
+ #string.gsub!(/(\$c)(.*)(\$\s)/, "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
396
+ #string.gsub!(/(\$c)(.*)(\.|$)/, "\\1<%= color(\"\\2\", :field_hilite) %>\\3")
397
+ elsif field == '300'
398
+ string.gsub!(/(\$a)(.*?)(\$|$)/, "\\1" + "\\2".blue + "\\3")
399
+ elsif field == 'record'
400
+ string.sub!(/(LEADER.{19})(.{1})/, "\\1" + "\\2".bold.blue) #colorizes the value of the standard (AACR2, ISBD, or none)
401
+ string.sub!(/(LEADER.{10})(.{1})/, "\\1" + "\\2".bold.blue) #colorizes the
402
+ end
403
+ string.gsub!( /(\$.)/, "\\1".bold )
404
+ string.gsub!( /^(\d\d\d)\s/, "\\1 ".bold)
405
+ string
406
+ end
407
+
408
+ def not_valid_value
409
+ print $clear_code
410
+ say("\aThat's not a valid value. Try again.".headline)
411
+ sleep 1
412
+ print "\a"
413
+ end
414
+
415
+
416
+ def say_help h
417
+ say(h)
418
+ ask("Hit enter to continue.".boldz)
419
+
420
+ end
421
+
422
+ def sort_menu records
423
+ loop do
424
+ choose do |menu|
425
+ menu.layout = :menu_only
426
+ menu.readline = true
427
+ menu.shell = true
428
+ #menu.prompt = "> "
429
+ menu.select_by = :index_or_name
430
+ menu.choice(:author){|cmd, d| say("not implemented yet") }
431
+ menu.choice(:date){|cmd, d| say("not implemented yet")}
432
+ menu.choice(:subfield, "in the form of 245a"){|cmd, d| say("not implemented yet")}
433
+ menu.choice(:relevancy){|cmd, d| say("not implemented yet")}
434
+ end
435
+ end
436
+ end
437
+
438
+
439
+
440
+
441
+ end
442
+
443
+
444
+ # Override HighLine's own defaults so that our large menu options do not display.
445
+ # This needs work to have better help for these error messages.
446
+
447
+ class Highline
448
+ class Menu
449
+ def update_responses( )
450
+ append_default unless default.nil?
451
+ @responses = {
452
+ :ambiguous_completion => "Ambiguous choice. ",
453
+ :ask_on_error => "? ",
454
+ :invalid_type => "You must enter a valid option.", :no_completion => "You must pick a valid option.", :not_in_range => "You must input a valid option." ,
455
+ :not_valid => "You must have a valid option."
456
+ }.merge(@responses)
457
+ end
458
+ end
459
+ end
460
+
461
+