rbbt-util 4.1.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/run_workflow.rb CHANGED
@@ -92,12 +92,15 @@ if options[:server]
92
92
  require 'compass'
93
93
 
94
94
  Workflow.require_workflow workflow
95
- WorkflowREST.add_workflows Workflow.workflows.last
95
+ WorkflowREST.add_workflows *Workflow.workflows
96
96
 
97
97
  WorkflowREST.setup
98
98
 
99
99
  Sinatra::Application.port = options[:port] || 4567
100
100
  Sinatra::Application.run = true
101
+ if File.exists? workflow
102
+ Sinatra::Application.views = File.join(File.dirname(workflow), 'www/views')
103
+ end
101
104
 
102
105
  else
103
106
 
@@ -1,9 +1,12 @@
1
+ require 'rbbt/util/misc'
1
2
  require 'rbbt/util/chain_methods'
3
+
2
4
  require 'json'
3
5
  module Annotated
4
6
  attr_accessor :annotation_types
5
7
  attr_accessor :context
6
8
  attr_accessor :container
9
+ attr_accessor :container_index
7
10
 
8
11
  def self.extended(base)
9
12
  base.annotation_types ||= []
@@ -30,53 +33,83 @@ module Annotated
30
33
 
31
34
  def self.load(object, info)
32
35
  annotation_types = info[:annotation_types]
36
+ annotation_types = annotation_types.split("+") if String === annotation_types
37
+
33
38
  annotation_types.each do |mod|
34
39
  mod = Misc.string2const(mod) if String === mod
35
- mod.setup_info(object, info)
40
+ mod.setup(object, *info.values_at(*mod.all_annotations))
36
41
  end
37
42
 
38
43
  object
39
44
  end
40
45
 
41
46
  def tsv_values(*fields)
42
- fields = fields.flatten
43
- info = self.info
44
- values = []
45
- fields.each do |field|
46
- values << case
47
- when field == "JSON"
48
- info.to_json
49
- when field == "literal"
50
- self.gsub(/\n|\t/, ' ')
51
- when info.include?(field.to_sym)
52
- info.delete(field.to_sym)
53
- when self.respond_to?(field)
54
- self.send(field)
47
+ if Array === self and (not AnnotatedArray === self or self.double_array)
48
+ Misc.zip_fields(self.compact.collect{|e| e.tsv_values(fields)})
49
+ else
50
+ fields = fields.flatten
51
+ info = self.info
52
+ values = []
53
+
54
+ fields.each do |field|
55
+ values << case
56
+ when Proc === field
57
+ field.call(self)
58
+ when field == "JSON"
59
+ info.to_json
60
+ when field == "annotation_types"
61
+ annotation_types.collect{|t| t.to_s} * "+"
62
+ when field == "literal array"
63
+ (self * "|").gsub(/\n|\t/, ' ')
64
+ when field == "literal"
65
+ self.gsub(/\n|\t/, ' ')
66
+ when info.include?(field.to_sym)
67
+ info.delete(field.to_sym)
68
+ when self.respond_to?(field)
69
+ self.send(field)
70
+ end
55
71
  end
72
+
73
+ values
56
74
  end
57
- values
58
75
  end
59
76
 
60
77
  def self.load_tsv_values(id, values, *fields)
61
78
  fields = fields.flatten
62
79
  info = {}
63
80
  literal_pos = fields.index "literal"
81
+ literal_array_pos = fields.index "literal array"
64
82
 
65
- object = if literal_pos.nil?
66
- id
83
+ object = case
84
+ when literal_pos
85
+ values[literal_pos]
86
+ when literal_array_pos
87
+ values[literal_array_pos].split("|").extend AnnotatedArray
67
88
  else
68
- v = values[literal_pos]
69
- v = v.first if Array === v
70
- v
89
+ id.dup
71
90
  end
72
91
 
