openwferu-extras 0.9.15 → 0.9.16
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/openwfe/extras/engine/db_persisted_engine.rb +100 -0
- data/lib/openwfe/extras/expool/dberrorjournal.rb +190 -0
- data/lib/openwfe/extras/expool/dbexpstorage.rb +267 -0
- data/lib/openwfe/extras/listeners/sqslisteners.rb +1 -3
- data/lib/openwfe/extras/misc/activityfeed.rb +275 -0
- data/lib/openwfe/extras/participants/activeparticipants.rb +87 -2
- data/lib/openwfe/extras/participants/{atomparticipants.rb → atomfeed_participants.rb} +20 -29
- data/lib/openwfe/extras/participants/atompub_participants.rb +286 -0
- data/lib/openwfe/extras/participants/csvparticipants.rb +5 -9
- data/lib/openwfe/extras/util/csvtable.rb +147 -14
- metadata +13 -5
@@ -0,0 +1,286 @@
|
|
1
|
+
#
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2007, John Mettraux, OpenWFE.org
|
4
|
+
# All rights reserved.
|
5
|
+
#
|
6
|
+
# Redistribution and use in source and binary forms, with or without
|
7
|
+
# modification, are permitted provided that the following conditions are met:
|
8
|
+
#
|
9
|
+
# . Redistributions of source code must retain the above copyright notice, this
|
10
|
+
# list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# . Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
# this list of conditions and the following disclaimer in the documentation
|
14
|
+
# and/or other materials provided with the distribution.
|
15
|
+
#
|
16
|
+
# . Neither the name of the "OpenWFE" nor the names of its contributors may be
|
17
|
+
# used to endorse or promote products derived from this software without
|
18
|
+
# specific prior written permission.
|
19
|
+
#
|
20
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
23
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
24
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
25
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
26
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
28
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
29
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
30
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
#++
|
32
|
+
#
|
33
|
+
|
34
|
+
#
|
35
|
+
# "made in Japan"
|
36
|
+
#
|
37
|
+
# John Mettraux at openwfe.org
|
38
|
+
#
|
39
|
+
|
40
|
+
#
|
41
|
+
# this participant requires atom-tools from
|
42
|
+
#
|
43
|
+
# http://code.necronomicorp.com/trac/atom-tools
|
44
|
+
#
|
45
|
+
# atom-tools' license is X11/MIT
|
46
|
+
#
|
47
|
+
|
48
|
+
require 'yaml'
|
49
|
+
require 'rexml/document'
|
50
|
+
|
51
|
+
require 'openwfe/participants/participants'
|
52
|
+
|
53
|
+
require 'rubygems'
|
54
|
+
|
55
|
+
begin
|
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'
|
74
|
+
|
75
|
+
|
76
|
+
module OpenWFE::Extras
|
77
|
+
|
78
|
+
#
|
79
|
+
# This participants posts (as in HTTP POST) a workitem
|
80
|
+
# to an AtomPub enabled resource.
|
81
|
+
#
|
82
|
+
# target_uri = "https://openwferu.wordpress.com/wp-app.php/posts"
|
83
|
+
#
|
84
|
+
# params = {}
|
85
|
+
# params[:username] = 'jmettraux'
|
86
|
+
# params[:password] = ENV['WORDPRESS_PASSWORD']
|
87
|
+
# params[:categories] = 'openwferu, test'
|
88
|
+
#
|
89
|
+
# engine.register_participant(
|
90
|
+
# "app", OpenWFE::Extras::AtomPubParticipant.new target_uri, params)
|
91
|
+
#
|
92
|
+
# This base implementation dumps workitem as YAML in the entry content.
|
93
|
+
#
|
94
|
+
# See BlogParticipant for a human-oriented blog posting participant.
|
95
|
+
#
|
96
|
+
class AtomPubParticipant
|
97
|
+
include OpenWFE::LocalParticipant
|
98
|
+
|
99
|
+
#
|
100
|
+
# The URI to post to
|
101
|
+
#
|
102
|
+
attr_accessor :target_uri
|
103
|
+
|
104
|
+
attr_accessor :author_name, :author_uri
|
105
|
+
|
106
|
+
|
107
|
+
def initialize (target_uri, params)
|
108
|
+
|
109
|
+
@target_uri = target_uri
|
110
|
+
|
111
|
+
@username = params[:username]
|
112
|
+
@password = params[:password]
|
113
|
+
|
114
|
+
@author_name = \
|
115
|
+
params[:author_name] || self.class.name
|
116
|
+
@author_uri = \
|
117
|
+
params[:author_uri] || "http://openwferu.rubyforge.org"
|
118
|
+
|
119
|
+
|
120
|
+
@categories = params[:categories] || []
|
121
|
+
@categories = @categories.split(",") if @categories.is_a?(String)
|
122
|
+
@categories = Array(@categories)
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# The incoming workitem will generate an atom entry that will
|
127
|
+
# get posted to the target URI.
|
128
|
+
#
|
129
|
+
# This consume() method returns the URI (as a String) where the
|
130
|
+
# just uploaded post can be edited.
|
131
|
+
#
|
132
|
+
def consume (workitem)
|
133
|
+
|
134
|
+
entry = Atom::Entry.new
|
135
|
+
entry.updated! # set updated time to now
|
136
|
+
|
137
|
+
render_author entry, workitem
|
138
|
+
render_categories entry, workitem
|
139
|
+
render_content entry, workitem
|
140
|
+
|
141
|
+
h = Atom::HTTP.new
|
142
|
+
h.user = @username
|
143
|
+
h.pass = @password
|
144
|
+
h.always_auth = :basic
|
145
|
+
|
146
|
+
res = Atom::Collection.new(@target_uri, h).post!(entry)
|
147
|
+
|
148
|
+
# initial implementation
|
149
|
+
# don't catch an error, let the process fail
|
150
|
+
|
151
|
+
#res.read_body
|
152
|
+
extract_new_link res
|
153
|
+
end
|
154
|
+
|
155
|
+
protected
|
156
|
+
|
157
|
+
#
|
158
|
+
# This base implementation simply uses a YAML dump of the workitem
|
159
|
+
# as the post content (with a content type of 'html').
|
160
|
+
#
|
161
|
+
def render_content (entry, workitem)
|
162
|
+
|
163
|
+
entry.title = \
|
164
|
+
workitem.participant_name + " " +
|
165
|
+
workitem.fei.expression_id + " " +
|
166
|
+
workitem.fei.workflow_instance_id
|
167
|
+
|
168
|
+
entry.content = workitem.to_yaml
|
169
|
+
entry.content["type"] = "html"
|
170
|
+
end
|
171
|
+
|
172
|
+
#
|
173
|
+
# This default implementation simply builds a single author
|
174
|
+
# out of the :author_name, :author_uri passed as initialization
|
175
|
+
# params.
|
176
|
+
#
|
177
|
+
def render_author (entry, workitem)
|
178
|
+
|
179
|
+
author = Atom::Author.new
|
180
|
+
author.name = author_name
|
181
|
+
author.uri = author_uri
|
182
|
+
|
183
|
+
entry.authors << author
|
184
|
+
end
|
185
|
+
|
186
|
+
#
|
187
|
+
# This base implementations simply adds the categories listed
|
188
|
+
# in the :categories initialization parameter.
|
189
|
+
# The target_uri is used as the scheme for the categories.
|
190
|
+
#
|
191
|
+
# You can override this method to add extra categories or to
|
192
|
+
# have completely different categories.
|
193
|
+
#
|
194
|
+
def render_categories (entry, workitem)
|
195
|
+
|
196
|
+
@categories.each do |s|
|
197
|
+
|
198
|
+
c = Atom::Category.new
|
199
|
+
|
200
|
+
c["scheme"] = @target_uri
|
201
|
+
c["term"] = s.strip
|
202
|
+
|
203
|
+
entry.categories << c
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
#
|
208
|
+
# Extracts the link of the newly created resource (newly posted blog
|
209
|
+
# entry), and returns it as a String.
|
210
|
+
#
|
211
|
+
def extract_new_link (response)
|
212
|
+
|
213
|
+
doc = REXML::Document.new response.read_body
|
214
|
+
|
215
|
+
#REXML::XPath.first(doc.root, "//link[@rel='edit']")
|
216
|
+
#
|
217
|
+
# doesn't work :(
|
218
|
+
|
219
|
+
REXML::XPath.first(doc.root, "//link[2]").attribute('href')
|
220
|
+
#
|
221
|
+
# will break if the order changes :(
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
#
|
226
|
+
# A participant that blogs.
|
227
|
+
#
|
228
|
+
# require 'openwfe/extras/participants/atompub_participants'
|
229
|
+
# include OpenWFE::Extras
|
230
|
+
#
|
231
|
+
# target_uri = "https://openwferu.wordpress.com/wp-app.php/posts"
|
232
|
+
#
|
233
|
+
# params = {}
|
234
|
+
# params[:username] = 'jeff'
|
235
|
+
# params[:password] = 'whatever'
|
236
|
+
#
|
237
|
+
# params[:categories] = 'openwferu, test'
|
238
|
+
#
|
239
|
+
# #params[:title_field] = "title"
|
240
|
+
# #
|
241
|
+
# # which workitem field will hold the post title ?
|
242
|
+
# # by default, it's "title"
|
243
|
+
#
|
244
|
+
# engine.register_participant "blogger", BlogParticipant.new(target_uri, params) do
|
245
|
+
# """
|
246
|
+
# paragraph 0
|
247
|
+
#
|
248
|
+
# paragraph 1 : ${f:message}
|
249
|
+
#
|
250
|
+
# paragraph 2
|
251
|
+
# """
|
252
|
+
# end
|
253
|
+
#
|
254
|
+
# This participant takes its template and the workitem it receives to
|
255
|
+
# publish a blog entry.
|
256
|
+
#
|
257
|
+
# The template can be specified as a block (as in the previous example)
|
258
|
+
# or via the :template parameter.
|
259
|
+
#
|
260
|
+
class BlogParticipant < AtomPubParticipant
|
261
|
+
include OpenWFE::TemplateMixin
|
262
|
+
|
263
|
+
def initialize (target_uri, params, &block)
|
264
|
+
|
265
|
+
super
|
266
|
+
|
267
|
+
@template = params[:template]
|
268
|
+
@block_template = block
|
269
|
+
|
270
|
+
@content_type = params[:content_type] || "html"
|
271
|
+
|
272
|
+
@title_field = params[:title_field] || "title"
|
273
|
+
end
|
274
|
+
|
275
|
+
protected
|
276
|
+
|
277
|
+
def render_content (entry, workitem)
|
278
|
+
|
279
|
+
entry.title = workitem.attributes[@title_field].to_s
|
280
|
+
|
281
|
+
entry.content = eval_template workitem
|
282
|
+
entry.content["type"] = @content_type
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
@@ -59,15 +59,11 @@ module Extras
|
|
59
59
|
# An example :
|
60
60
|
#
|
61
61
|
# class TestDefinition0 < ProcessDefinition
|
62
|
-
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
# decision
|
68
|
-
# _print "${f:take_umbrella?}"
|
69
|
-
# end
|
70
|
-
# end
|
62
|
+
# sequence do
|
63
|
+
# set :field => "weather", :value => "cloudy"
|
64
|
+
# set :field => "month", :value => "may"
|
65
|
+
# decision
|
66
|
+
# _print "${f:take_umbrella?}"
|
71
67
|
# end
|
72
68
|
# end
|
73
69
|
#
|
@@ -50,6 +50,63 @@ include OpenWFE
|
|
50
50
|
module OpenWFE
|
51
51
|
module Extras
|
52
52
|
|
53
|
+
#
|
54
|
+
# A regexp for checking if a string is a numeric Ruby range
|
55
|
+
#
|
56
|
+
RUBY_NUMERIC_RANGE_REGEXP = Regexp.compile(
|
57
|
+
"^\\d+(\\.\\d+)?\\.{2,3}\\d+(\\.\\d+)?$")
|
58
|
+
|
59
|
+
#
|
60
|
+
# A regexp for checking if a string is an alpha Ruby range
|
61
|
+
#
|
62
|
+
RUBY_ALPHA_RANGE_REGEXP = Regexp.compile(
|
63
|
+
"^([A-Za-z])(\\.{2,3})([A-Za-z])$")
|
64
|
+
|
65
|
+
#
|
66
|
+
# If the string contains a Ruby range definition
|
67
|
+
# (ie something like "93.0..94.5" or "56..72"), it will return
|
68
|
+
# the Range instance.
|
69
|
+
# Will return nil else.
|
70
|
+
#
|
71
|
+
# The Ruby range returned (if any) will accept String or Numeric,
|
72
|
+
# ie (4..6).include?("5") will yield true.
|
73
|
+
#
|
74
|
+
def to_ruby_range (s)
|
75
|
+
|
76
|
+
range = if RUBY_NUMERIC_RANGE_REGEXP.match(s)
|
77
|
+
|
78
|
+
eval s
|
79
|
+
else
|
80
|
+
|
81
|
+
m = RUBY_ALPHA_RANGE_REGEXP.match(s)
|
82
|
+
|
83
|
+
if m
|
84
|
+
eval "'#{m[1]}'#{m[2]}'#{m[3]}'"
|
85
|
+
else
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class << range
|
91
|
+
|
92
|
+
alias :old_include? :include?
|
93
|
+
|
94
|
+
def include? (elt)
|
95
|
+
|
96
|
+
elt = if first.is_a?(Numeric)
|
97
|
+
Float(elt)
|
98
|
+
else
|
99
|
+
elt
|
100
|
+
end
|
101
|
+
|
102
|
+
old_include?(elt)
|
103
|
+
end
|
104
|
+
|
105
|
+
end if range
|
106
|
+
|
107
|
+
range
|
108
|
+
end
|
109
|
+
|
53
110
|
#
|
54
111
|
# A 'CsvTable' is called a 'decision table' in OpenWFEja (the initial
|
55
112
|
# Java implementation of OpenWFE).
|
@@ -128,6 +185,15 @@ module Extras
|
|
128
185
|
# Such comparisons are done after the elements are transformed to float
|
129
186
|
# numbers. By default, non-numeric arguments will get compared as Strings.
|
130
187
|
#
|
188
|
+
# Ruby ranges are also accepted in cells.
|
189
|
+
#
|
190
|
+
# in:f0,out:result
|
191
|
+
# ,
|
192
|
+
# 0..32,low
|
193
|
+
# 33..66,medium
|
194
|
+
# 67..100,high
|
195
|
+
#
|
196
|
+
# will set the field 'result' to 'low' for f0 => 24
|
131
197
|
#
|
132
198
|
# Disclaimer : the decision / CSV table system is no replacement for
|
133
199
|
# full rule engines with forward and backward chaining, RETE implementation
|
@@ -141,21 +207,32 @@ module Extras
|
|
141
207
|
#
|
142
208
|
# Currently, two options are supported, "ignorecase" and "through".
|
143
209
|
#
|
144
|
-
# "ignorecase", if found by the CsvTable will make any match (in the "in"
|
145
|
-
#
|
210
|
+
# * "ignorecase", if found by the CsvTable will make any match (in the "in"
|
211
|
+
# columns) case unsensitive.
|
212
|
+
#
|
213
|
+
# * "through", will make sure that EVERY row is evaluated and potentially
|
214
|
+
# applied. The default behaviour (without "through"), is to stop the
|
215
|
+
# evaluation after applying the results of the first matching row.
|
216
|
+
#
|
217
|
+
# * "accumulate", behaves as with "through" set but instead of overriding
|
218
|
+
# values each time a match is found, will gather them in an array.
|
146
219
|
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
220
|
+
# accumulate
|
221
|
+
# in:f0,out:result
|
222
|
+
# ,
|
223
|
+
# ,normal
|
224
|
+
# >10,large
|
225
|
+
# >100,xl
|
150
226
|
#
|
227
|
+
# will yield { result => [ 'normal', 'large' ]} for f0 => 56
|
151
228
|
#
|
152
229
|
# CSV Tables are available to workflows as CsvParticipant.
|
153
230
|
#
|
154
231
|
#
|
155
232
|
# See also :
|
156
233
|
#
|
157
|
-
# http://jmettraux.wordpress.com/2007/02/11/ruby-decision-tables/
|
158
|
-
# http://rubyforge.org/viewvc/trunk/openwfe-ruby/test/extras/csv_test.rb?root=openwferu&view=co
|
234
|
+
# * http://jmettraux.wordpress.com/2007/02/11/ruby-decision-tables/
|
235
|
+
# * http://rubyforge.org/viewvc/trunk/openwfe-ruby/test/extras/csv_test.rb?root=openwferu&view=co
|
159
236
|
#
|
160
237
|
class CsvTable
|
161
238
|
|
@@ -163,7 +240,8 @@ module Extras
|
|
163
240
|
:first_match,
|
164
241
|
:ignore_case,
|
165
242
|
:header,
|
166
|
-
:rows
|
243
|
+
:rows,
|
244
|
+
:accumulate
|
167
245
|
|
168
246
|
#
|
169
247
|
# The constructor for CsvTable, you can pass a String, an Array
|
@@ -174,6 +252,7 @@ module Extras
|
|
174
252
|
|
175
253
|
@first_match = true
|
176
254
|
@ignore_case = false
|
255
|
+
@accumulate = false
|
177
256
|
|
178
257
|
@header = nil
|
179
258
|
@rows = []
|
@@ -201,7 +280,7 @@ module Extras
|
|
201
280
|
@rows.each do |row|
|
202
281
|
|
203
282
|
if matches?(row, flow_expression, workitem)
|
204
|
-
apply
|
283
|
+
apply row, flow_expression, workitem
|
205
284
|
break if @first_match
|
206
285
|
end
|
207
286
|
end
|
@@ -253,7 +332,7 @@ module Extras
|
|
253
332
|
|
254
333
|
def matches? (row, fexp, wi)
|
255
334
|
|
256
|
-
return false if empty_row?
|
335
|
+
return false if empty_row?(row)
|
257
336
|
|
258
337
|
#puts
|
259
338
|
#puts "__row match ?"
|
@@ -279,9 +358,16 @@ module Extras
|
|
279
358
|
#puts "__does '#{value}' match '#{cell}' ?"
|
280
359
|
|
281
360
|
b = if cell[0, 1] == '<' or cell[0, 1] == '>'
|
282
|
-
|
361
|
+
|
362
|
+
numeric_compare value, cell
|
283
363
|
else
|
284
|
-
|
364
|
+
|
365
|
+
range = to_ruby_range cell
|
366
|
+
if range
|
367
|
+
range.include?(value)
|
368
|
+
else
|
369
|
+
regex_compare value, cell
|
370
|
+
end
|
285
371
|
end
|
286
372
|
|
287
373
|
return false unless b
|
@@ -326,16 +412,17 @@ module Extras
|
|
326
412
|
begin
|
327
413
|
return OpenWFE::eval_safely(s, 4)
|
328
414
|
rescue Exception => e
|
329
|
-
return false
|
330
415
|
end
|
416
|
+
|
417
|
+
false
|
331
418
|
end
|
332
419
|
|
333
420
|
def narrow (s)
|
334
421
|
begin
|
335
422
|
return Float(s)
|
336
423
|
rescue Exception => e
|
337
|
-
return s
|
338
424
|
end
|
425
|
+
s
|
339
426
|
end
|
340
427
|
|
341
428
|
def resolve_in_header (in_header)
|
@@ -362,6 +449,7 @@ module Extras
|
|
362
449
|
|
363
450
|
value = OpenWFE::dosub(value, fexp, wi)
|
364
451
|
|
452
|
+
#puts "___ value.class:#{value.class}"
|
365
453
|
#puts "___ value:'#{value}'"
|
366
454
|
#puts "___ value:'"+value+"'"
|
367
455
|
|
@@ -369,6 +457,9 @@ module Extras
|
|
369
457
|
|
370
458
|
#puts "___ t:'#{type}' target:'#{target}'"
|
371
459
|
|
460
|
+
value = accumulate_values(type, target, value, wi, fexp) \
|
461
|
+
if @accumulate
|
462
|
+
|
372
463
|
if type == "v"
|
373
464
|
fexp.set_variable(target, value) if fexp
|
374
465
|
elsif type == "f"
|
@@ -379,6 +470,42 @@ module Extras
|
|
379
470
|
end
|
380
471
|
end
|
381
472
|
|
473
|
+
#
|
474
|
+
# 'accumulate' is on, this method got called to compute the
|
475
|
+
# new value.
|
476
|
+
#
|
477
|
+
# If it finds nothing in the target field, the new value is
|
478
|
+
# value.
|
479
|
+
# If there is already a value and its an array, the new value
|
480
|
+
# will be current_array + value.
|
481
|
+
# Else the two values (current and new) are combined into an array.
|
482
|
+
#
|
483
|
+
# Sorry, if you want f([ x ], y) -> [[ x ], y]... It's not
|
484
|
+
# implemented like that.
|
485
|
+
#
|
486
|
+
def accumulate_values (type, target, value, workitem, fexp)
|
487
|
+
|
488
|
+
current_value = case type
|
489
|
+
when 'v'
|
490
|
+
if fexp
|
491
|
+
fexp.lookup_variable target
|
492
|
+
else
|
493
|
+
nil
|
494
|
+
end
|
495
|
+
when 'f'
|
496
|
+
workitem.lookup_attribute target
|
497
|
+
when 'r'
|
498
|
+
nil
|
499
|
+
end
|
500
|
+
|
501
|
+
return value unless current_value
|
502
|
+
|
503
|
+
return current_value + Array(value) \
|
504
|
+
if current_value.is_a?(Array)
|
505
|
+
|
506
|
+
[ current_value, value ]
|
507
|
+
end
|
508
|
+
|
382
509
|
def parse_header_row (row)
|
383
510
|
|
384
511
|
row.each_with_index do |cell, icol|
|
@@ -398,6 +525,12 @@ module Extras
|
|
398
525
|
next
|
399
526
|
end
|
400
527
|
|
528
|
+
if s == "accumulate"
|
529
|
+
@first_match = false
|
530
|
+
@accumulate = true
|
531
|
+
next
|
532
|
+
end
|
533
|
+
|
401
534
|
if OpenWFE::starts_with(cell, "in:") or OpenWFE::starts_with(cell, "out:")
|
402
535
|
@header = Header.new unless @header
|
403
536
|
@header.add cell, icol
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: openwferu-extras
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.9.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.9.16
|
7
|
+
date: 2007-11-19 00:00:00 +09:00
|
8
8
|
summary: OpenWFEru extras (sqs, csv, ...)
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,15 +29,23 @@ post_install_message:
|
|
29
29
|
authors:
|
30
30
|
- John Mettraux
|
31
31
|
files:
|
32
|
+
- lib/openwfe/extras/engine
|
33
|
+
- lib/openwfe/extras/engine/db_persisted_engine.rb
|
34
|
+
- lib/openwfe/extras/expool
|
35
|
+
- lib/openwfe/extras/expool/dberrorjournal.rb
|
36
|
+
- lib/openwfe/extras/expool/dbexpstorage.rb
|
32
37
|
- lib/openwfe/extras/listeners
|
33
|
-
- lib/openwfe/extras/participants
|
34
|
-
- lib/openwfe/extras/util
|
35
38
|
- lib/openwfe/extras/listeners/sqslisteners.rb
|
39
|
+
- lib/openwfe/extras/misc
|
40
|
+
- lib/openwfe/extras/misc/activityfeed.rb
|
41
|
+
- lib/openwfe/extras/participants
|
36
42
|
- lib/openwfe/extras/participants/activeparticipants.rb
|
37
|
-
- lib/openwfe/extras/participants/
|
43
|
+
- lib/openwfe/extras/participants/atomfeed_participants.rb
|
44
|
+
- lib/openwfe/extras/participants/atompub_participants.rb
|
38
45
|
- lib/openwfe/extras/participants/csvparticipants.rb
|
39
46
|
- lib/openwfe/extras/participants/sqsparticipants.rb
|
40
47
|
- lib/openwfe/extras/participants/twitterparticipants.rb
|
48
|
+
- lib/openwfe/extras/util
|
41
49
|
- lib/openwfe/extras/util/csvtable.rb
|
42
50
|
- lib/openwfe/extras/util/sqs.rb
|
43
51
|
test_files: []
|