zcc 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+