73
- fields.each_with_index do |field,i|
74
- if field == "JSON"
75
- JSON.parse(values[i]).each do |key, value|
76
- info[key.to_sym] = value
92
+ if Array === values
93
+ Misc.zip_fields(values).collect do |list|
94
+ fields.each_with_index do |field,i|
95
+ if field == "JSON"
96
+ JSON.parse(list[i]).each do |key, value|
97
+ info[key.to_sym] = value
98
+ end
99
+ else
100
+ info[field.to_sym] = list[i]
101
+ end
102
+ end
103
+ end
104
+ else
105
+ fields.each_with_index do |field,i|
106
+ if field == "JSON"
107
+ JSON.parse(values[i]).each do |key, value|
108
+ info[key.to_sym] = value
109
+ end
110
+ else
111
+ info[field.to_sym] = values[i]
77
112
  end
78
- else
79
- info[field.to_sym] = values[i]
80
113
  end
81
114
  end
82
115
 
@@ -84,44 +117,71 @@ module Annotated
84
117
  end
85
118
 
86
119
  def self.tsv(annotations, *fields)
120
+ return nil if annotations.nil?
87
121
  fields = case
88
122
  when ((fields.compact.empty?) and not annotations.empty?)
89
- fields = annotations.first.annotations
123
+ fields = AnnotatedArray === annotations ? annotations.annotations : annotations.first.annotations
90
124
  fields << :annotation_types
91
125
  when (fields == [:literal] and not annotations.empty?)
92
- fields = annotations.first.annotations
93
126
  fields << :literal
94
127
  when (fields == [:all] and not annotations.empty?)
95
- fields = [:annotation_types] + annotations.first.annotations
128
+ fields = [:annotation_types] + (Annotated === annotations ? annotations.annotations : annotations.first.annotations)
96
129
  fields << :literal
97
130
  else
98
131
  fields.flatten
99
132
  end
133
+
100
134
  fields = fields.collect{|f| f.to_s}
101
135
 
102
- tsv = TSV.setup({}, :key_field => "ID", :fields => fields, :type => :list )
136
+ fields = fields.collect{|f| ((f == "literal" and AnnotatedArray === annotations) ? "literal array" : f)}
103
137
 
104
- annotations.each do |annotation|
105
- tsv[annotation.id] = annotation.tsv_values(fields)
138
+ case
139
+ when (Annotated === annotations and not annotations.double_array)
140
+ tsv = TSV.setup({}, :key_field => "Single", :fields => fields, :type => :list, :unnamed => true)
141
+ tsv[annotations.id] = annotations.tsv_values(*fields)
142
+ when Array === annotations
143
+ tsv = TSV.setup({}, :key_field => "ID", :fields => fields, :type => :list, :unnamed => true)
144
+ annotations.compact.each do |annotation|
145
+ tsv[annotation.id] = annotation.tsv_values(*fields)
146
+ end
147
+ else
148
+ raise "Annotations need to be an Array to create TSV"
106
149
  end
107
150
 
108
151
  tsv
109
152
  end
110
153
 
111
154
  def self.load_tsv(tsv)
112
- tsv.collect do |id, values|
113
- Annotated.load_tsv_values(id, values, tsv.fields)
155
+ tsv.with_unnamed do
156
+ annotated_entities = tsv.collect do |id, values|
157
+ Annotated.load_tsv_values(id, values, tsv.fields)
158
+ end
159
+
160
+ if tsv.key_field == "Single"
161
+ annotated_entities.first
162
+ else
163
+ annotated_entities[0].annotate annotated_entities unless annotated_entities.empty?
164
+ end
114
165
  end
115
166
  end
116
167
 
117
168
  def make_list
118
169
  new = [self]
119
170
  annotation_types.each do |mod|
120
- mod.setup(new, *info.values_at(*mod.annotations))
171
+ mod.setup(new, *info.values_at(*mod.all_annotations))
121
172
  end
122
173
  new.context = self.context
123
174
  new
124
175
  end
176
+
177
+ def annotate(object)
178
+ annotation_types.each do |mod|
179
+ mod.setup(object, *info.values_at(*mod.annotations))
180
+ end
181
+ object.context = self.context
182
+ object.container = self.container
183
+ object
184
+ end
125
185
  end
126
186
 
127
187
 
@@ -145,12 +205,12 @@ module Annotation
145
205
 
146
206
  def self.extended(object)
147
207
  self.send(:prev_annotation_extended, object)
