rbbt-util 4.4.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -69,6 +69,10 @@ class FixWidthTable
69
69
  end
70
70
  alias << add
71
71
 
72
+ def last_pos
73
+ pos(size - 1)
74
+ end
75
+
72
76
  def pos(index)
73
77
  return nil if index < 0 or index >= size
74
78
  @file.seek(5 + (record_size) * index, IO::SEEK_SET)
@@ -156,7 +160,7 @@ class FixWidthTable
156
160
  idx = idx - 1
157
161
  end
158
162
 
159
- idx
163
+ idx.to_i
160
164
  end
161
165
 
162
166
  def get_range(pos)
data/lib/rbbt/persist.rb CHANGED
@@ -93,6 +93,7 @@ module Persist
93
93
  f = File.open(path, 'rb')
94
94
  res = f.read
95
95
  f.close
96
+ res.force_encoding("ASCII-8BIT") if res.respond_to? :force_encoding
96
97
  res
97
98
  when :array
98
99
  res = Open.read(path).split("\n", -1)
@@ -106,8 +107,6 @@ module Persist
106
107
  Open.read(path).to_f
107
108
  when :integer
108
109
  Open.read(path).to_i
109
- when :tsv
110
- TSV.open(Open.open(path))
111
110
  else
112
111
  raise "Unknown persistence: #{ type }"
113
112
  end
@@ -132,6 +131,7 @@ module Persist
132
131
  when :string, :text
133
132
  Open.write(path, content)
134
133
  when :binary
134
+ content.force_encoding("ASCII-8BIT") if content.respond_to? :force_encoding
135
135
  f = File.open(path, 'wb')
136
136
  f.puts content
137
137
  f.close
@@ -197,31 +197,48 @@ module Persist
197
197
  repo[key]
198
198
  end
199
199
  Annotated.load_tsv_values(key, values, "literal", "annotation_types", "JSON")
200
- when keys.any?
200
+ when (keys.any? and not keys.first =~ /ANNOTATED_DOUBLE_ARRAY/)
201
201
  repo.read_and_close do
