require 'pione/global/interactive-variable' require 'pione/front/interactive-front' require 'pione/util/cgi' module Pione module Command class PioneInteractive < BasicCommand # # libraries # require 'rexml/document' # # informations # define(:toplevel, true) define(:name, "pione-interactive") define(:desc, "interactive action handler") define(:front, Front::InteractiveFront) # # arguments # argument(:type) do |item| item.type = :symbol_downcase item.desc = "View type" end # # options # option(:public) do |item| item.desc = "public directory for interactive operation pages" item.type = :location item.long = "--public" item.arg = "DIR" item.init = "./public" item.default = "./" end option(:output) do |item| item.desc = "Output file" item.type = :location item.long = "--output" item.short = "-o" item.arg = "FILE" end option(:timeout) do |item| item.desc = "timeout after the second" item.type = :integer item.long = "--timeout" item.arg = "SEC" end # # command lifecycle: setup phase # phase(:setup) do |seq| seq << :session_id seq << :interaction_id end setup(:session_id) do |item| item.desc = "Setup session ID" item.process do if ENV["PIONE_SESSION_ID"] model[:session_id] = ENV["PIONE_SESSION_ID"] model[:request_from] = ENV["PIONE_REQUEST_FROM"] else # debug mode only require 'webrick' end end end setup(:interaction_id) do |item| item.desc = "Setup interaction ID" item.assign { Util::UUID.generate } end # # command lifecycle: execution phase # phase(:execution) do |seq| seq << :render seq << :print_result end execution(:render) do |item| item.desc = "Render a widget" # this is called from webclient item.process do test(model[:session_id]) test(model[:request_from]) webclient = DRb::DRbObject.new_with_uri(model[:request_from]) case model[:type] when :browser result, status = webclient.request_interaction( model[:session_id], model[:interaction_id], :browser, {:front_address => model[:front].uri.to_s}) when :dialog result, status = webclient.request_interaction( model[:session_id], model[:interaction_id], :dialog, {:content => model[:content], :script => model[:script]}) else cmd.abort('Type "%s" is unknown.' % model[:type]) end model[:result] = result # command fails if the status is "failure" if status == "failure" self.exit_status = false end end # this is called from the exception of webclient item.process do test(not(model[:session_id] and model[:request_from])) test(model[:definition]) begin template = < pione-interactive
%s
HTML html = template % [model[:content], model[:script]] model[:debug_server] = WEBrick::HTTPServer.new( :Port => 8080, :Logger => WEBrick::Log.new($stderr) ) # page handler on '/' model[:debug_server].mount_proc("/") do |req, res| res.body = html res['Content-Type'] = "text/html" end # shutdown handler on '/shutdown' model[:debug_server].mount_proc("/shutdown") do |req, res| model[:result] = req.body model[:debug_server].shutdown end # `Kernel.trap` can take multiple INT handlers trap("INT") { model[:debug_server].shutdown } # show the location $stderr.puts "See http://localhost:8080" # start the debug server model[:debug_server].start ensure if model[:debug_server] model[:debug_server].shutdown end end end # this is called from the exception of webclient item.process do test(not(model[:session_id] and model[:request_from])) test(model[:type] == :page) begin model[:debug_server] = WEBrick::HTTPServer.new( :Port => 8080, :Logger => WEBrick::Log.new($stderr) ) # page handler on '/' model[:debug_server].mount("/", WEBrick::HTTPServlet::FileHandler, model[:public].path.to_s) # finish model[:debug_server].mount_proc("/finish") do |req, res| model[:result] = req.query["result"] model[:debug_server].shutdown end # shutdown handler on '/shutdown' model[:debug_server].mount_proc("/shutdown") do |req, res| model[:result] = req.body model[:debug_server].shutdown end # `Kernel.trap` can take multiple INT handlers trap("INT") { model[:debug_server].shutdown } # show the location $stderr.puts "See http://localhost:8080" # start the debug server model[:debug_server].start ensure if model[:debug_server] model[:debug_server].shutdown end end end end # Print a result string of interactive action to stdout. execution(:print_result) do |item| item.desc = "Print a result string." item.process do if model[:output] model[:output].write model[:result] else $stdout.print model[:result] end end end end end end