lib/adhearsion/call_controller/output.rb in adhearsion-2.4.0 vs lib/adhearsion/call_controller/output.rb in adhearsion-2.5.0

- old
+ new

@@ -9,33 +9,36 @@ autoload :AsyncPlayer autoload :Formatter autoload :Player PlaybackError = Class.new Adhearsion::Error # Represents failure to play audio, such as when the sound file cannot be found + NoDocError = Class.new Adhearsion::Error # Represents failure to provide documents to playback # # Speak output using text-to-speech (TTS) # # @param [String, #to_s] text The text to be rendered # @param [Hash] options A set of options for output # - # @raises [PlaybackError] if the given argument could not be played + # @raise [PlaybackError] if the given argument could not be played # def say(text, options = {}) + return unless text player.play_ssml(text, options) || player.output(output_formatter.ssml_for_text(text.to_s), options) end alias :speak :say # # Speak output using text-to-speech (TTS) and return as soon as it begins # # @param [String, #to_s] text The text to be rendered # @param [Hash] options A set of options for output # - # @raises [PlaybackError] if the given argument could not be played + # @raise [PlaybackError] if the given argument could not be played # def say!(text, options = {}) + return unless text async_player.play_ssml(text, options) || async_player.output(output_formatter.ssml_for_text(text.to_s), options) end alias :speak! :say! @@ -45,11 +48,11 @@ # say_characters('abc123') # # @param [String, #to_s] characters The string of characters to be spoken # @param [Hash] options A set of options for output # - # @raises [PlaybackError] if the given argument could not be played + # @raise [PlaybackError] if the given argument could not be played # def say_characters(characters, options = {}) player.play_ssml output_formatter.ssml_for_characters(characters), options true end @@ -60,11 +63,11 @@ # say_characters!('abc123') # # @param [String, #to_s] characters The string of characters to be spoken # @param [Hash] options A set of options for output # - # @raises [PlaybackError] if the given argument could not be played + # @raise [PlaybackError] if the given argument could not be played # def say_characters!(characters, options = {}) async_player.play_ssml output_formatter.ssml_for_characters(characters), options end @@ -86,16 +89,19 @@ # @example Play sound file, speak number, play two more sound files # play %w"http://www.example.com/a-connect-charge-of.wav 22 /path/to/cents-per-minute.wav /path/to/will-apply.mp3" # @example Play two sound files # play "/path/to/you-sound-cute.mp3", "/path/to/what-are-you-wearing.wav" # - # @raises [PlaybackError] if (one of) the given argument(s) could not be played + # @raise [PlaybackError] if (one of) the given argument(s) could not be played # - def play(*arguments) - options = process_output_options arguments - player.play_ssml output_formatter.ssml_for_collection(arguments), options + def play(*outputs, options) + options = process_output_options outputs, options + ssml = output_formatter.ssml_for_collection(outputs) || return + player.play_ssml ssml, options true + rescue NoDocError + false end # # Plays the specified sound file names and returns as soon as it begins. This method will handle Time/DateTime objects (e.g. Time.now), # Fixnums (e.g. 1000), Strings which are valid Fixnums (e.g "123"), and direct sound files. To specify how the Date/Time objects are said @@ -114,16 +120,19 @@ # @example Play sound file, speak number, play two more sound files # play %w"http://www.example.com/a-connect-charge-of.wav 22 /path/to/cents-per-minute.wav /path/to/will-apply.mp3" # @example Play two sound files # play "/path/to/you-sound-cute.mp3", "/path/to/what-are-you-wearing.wav" # - # @raises [PlaybackError] if (one of) the given argument(s) could not be played - # @returns [Punchblock::Component::Output] + # @raise [PlaybackError] if (one of) the given argument(s) could not be played + # @return [Punchblock::Component::Output] # - def play!(*arguments) - options = process_output_options arguments - async_player.play_ssml output_formatter.ssml_for_collection(arguments), options + def play!(*outputs, options) + options = process_output_options outputs, options + ssml = output_formatter.ssml_for_collection(outputs) || return + async_player.play_ssml ssml, options + rescue NoDocError + false end # # Plays the given audio file. # SSML supports http:// paths and full disk paths. @@ -132,11 +141,11 @@ # @param [String] file http:// URL or full disk path to the sound file # @param [Hash] options Additional options # @option options [String] :fallback The text to play if the file is not available # @option options [Symbol] :renderer The media engine to use for rendering the file # - # @raises [PlaybackError] if (one of) the given argument(s) could not be played + # @raise [PlaybackError] if (one of) the given argument(s) could not be played # def play_audio(file, options = {}) renderer = options.delete :renderer player.play_ssml(output_formatter.ssml_for_audio(file, options), renderer: renderer) true @@ -149,12 +158,12 @@ # # @param [String] file http:// URL or full disk path to the sound file # @param [Hash] options Additional options to specify how exactly to say time specified. # @option options [String] :fallback The text to play if the file is not available # - # @raises [PlaybackError] if (one of) the given argument(s) could not be played - # @returns [Punchblock::Component::Output] + # @raise [PlaybackError] if (one of) the given argument(s) could not be played + # @return [Punchblock::Component::Output] # def play_audio!(file, options = {}) renderer = options.delete :renderer async_player.play_ssml(output_formatter.ssml_for_audio(file, options), renderer: renderer) end @@ -170,11 +179,11 @@ # Please refer to the SSML specification. # @see http://www.w3.org/TR/ssml-sayas/#S3.1 # @option options [String] :strftime This format is what defines the string that is sent to the Speech Synthesis Engine. # It uses Time::strftime symbols. # - # @raises [ArgumentError] if the given argument can not be played + # @raise [ArgumentError] if the given argument can not be played # def play_time(time, options = {}) raise ArgumentError unless [Date, Time, DateTime].include?(time.class) && options.is_a?(Hash) player.play_ssml output_formatter.ssml_for_time(time, options) true @@ -191,12 +200,12 @@ # Please refer to the SSML specification. # @see http://www.w3.org/TR/ssml-sayas/#S3.1 # @option options [String] :strftime This format is what defines the string that is sent to the Speech Synthesis Engine. # It uses Time::strftime symbols. # - # @raises [ArgumentError] if the given argument can not be played - # @returns [Punchblock::Component::Output] + # @raise [ArgumentError] if the given argument can not be played + # @return [Punchblock::Component::Output] # def play_time!(time, options = {}) raise ArgumentError unless [Date, Time, DateTime].include?(time.class) && options.is_a?(Hash) async_player.play_ssml output_formatter.ssml_for_time(time, options) end @@ -204,13 +213,13 @@ # # Plays the given Numeric argument or string representing a decimal number. # When playing numbers, Adhearsion assumes you're saying the number, not the digits. For example, play("100") # is pronounced as "one hundred" instead of "one zero zero". # - # @param [Numeric, String] Numeric or String containing a valid Numeric, like "321". + # @param [Numeric, String] number Numeric or String containing a valid Numeric, like "321". # - # @raises [ArgumentError] if the given argument can not be played + # @raise [ArgumentError] if the given argument can not be played # def play_numeric(number) raise ArgumentError unless number.kind_of?(Numeric) || number =~ /^\d+$/ player.play_ssml output_formatter.ssml_for_numeric(number) true @@ -219,14 +228,14 @@ # # Plays the given Numeric argument or string representing a decimal number and returns as soon as it begins. # When playing numbers, Adhearsion assumes you're saying the number, not the digits. For example, play("100") # is pronounced as "one hundred" instead of "one zero zero". # - # @param [Numeric, String] Numeric or String containing a valid Numeric, like "321". + # @param [Numeric, String] number Numeric or String containing a valid Numeric, like "321". # - # @raises [ArgumentError] if the given argument can not be played - # @returns [Punchblock::Component::Output] + # @raise [ArgumentError] if the given argument can not be played + # @return [Punchblock::Component::Output] # def play_numeric!(number) raise ArgumentError unless number.kind_of?(Numeric) || number =~ /^\d+$/ async_player.play_ssml output_formatter.ssml_for_numeric(number) end @@ -240,29 +249,29 @@ # "Please press a button" # end # input = interruptible_play ssml # play input unless input.nil? # - # @param [String, Numeric, Date, Time, RubySpeech::SSML::Speak, Array, Hash] The argument to play to the user, or an array of arguments. - # @param [Hash] Additional options. + # @param [String, Numeric, Date, Time, RubySpeech::SSML::Speak, Array, Hash] outputs The argument to play to the user, or an array of arguments. + # @param [Hash] options Additional options. # # @return [String, nil] The single DTMF character entered by the user, or nil if nothing was entered - # @raises [PlaybackError] if (one of) the given argument(s) could not be played + # @raise [PlaybackError] if (one of) the given argument(s) could not be played # - def interruptible_play(*outputs) - options = process_output_options outputs + def interruptible_play(*outputs, options) + options = process_output_options outputs, options outputs.find do |output| digit = stream_file output, '0123456789#*', options return digit if digit end end # # Plays a single output, not only files, accepting interruption by one of the digits specified # - # @param [Object] String or Hash specifying output and options - # @param [String] String with the digits that are allowed to interrupt output + # @param [Object] argument String or Hash specifying output and options + # @param [String] digits String with the digits that are allowed to interrupt output # # @return [String, nil] The pressed digit, or nil if nothing was pressed # @private # def stream_file(argument, digits = '0123456789#*', output_options = {}) @@ -294,11 +303,16 @@ def async_player @async_player ||= AsyncPlayer.new(self) end # @private - def process_output_options(arguments) - arguments.last.is_a?(Hash) && arguments.count > 1 ? arguments.pop : {} + def process_output_options(outputs, options) + if options.is_a?(Hash) && outputs.count > 0 + options + else + outputs << options + {} + end end # # @return [Formatter] an output formatter for the preparation of SSML documents for submission to the engine #