202
- keys.collect{|key|
202
+ keys.sort_by{|k| k.split(":").last.to_i}.collect{|key|
203
203
  v = repo[key]
204
204
  Annotated.load_tsv_values(key, v, "literal", "annotation_types", "JSON")
205
205
  }
206
206
  end
207
+ when (keys.any? and keys.first =~ /ANNOTATED_DOUBLE_ARRAY/)
208
+ repo.read_and_close do
209
+
210
+ res = keys.sort_by{|k| k.split(":").last.to_i}.collect{|key|
211
+ v = repo[key]
212
+ Annotated.load_tsv_values(key, v, "literal", "annotation_types", "JSON")
213
+ }
214
+
215
+ res.first.annotate res
216
+ res.extend AnnotatedArray
217
+
218
+ res
219
+ end
207
220
  else
208
221
  entities = yield
209
222
 
210
- Misc.lock(repo.persistence_path) do
211
- repo.write_and_close do
212
- case
213
- when entities.nil?
214
- repo[subkey + "NIL"] = nil
215
- when entities.empty?
216
- repo[subkey + "EMPTY"] = nil
217
- when (not Array === entities or AnnotatedArray === entities)
218
- tsv_values = entities.tsv_values("literal", "annotation_types", "JSON")
219
- repo[subkey + entities.id << ":" << "SINGLE"] = tsv_values
220
- else
221
- entities.each do |e|
222
- tsv_values = e.tsv_values("literal", "annotation_types", "JSON")
223
- repo[subkey + e.id] = tsv_values
224
- end
223
+ repo.write_and_close do
224
+ case
225
+ when entities.nil?
226
+ repo[subkey + "NIL"] = nil
227
+ when entities.empty?
228
+ repo[subkey + "EMPTY"] = nil
229
+ when (not Array === entities or (AnnotatedArray === entities and not Array === entities.first))
230
+ tsv_values = entities.tsv_values("literal", "annotation_types", "JSON")
231
+ repo[subkey + entities.id << ":" << "SINGLE"] = tsv_values
232
+ when (not Array === entities or (AnnotatedArray === entities and AnnotatedArray === entities.first))
233
+ entities.each_with_index do |e,i|
234
+ tsv_values = e.tsv_values("literal", "annotation_types", "JSON")
235
+ repo[subkey + e.id << ":ANNOTATED_DOUBLE_ARRAY:" << i.to_s] = tsv_values
236
+ end
237
+ else
238
+ entities.each_with_index do |e,i|
239
+ next if e.nil?
240
+ tsv_values = e.tsv_values("literal", "annotation_types", "JSON")
241
+ repo[subkey + e.id << ":" << i.to_s] = tsv_values
225
242
  end
226
243
  end
227
244
  end
@@ -230,23 +247,23 @@ module Persist
230
247
  end
231
248
 
232
249
  else
233
- Misc.lock(path) do
234
- if is_persisted?(path, persist_options)
235
- Log.debug "Persist up-to-date: #{ path } - #{persist_options.inspect[0..100]}"
236
- return nil if persist_options[:no_load]
237
- return load_file(path, type)
238
- else
239
- Log.debug "Persist create: #{ path } - #{persist_options.inspect[0..100]}"
240
- end
241
- begin
242
- res = yield
250
+ if is_persisted?(path, persist_options)
251
+ Log.debug "Persist up-to-date: #{ path } - #{persist_options.inspect[0..100]}"
252
+ return nil if persist_options[:no_load]
253
+ return load_file(path, type)
254
+ else
255
+ Log.debug "Persist create: #{ path } - #{persist_options.inspect[0..100]}"
256
+ end
257
+ begin
258
+ res = yield
259
+ Misc.lock(path) do
243
260
  save_file(path, type, res)
244
- res
245
- rescue
246
- Log.high "Error in persist. Erasing '#{ path }'"
247
- FileUtils.rm path if File.exists? path
248
- raise $!
249
261
  end
262
+ res
263
+ rescue
264
+ Log.high "Error in persist. Erasing '#{ path }'"
265
+ FileUtils.rm path if File.exists? path
266
+ raise $!
250
267
  end
251
268
  end
252
269
 
@@ -82,13 +82,15 @@ module Persist
82
82
  end
83
83
 
84
84
  def write_and_close
85
- write if @closed or not write?
86
- res = begin
87
- yield
88
- ensure
89
- close
90
- end
91
- res
85
+ Misc.lock(persistence_path) do
86
+ write if @closed or not write?
87
+ res = begin
88
+ yield
89
+ ensure
90
+ close
91
+ end
92
+ res
93
+ end
92
94
  end
93
95
 
94
96
  def read_and_close
@@ -135,7 +137,15 @@ module Persist
135
137
  persist_options[:data]
136
138
  when persist_options[:persist]
137
139
 
138
- filename ||= source.filename if source.respond_to? :filename
140
+ filename ||= case
141
+ when source.respond_to?(:filename)
142
+ source.filename
143
+ when source.respond_to?(:cmd)
144
+ "CMD-#{Misc.digest(source.cmd)}"
145
+ else
146
+ source.object_id.to_s
147
+ end
148
+
139
149
  filename ||= source.object_id.to_s
140
150
 
141
151
  path = persistence_path(filename, persist_options, options)
@@ -161,25 +171,26 @@ module Persist
161
171
 
162
172
  begin
163
173
  if data.respond_to? :persistence_path and data != persist_options[:data]
164
- Misc.lock data.persistence_path do
165
- data.write_and_close do
166
- yield data
167
- end
174
+ data.write_and_close do
175
+ yield data
168
176
  end
169
177
  else
170
178
  yield data
171
179
  end
172
180
  rescue Exception
181
+ FileUtils.rm path if path and File.exists? path
182
+ raise $!
183
+ ensure
173
184
  begin
174
- data.close if data.respondo_to? :close
185
+ data.close if data.respond_to? :close
175
186
  rescue
187
+ raise $!
176
188
  end
177
- FileUtils.rm path if path and File.exists? path
178
- raise $!
179
189
  end
180
190
 
181
191
  data.read if data.respond_to? :read and ((data.respond_to?(:write?) and data.write?) or (data.respond_to?(:closed?) and data.closed?))
182
192
 
193
+
183
194
  data
184
195
  end
185
196
 
data/lib/rbbt/resource.rb CHANGED
@@ -29,7 +29,11 @@ module Resource
29
29
 
30
30
  def resource_method_missing(name, prev = nil, *args)
31
31
  # Fix problem with ruby 1.9 calling methods by its own initiative. ARG
32
- root.send(name, prev, *args)
32
+ if prev.nil?
33
+ root.send(name, *args)
34
+ else
35
+ root.send(name, prev, *args)
36
+ end
33
37
  end
34
38
 
35
39
  def [](file = nil)
@@ -41,7 +45,6 @@ module Resource
41
45
  end
42
46
 
43
47
  def claim(path, type, content = nil, &block)
44
- path = path.find if path.respond_to? :find
45
48
  if type == :rake
46
49
  @rake_dirs[path] = content
47
50
  else
@@ -56,28 +59,30 @@ module Resource
56
59
  end
57
60
  end
58
61
 
59
- def produce(path)
62
+ def produce(path, force = false)
60
63
  case
61
64
  when @resources.include?(path)
62
65
  type, content = @resources[path]
63
66
  when has_rake(path)
64
67
  type = :rake
65
68
  rake_dir, content = rake_for(path)
69
+ rake_dir = Path.setup(rake_dir.dup, self.pkgdir, self)
66
70
  else
67
71
  raise "Resource #{ path } does not seem to be claimed"
68
72
  end
69
73
 
70
- if not File.exists? path
71
- Misc.lock path + '.produce' do
74
+ final_path = path.respond_to?(:find) ? (force ? path.find(:user) : path.find) : path
75
+ if not File.exists? final_path or force
76
+ Misc.lock final_path + '.produce' do
72
77
  begin
73
78
  case type
74
79
  when :string
75
- Open.write(path, content)
80
+ Open.write(final_path, content)
76
81
  when :url
77
- Open.write(path, Open.open(content))
82
+ Open.write(final_path, Open.open(content))
78
83
  when :proc
79
84
  data = content.call
80
- Open.write(path, data)
85
+ Open.write(final_path, data)
81
86
  when :rake
82
87
  run_rake(path, content, rake_dir)
83
88
  when :install
@@ -99,7 +104,7 @@ source "$INSTALL_HELPER_FILE"
99
104
  raise "Could not produce #{ resource }. (#{ type }, #{ content })"
100
105
  end
101
106
  rescue
102
- FileUtils.rm path if File.exists? path
107
+ FileUtils.rm_rf final_path if File.exists? final_path
103
108
  raise $!
104
109
  end
105
110
  end
@@ -117,19 +117,19 @@ module Path
117
117
  end
118
118
  end
119
119
 
120
- def produce
120
+ def produce(force = false)
121
121
  path = self.find
122
- return self if File.exists? path
122
+ return self if File.exists?(path) and not force
123
123
 
124
124
  raise "No resource defined to produce file: #{ self }" if resource.nil?
125
125
 
126
- resource.produce path
126
+ resource.produce self, force
127
127
 
128
128
  path
129
129
  end
130
130
 
131
- def read
132
- Open.read(self.produce.find)
131
+ def read(&block)
132
+ Open.read(self.produce.find, &block)
133
133
  end
134
134
 
135
135
  def open(options = {})
@@ -37,12 +37,16 @@ module Rake
37
37
 
38
38
  raise TaskNotFound if Rake::Task[task].nil?
39
39
 
40
- Misc.in_dir(dir) do
41
- Rake::Task[task].invoke
40
+ t = nil
41
+ pid = Process.fork{
42
+ Misc.in_dir(dir) do
43
+ Rake::Task[task].invoke
42
44
 
43
- Rake::Task.clear
44
- Rake::FileTask.clear_files
45
- end
45
+ Rake::Task.clear
46
+ Rake::FileTask.clear_files
47
+ end
48
+ }
49
+ Process.wait(pid)
46
50
 
47
51
  end
48
52
  end
@@ -8,7 +8,7 @@ module Path
8
8
  l =~ /rbbt\/resource\/path\.rb/ or
9
9
  l =~ /rbbt\/util\/misc\.rb/ or
10
10
  l =~ /progress-monitor\.rb/
11
- }.first.sub(/\.rb.*/,'.rb') if file.nil?
11
+ }.first.sub(/\.rb[^\w].*/,'.rb') if file.nil?
12
12
 
