pione 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +1 -0
- data/History.txt +7 -0
- data/example/DeferredChoice/DeferredChoice.pione +14 -7
- data/{misc → example/DeferredChoice/bin}/ui.xml +11 -6
- data/example/DeferredChoice/pione-package.json +1 -1
- data/example/DeferredChoiceWithPage/DeferredChoiceWithPage.pione +47 -0
- data/example/DeferredChoiceWithPage/etc/index.html +22 -0
- data/example/DeferredChoiceWithPage/pione-package.json +18 -0
- data/example/Interaction/Interaction.pione +27 -0
- data/example/Interaction/bin/show-environment.cgi +45 -0
- data/example/Interaction/etc/.hidden-file.txt +1 -0
- data/example/Interaction/etc/cgi.html +46 -0
- data/example/Interaction/etc/create-files.html +51 -0
- data/example/Interaction/etc/delete-files.html +31 -0
- data/example/Interaction/etc/get-files.html +21 -0
- data/example/Interaction/etc/index.html +18 -0
- data/example/Interaction/etc/list-files.html +36 -0
- data/example/Interaction/pione-package.json +24 -0
- data/lib/pione/agent/job-manager.rb +19 -3
- data/lib/pione/agent/logger.rb +9 -9
- data/lib/pione/agent/messenger.rb +3 -2
- data/lib/pione/agent/task-worker.rb +32 -10
- data/lib/pione/command/option.rb +18 -0
- data/lib/pione/command/pione-client.rb +51 -22
- data/lib/pione/command/pione-interactive.rb +128 -55
- data/lib/pione/command/pione-package-build.rb +3 -3
- data/lib/pione/command/pione-task-worker.rb +23 -10
- data/lib/pione/command/pione-tuple-space-provider.rb +8 -8
- data/lib/pione/command/spawner.rb +28 -1
- data/lib/pione/front/interactive-front.rb +76 -0
- data/lib/pione/global/interactive-variable.rb +26 -0
- data/lib/pione/log/message-log-receiver.rb +4 -2
- data/lib/pione/model/task-worker-broker-model.rb +7 -1
- data/lib/pione/package/package-archiver.rb +16 -9
- data/lib/pione/package/package-handler.rb +6 -0
- data/lib/pione/package/package-info.rb +4 -0
- data/lib/pione/package/package-reader.rb +2 -4
- data/lib/pione/package/package-scanner.rb +23 -3
- data/lib/pione/rule-engine.rb +48 -19
- data/lib/pione/rule-engine/action-handler.rb +29 -5
- data/lib/pione/rule-engine/basic-handler.rb +27 -19
- data/lib/pione/test-helper/command-helper.rb +1 -1
- data/lib/pione/tuple-space/tuple-definition.yml +2 -3
- data/lib/pione/tuple-space/tuple-space-server.rb +8 -0
- data/lib/pione/util/cgi.rb +326 -0
- data/lib/pione/version.rb +1 -1
- data/lib/rootage/normalizer.rb +4 -0
- data/lib/rootage/option.rb +11 -4
- data/test/agent/spec_logger.rb +0 -1
- data/test/agent/spec_messenger.rb +1 -1
- data/test/command/spec_pione-client.rb +4 -4
- data/test/log/spec_message-log.rb +1 -1
- data/test/rule-engine/spec_action-handler.rb +25 -5
- data/test/rule-engine/spec_empty-handler.rb +36 -3
- data/test/rule-engine/spec_flow-handler.rb +90 -7
- metadata +22 -72
- data/misc/test-drb-stop-service.rb +0 -34
- data/misc/test-many-waiters-client.rb +0 -56
- data/misc/test-many-waiters-server.rb +0 -14
@@ -0,0 +1,36 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>Interaction Example: List files</title>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<h1>POST Method Example</h1>
|
9
|
+
|
10
|
+
<section>
|
11
|
+
<h2>List with no options</h2>
|
12
|
+
<form action="./" method="POST">
|
13
|
+
<input type="hidden" name="pione-action" value="list" />
|
14
|
+
<button type="submit">List files</button>
|
15
|
+
</form>
|
16
|
+
</section>
|
17
|
+
|
18
|
+
<section>
|
19
|
+
<h2>List with pione-show-all=true</h2>
|
20
|
+
<form action="./" method="POST">
|
21
|
+
<input type="hidden" name="pione-action" value="list" />
|
22
|
+
<input type="hidden" name="pione-show-all" value="true" />
|
23
|
+
<button type="submit">List files</button>
|
24
|
+
</form>
|
25
|
+
</section>
|
26
|
+
|
27
|
+
<section>
|
28
|
+
<h2>List with pione-show-all=false</h2>
|
29
|
+
<form action="./" method="POST">
|
30
|
+
<input type="hidden" name="pione-action" value="list" />
|
31
|
+
<input type="hidden" name="pione-show-all" value="false" />
|
32
|
+
<button type="submit">List files</button>
|
33
|
+
</form>
|
34
|
+
</section>
|
35
|
+
</body>
|
36
|
+
</html>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"PackageName": "Interaction",
|
3
|
+
"Parents": [
|
4
|
+
|
5
|
+
],
|
6
|
+
"Documents": [
|
7
|
+
"Interaction.pione"
|
8
|
+
],
|
9
|
+
"Scenarios": [
|
10
|
+
|
11
|
+
],
|
12
|
+
"Bins": [
|
13
|
+
"bin/show-environment.cgi"
|
14
|
+
],
|
15
|
+
"Etcs": [
|
16
|
+
"etc/create-files.html",
|
17
|
+
"etc/list-files.html",
|
18
|
+
"etc/get-files.html",
|
19
|
+
"etc/index.html",
|
20
|
+
"etc/delete-files.html",
|
21
|
+
"etc/cgi.html",
|
22
|
+
"etc/.hidden-file.txt"
|
23
|
+
]
|
24
|
+
}
|
@@ -54,6 +54,11 @@ module Pione
|
|
54
54
|
|
55
55
|
# share my environment
|
56
56
|
write(TupleSpace::EnvTuple.new(@env.dumpable)) # need to be dumpable
|
57
|
+
|
58
|
+
# collect tuple space attributes
|
59
|
+
@request_from = @tuple_space.attribute("request_from")
|
60
|
+
@session_id = @tuple_space.attribute("session_id")
|
61
|
+
@client_ui = @tuple_space.attribute("client_ui")
|
57
62
|
end
|
58
63
|
|
59
64
|
def transit_to_sleep
|
@@ -69,9 +74,20 @@ module Pione
|
|
69
74
|
else
|
70
75
|
# call root rule of the current package
|
71
76
|
list.each do |env, inputs|
|
72
|
-
|
73
|
-
|
74
|
-
|
77
|
+
engine_param = {
|
78
|
+
:tuple_space => @tuple_space,
|
79
|
+
:env => @env,
|
80
|
+
:package_id => @env.current_package_id,
|
81
|
+
:rule_name => "Root",
|
82
|
+
:inputs => inputs,
|
83
|
+
:param_set => Lang::ParameterSet.new,
|
84
|
+
:domain_id => 'root',
|
85
|
+
:caller_id => nil,
|
86
|
+
:request_from => @request_from,
|
87
|
+
:session_id => @session_id,
|
88
|
+
:client_ui => @client_ui
|
89
|
+
}
|
90
|
+
RuleEngine.make(engine_param).handle
|
75
91
|
end
|
76
92
|
end
|
77
93
|
|
data/lib/pione/agent/logger.rb
CHANGED
@@ -5,15 +5,15 @@ module Pione
|
|
5
5
|
class Logger < TupleSpaceClient
|
6
6
|
set_agent_type :logger, self
|
7
7
|
|
8
|
-
attr_reader :log_location
|
9
|
-
attr_reader :
|
8
|
+
attr_reader :log_location # location of log file
|
9
|
+
attr_reader :temporary_location # temporary location
|
10
10
|
|
11
11
|
# Create a logger agent.
|
12
12
|
def initialize(tuple_space, location)
|
13
13
|
super(tuple_space)
|
14
14
|
@log_id = Time.now.iso8601(3)
|
15
15
|
@log_location = location.directory? ? location + "pione-process.log" : location
|
16
|
-
@
|
16
|
+
@temporary_location = get_temporary_location
|
17
17
|
end
|
18
18
|
|
19
19
|
#
|
@@ -40,7 +40,7 @@ module Pione
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
# Copy from
|
43
|
+
# Copy from temporary location to log location.
|
44
44
|
def transit_to_terminate
|
45
45
|
begin
|
46
46
|
write_records(take_all!(TupleSpace::ProcessLogTuple.any))
|
@@ -48,8 +48,8 @@ module Pione
|
|
48
48
|
# logger is terminated at last in termination processes, so tuple space may be closed
|
49
49
|
Log::SystemLog.warn("logger agent failed to take process logs.", self, e)
|
50
50
|
end
|
51
|
-
if @log_location != @
|
52
|
-
@
|
51
|
+
if @log_location != @temporary_location
|
52
|
+
@temporary_location.copy(@log_location)
|
53
53
|
end
|
54
54
|
super
|
55
55
|
end
|
@@ -63,13 +63,13 @@ module Pione
|
|
63
63
|
# Write records with sorting.
|
64
64
|
def write_records(tuples)
|
65
65
|
tuples.sort{|a,b| a.timestamp <=> b.timestamp}.each do |tuple|
|
66
|
-
@
|
66
|
+
@temporary_location.append tuple.message.format(@log_id) + "\n"
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
# Get the
|
70
|
+
# Get the temporary location. If the log location doesn't suport append
|
71
71
|
# writing, output location is in local filesystem.
|
72
|
-
def
|
72
|
+
def get_temporary_location
|
73
73
|
if @log_location.real_appendable?
|
74
74
|
@log_location
|
75
75
|
else
|
@@ -8,11 +8,12 @@ module Pione
|
|
8
8
|
# tuple space
|
9
9
|
# @param receiver [Log::MessageLogReceiver]
|
10
10
|
# message log receiver
|
11
|
-
def initialize(tuple_space, receiver)
|
11
|
+
def initialize(tuple_space, receiver, session_id)
|
12
12
|
super(tuple_space)
|
13
13
|
|
14
14
|
# message log receiver
|
15
15
|
@receiver = receiver
|
16
|
+
@session_id = session_id
|
16
17
|
end
|
17
18
|
|
18
19
|
#
|
@@ -34,7 +35,7 @@ module Pione
|
|
34
35
|
tuples.sort{|a,b| a.timestamp <=> b.timestamp}.each do |tuple|
|
35
36
|
tuple.contents.tap do |contents|
|
36
37
|
(contents.kind_of?(String) ? [contents] : contents).each do |msg|
|
37
|
-
@receiver.receive(msg, tuple.level, tuple.head, tuple.color)
|
38
|
+
@receiver.receive(msg, tuple.level, tuple.head, tuple.color, @session_id)
|
38
39
|
end
|
39
40
|
end
|
40
41
|
end
|
@@ -12,6 +12,17 @@ module Pione
|
|
12
12
|
attr_reader :execution_thread
|
13
13
|
attr_accessor :once # the agent will be killed at task completion if true
|
14
14
|
|
15
|
+
# @param [Pione::TupleSpace::TupleSpaceServer] tuple_space
|
16
|
+
# tuple space
|
17
|
+
# @param [String] features
|
18
|
+
# features that the task worker has
|
19
|
+
# @param [Hash] option
|
20
|
+
# @option option [] :env
|
21
|
+
# a environment object
|
22
|
+
# @option option [String] :session_id
|
23
|
+
# session ID
|
24
|
+
# @option option [URI] :request_from
|
25
|
+
# URI that a client requested from
|
15
26
|
def initialize(tuple_space, features, env=nil)
|
16
27
|
super(tuple_space)
|
17
28
|
@tuple_space = tuple_space
|
@@ -43,6 +54,12 @@ module Pione
|
|
43
54
|
# transitions
|
44
55
|
#
|
45
56
|
|
57
|
+
def transit_to_init
|
58
|
+
@request_from = @tuple_space.attribute("request_from")
|
59
|
+
@session_id = @tuple_space.attribute("session_id")
|
60
|
+
@client_ui = @tuple_space.attribute("client_ui")
|
61
|
+
end
|
62
|
+
|
46
63
|
# Take a task and turn it to foreground.
|
47
64
|
def transit_to_take_task
|
48
65
|
return take(TupleSpace::TaskTuple.new(features: @features))
|
@@ -122,16 +139,21 @@ module Pione
|
|
122
139
|
|
123
140
|
# Make an engine from the task.
|
124
141
|
def make_engine(task)
|
125
|
-
|
126
|
-
@tuple_space,
|
127
|
-
@env,
|
128
|
-
task.package_id,
|
129
|
-
task.rule_name,
|
130
|
-
task.inputs,
|
131
|
-
task.param_set,
|
132
|
-
task.domain_id,
|
133
|
-
task.caller_id
|
134
|
-
|
142
|
+
param = {
|
143
|
+
:tuple_space => @tuple_space,
|
144
|
+
:env => @env,
|
145
|
+
:package_id => task.package_id,
|
146
|
+
:rule_name => task.rule_name,
|
147
|
+
:inputs => task.inputs,
|
148
|
+
:param_set => task.param_set,
|
149
|
+
:domain_id => task.domain_id,
|
150
|
+
:caller_id => task.caller_id,
|
151
|
+
:request_from => @request_from,
|
152
|
+
:session_id => @session_id,
|
153
|
+
:client_ui => @client_ui
|
154
|
+
}
|
155
|
+
|
156
|
+
RuleEngine.make(param)
|
135
157
|
end
|
136
158
|
|
137
159
|
# Spawn child task worker. This method repeats to create a child agent
|
data/lib/pione/command/option.rb
CHANGED
@@ -207,5 +207,23 @@ module Pione
|
|
207
207
|
end
|
208
208
|
end
|
209
209
|
end
|
210
|
+
|
211
|
+
module SessionOption
|
212
|
+
extend Rootage::OptionCollection
|
213
|
+
|
214
|
+
define(:request_from) do |item|
|
215
|
+
item.type = :uri
|
216
|
+
item.long = "--request-from"
|
217
|
+
item.arg = "URI"
|
218
|
+
item.desc = "URI that the client requested the job from"
|
219
|
+
end
|
220
|
+
|
221
|
+
define(:session_id) do |item|
|
222
|
+
item.type = :string
|
223
|
+
item.long = "--session-id"
|
224
|
+
item.arg = "ID"
|
225
|
+
item.desc = "Session id of the job"
|
226
|
+
end
|
227
|
+
end
|
210
228
|
end
|
211
229
|
end
|
@@ -49,6 +49,9 @@ module Pione
|
|
49
49
|
option(NotificationOption.notification_targets)
|
50
50
|
option(NotificationOption.notification_receivers)
|
51
51
|
|
52
|
+
option(SessionOption.request_from)
|
53
|
+
option(SessionOption.session_id)
|
54
|
+
|
52
55
|
option(:input_location) do |item|
|
53
56
|
item.type = :location
|
54
57
|
item.short = '-i'
|
@@ -57,23 +60,23 @@ module Pione
|
|
57
60
|
item.desc = 'Set input directory'
|
58
61
|
end
|
59
62
|
|
60
|
-
option(:
|
63
|
+
option(:base_location) do |item|
|
61
64
|
item.type = :location
|
62
|
-
item.short = '-
|
63
|
-
item.long = '--
|
65
|
+
item.short = '-b'
|
66
|
+
item.long = '--base'
|
64
67
|
item.arg = 'LOCATION'
|
65
|
-
item.desc = 'Set
|
66
|
-
item.init = "local:./
|
68
|
+
item.desc = 'Set process base location'
|
69
|
+
item.init = "local:./process/"
|
67
70
|
|
68
71
|
item.process do |location|
|
69
|
-
model[:
|
72
|
+
model[:base_location] = location
|
70
73
|
if location.scheme == "myftp"
|
71
74
|
model[:myftp] = URI.parse(uri).normalize
|
72
75
|
end
|
73
76
|
end
|
74
77
|
|
75
78
|
item.exception(ArgumentError) do |e, val|
|
76
|
-
raise OptionError.new(cmd, "
|
79
|
+
raise OptionError.new(cmd, "base location '%s' is bad in %s" % [uri, cmd.name])
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
@@ -135,7 +138,7 @@ module Pione
|
|
135
138
|
item.arg = '[SCENARIO]'
|
136
139
|
item.desc = 'rehearse the scenario'
|
137
140
|
|
138
|
-
item.assign {|val| val.size != 0 ? val : :anything}
|
141
|
+
item.assign {|val| not(val.nil?) and val.size != 0 ? val : :anything}
|
139
142
|
end
|
140
143
|
|
141
144
|
option(:timeout) do |item|
|
@@ -145,6 +148,13 @@ module Pione
|
|
145
148
|
item.desc = 'timeout processing after SEC'
|
146
149
|
end
|
147
150
|
|
151
|
+
option(:client_ui) do |item|
|
152
|
+
item.type = :string
|
153
|
+
item.long = "--client-ui"
|
154
|
+
item.arg = "TYPE"
|
155
|
+
item.desc = "Type of the client's user interface"
|
156
|
+
end
|
157
|
+
|
148
158
|
option_post(:validate_task_worker_size) do |item|
|
149
159
|
item.desc = "Validate task worker size"
|
150
160
|
item.process do
|
@@ -173,7 +183,7 @@ module Pione
|
|
173
183
|
seq << :spawner_thread_group
|
174
184
|
seq << :ftp_server
|
175
185
|
seq << :tuple_space
|
176
|
-
seq << :
|
186
|
+
seq << :base_location
|
177
187
|
seq << :lang_environment
|
178
188
|
seq << :package
|
179
189
|
seq << :scenario
|
@@ -217,18 +227,32 @@ module Pione
|
|
217
227
|
# write tuples
|
218
228
|
model[:tuple_space].write(TupleSpace::ProcessInfoTuple.new('standalone', 'Standalone'))
|
219
229
|
model[:tuple_space].write(TupleSpace::DryRunTuple.new(model[:dry_run]))
|
230
|
+
|
231
|
+
if model[:request_from]
|
232
|
+
model[:tuple_space].write(TupleSpace::AttributeTuple.new("request_from", model[:request_from]))
|
233
|
+
end
|
234
|
+
|
235
|
+
if model[:session_id]
|
236
|
+
model[:tuple_space].write(TupleSpace::AttributeTuple.new("session_id", model[:session_id]))
|
237
|
+
end
|
238
|
+
|
239
|
+
if model[:client_ui]
|
240
|
+
model[:tuple_space].write(TupleSpace::AttributeTuple.new("client_ui", model[:client_ui]))
|
241
|
+
else
|
242
|
+
model[:tuple_space].write(TupleSpace::AttributeTuple.new("client_ui", "GUI"))
|
243
|
+
end
|
220
244
|
end
|
221
245
|
end
|
222
246
|
|
223
|
-
setup(:
|
224
|
-
item.desc = "Setup
|
247
|
+
setup(:base_location) do |item|
|
248
|
+
item.desc = "Setup base location"
|
225
249
|
|
226
250
|
# setup location
|
227
251
|
item.process do
|
228
|
-
case model[:
|
252
|
+
case model[:base_location]
|
229
253
|
when Location::LocalLocation
|
230
|
-
model[:
|
231
|
-
model[:
|
254
|
+
model[:base_location] = Location[model[:base_location].path.expand_path]
|
255
|
+
model[:base_location].path.mkpath
|
232
256
|
when Location::DropboxLocation
|
233
257
|
Location::DropboxLocation.setup_for_cui_client(tuple_space_server)
|
234
258
|
end
|
@@ -236,13 +260,13 @@ module Pione
|
|
236
260
|
|
237
261
|
# mkdir
|
238
262
|
item.process do
|
239
|
-
test(not(model[:
|
240
|
-
model[:
|
263
|
+
test(not(model[:base_location].exist?))
|
264
|
+
model[:base_location].mkdir
|
241
265
|
end
|
242
266
|
|
243
267
|
# set base location into tuple space
|
244
268
|
item.process do
|
245
|
-
model[:tuple_space].set_base_location(model[:
|
269
|
+
model[:tuple_space].set_base_location(model[:base_location])
|
246
270
|
end
|
247
271
|
end
|
248
272
|
|
@@ -270,7 +294,7 @@ module Pione
|
|
270
294
|
|
271
295
|
# upload the package
|
272
296
|
item.process do
|
273
|
-
model[:package_handler].upload(model[:
|
297
|
+
model[:package_handler].upload(model[:base_location] + "package")
|
274
298
|
end
|
275
299
|
|
276
300
|
item.exception(Package::InvalidPackage) do |e|
|
@@ -349,7 +373,7 @@ module Pione
|
|
349
373
|
receiver = Log::CUIMessageLogReceiver.new
|
350
374
|
end
|
351
375
|
|
352
|
-
Agent::Messenger.new(model[:tuple_space], receiver).start
|
376
|
+
Agent::Messenger.new(model[:tuple_space], receiver, model[:session_id]).start
|
353
377
|
end
|
354
378
|
end
|
355
379
|
|
@@ -358,7 +382,7 @@ module Pione
|
|
358
382
|
item.desc = "Start a logger agent"
|
359
383
|
|
360
384
|
item.assign(:logger) do
|
361
|
-
Agent::Logger.start(model[:tuple_space], model[:
|
385
|
+
Agent::Logger.start(model[:tuple_space], model[:base_location])
|
362
386
|
end
|
363
387
|
end
|
364
388
|
|
@@ -412,7 +436,12 @@ module Pione
|
|
412
436
|
item.desc = "Spawn a task worker"
|
413
437
|
|
414
438
|
item.process do
|
415
|
-
|
439
|
+
param = {
|
440
|
+
:features => Global.features,
|
441
|
+
:tuple_space_id => model[:tuple_space].uuid
|
442
|
+
}
|
443
|
+
|
444
|
+
Command::PioneTaskWorker.spawn(model, param)
|
416
445
|
end
|
417
446
|
|
418
447
|
item.exception(SpawnError) do |e|
|
@@ -506,7 +535,7 @@ module Pione
|
|
506
535
|
|
507
536
|
pscenario = test(model[:package_handler].find_scenario(model[:rehearse]))
|
508
537
|
|
509
|
-
errors = pscenario.validate(model[:
|
538
|
+
errors = pscenario.validate(model[:base_location])
|
510
539
|
if errors.empty?
|
511
540
|
Log::SystemLog.info "Rehearsal Result: Succeeded"
|
512
541
|
else
|
@@ -1,3 +1,7 @@
|
|
1
|
+
require 'pione/global/interactive-variable'
|
2
|
+
require 'pione/front/interactive-front'
|
3
|
+
require 'pione/util/cgi'
|
4
|
+
|
1
5
|
module Pione
|
2
6
|
module Command
|
3
7
|
class PioneInteractive < BasicCommand
|
@@ -7,11 +11,6 @@ module Pione
|
|
7
11
|
|
8
12
|
require 'rexml/document'
|
9
13
|
|
10
|
-
# debug mode only
|
11
|
-
unless ENV["PIONE_JOB_ID"]
|
12
|
-
require 'webrick'
|
13
|
-
end
|
14
|
-
|
15
14
|
#
|
16
15
|
# informations
|
17
16
|
#
|
@@ -19,40 +18,43 @@ module Pione
|
|
19
18
|
define(:toplevel, true)
|
20
19
|
define(:name, "pione-interactive")
|
21
20
|
define(:desc, "interactive action handler")
|
21
|
+
define(:front, Front::InteractiveFront)
|
22
22
|
|
23
23
|
#
|
24
24
|
# arguments
|
25
25
|
#
|
26
26
|
|
27
|
-
argument(:
|
28
|
-
item.type
|
29
|
-
item.desc
|
30
|
-
item.missing = "There are no definition file."
|
27
|
+
argument(:type) do |item|
|
28
|
+
item.type = :symbol_downcase
|
29
|
+
item.desc = "View type"
|
31
30
|
end
|
32
31
|
|
33
32
|
#
|
34
33
|
# options
|
35
34
|
#
|
36
35
|
|
37
|
-
option(:
|
38
|
-
item.
|
39
|
-
item.
|
40
|
-
item.
|
41
|
-
item.
|
36
|
+
option(:public) do |item|
|
37
|
+
item.desc = "public directory for interactive operation pages"
|
38
|
+
item.type = :location
|
39
|
+
item.long = "--public"
|
40
|
+
item.arg = "DIR"
|
41
|
+
item.init = "./public"
|
42
|
+
item.default = "./"
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
-
item.desc
|
46
|
-
|
47
|
-
item.
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
option(:output) do |item|
|
46
|
+
item.desc = "Output file"
|
47
|
+
item.type = :location
|
48
|
+
item.long = "--output"
|
49
|
+
item.short = "-o"
|
50
|
+
item.arg = "FILE"
|
51
|
+
end
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
option(:timeout) do |item|
|
54
|
+
item.desc = "timeout after the second"
|
55
|
+
item.type = :integer
|
56
|
+
item.long = "--timeout"
|
57
|
+
item.arg = "SEC"
|
56
58
|
end
|
57
59
|
|
58
60
|
#
|
@@ -60,49 +62,75 @@ module Pione
|
|
60
62
|
#
|
61
63
|
|
62
64
|
phase(:setup) do |seq|
|
63
|
-
seq << :
|
65
|
+
seq << :session_id
|
66
|
+
seq << :interaction_id
|
64
67
|
end
|
65
68
|
|
66
|
-
setup(:
|
67
|
-
item.desc = "
|
69
|
+
setup(:session_id) do |item|
|
70
|
+
item.desc = "Setup session ID"
|
68
71
|
item.process do
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
prefix = prefix ? prefix + ":" : ""
|
77
|
-
|
78
|
-
# get embeded contents
|
79
|
-
content = REXML::XPath.first(doc, "/#{prefix}interactive/#{prefix}content")
|
80
|
-
model[:content] = ""
|
81
|
-
content.elements.each {|e| fm.write(e, model[:content])}
|
82
|
-
|
83
|
-
# get embeded script
|
84
|
-
script = REXML::XPath.first(doc, "/#{prefix}interactive/#{prefix}script")
|
85
|
-
model[:script] = script.text
|
72
|
+
if ENV["PIONE_SESSION_ID"]
|
73
|
+
model[:session_id] = ENV["PIONE_SESSION_ID"]
|
74
|
+
model[:request_from] = ENV["PIONE_REQUEST_FROM"]
|
75
|
+
else
|
76
|
+
# debug mode only
|
77
|
+
require 'webrick'
|
78
|
+
end
|
86
79
|
end
|
87
80
|
end
|
88
81
|
|
82
|
+
setup(:interaction_id) do |item|
|
83
|
+
item.desc = "Setup interaction ID"
|
84
|
+
item.assign { Util::UUID.generate }
|
85
|
+
end
|
86
|
+
|
89
87
|
#
|
90
88
|
# command lifecycle: execution phase
|
91
89
|
#
|
92
90
|
|
93
91
|
phase(:execution) do |seq|
|
94
|
-
|
95
|
-
|
96
|
-
else
|
97
|
-
# debug mode
|
98
|
-
seq << :debug_mode
|
99
|
-
seq << :print_result
|
100
|
-
end
|
92
|
+
seq << :render
|
93
|
+
seq << :print_result
|
101
94
|
end
|
102
95
|
|
103
|
-
execution(:
|
104
|
-
item.desc = "
|
96
|
+
execution(:render) do |item|
|
97
|
+
item.desc = "Render a widget"
|
98
|
+
|
99
|
+
# this is called from webclient
|
100
|
+
item.process do
|
101
|
+
test(model[:session_id])
|
102
|
+
test(model[:request_from])
|
103
|
+
|
104
|
+
webclient = DRb::DRbObject.new_with_uri(model[:request_from])
|
105
|
+
case model[:type]
|
106
|
+
when :browser
|
107
|
+
result, status = webclient.request_interaction(
|
108
|
+
model[:session_id],
|
109
|
+
model[:interaction_id],
|
110
|
+
:browser,
|
111
|
+
{:front_address => model[:front].uri.to_s})
|
112
|
+
when :dialog
|
113
|
+
result, status = webclient.request_interaction(
|
114
|
+
model[:session_id],
|
115
|
+
model[:interaction_id],
|
116
|
+
:dialog,
|
117
|
+
{:content => model[:content], :script => model[:script]})
|
118
|
+
else
|
119
|
+
cmd.abort('Type "%s" is unknown.' % model[:type])
|
120
|
+
end
|
121
|
+
model[:result] = result
|
122
|
+
|
123
|
+
# command fails if the status is "failure"
|
124
|
+
if status == "failure"
|
125
|
+
self.exit_status = false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# this is called from the exception of webclient
|
105
130
|
item.process do
|
131
|
+
test(not(model[:session_id] and model[:request_from]))
|
132
|
+
test(model[:definition])
|
133
|
+
|
106
134
|
begin
|
107
135
|
template = <<HTML
|
108
136
|
<!DOCTYPE html>
|
@@ -174,13 +202,58 @@ HTML
|
|
174
202
|
end
|
175
203
|
end
|
176
204
|
end
|
205
|
+
|
206
|
+
# this is called from the exception of webclient
|
207
|
+
item.process do
|
208
|
+
test(not(model[:session_id] and model[:request_from]))
|
209
|
+
test(model[:type] == :page)
|
210
|
+
|
211
|
+
begin
|
212
|
+
model[:debug_server] = WEBrick::HTTPServer.new(
|
213
|
+
:Port => 8080, :Logger => WEBrick::Log.new($stderr)
|
214
|
+
)
|
215
|
+
|
216
|
+
# page handler on '/'
|
217
|
+
model[:debug_server].mount("/", WEBrick::HTTPServlet::FileHandler, model[:public].path.to_s)
|
218
|
+
|
219
|
+
# finish
|
220
|
+
model[:debug_server].mount_proc("/finish") do |req, res|
|
221
|
+
model[:result] = req.query["result"]
|
222
|
+
model[:debug_server].shutdown
|
223
|
+
end
|
224
|
+
|
225
|
+
# shutdown handler on '/shutdown'
|
226
|
+
model[:debug_server].mount_proc("/shutdown") do |req, res|
|
227
|
+
model[:result] = req.body
|
228
|
+
model[:debug_server].shutdown
|
229
|
+
end
|
230
|
+
|
231
|
+
# `Kernel.trap` can take multiple INT handlers
|
232
|
+
trap("INT") { model[:debug_server].shutdown }
|
233
|
+
|
234
|
+
# show the location
|
235
|
+
$stderr.puts "See http://localhost:8080"
|
236
|
+
|
237
|
+
# start the debug server
|
238
|
+
model[:debug_server].start
|
239
|
+
ensure
|
240
|
+
if model[:debug_server]
|
241
|
+
model[:debug_server].shutdown
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
177
246
|
end
|
178
247
|
|
179
248
|
# Print a result string of interactive action to stdout.
|
180
249
|
execution(:print_result) do |item|
|
181
250
|
item.desc = "Print a result string."
|
182
251
|
item.process do
|
183
|
-
|
252
|
+
if model[:output]
|
253
|
+
model[:output].write model[:result]
|
254
|
+
else
|
255
|
+
$stdout.print model[:result]
|
256
|
+
end
|
184
257
|
end
|
185
258
|
end
|
186
259
|
end
|