start and end scripts run automatically
[zcc.git] / lib / zcc / record.rb
blob739f94ccab7d2bf8023098611151e8e68f2aafec
1 module ZCC\r
2   \r
3   class Record     \r
4   attr_accessor :selected, :marc, :authorities, :rank\r
5   attr_reader :zserver\r
6     def initialize(marc, zserver, selected = false)\r
7       @marc = marc\r
8       @zserver = zserver\r
9       @selected = selected\r
10       @rank = 0\r
11     end\r
12     \r
13     #def authorities<< (authority)\r
14     #end\r
15     \r
16     def to_s\r
17       full_string = "\n---------------RECORD----------------\nzserver: " + zserver.to_s + "\n" +  marc.to_s +  "---------------RECORD----------------\n"\r
18       full_string\r
19     end\r
20     \r
21     def title \r
22       self.marc['245']['a']\r
23     end \r
24     \r
25     def author \r
26     end #1XX?\r
27     \r
28     def extent \r
29       self.marc['260']['a']\r
30     end \r
31     \r
32     def year_260\r
33       if self.marc['260'] && self.marc['260']['c']\r
34         date = self.marc['260']['c'].dup\r
35         date.gsub!('[', '')\r
36         date.gsub!(']', '')\r
37         date.gsub!('c','')\r
38         date\r
39       else\r
40         date = '0'\r
41         date\r
42       end\r
43     end\r
44     \r
45     def years_fixed \r
46     end\r
47     \r
48     def save(format)\r
49     end #save MARC record to file in proper format (MARC, MARCXML)\r
50     \r
51     \r
52     \r
53     # linter depends on Perl's MARC::Lint and hence Perl's MARC::Record\r
54     # Use cpan to install them.\r
55     def linter\r
56       rec = self.marc\r
57       xml_rec = (rec.to_xml).to_s\r
58       if LINTER == false\r
59         puts 'You do not have the Perl MARC::Lint module installed or have disabled this feature.'\r
60         return\r
61       end\r
62       contents = `perl "#{ROOT}"/linter.pl "#{xml_rec}"`\r
63       if contents.empty?\r
64         puts "there were no errors detected by the linter."\r
65       else\r
66         puts contents   \r
67       end\r
68       if rec.leader[18,1] == 'a'\r
69         puts "Leader indicates: AACR"\r
70       elsif rec.leader[18,1] == 'i'\r
71         puts "Leader indicates: ISBD"\r
72       else\r
73         puts "Leader indicates NOT AACR nor ISBD."\r
74       end\r
75     end\r
76  \r
77      #++ 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.\r
78   def local_script(script)\r
79     #print $clear_code\r
80     record = self.marc\r
82     #--creating my procs for creating fields and appending subfields\r
83     # these two should probably be moved to methods\r
84     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;}\r
86     append_subfield = proc{|record, field, subfield, val| \r
87       field = field.to_s\r
88       subfield = subfield.to_s\r
89       value = val.dup\r
90       value = value.to_s\r
91       if value.include?('proc ')\r
92         #I've had problems with this bit but it seems to work now\r
93         value = value.sub(/^proc /, '')\r
94         real_value = eval("#{$procs[value]}") \r
95         next if real_value == nil                \r
96         record[field].append(MARC::Subfield.new(subfield, real_value))\r
97       elsif\r
98         record[field].append(MARC::Subfield.new(subfield, value))\r
99       end\r
100     }\r
102     script.each do |single_script|\r
103       puts "--------------------------------------" if $testing\r
104       puts single_script.join(', ') if $testing\r
105       op, field, subfield, filler= single_script\r
106       field = field.to_s\r
107       subfield = subfield.to_s\r
108       operation = op.dup\r
109       if operation.include?('proc ')\r
110         operation = operation.dup.sub(/^proc /, '')\r
111         eval("#{$procs[operation]}")\r
112       elsif operation == 'create-field'\r
113         create_datafield.call(record, field, subfield, filler)\r
114       elsif operation == 'append-subfield'\r
115         append_subfield.call(record, field, subfield, filler)\r
116       elsif operation == 'prompt'\r
117         field_data = ask("What do you want to go into the #{field}#{subfield} #{filler}? ")\r
118         \r
119         next if field_data.empty?\r
120         m_fields = record.find_all{|x| x.tag == field}\r
121         if m_fields.empty?\r
122           puts "m_fields is empty!!"\r
123           create_datafield.call(record, field, ' ', ' ')\r
124           m_fields = record.find_all{|x| x.tag == field}\r
125         end\r
126         m_fields.each {|field| field.append(MARC::Subfield.new(subfield, field_data))}\r
127       elsif operation == 'remove'\r
128         to_remove = record.find_all {|f|  f.tag =~ Regexp.new( field.gsub('X','.'))}\r
129         to_remove.each do |remove|\r
130           record.fields.delete(remove)\r
131         end\r
132       elsif operation == 'sort-tags' ##This doesn't work right now\r
133         puts "sorting by tag"\r
134         puts record , "################"\r
135         record = record.sort_by{| field | field.tag}\r
136         puts record\r
137         STDIN.gets\r
138       else\r
139         puts "there's nothing for that yet in local_script"\r
140       end\r
141       puts record if $testing\r
142     end\r
144     record\r
145   end\r
147     \r
148   \r
149     def edit\r
150       puts "Subfield Editing"\r
151       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. "\r
152       continue = true\r
153       while continue\r
154               fs = ask("What field and subfield would you like to edit (in form 245a) or quit?\n>   "){|q| q.readline = true}\r
155         if fs == 'q' || fs == 'quit'\r
156           continue = false\r
157         next\r
158         end\r
159         if !(fs =~/\d\d\d\w/ )\r
160           puts "That's not a valid value"\r
161           next\r
162         end\r
163         self.change_subfield(fs)\r
164       end\r
165     end\r
167     #edit_subfield is passed to a MARC::Record object and give a subfield\r
168     def change_subfield(fs)\r
169       field_subfield = subfield_parse(fs)\r
170       field = field_subfield[0]\r
171       subfield = field_subfield[1]\r
173       fields = self.marc.find_all {|f| f.tag == field}\r
174       subfields = []\r
175       for field in fields\r
176               subfields << field.find_all {|s| s.code == subfield}\r
177       end\r
178       subfields.flatten!\r
179       if subfields.length > 1\r
180         i = 0\r
181         for subfield in subfields\r
182                 puts "#{i}\t#{subfield}"\r
183           i += 1\r
184         end\r
185               num_to_change = ask("Which subfield do you want to change?"){|q| q.readline = true}\r
186               subfield_to_change = subfields[num_to_change.to_i]\r
187       elsif subfields.length == 1\r
188         subfield_to_change = subfields[0]\r
189       elsif subfields.empty?\r
190         puts "No such subfield!"\r
191               return nil\r
192       end\r
193       \r
195       puts self.marc; puts\r
197       print "Currently:\t"\r
198       puts subfield_to_change.value \r
199       edit = ask("Your edit:\t"){|q| q.readline = true}\r
200       subfield_to_change.value = edit\r
201       puts; puts self.marc; puts\r
203     end\r
205     #subfield_parse method for getting from '245a' to ['245','a']\r
206     def subfield_parse(combined)\r
207       field_subfield = []\r
208       field_subfield << combined[0, 3]\r
209       field_subfield << combined[3,1]\r
210     end\r
211   \r
212     def full_edit\r
213       #puts self.class\r
214       orig_marc = Tempfile.new("orig_marc-")\r
215       orig_marc << self.marc.to_marc\r
216       orig_marc.close\r
217       \r
218       line_format = `yaz-marcdump #{orig_marc.path}`\r
219       \r
220       out = Tempfile.new("full_edit-")\r
221       out << line_format\r
222       out.close\r
223       \r
224       system("#{TEXT_EDITOR} #{out.path}")\r
226       final = Tempfile.new("final-")\r
227       final.close\r
228       `yaz-marcdump -i line -o marc #{out.path} > #{final.path}`\r
229       \r
230       record = MARC::Reader.new(final.path)\r
231       for rec in record\r
232         puts rec\r
233         self.marc = rec\r
234         puts rec.class\r
235       end\r
236       puts self.marc.inspect\r
237       \r
238     end\r
240     \r
241    # To use marc_to_csv it must be passed a csv template in the order of the fields.\r
242   # See the zoomer.yaml file for instructions on creating a template.\r
243   # See the main script for turning this feature on.\r
244   def marc_to_csv(template)\r
245     values = []\r
246     template.each do |template|\r
247       field, subfield, leng = template\r
248       field = field.to_s\r
249       subfield = subfield.to_s\r
250       if field == 'prompt'\r
251         value = ask("prompt: please enter the #{field} #{subfield}") #--subfield here is a label for the prompt\r
252         \r
253         value = "\"#{value}\","\r
254         values << value\r
255       elsif field.length == 3 and field.match('\d')\r
256         fields = self.marc.find_all { | f |  f.tag =~ Regexp.new( field.gsub('X','.'))}\r
257         value = ''\r
258         if fields.empty?\r
259           #puts "oh, no!"\r
260           value = blank_field_prompt(field, subfield)\r
261           #eval(blank_field_prompt)\r
262         else\r
263           fields.each do |f|\r
264             if f[subfield]\r
265               value += f[subfield] + "|"\r
266             else\r
267               value = blank_field_prompt(field, subfield)\r
268             end\r
269           end\r
270         end\r
271         value.sub!(/\|$/, '')\r
272         value = value[0, leng] if leng\r
273         #puts "value: #{value}"\r
274         value = "\"#{value}\","\r
275         values << value\r
277       else\r
278         puts "this is not a valid value for marc_to_csv"\r
279       end\r
280     end\r
281     #puts values\r
282     values[-1].sub!(/\,$/, '')\r
283     values = values.to_s\r
284     values += "\n"\r
285   end\r
287  \r
289     \r
290   end\r
292 end\r