148
- object.extend Annotated
149
- if not object.annotation_types.include? self
150
- object.annotation_types.concat self.inheritance
151
- object.annotation_types << self
152
- object.annotation_types.uniq!
153
- end
208
+ object.extend Annotated unless Annotated == object
209
+ if not object.annotation_types.include? self
210
+ object.annotation_types.concat self.inheritance
211
+ object.annotation_types << self
212
+ object.annotation_types.uniq!
213
+ end
154
214
  end
155
215
 
156
216
  def self.included(base)
@@ -166,7 +226,7 @@ module Annotation
166
226
  end
167
227
 
168
228
  def update_annotations
169
- @all_annotations = all_inheritance.inject([]){|acc,mod| acc.concat mod.annotations}.concat(@annotations)
229
+ @all_annotations = all_inheritance.inject([]){|acc,mod| acc.concat mod.all_annotations}.concat(@annotations)
170
230
  end
171
231
 
172
232
  def annotation(*values)
@@ -179,14 +239,14 @@ module Annotation
179
239
  end
180
240
 
181
241
  def setup_info(object, info)
182
- object.extend self
242
+ object.extend self unless self === object
183
243
  all_annotations.each do |annotation|
184
244
  object.send(annotation.to_s + '=', info[annotation])
185
245
  end
186
246
  end
187
247
 
188
248
  def setup(object, *values)
189
- object.extend self
249
+ object.extend self unless self === object
190
250
 
191
251
  inputs = Misc.positional2hash(all_annotations, *values)
192
252
  inputs.each do |name, value|
@@ -195,29 +255,47 @@ module Annotation
195
255
 
196
256
  object
197
257
  end
258
+
198
259
  end
199
260
 
200
261
  module AnnotatedArray
201
262
  extend ChainMethods
202
263
  self.chain_prefix = :annotated_array
203
264
 
265
+ def double_array
266
+ AnnotatedArray === self.first
267
+ end
268
+
269
+ def annotated_array_first
270
+ self[0]
271
+ end
272
+
273
+ def annotated_array_last
274
+ self[-1]
275
+ end
276
+
204
277
  def annotated_array_get_brackets(pos)
205
278
  value = annotated_array_clean_get_brackets(pos)
206
279
  annotation_types.each do |mod|
207
- mod.setup(value, *info.values_at(*mod.annotations))
280
+ mod.setup(value, *info.values_at(*mod.all_annotations))
208
281
  end
209
282
  value.context = self.context
210
283
  value.container = self
284
+ value.container_index = pos
211
285
  value
212
286
  end
213
287
 
214
288
  def annotated_array_each
289
+ i = 0
215
290
  annotated_array_clean_each do |value|
291
+ value = value.dup if value.frozen?
216
292
  annotation_types.each do |mod|
217
293
  mod.setup(value, info)
218
294
  end
219
295
  value.context = self.context
220
296
  value.container = self
297
+ value.container_index = i
298
+ i += 1
221
299
  yield value
222
300
  end
223
301
  end
@@ -237,7 +315,7 @@ module AnnotatedArray
237
315
  annotated_array_each do |value|
238
316
  res << value if yield(value)
239
317
  end
240
-
318
+
241
319
  annotation_types.each do |mod|
242
320
  mod.setup(res, *info.values_at(*mod.annotations))
243
321
  end
@@ -252,7 +330,7 @@ module AnnotatedArray
252
330
  annotated_array_each do |value|
253
331
  res << value unless yield(value)
254
332
  end
255
-
333
+
256
334
  annotation_types.each do |mod|
257
335
  mod.setup(res, *info.values_at(*mod.annotations))
258
336
  end
@@ -265,7 +343,7 @@ module AnnotatedArray
265
343
  def annotated_array_subset(list)
266
344
  value = (self & list)
267
345
  annotation_types.each do |mod|
268
- mod.setup(value, *info.values_at(*mod.annotations))
346
+ mod.setup(value, *info.values_at(*mod.all_annotations))
269
347
  end
270
348
  value.context = self.context
271
349
  value.container = self.container
@@ -282,6 +360,18 @@ module AnnotatedArray
282
360
  value
283
361
  end
284
362
 
363
+ def annotated_array_compact
364
+ value = self.annotated_array_clean_compact
365
+
366
+ annotation_types.each do |mod|
367
+ mod.setup(value, *info.values_at(*mod.annotations))
368
+ end
369
+
370
+ value.context = self.context
371
+ value.container = self.container
372
+ value
373
+ end
374
+
285
375
  def annotated_array_uniq
