openwferu-extras 0.9.16 → 0.9.17
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/openwfe/extras/expool/dberrorjournal.rb +5 -6
- data/lib/openwfe/extras/expool/dbexpstorage.rb +104 -26
- data/lib/openwfe/extras/listeners/sqslisteners.rb +13 -16
- data/lib/openwfe/extras/misc/activityfeed.rb +7 -20
- data/lib/openwfe/extras/misc/basecamp.rb +485 -0
- data/lib/openwfe/extras/participants/activeparticipants.rb +202 -45
- data/lib/openwfe/extras/participants/atomfeed_participants.rb +3 -18
- data/lib/openwfe/extras/participants/atompub_participants.rb +4 -22
- data/lib/openwfe/extras/participants/basecamp_participants.rb +87 -0
- data/lib/openwfe/extras/participants/csvparticipants.rb +14 -10
- data/lib/openwfe/extras/participants/sqsparticipants.rb +9 -8
- data/lib/openwfe/extras/participants/twitterparticipants.rb +4 -19
- metadata +42 -36
- data/lib/openwfe/extras/util/csvtable.rb +0 -620
- data/lib/openwfe/extras/util/sqs.rb +0 -581
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
#--
|
3
|
-
# Copyright (c) 2007, John Mettraux OpenWFE.org
|
3
|
+
# Copyright (c) 2007-2008, John Mettraux, Tomaso Tosolini OpenWFE.org
|
4
4
|
# All rights reserved.
|
5
5
|
#
|
6
6
|
# Redistribution and use in source and binary forms, with or without
|
@@ -37,11 +37,10 @@
|
|
37
37
|
# John Mettraux at openwfe.org
|
38
38
|
#
|
39
39
|
|
40
|
-
require 'rubygems'
|
40
|
+
#require 'rubygems'
|
41
41
|
|
42
42
|
#require_gem 'activerecord'
|
43
|
-
gem 'activerecord'
|
44
|
-
require 'active_record'
|
43
|
+
gem 'activerecord'; require 'active_record'
|
45
44
|
|
46
45
|
|
47
46
|
require 'openwfe/workitem'
|
@@ -81,7 +80,12 @@ module Extras
|
|
81
80
|
t.column :store_name, :string
|
82
81
|
t.column :dispatch_time, :timestamp
|
83
82
|
t.column :last_modified, :timestamp
|
83
|
+
|
84
|
+
t.column :yattributes, :text
|
85
|
+
# when using compact_workitems, attributes are stored here
|
86
|
+
|
84
87
|
end
|
88
|
+
add_index :workitems, :fei, :unique => true
|
85
89
|
add_index :workitems, :wfid
|
86
90
|
add_index :workitems, :wf_name
|
87
91
|
add_index :workitems, :wf_revision
|
@@ -90,12 +94,14 @@ module Extras
|
|
90
94
|
|
91
95
|
create_table :fields do |t|
|
92
96
|
t.column :fkey, :string, :null => false
|
97
|
+
t.column :vclass, :string, :null => false
|
93
98
|
t.column :svalue, :string
|
94
99
|
t.column :yvalue, :text
|
95
100
|
t.column :workitem_id, :integer, :null => false
|
96
101
|
end
|
97
102
|
add_index :fields, [ :workitem_id, :fkey ], :unique => true
|
98
103
|
add_index :fields, :fkey
|
104
|
+
add_index :fields, :vclass
|
99
105
|
add_index :fields, :svalue
|
100
106
|
end
|
101
107
|
|
@@ -109,7 +115,7 @@ module Extras
|
|
109
115
|
#
|
110
116
|
# Reopening InFlowWorkItem to add a 'db_id' attribute.
|
111
117
|
#
|
112
|
-
class InFlowWorkItem
|
118
|
+
class OpenWFE::InFlowWorkItem
|
113
119
|
|
114
120
|
attr_accessor :db_id
|
115
121
|
end
|
@@ -146,6 +152,9 @@ module Extras
|
|
146
152
|
|
147
153
|
has_many :fields, :dependent => :destroy
|
148
154
|
|
155
|
+
serialize :yattributes
|
156
|
+
|
157
|
+
|
149
158
|
#
|
150
159
|
# Returns the flow expression id of this work (its unique OpenWFEru
|
151
160
|
# identifier) as a FlowExpressionId instance.
|
@@ -182,8 +191,22 @@ module Extras
|
|
182
191
|
|
183
192
|
i.store_name = store_name
|
184
193
|
|
185
|
-
|
186
|
-
|
194
|
+
|
195
|
+
# This is a field set by the active participant immediately
|
196
|
+
# before calling this method.
|
197
|
+
# the default behavior is "use field method"
|
198
|
+
|
199
|
+
if wi.attributes["compact_workitems"]
|
200
|
+
|
201
|
+
wi.attributes.delete("compact_workitems")
|
202
|
+
i.yattributes= wi.attributes
|
203
|
+
else
|
204
|
+
|
205
|
+
i.yattributes= nil
|
206
|
+
|
207
|
+
wi.attributes.each do |k, v|
|
208
|
+
i.fields << Field.new_field(k, v)
|
209
|
+
end
|
187
210
|
end
|
188
211
|
|
189
212
|
i.save!
|
@@ -217,11 +240,12 @@ module Extras
|
|
217
240
|
#
|
218
241
|
def fields_hash
|
219
242
|
|
220
|
-
|
221
|
-
|
222
|
-
|
243
|
+
return self.yattributes if self.yattributes
|
244
|
+
|
245
|
+
fields.inject({}) do |r, f|
|
246
|
+
r[f.fkey] = f.value
|
247
|
+
r
|
223
248
|
end
|
224
|
-
h
|
225
249
|
end
|
226
250
|
|
227
251
|
#
|
@@ -231,10 +255,17 @@ module Extras
|
|
231
255
|
#
|
232
256
|
def replace_fields (fhash)
|
233
257
|
|
234
|
-
|
258
|
+
if self.yattributes
|
235
259
|
|
236
|
-
|
237
|
-
|
260
|
+
self.yattributes = fhash
|
261
|
+
|
262
|
+
else
|
263
|
+
|
264
|
+
fields.delete_all
|
265
|
+
|
266
|
+
fhash.each do |k, v|
|
267
|
+
fields << Field.new_field(k, v)
|
268
|
+
end
|
238
269
|
end
|
239
270
|
|
240
271
|
#f = Field.new_field("___map_type", "smap")
|
@@ -253,8 +284,12 @@ module Extras
|
|
253
284
|
# wi.field :customer_name
|
254
285
|
#
|
255
286
|
def field (key)
|
287
|
+
|
288
|
+
if self.yattributes
|
289
|
+
return self.yattributes[key.to_s]
|
290
|
+
end
|
256
291
|
|
257
|
-
fields.find_by_fkey
|
292
|
+
fields.find_by_fkey key.to_s
|
258
293
|
end
|
259
294
|
|
260
295
|
#
|
@@ -273,6 +308,15 @@ module Extras
|
|
273
308
|
alias :forward :reply
|
274
309
|
alias :proceed :reply
|
275
310
|
|
311
|
+
#
|
312
|
+
# Simply sets the 'last_modified' field to now.
|
313
|
+
# (Doesn't save the workitem though).
|
314
|
+
#
|
315
|
+
def touch
|
316
|
+
|
317
|
+
self.last_modified = Time.now
|
318
|
+
end
|
319
|
+
|
276
320
|
#
|
277
321
|
# Opening engine to update its reply method to accept these
|
278
322
|
# active record workitems.
|
@@ -303,7 +347,7 @@ module Extras
|
|
303
347
|
# The result is a Hash whose keys are the store names and whose
|
304
348
|
# values are list of workitems.
|
305
349
|
#
|
306
|
-
def
|
350
|
+
def self.find_in_stores (storename_list)
|
307
351
|
|
308
352
|
workitems = find_all_by_store_name(storename_list)
|
309
353
|
|
@@ -319,7 +363,15 @@ module Extras
|
|
319
363
|
#
|
320
364
|
# A kind of 'google search' among workitems
|
321
365
|
#
|
322
|
-
|
366
|
+
# == Note
|
367
|
+
#
|
368
|
+
# when this is used on compact_workitems, it will not be able to search
|
369
|
+
# info within the fields, because they aren't used by this kind of
|
370
|
+
# workitems. In this case the search will be limited to participant_name
|
371
|
+
#
|
372
|
+
def self.search (search_string, storename_list=nil)
|
373
|
+
|
374
|
+
#t = OpenWFE::Timer.new
|
323
375
|
|
324
376
|
storename_list = Array(storename_list) if storename_list
|
325
377
|
|
@@ -334,49 +386,54 @@ module Extras
|
|
334
386
|
|
335
387
|
ids = result.collect { |wi| wi.id }
|
336
388
|
|
337
|
-
#
|
338
|
-
|
339
|
-
fields = Field.find(
|
340
|
-
:all,
|
341
|
-
:conditions => conditions(
|
342
|
-
"svalue", search_string, storename_list),
|
343
|
-
:include => :workitem)
|
344
|
-
|
345
|
-
merge_search_results(ids, result, fields)
|
389
|
+
# search in fields
|
346
390
|
|
347
|
-
|
391
|
+
fields = Field.search search_string, storename_list
|
392
|
+
merge_search_results ids, result, fields
|
348
393
|
|
349
|
-
|
350
|
-
:all,
|
351
|
-
:conditions => conditions(
|
352
|
-
"fkey", search_string, storename_list),
|
353
|
-
:include => :workitem)
|
354
|
-
|
355
|
-
merge_search_results(ids, result, fields)
|
394
|
+
#puts "... took #{t.duration} ms"
|
356
395
|
|
357
396
|
# over.
|
358
397
|
|
359
398
|
result
|
360
399
|
end
|
361
400
|
|
401
|
+
#
|
402
|
+
# Not really about 'just launched', but rather about finding the first
|
403
|
+
# workitem for a given process instance (wfid) and a participant.
|
404
|
+
# It deserves its own method because the workitem could be in a
|
405
|
+
# subprocess, thus escaping the vanilla find_by_wfid_and_participant()
|
406
|
+
#
|
407
|
+
def self.find_just_launched (wfid, participant_name)
|
408
|
+
|
409
|
+
find(
|
410
|
+
:first,
|
411
|
+
:conditions => [
|
412
|
+
"wfid LIKE ? AND participant_name = ?",
|
413
|
+
"#{wfid}%",
|
414
|
+
participant_name ])
|
415
|
+
end
|
416
|
+
|
362
417
|
protected
|
363
418
|
|
364
419
|
#
|
365
420
|
# builds the condition (the WHERE clause) for the
|
366
421
|
# search.
|
367
422
|
#
|
368
|
-
def
|
423
|
+
def self.conditions (keyname, search_string, storename_list)
|
424
|
+
|
425
|
+
cs = [ "#{keyname} LIKE ?", search_string ]
|
369
426
|
|
370
427
|
if storename_list
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
[ "#{keyname} LIKE ?",
|
375
|
-
search_string ]
|
428
|
+
|
429
|
+
cs[0] = "#{cs[0]} AND workitems.store_name IN (?)"
|
430
|
+
cs << storename_list
|
376
431
|
end
|
432
|
+
|
433
|
+
cs
|
377
434
|
end
|
378
435
|
|
379
|
-
def
|
436
|
+
def self.merge_search_results (ids, wis, new_wis)
|
380
437
|
|
381
438
|
return if new_wis.size < 1
|
382
439
|
|
@@ -414,13 +471,16 @@ module Extras
|
|
414
471
|
|
415
472
|
f = Field.new
|
416
473
|
f.fkey = key
|
474
|
+
f.vclass = value.class.to_s
|
417
475
|
f.value = value
|
418
476
|
f
|
419
477
|
end
|
420
478
|
|
421
479
|
def value= (v)
|
422
480
|
|
423
|
-
|
481
|
+
limit = connection.native_database_types[:string][:limit]
|
482
|
+
|
483
|
+
if v.is_a?(String) and v.length <= limit
|
424
484
|
self.svalue = v
|
425
485
|
else
|
426
486
|
self.yvalue = v
|
@@ -429,9 +489,72 @@ module Extras
|
|
429
489
|
|
430
490
|
def value
|
431
491
|
|
432
|
-
|
433
|
-
|
492
|
+
self.svalue || self.yvalue
|
493
|
+
end
|
494
|
+
|
495
|
+
#
|
496
|
+
# Will return all the fields that contain the given text.
|
497
|
+
#
|
498
|
+
# Looks in svalue and fkey. Looks as well in yvalue if it contains
|
499
|
+
# a string.
|
500
|
+
#
|
501
|
+
# This method is used by Workitem.search()
|
502
|
+
#
|
503
|
+
def self.search (text, storename_list=nil)
|
504
|
+
|
505
|
+
cs = build_search_conditions(text)
|
506
|
+
|
507
|
+
if storename_list
|
508
|
+
|
509
|
+
cs[0] = "(#{cs[0]}) AND workitems.store_name IN (?)"
|
510
|
+
cs << storename_list
|
511
|
+
end
|
512
|
+
|
513
|
+
find :all, :conditions => cs, :include => :workitem
|
434
514
|
end
|
515
|
+
|
516
|
+
protected
|
517
|
+
|
518
|
+
#
|
519
|
+
# The search operates on the content of these columns
|
520
|
+
#
|
521
|
+
FIELDS_TO_SEARCH = %w{ svalue fkey yvalue }
|
522
|
+
|
523
|
+
#
|
524
|
+
# Builds the condition array for a pseudo text search
|
525
|
+
#
|
526
|
+
def self.build_search_conditions (text)
|
527
|
+
|
528
|
+
has_percent = (text.index("%") != nil)
|
529
|
+
|
530
|
+
conds = []
|
531
|
+
|
532
|
+
conds << FIELDS_TO_SEARCH.collect { |key|
|
533
|
+
|
534
|
+
count = has_percent ? 1 : 4
|
535
|
+
|
536
|
+
s = ([ "#{key} LIKE ?" ] * count).join(" OR ")
|
537
|
+
|
538
|
+
s = "(vclass = ? AND (#{s}))" if key == 'yvalue'
|
539
|
+
|
540
|
+
s
|
541
|
+
}.join(" OR ")
|
542
|
+
|
543
|
+
FIELDS_TO_SEARCH.each do |key|
|
544
|
+
|
545
|
+
conds << 'String' if key == 'yvalue'
|
546
|
+
|
547
|
+
conds << text
|
548
|
+
|
549
|
+
unless has_percent
|
550
|
+
conds << "% #{text} %"
|
551
|
+
conds << "% #{text}"
|
552
|
+
conds << "#{text} %"
|
553
|
+
end
|
554
|
+
end
|
555
|
+
|
556
|
+
conds
|
557
|
+
end
|
435
558
|
end
|
436
559
|
|
437
560
|
|
@@ -469,16 +592,46 @@ module Extras
|
|
469
592
|
# # ...
|
470
593
|
# end
|
471
594
|
#
|
595
|
+
# == Compact workitems
|
596
|
+
#
|
597
|
+
# It is possible to save all the workitem data into a single table,
|
598
|
+
# the workitems table, without
|
599
|
+
# splitting info between workitems and fields tables.
|
600
|
+
#
|
601
|
+
# You can configure the "compact_workitems" behavior by adding to the
|
602
|
+
# previous lines:
|
603
|
+
#
|
604
|
+
# active0 = engine.register_participant(
|
605
|
+
# :active0, OpenWFE::Extras::ActiveParticipant)
|
606
|
+
#
|
607
|
+
# active0.compact_workitems = true
|
608
|
+
#
|
609
|
+
# This behaviour is determined participant per participant, it's ok to
|
610
|
+
# have a participant instance that compacts will there is another that
|
611
|
+
# doesn't compact.
|
612
|
+
#
|
472
613
|
class ActiveParticipant
|
473
614
|
include OpenWFE::LocalParticipant
|
474
615
|
|
616
|
+
#
|
617
|
+
# when compact_workitems is set to true, the attributes of a workitem
|
618
|
+
# are stored in the yattributes column (they are not expanded into
|
619
|
+
# the Fields table).
|
620
|
+
# By default, workitem attributes are expanded.
|
621
|
+
#
|
622
|
+
attr :compact_workitems, true
|
623
|
+
|
475
624
|
#
|
476
625
|
# This is the method called by the OpenWFEru engine to hand a
|
477
626
|
# workitem to this participant.
|
478
627
|
#
|
479
628
|
def consume (workitem)
|
480
629
|
|
481
|
-
|
630
|
+
if compact_workitems
|
631
|
+
workitem.attributes["compact_workitems"] = true
|
632
|
+
end
|
633
|
+
|
634
|
+
Workitem.from_owfe_workitem workitem
|
482
635
|
end
|
483
636
|
|
484
637
|
#
|
@@ -533,6 +686,10 @@ module Extras
|
|
533
686
|
#
|
534
687
|
def consume (workitem)
|
535
688
|
|
689
|
+
if compact_workitems
|
690
|
+
workitem.attributes["compact_workitems"] = true
|
691
|
+
end
|
692
|
+
|
536
693
|
Workitem.from_owfe_workitem(workitem, @store_name)
|
537
694
|
end
|
538
695
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
#--
|
3
|
-
# Copyright (c) 2007, John Mettraux, OpenWFE.org
|
3
|
+
# Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
|
4
4
|
# All rights reserved.
|
5
5
|
#
|
6
6
|
# Redistribution and use in source and binary forms, with or without
|
@@ -47,23 +47,8 @@
|
|
47
47
|
|
48
48
|
require 'monitor'
|
49
49
|
|
50
|
-
require 'rubygems'
|
51
|
-
|
52
|
-
begin
|
53
|
-
require 'atom/collection'
|
54
|
-
rescue LoadError
|
55
|
-
#
|
56
|
-
# soft dependency on 'atom-tools'
|
57
|
-
#
|
58
|
-
puts
|
59
|
-
puts
|
60
|
-
puts "'atom/collection' is missing. You can install with :"
|
61
|
-
puts
|
62
|
-
puts " [sudo] gem install atom-tools"
|
63
|
-
puts
|
64
|
-
puts
|
65
|
-
exit 1
|
66
|
-
end
|
50
|
+
#require 'rubygems'
|
51
|
+
require 'atom/collection' # gem 'atom-tools'
|
67
52
|
|
68
53
|
require 'openwfe/participants/participant'
|
69
54
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#
|
2
2
|
#--
|
3
|
-
# Copyright (c) 2007, John Mettraux, OpenWFE.org
|
3
|
+
# Copyright (c) 2007-2008, John Mettraux, OpenWFE.org
|
4
4
|
# All rights reserved.
|
5
5
|
#
|
6
6
|
# Redistribution and use in source and binary forms, with or without
|
@@ -50,27 +50,9 @@ require 'rexml/document'
|
|
50
50
|
|
51
51
|
require 'openwfe/participants/participants'
|
52
52
|
|
53
|
-
require 'rubygems'
|
54
|
-
|
55
|
-
|
56
|
-
require 'atom/entry'
|
57
|
-
require 'atom/collection'
|
58
|
-
rescue LoadError
|
59
|
-
#
|
60
|
-
# soft dependency on 'atom-tools'
|
61
|
-
#
|
62
|
-
puts
|
63
|
-
puts
|
64
|
-
puts "'atom/collection' is missing. You can install with :"
|
65
|
-
puts
|
66
|
-
puts " [sudo] gem install atom-tools"
|
67
|
-
puts
|
68
|
-
puts
|
69
|
-
exit 1
|
70
|
-
end
|
71
|
-
|
72
|
-
require 'openwfe/participants/participant'
|
73
|
-
require 'openwfe/participants/participants'
|
53
|
+
#require 'rubygems'
|
54
|
+
require 'atom/entry' # gem 'atom-tools'
|
55
|
+
require 'atom/collection'
|
74
56
|
|
75
57
|
|
76
58
|
module OpenWFE::Extras
|