13
13
  file = File.expand_path file
14
14
  return Path.setup(file) if File.exists? File.join(file, relative_to)
@@ -82,7 +82,7 @@ module Resource
82
82
 
83
83
 
84
84
  def rake_for(path)
85
- entry = @rake_dirs.reject{|dir, content|
85
+ @rake_dirs.reject{|dir, content|
86
86
  !Misc.common_path(dir, path)
87
87
  }.sort_by{|dir, content|
88
88
  dir.length
@@ -97,6 +97,8 @@ module Resource
97
97
  task = Misc.path_relative_to rake_dir, path
98
98
  rakefile = rakefile.produce if rakefile.respond_to? :produce
99
99
 
100
+ rake_dir = rake_dir.find if rake_dir.respond_to? :find
101
+
100
102
  begin
101
103
  Rake.run(rakefile, rake_dir, task)
102
104
  rescue Rake::TaskNotFound
data/lib/rbbt/tsv.rb CHANGED
@@ -17,7 +17,9 @@ require 'rbbt/tsv/filter'
17
17
 
18
18
  module TSV
19
19
  def self.setup(hash, options = {})
20
- hash = Misc.array2hash hash if Array === hash
20
+ options = Misc.add_defaults options, :default_value => []
21
+ default_value = Misc.process_options options, :default_value
22
+ hash = Misc.array2hash(hash, default_value) if Array === hash
21
23
  hash.extend TSV
22
24
 
23
25
  IndiferentHash.setup(options)
@@ -40,9 +42,14 @@ module TSV
40
42
  filename = get_filename source
41
43
  serializer = Misc.process_options options, :serializer
42
44
  unnamed = Misc.process_options options, :unnamed
45
+ entity_options = Misc.process_options options, :entity_options
43
46
 
44
- Log.debug "TSV open: #{ filename } - #{options.inspect}"
47
+ Log.debug "TSV open: #{ filename } - #{options.inspect}.#{unnamed ? " [unnamed]" : "[not unnamed]"}"
45
48
 
49
+ data = nil
50
+
51
+ lock_filename = filename.nil? ? nil : Persist.persistence_path(filename, {:dir => Rbbt.tmp.tsv_open_locks.find})
52
+ Misc.lock lock_filename do
46
53
  data = Persist.persist_tsv source, filename, options, persist_options do |data|
47
54
  if serializer
48
55
  data.extend TSV unless TSV === data
@@ -56,14 +63,17 @@ module TSV
56
63
 
57
64
  data.filename = filename.to_s unless filename.nil?
58
65
  if data.identifiers.nil? and Path === filename and filename.identifier_file_path
59
- data.identifiers = filename.identifier_file_path.dup
66
+ data.identifiers = filename.identifier_file_path.to_s
60
67
  end
61
68
 
62
69
  data
63
70
  end
71
+ end
64
72
 
65
73
  data.unnamed = unnamed unless unnamed.nil?
66
74
 
75
+ data.entity_options = entity_options
76
+
67
77
  data
68
78
  end
69
79
 
@@ -72,13 +82,13 @@ module TSV
72
82
  end
73
83
 
74
84
  def self.parse(stream, data, options = {})
75
- monitor, grep = Misc.process_options options, :monitor, :grep
85
+ monitor, grep, invert_grep = Misc.process_options options, :monitor, :grep, :invert_grep
76
86
 
77
87
  parser = Parser.new stream, options
78
88
 
79
89
  if grep
80
90
  stream.rewind
81
- stream = Open.grep(stream, grep)
91
+ stream = Open.grep(stream, grep, invert_grep)
82
92
  parser.first_line = stream.gets
83
93
  end
84
94
 
@@ -131,10 +141,11 @@ module TSV
131
141
  progress_monitor = nil
132
142
  end
133
143
 
134
- while not line.nil?
144
+ while not line.nil?
135
145
  begin
136
146
  progress_monitor.tick(stream.pos) if progress_monitor
137
147
 
148
+ line = Misc.fixutf8(line)
138
149
  line = parser.process line
139
150
  parts = parser.chop_line line
140
151
  key, values = parser.get_values parts
@@ -142,8 +153,12 @@ module TSV
142
153
  parser.add_to_data data, key, values
143
154
  line = stream.gets
144
155
  rescue Parser::SKIP_LINE
145
- line = stream.gets
146
- next
156
+ begin
157
+ line = stream.gets
158
+ next
159
+ rescue IOError
160
+ break
161
+ end
147
162
  rescue Parser::END_PARSING
148
163
  break
149
164
  rescue IOError