lib/punchblock/component/output.rb in punchblock-1.9.4 vs lib/punchblock/component/output.rb in punchblock-2.0.0.beta1
- old
+ new
@@ -3,178 +3,134 @@
module Punchblock
module Component
class Output < ComponentNode
register :output, :output
- ##
- # Creates an Rayo Output command
- #
- # @param [Hash] options
- # @option options [String, Optional] :text to speak back
- # @option options [String, Optional] :voice with which to render TTS
- # @option options [String, Optional] :ssml document to render TTS
- # @option options [Symbol] :interrupt_on input type on which to interrupt output. May be :speech, :dtmf or :any
- # @option options [Integer] :start_offset Indicates some offset through which the output should be skipped before rendering begins.
- # @option options [true, false] :start_paused Indicates wether or not the component should be started in a paused state to be resumed at a later time.
- # @option options [Integer] :repeat_interval Indicates the duration of silence that should space repeats of the rendered document.
- # @option options [Integer] :repeat_times Indicates the number of times the output should be played.
- # @option options [Integer] :max_time Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
- #
- # @return [Command::Output] an Rayo "output" command
- #
- # @example
- # output :text => 'Hello brown cow.'
- #
- # returns:
- # <output xmlns="urn:xmpp:rayo:output:1">Hello brown cow.</output>
- #
- def self.new(options = {})
- super().tap do |new_node|
- case options
- when Hash
- new_node.ssml = options.delete(:ssml) if options[:ssml]
- new_node << options.delete(:text) if options[:text]
- options.each_pair { |k,v| new_node.send :"#{k}=", v }
- when Nokogiri::XML::Element
- new_node.inherit options
+ class Document < RayoNode
+ register :document, :output
+
+ SSML_CONTENT_TYPE = 'application/ssml+xml'
+
+ # @return [String] the URL from which the fetch the grammar
+ attribute :url
+
+ # @return [String] the document content type
+ attribute :content_type, String, default: ->(grammar, attribute) { grammar.url ? nil : SSML_CONTENT_TYPE }
+
+ # @return [String, RubySpeech::SSML::Speak, URIList] the document
+ attribute :value
+
+ def inherit(xml_node)
+ super
+ self.value = if ssml?
+ RubySpeech::SSML.import xml_node.content
+ elsif urilist?
+ URIList.import xml_node.content
+ else
+ xml_node.content
end
+ self
end
- end
- ##
- # @return [String] the TTS voice to use
- #
- def voice
- read_attr :voice
- end
+ def rayo_attributes
+ {
+ 'url' => url,
+ 'content-type' => content_type
+ }
+ end
- ##
- # @param [String] voice to use when rendering TTS
- #
- def voice=(voice)
- write_attr :voice, voice
- end
+ def rayo_children(root)
+ root.cdata xml_value
+ super
+ end
- ##
- # @return [String] the SSML document to render TTS
- #
- def ssml
- node = children.first
- RubySpeech::SSML.import node if node
- end
+ private
- ##
- # @param [String] ssml the SSML document to render TTS
- #
- def ssml=(ssml)
- return unless ssml
- unless ssml.is_a?(RubySpeech::SSML::Element)
- ssml = RubySpeech::SSML.import ssml
+ def xml_value
+ if ssml?
+ value.to_xml
+ elsif urilist?
+ value.to_s
+ elsif
+ value
+ end
end
- self << ssml
- end
- ##
- # @return [Symbol] input type on which to interrupt output
- #
- def interrupt_on
- read_attr :'interrupt-on', :to_sym
- end
+ def ssml?
+ content_type == SSML_CONTENT_TYPE
+ end
- ##
- # @param [Symbol] other input type on which to interrupt output. May be :speech, :dtmf or :any
- #
- def interrupt_on=(other)
- write_attr :'interrupt-on', other
+ def urilist?
+ content_type == 'text/uri-list'
+ end
end
- ##
- # @return [Integer] Indicates some offset through which the output should be skipped before rendering begins.
- #
- def start_offset
- read_attr :'start-offset', :to_i
+ def inherit(xml_node)
+ document_nodes = xml_node.xpath 'ns:document', ns: self.class.registered_ns
+ self.render_documents = document_nodes.to_a.map { |node| Document.from_xml node }
+ super
end
- ##
- # @param [Integer] other Indicates some offset through which the output should be skipped before rendering begins.
- #
- def start_offset=(other)
- write_attr :'start-offset', other, :to_i
- end
+ # @return [String] the TTS voice to use
+ attribute :voice, String
- ##
- # @return [true, false] Indicates wether or not the component should be started in a paused state to be resumed at a later time.
- #
- def start_paused
- read_attr(:'start-paused') == 'true'
- end
+ # @return [Symbol] input type on which to interrupt output
+ attribute :interrupt_on, Symbol
- ##
- # @param [true, false] other Indicates wether or not the component should be started in a paused state to be resumed at a later time.
- #
- def start_paused=(other)
- write_attr :'start-paused', other, :to_s
- end
+ # @return [Integer] Indicates some offset through which the output should be skipped before rendering begins.
+ attribute :start_offset, Integer
- ##
+ # @return [true, false] Indicates wether or not the component should be started in a paused state to be resumed at a later time.
+ attribute :start_paused, Boolean, default: false
+
# @return [Integer] Indicates the duration of silence that should space repeats of the rendered document.
- #
- def repeat_interval
- read_attr :'repeat-interval', :to_i
- end
+ attribute :repeat_interval, Integer
- ##
- # @param [Integer] other Indicates the duration of silence that should space repeats of the rendered document.
- #
- def repeat_interval=(other)
- write_attr :'repeat-interval', other, :to_i
- end
-
- ##
# @return [Integer] Indicates the number of times the output should be played.
- #
- def repeat_times
- read_attr :'repeat-times', :to_i
- end
+ attribute :repeat_times, Integer
- ##
- # @param [Integer] other Indicates the number of times the output should be played.
- #
- def repeat_times=(other)
- write_attr :'repeat-times', other, :to_i
- end
-
- ##
# @return [Integer] Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
- #
- def max_time
- read_attr :'max-time', :to_i
- end
+ attribute :max_time, Integer
- ##
- # @param [Integer] other Indicates the maximum amount of time for which the output should be allowed to run before being terminated. Includes repeats.
- #
- def max_time=(other)
- write_attr :'max-time', other, :to_i
+ # @return [String] the rendering engine requested by the component
+ attribute :renderer, String
+
+ def rayo_attributes
+ {
+ 'voice' => voice,
+ 'interrupt-on' => interrupt_on,
+ 'start-offset' => start_offset,
+ 'start-paused' => start_paused,
+ 'repeat-interval' => repeat_interval,
+ 'repeat-times' => repeat_times,
+ 'max-time' => max_time,
+ 'renderer' => renderer
+ }
end
- ##
- # @return [String] the rendering engine requested by the component
- #
- def renderer
- read_attr :renderer
+ def rayo_children(root)
+ render_documents.each do |render_document|
+ render_document.to_rayo root.parent
+ end
+ super
end
+ # @return [Document] the document to render
+ attribute :render_documents, Array[Document], default: []
+
##
- # @param [String] the rendering engine to use with this component
+ # @param [Hash] other
+ # @option other [String] :content_type the document content type
+ # @option other [String] :value the output doucment
+ # @option other [String] :url the url from which to fetch the document
#
- def renderer=(renderer)
- write_attr :renderer, renderer
+ def render_document=(other)
+ self.render_documents = [other].compact
end
- def inspect_attributes
- super + [:voice, :ssml, :interrupt_on, :start_offset, :start_paused, :repeat_interval, :repeat_times, :max_time, :renderer]
+ def ssml=(other)
+ self.render_documents = [{:value => other}]
end
state_machine :state do
event :paused do
transition :executing => :paused
@@ -279,34 +235,26 @@
end
class Seek < CommandNode # :nodoc:
register :seek, :output
- def self.new(options = {})
- super.tap do |new_node|
- new_node.direction = options[:direction]
- new_node.amount = options[:amount]
- end
- end
+ attribute :direction
+ attribute :amount
- def direction=(other)
- write_attr :direction, other
- end
-
- def amount=(other)
- write_attr :amount, other
- end
-
def request!
source.seeking!
super
end
def execute!
source.stopped_seeking!
super
end
+
+ def rayo_attributes
+ {'direction' => direction, 'amount' => amount}
+ end
end
##
# Creates an Rayo speed up message for the current Output
#
@@ -494,11 +442,15 @@
super
end
end
class Complete
- class Success < Event::Complete::Reason
- register :success, :output_complete
+ class Finish < Event::Complete::Reason
+ register :finish, :output_complete
+ end
+
+ class MaxTime < Event::Complete::Reason
+ register :'max-time', :output_complete
end
end
end # Output
end # Command
end # Punchblock