286
376
  value = self.annotated_array_clean_uniq
287
377
 
@@ -353,11 +443,6 @@ module AnnotatedArray
353
443
  value << e if method.shift
354
444
  end
355
445
 
356
- #annotation_types.each do |mod|
357
- # mod.setup(value, *info.values_at(*mod.annotations))
358
- #end
359
- #value.context = self.context
360
- #value.container = self.container
361
446
  value
362
447
  end
363
448
  end
data/lib/rbbt/persist.rb CHANGED
@@ -10,6 +10,8 @@ module Persist
10
10
  CACHEDIR="/tmp/tsv_persistent_cache"
11
11
  FileUtils.mkdir CACHEDIR unless File.exist? CACHEDIR
12
12
 
13
+ MEMORY = {}
14
+
13
15
  def self.cachedir=(cachedir)
14
16
  CACHEDIR.replace cachedir
15
17
  FileUtils.mkdir_p CACHEDIR unless File.exist? CACHEDIR
@@ -62,7 +64,11 @@ module Persist
62
64
  persistence_dir = Misc.process_options(persist_options, :dir) || CACHEDIR
63
65
 
64
66
  filename = perfile.gsub(/\s/,'_').gsub(/\//,'>')
65
- options_md5 = Misc.hash2md5 options
67
+ clean_options = options
68
+ clean_options.delete :unnamed
69
+ clean_options.delete "unnamed"
70
+
71
+ options_md5 = Misc.hash2md5 clean_options
66
72
  filename << ":" << options_md5 unless options_md5.empty?
67
73
 
68
74
  File.join(persistence_dir, filename)
@@ -75,6 +81,8 @@ module Persist
75
81
  nil
76
82
  when :boolean
77
83
  TRUE_STRINGS.include? Open.read(path).chomp.strip
84
+ when :annotations
85
+ Annotated.load_tsv TSV.open(path)
78
86
  when :tsv
79
87
  TSV.open(path)
80
88
  when :marshal_tsv
@@ -104,7 +112,7 @@ module Persist
104
112
 
105
113
  def self.save_file(path, type, content)
106
114
 
107
- return if (content.nil? and File.exists? path)
115
+ return if content.nil?
108
116
 
109
117
  case (type || "nil").to_sym
110
118
  when :nil
@@ -116,6 +124,8 @@ module Persist
116
124
  Open.write(path, content.file.read)
117
125
  when :tsv
118
126
  Open.write(path, content.to_s)
127
+ when :annotations
128
+ Open.write(path, Annotated.tsv(content, :all).to_s)
119
129
  when :string, :text
120
130
  Open.write(path, content)
121
131
  when :array
@@ -140,19 +150,27 @@ module Persist
140
150
  def self.persist(name, type = nil, persist_options = {})
141
151
  type ||= :marshal
142
152
  persist_options = Misc.add_defaults persist_options, :persist => true
153
+ other_options = Misc.process_options persist_options, :other
143
154
 
144
155
  if persist_options[:persist]
145
- path = persistence_path(name, persist_options)
146
- Misc.lock(path) do
147
- if is_persisted?(path, persist_options)
148
- Log.debug "Persist up-to-date: #{ path } - #{persist_options.inspect}"
149
- return load_file(path, type)
150
- else
151
- Log.debug "Persist create: #{ path } - #{persist_options.inspect}"
156
+ path = persistence_path(name, persist_options, other_options || {})
157
+
158
+ case type
159
+ when :memory
160
+ Persist::MEMORY[path] ||= yield
161
+ else
162
+ Misc.lock(path) do
163
+ if is_persisted?(path, persist_options)
164
+ Log.debug "Persist up-to-date: #{ path } - #{persist_options.inspect[0..100]}"
165
+ return nil if persist_options[:no_load]
166
+ return load_file(path, type)
167
+ else
168
+ Log.debug "Persist create: #{ path } - #{persist_options.inspect[0..100]}"
169
+ end
170
+ res = yield
171
+ save_file(path, type, res)
172
+ res
152
173
  end
153
- res = yield
154
- save_file(path, type, res)
155
- res
156
174
  end
157
175
  else
158
176
  yield