punchblock 1.9.4 → 2.0.0.beta1

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.
Files changed (142) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -2
  4. data/CHANGELOG.md +17 -0
  5. data/Gemfile +1 -0
  6. data/Guardfile +4 -0
  7. data/README.markdown +6 -0
  8. data/Rakefile +16 -0
  9. data/benchmarks/ami_event_name_comparison.rb +14 -0
  10. data/benchmarks/channel.rb +27 -0
  11. data/lib/punchblock/client.rb +2 -6
  12. data/lib/punchblock/command/accept.rb +3 -24
  13. data/lib/punchblock/command/answer.rb +3 -24
  14. data/lib/punchblock/command/dial.rb +24 -76
  15. data/lib/punchblock/command/hangup.rb +3 -19
  16. data/lib/punchblock/command/join.rb +21 -70
  17. data/lib/punchblock/command/mute.rb +3 -3
  18. data/lib/punchblock/command/redirect.rb +6 -39
  19. data/lib/punchblock/command/reject.rb +14 -54
  20. data/lib/punchblock/command/unjoin.rb +8 -40
  21. data/lib/punchblock/command/unmute.rb +3 -3
  22. data/lib/punchblock/command_node.rb +0 -17
  23. data/lib/punchblock/component/asterisk/agi/command.rb +20 -127
  24. data/lib/punchblock/component/asterisk/ami/action.rb +30 -117
  25. data/lib/punchblock/component/component_node.rb +1 -1
  26. data/lib/punchblock/component/input.rb +89 -268
  27. data/lib/punchblock/component/output.rb +106 -154
  28. data/lib/punchblock/component/prompt.rb +51 -0
  29. data/lib/punchblock/component/record.rb +41 -130
  30. data/lib/punchblock/component.rb +1 -0
  31. data/lib/punchblock/connection/asterisk.rb +31 -4
  32. data/lib/punchblock/connection/xmpp.rb +6 -14
  33. data/lib/punchblock/core_ext/blather/stanza.rb +1 -1
  34. data/lib/punchblock/event/active_speaker.rb +2 -10
  35. data/lib/punchblock/event/answered.rb +3 -3
  36. data/lib/punchblock/event/asterisk/ami/event.rb +15 -47
  37. data/lib/punchblock/event/complete.rb +26 -48
  38. data/lib/punchblock/event/dtmf.rb +3 -13
  39. data/lib/punchblock/event/end.rb +10 -11
  40. data/lib/punchblock/event/joined.rb +5 -25
  41. data/lib/punchblock/event/offer.rb +4 -25
  42. data/lib/punchblock/event/ringing.rb +3 -3
  43. data/lib/punchblock/event/unjoined.rb +5 -25
  44. data/lib/punchblock/event.rb +0 -10
  45. data/lib/punchblock/has_headers.rb +20 -26
  46. data/lib/punchblock/rayo_node.rb +46 -23
  47. data/lib/punchblock/ref.rb +39 -18
  48. data/lib/punchblock/translator/asterisk/agi_app.rb +15 -0
  49. data/lib/punchblock/translator/asterisk/agi_command.rb +3 -1
  50. data/lib/punchblock/translator/asterisk/ami_error_converter.rb +20 -0
  51. data/lib/punchblock/translator/asterisk/call.rb +60 -39
  52. data/lib/punchblock/translator/asterisk/channel.rb +41 -0
  53. data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +4 -1
  54. data/lib/punchblock/translator/asterisk/component/asterisk/ami_action.rb +4 -4
  55. data/lib/punchblock/translator/asterisk/component/composed_prompt.rb +62 -0
  56. data/lib/punchblock/translator/asterisk/component/input.rb +1 -0
  57. data/lib/punchblock/translator/asterisk/component/mrcp_native_prompt.rb +56 -0
  58. data/lib/punchblock/translator/asterisk/component/mrcp_prompt.rb +53 -0
  59. data/lib/punchblock/translator/asterisk/component/mrcp_recog_prompt.rb +99 -0
  60. data/lib/punchblock/translator/asterisk/component/output.rb +30 -22
  61. data/lib/punchblock/translator/asterisk/component/record.rb +8 -6
  62. data/lib/punchblock/translator/asterisk/component.rb +6 -5
  63. data/lib/punchblock/translator/asterisk/unimrcp_app.rb +26 -0
  64. data/lib/punchblock/translator/asterisk.rb +24 -28
  65. data/lib/punchblock/translator/dtmf_recognizer.rb +39 -20
  66. data/lib/punchblock/translator/freeswitch/call.rb +15 -14
  67. data/lib/punchblock/translator/freeswitch/component/abstract_output.rb +5 -4
  68. data/lib/punchblock/translator/freeswitch/component/flite_output.rb +1 -1
  69. data/lib/punchblock/translator/freeswitch/component/input.rb +5 -0
  70. data/lib/punchblock/translator/freeswitch/component/output.rb +2 -2
  71. data/lib/punchblock/translator/freeswitch/component/record.rb +19 -13
  72. data/lib/punchblock/translator/freeswitch/component/tts_output.rb +2 -2
  73. data/lib/punchblock/translator/freeswitch/component.rb +2 -5
  74. data/lib/punchblock/translator/freeswitch.rb +2 -2
  75. data/lib/punchblock/translator/input_component.rb +33 -13
  76. data/lib/punchblock/uri_list.rb +21 -0
  77. data/lib/punchblock/version.rb +1 -1
  78. data/lib/punchblock.rb +4 -3
  79. data/punchblock.gemspec +7 -3
  80. data/spec/punchblock/client/component_registry_spec.rb +1 -1
  81. data/spec/punchblock/client_spec.rb +10 -26
  82. data/spec/punchblock/command/accept_spec.rb +41 -7
  83. data/spec/punchblock/command/answer_spec.rb +51 -7
  84. data/spec/punchblock/command/dial_spec.rb +56 -14
  85. data/spec/punchblock/command/hangup_spec.rb +41 -7
  86. data/spec/punchblock/command/join_spec.rb +53 -11
  87. data/spec/punchblock/command/mute_spec.rb +19 -4
  88. data/spec/punchblock/command/redirect_spec.rb +40 -10
  89. data/spec/punchblock/command/reject_spec.rb +43 -11
  90. data/spec/punchblock/command/unjoin_spec.rb +40 -9
  91. data/spec/punchblock/command/unmute_spec.rb +19 -4
  92. data/spec/punchblock/command_node_spec.rb +0 -4
  93. data/spec/punchblock/component/asterisk/agi/command_spec.rb +16 -39
  94. data/spec/punchblock/component/asterisk/ami/action_spec.rb +50 -53
  95. data/spec/punchblock/component/component_node_spec.rb +3 -5
  96. data/spec/punchblock/component/input_spec.rb +194 -61
  97. data/spec/punchblock/component/output_spec.rb +194 -62
  98. data/spec/punchblock/component/prompt_spec.rb +132 -0
  99. data/spec/punchblock/component/record_spec.rb +70 -32
  100. data/spec/punchblock/connection/asterisk_spec.rb +17 -3
  101. data/spec/punchblock/connection/freeswitch_spec.rb +4 -4
  102. data/spec/punchblock/connection/xmpp_spec.rb +20 -38
  103. data/spec/punchblock/event/answered_spec.rb +12 -10
  104. data/spec/punchblock/event/asterisk/ami/event_spec.rb +27 -22
  105. data/spec/punchblock/event/complete_spec.rb +15 -19
  106. data/spec/punchblock/event/dtmf_spec.rb +5 -6
  107. data/spec/punchblock/event/end_spec.rb +20 -10
  108. data/spec/punchblock/event/joined_spec.rb +8 -7
  109. data/spec/punchblock/event/offer_spec.rb +41 -12
  110. data/spec/punchblock/event/ringing_spec.rb +12 -10
  111. data/spec/punchblock/event/started_speaking_spec.rb +5 -6
  112. data/spec/punchblock/event/stopped_speaking_spec.rb +5 -6
  113. data/spec/punchblock/event/unjoined_spec.rb +7 -7
  114. data/spec/punchblock/ref_spec.rb +86 -9
  115. data/spec/punchblock/translator/asterisk/call_spec.rb +317 -154
  116. data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +28 -5
  117. data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +15 -13
  118. data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +237 -0
  119. data/spec/punchblock/translator/asterisk/component/input_spec.rb +171 -14
  120. data/spec/punchblock/translator/asterisk/component/mrcp_native_prompt_spec.rb +652 -0
  121. data/spec/punchblock/translator/asterisk/component/mrcp_prompt_spec.rb +646 -0
  122. data/spec/punchblock/translator/asterisk/component/output_spec.rb +127 -77
  123. data/spec/punchblock/translator/asterisk/component/record_spec.rb +17 -8
  124. data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +2 -2
  125. data/spec/punchblock/translator/asterisk/component_spec.rb +3 -7
  126. data/spec/punchblock/translator/asterisk_spec.rb +20 -24
  127. data/spec/punchblock/translator/freeswitch/call_spec.rb +103 -99
  128. data/spec/punchblock/translator/freeswitch/component/flite_output_spec.rb +17 -8
  129. data/spec/punchblock/translator/freeswitch/component/input_spec.rb +26 -14
  130. data/spec/punchblock/translator/freeswitch/component/output_spec.rb +30 -52
  131. data/spec/punchblock/translator/freeswitch/component/record_spec.rb +23 -19
  132. data/spec/punchblock/translator/freeswitch/component/tts_output_spec.rb +18 -8
  133. data/spec/punchblock/translator/freeswitch/component_spec.rb +4 -8
  134. data/spec/punchblock/translator/freeswitch_spec.rb +11 -14
  135. data/spec/punchblock/uri_list_spec.rb +49 -0
  136. data/spec/punchblock_spec.rb +11 -1
  137. data/spec/spec_helper.rb +7 -11
  138. data/spec/support/mock_connection_with_event_handler.rb +1 -1
  139. metadata +104 -24
  140. data/lib/punchblock/header.rb +0 -9
  141. data/lib/punchblock/key_value_pair_node.rb +0 -51
  142. data/spec/punchblock/header_spec.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1cb4362475b7ff78950c6a3b6c26079e98f5741a
4
- data.tar.gz: 6e6bf5c7f14bf24e1ea4ca9cb84b1f8e2365935b
3
+ metadata.gz: 49f42b835052273a5744b92e6b84779b2782e0cc
4
+ data.tar.gz: fbcc1abd28ccbf6fbd8ecb200fda82c31ec1ac6c
5
5
  SHA512:
6
- metadata.gz: b5b5d40cd306d3e292b56189f085165c3a39f2e4f069f7b7298cafee1ad65f7b3a597a1db49c79771f1027b3026d0ee6bb9576020b4114c7e08c4ce19aef6b48
7
- data.tar.gz: 93b07c8cc0bdb8472c4b511008e054068c13a79dfa780fe08a3f09ac4b9dbc76b195e55505128291bdef3262461bfb7fb634ba672a8670589c1c6ca3928f664b
6
+ metadata.gz: 5f6b8381a4bb5f30389ee46854e7a5ce569147721de0af96d4a995cea6ca5a6b3f97ecdf53538ea81c48cda8530476f5568a66b985c14254bd9c5f9254993cf8
7
+ data.tar.gz: 7af2927dda7105ab22949cecca00725c97906f0df79d3996b662e0460c3e562137ed3f2a4bab3293902cec8c525165fb67d624727bd2708f70a9ac9ec25e6056
data/.gitignore CHANGED
@@ -12,3 +12,4 @@ vendor
12
12
  .rbx/
13
13
  *.rbc
14
14
  tmp
15
+ coverage
data/.travis.yml CHANGED
@@ -8,7 +8,6 @@ rvm:
8
8
  - ruby-head
9
9
  matrix:
10
10
  allow_failures:
11
- - rvm: rbx-19mode
12
- - rvm: jruby-19mode
11
+ - rvm: ruby-head
13
12
  notifications:
14
13
  irc: "irc.freenode.org#adhearsion"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # [develop](https://github.com/adhearsion/punchblock)
2
2
 
3
+ # [v2.0.0.beta1](https://github.com/adhearsion/punchblock/compare/v1.9.4...v2.0.0.beta1) - [2013-08-20](https://rubygems.org/gems/punchblock/versions/2.0.0.beta1)
4
+ * Bugfix: Reconnect dead Asterisk streams correctly
5
+ * Feature: Added FS support for initial timeout and final timeout on Record.
6
+ * Feature: Compliance with v0.2 of the published Rayo spec (http://xmpp.org/extensions/xep-0327.html)
7
+ * Feature: Add support for Rayo Prompt component (no support on FS)
8
+ * Change: Models are now plain ruby objects, not XML nodes, and are imported from/exported to XML when necessary for communicating over XMPP.
9
+ * Change: `#headers` and AMI `#attributes` now do not have their names modified. A header of `'Call-ID'` will no longer be modified to `:call_id`.
10
+ * Change: AMI Events/Actions now have `#headers(=)` rather than `#attributes(=)`
11
+ * Change: Remove event queue
12
+ * Bugfix: Include AMI response text_body in AMI component complete events
13
+ * Bugfix: Avoid crashing translators (Asterisk or FreeSWITCH) by instructing them to call back to terminated Call objects
14
+ * Bugfix: Detect MRCPSynth failure in output component.
15
+ * Bugfix: Handle AMI errors indicating dead channels correctly
16
+
3
17
  # [v1.9.4](https://github.com/adhearsion/punchblock/compare/v1.9.3...v1.9.4) - [2013-06-08](https://rubygems.org/gems/punchblock/versions/1.9.4)
4
18
  * Bugfix: Finish more setup before sending output ref on Asterisk
5
19
  * Bugfix: Allow early media TTS on Asterisk in addition to audio playback
@@ -29,6 +43,9 @@
29
43
  # [v1.8.2](https://github.com/adhearsion/punchblock/compare/v1.8.1...v1.8.2) - [2013-04-19](https://rubygems.org/gems/punchblock/versions/1.8.2)
30
44
  * Bugfix: Input initial timeout was being set as a float rather than an integer
31
45
 
46
+ # [v1.8.2](https://github.com/adhearsion/punchblock/compare/v1.8.1...v1.8.2) - [2013-04-19](https://rubygems.org/gems/punchblock/versions/1.8.2)
47
+ * Bugfix: Input initial timeout was being set as a float rather than an integer
48
+
32
49
  # [v1.8.1](https://github.com/adhearsion/punchblock/compare/v1.8.0...v1.8.1) - [2013-03-25](https://rubygems.org/gems/punchblock/versions/1.8.1)
33
50
  * Bugfix: FreeSWITCH was requiring a from attribute on a dial command
34
51
  * Bugfix: Asterisk translator now properly checks for existence of the recordings directory
data/Gemfile CHANGED
@@ -2,3 +2,4 @@ source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
4
  gem 'bluecloth' unless RUBY_PLATFORM =~ /java/
5
+ gem 'activesupport', '~> 3.0' if RUBY_VERSION == "1.9.2"
data/Guardfile CHANGED
@@ -3,3 +3,7 @@ guard 'rspec', :cli => '--format documentation' do
3
3
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
4
  watch('spec/spec_helper.rb') { "spec/" }
5
5
  end
6
+
7
+ guard 'rake', task: 'benchmark' do
8
+ watch(/benchmarks\/*/)
9
+ end
data/README.markdown CHANGED
@@ -1,3 +1,9 @@
1
+ [![Gem Version](https://badge.fury.io/rb/punchblock.png)](https://rubygems.org/gems/punchblock)
2
+ [![Build Status](https://secure.travis-ci.org/adhearsion/punchblock.png?branch=develop)](http://travis-ci.org/adhearsion/punchblock)
3
+ [![Dependency Status](https://gemnasium.com/adhearsion/punchblock.png?travis)](https://gemnasium.com/adhearsion/punchblock)
4
+ [![Code Climate](https://codeclimate.com/github/adhearsion/punchblock.png)](https://codeclimate.com/github/adhearsion/punchblock)
5
+ [![Coverage Status](https://coveralls.io/repos/adhearsion/punchblock/badge.png?branch=develop)](https://coveralls.io/r/adhearsion/punchblock)
6
+
1
7
  # Punchblock
2
8
  Punchblock is a middleware library for telephony applications. Like Rack is to Rails and Sinatra, Punchblock provides a consistent API on top of several underlying third-party call control protocols.
3
9
 
data/Rakefile CHANGED
@@ -35,3 +35,19 @@ task :encodeify do
35
35
  end
36
36
  end
37
37
  end
38
+
39
+ require 'timeout'
40
+ desc "Run benchmarks"
41
+ task :benchmark do
42
+ begin
43
+ Timeout.timeout(120) do
44
+ glob = File.expand_path("../benchmarks/*.rb", __FILE__)
45
+ Dir[glob].each { |benchmark| load benchmark }
46
+ end
47
+ rescue Exception, Timeout::Error => ex
48
+ puts "ERROR: Couldn't complete benchmark: #{ex.class}: #{ex}"
49
+ puts " #{ex.backtrace.join("\n ")}"
50
+
51
+ exit 1 unless ENV['CI'] # Hax for running benchmarks on Travis
52
+ end
53
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'benchmark/ips'
6
+
7
+ string = 'FullyBooted'
8
+ FULLY_BOOTED = 'fullybooted'
9
+
10
+ Benchmark.ips do |ips|
11
+ ips.report("downcase+compare") { string.downcase == 'fullybooted' }
12
+ ips.report("casecmp") { string.casecmp('fullybooted') == 0 }
13
+ ips.report("casecmp w/ constant") { string.casecmp(FULLY_BOOTED) == 0 }
14
+ end
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'bundler/setup'
5
+ require 'benchmark/ips'
6
+ require 'punchblock/translator/asterisk/channel'
7
+
8
+ channel_string = 'abc123'
9
+ channel = Punchblock::Translator::Asterisk::Channel.new('abc123')
10
+
11
+ class Wrapper
12
+ def initialize(string)
13
+ @string = string
14
+ end
15
+
16
+ def to_s
17
+ @string
18
+ end
19
+ end
20
+
21
+ wrapper = Wrapper.new 'abc123'
22
+
23
+ Benchmark.ips do |ips|
24
+ ips.report("string nesting") { "SIP/#{channel_string}" }
25
+ ips.report("wrapper nesting") { "SIP/#{wrapper}" }
26
+ ips.report("delegate nesting") { "SIP/#{channel}" }
27
+ end
@@ -8,7 +8,7 @@ module Punchblock
8
8
 
9
9
  include HasGuardedHandlers
10
10
 
11
- attr_reader :connection, :event_queue, :component_registry
11
+ attr_reader :connection, :component_registry
12
12
 
13
13
  delegate :run, :stop, :to => :connection
14
14
 
@@ -16,11 +16,9 @@ module Punchblock
16
16
  # @option options [Connection::XMPP] :connection The Punchblock connection to use for this session
17
17
  #
18
18
  def initialize(options = {})
19
- @event_queue = Queue.new
20
19
  @connection = options[:connection]
21
20
  @connection.event_handler = lambda { |event| self.handle_event event } if @connection
22
21
  @component_registry = ComponentRegistry.new
23
- @write_timeout = options[:write_timeout] || 3
24
22
  end
25
23
 
26
24
  def handle_event(event)
@@ -28,7 +26,7 @@ module Punchblock
28
26
  if event.source
29
27
  event.source.add_event event
30
28
  else
31
- trigger_handler(:event, event) || event_queue.push(event)
29
+ trigger_handler :event, event
32
30
  end
33
31
  end
34
32
 
@@ -49,7 +47,6 @@ module Punchblock
49
47
  end
50
48
 
51
49
  def execute_command(command, options = {})
52
- async = options.has_key?(:async) ? options.delete(:async) : true
53
50
  command.client = self
54
51
  if command.respond_to?(:register_handler)
55
52
  command.register_handler :internal do |event|
@@ -57,7 +54,6 @@ module Punchblock
57
54
  end
58
55
  end
59
56
  connection.write command, options
60
- command.response(@write_timeout).tap { |result| raise result if result.is_a? Exception } unless async
61
57
  end
62
58
  end
63
59
  end
@@ -6,27 +6,6 @@ module Punchblock
6
6
  register :accept, :core
7
7
 
8
8
  include HasHeaders
9
-
10
- ##
11
- # Create a Rayo accept command. This is equivalent to a SIP "180 Trying"
12
- #
13
- # @param [Hash] options
14
- # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
15
- # the call. Can be either a hash of key-value pairs, or an array of
16
- # Header objects.
17
- #
18
- # @return [Command::Accept] a formatted Rayo accept command
19
- #
20
- # @example
21
- # Accept.new.to_xml
22
- #
23
- # returns:
24
- # <accept xmlns="urn:xmpp:rayo:1"/>
25
- def self.new(options = {})
26
- super().tap do |new_node|
27
- new_node.headers = options[:headers]
28
- end
29
- end
30
- end # Accept
31
- end # Command
32
- end # Punchblock
9
+ end
10
+ end
11
+ end
@@ -6,27 +6,6 @@ module Punchblock
6
6
  register :answer, :core
7
7
 
8
8
  include HasHeaders
9
-
10
- ##
11
- # Create a Rayo answer command. This is equivalent to a SIP "200 OK"
12
- #
13
- # @param [Hash] options
14
- # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
15
- # the call. Can be either a hash of key-value pairs, or an array of
16
- # Header objects.
17
- #
18
- # @return [Command::Answer] a formatted Rayo answer command
19
- #
20
- # @example
21
- # Answer.new.to_xml
22
- #
23
- # returns:
24
- # <answer xmlns="urn:xmpp:rayo:1"/>
25
- def self.new(options = {})
26
- super().tap do |new_node|
27
- new_node.headers = options[:headers]
28
- end
29
- end
30
- end # Answer
31
- end # Command
32
- end # Punchblock
9
+ end
10
+ end
11
+ end
@@ -7,94 +7,42 @@ module Punchblock
7
7
 
8
8
  include HasHeaders
9
9
 
10
- ##
11
- # Create a dial command
12
- #
13
- # @param [Hash] options
14
- # @option options [String] :to destination to dial
15
- # @option options [String, Optional] :from what to set the Caller ID to
16
- # @option options [Integer, Optional] :timeout in milliseconds
17
- # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
18
- # the new call. Can be either a hash of key-value pairs, or an array of
19
- # Header objects.
20
- # @option options [Join, Hash, Optional] :join a join (or set of join parameters) to
21
- # nest within the dial
22
- #
23
- # @return [Command::Dial] a formatted Rayo dial command
24
- #
25
- # @example
26
- # dial :to => 'tel:+14155551212', :from => 'tel:+13035551212'
27
- #
28
- # returns:
29
- # <dial to='tel:+13055195825' from='tel:+14152226789' xmlns='urn:xmpp:rayo:1' />
30
- #
31
- def self.new(options = {})
32
- super().tap do |new_node|
33
- options.each_pair { |k,v| new_node.send :"#{k}=", v }
34
- end
35
- end
36
-
37
- ##
38
10
  # @return [String] destination to dial
39
- def to
40
- read_attr :to
41
- end
42
-
43
- ##
44
- # @param [String] dial_to destination to dial
45
- def to=(dial_to)
46
- write_attr :to, dial_to
47
- end
11
+ attribute :to
48
12
 
49
- ##
50
13
  # @return [String] the caller ID
51
- def from
52
- read_attr :from
53
- end
14
+ attribute :from
54
15
 
55
- ##
56
- # @param [String] dial_from what to set the caller ID to
57
- def from=(dial_from)
58
- write_attr :from, dial_from
59
- end
60
-
61
- ##
62
16
  # @return [Integer] timeout in milliseconds
63
- def timeout
64
- read_attr :timeout, :to_i
65
- end
17
+ attribute :timeout, Integer
66
18
 
67
- ##
68
- # @param [Integer] other timeout in milliseconds
69
- def timeout=(other)
70
- write_attr :timeout, other
71
- end
72
-
73
- ##
74
19
  # @return [Join] the nested join
75
- #
76
- def join
77
- element = find_first 'ns:join', :ns => Join.registered_ns
78
- Join.new element if element
20
+ attribute :join, Join
21
+
22
+ def inherit(xml_node)
23
+ if join_element = xml_node.at_xpath('ns:join', ns: Join.registered_ns)
24
+ self.join = Join.from_xml(join_element)
25
+ end
26
+ super
79
27
  end
80
28
 
81
- ##
82
- # @param [Hash, Join] other a join or hash of join options
83
- #
84
- def join=(other)
85
- remove_children :join
86
- join = Join.new(other) unless other.is_a?(Join)
87
- self << join
29
+ def rayo_attributes
30
+ {to: to, from: from, timeout: timeout}
88
31
  end
89
32
 
90
- def response=(other)
91
- @target_call_id = other.id if other.is_a?(Ref)
33
+ def rayo_children(root)
34
+ join.to_rayo(root.parent) if join
92
35
  super
93
36
  end
94
37
 
95
- def inspect_attributes # :nodoc:
96
- [:to, :from, :join] + super
38
+ def response=(other)
39
+ if other.is_a?(Ref)
40
+ @transport = other.scheme
41
+ @target_call_id = other.call_id
42
+ @domain = other.domain
43
+ end
44
+ super
97
45
  end
98
- end # Dial
99
- end # Command
100
- end # Punchblock
46
+ end
47
+ end
48
+ end
@@ -6,22 +6,6 @@ module Punchblock
6
6
  register :hangup, :core
7
7
 
8
8
  include HasHeaders
9
-
10
- ##
11
- # Create a Rayo hangup command
12
- #
13
- # @param [Hash] options
14
- # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
15
- # the call. Can be either a hash of key-value pairs, or an array of
16
- # Header objects.
17
- #
18
- # @return [Command::Hangup] a formatted Rayo redirect command
19
- #
20
- def self.new(options = {})
21
- super().tap do |new_node|
22
- new_node.headers = options[:headers]
23
- end
24
- end
25
- end # Hangup
26
- end # Command
27
- end # Punchblock
9
+ end
10
+ end
11
+ end
@@ -7,82 +7,33 @@ module Punchblock
7
7
 
8
8
  VALID_DIRECTIONS = [:duplex, :send, :recv].freeze
9
9
 
10
- ##
11
- # Create a join command
12
- #
13
- # @param [Hash] options
14
- # @option options [String, Optional] :call_id the call ID to join
15
- # @option options [String, Optional] :mixer_name the mixer name to join
16
- # @option options [Symbol, Optional] :direction the direction in which media should flow
17
- # @option options [Symbol, Optional] :media the method by which to negotiate media
18
- #
19
- # @return [Command::Join] a formatted Rayo join command
20
- #
21
- def self.new(options = {})
22
- super().tap do |new_node|
23
- case options
24
- when Nokogiri::XML::Node
25
- new_node.inherit options
26
- when Hash
27
- options.each_pair { |k,v| new_node.send :"#{k}=", v }
28
- end
29
- end
30
- end
31
-
32
- ##
33
10
  # @return [String] the call ID to join
34
- def call_id
35
- read_attr :'call-id'
36
- end
11
+ attribute :call_uri
12
+ alias :call_id= :call_uri=
37
13
 
38
- ##
39
- # @param [String] other the call ID to join
40
- def call_id=(other)
41
- write_attr :'call-id', other
42
- end
43
-
44
- ##
45
14
  # @return [String] the mixer name to join
46
- def mixer_name
47
- read_attr :'mixer-name'
48
- end
15
+ attribute :mixer_name
49
16
 
50
- ##
51
- # @param [String] other the mixer name to join
52
- def mixer_name=(other)
53
- write_attr :'mixer-name', other
54
- end
55
-
56
- ##
57
- # @return [String] the direction in which media should flow
58
- def direction
59
- read_attr :direction, :to_sym
60
- end
61
-
62
- ##
63
- # @param [String] other the direction in which media should flow. Can be :duplex, :recv or :send
64
- def direction=(direction)
65
- if direction && !VALID_DIRECTIONS.include?(direction.to_sym)
66
- raise ArgumentError, "Invalid Direction (#{direction}), use: #{VALID_DIRECTIONS*' '}"
17
+ # @param [#to_sym] other the direction in which media should flow. Can be :duplex, :recv or :send
18
+ attribute :direction, Symbol
19
+ def direction=(other)
20
+ if other && !VALID_DIRECTIONS.include?(other.to_sym)
21
+ raise ArgumentError, "Invalid Direction (#{other.inspect}), use: #{VALID_DIRECTIONS*' '}"
67
22
  end
68
- write_attr :direction, direction
23
+ super
69
24
  end
70
25
 
71
- ##
72
- # @return [String] the method by which to negotiate media
73
- def media
74
- read_attr :media, :to_sym
75
- end
76
-
77
- ##
78
- # @param [String] other the method by which to negotiate media. Can be :direct or :bridge
79
- def media=(other)
80
- write_attr :media, other
81
- end
26
+ # @return [#to_sym] the method by which to negotiate media
27
+ attribute :media, Symbol
82
28
 
83
- def inspect_attributes # :nodoc:
84
- [:call_id, :mixer_name, :direction, :media] + super
29
+ def rayo_attributes
30
+ {
31
+ 'call-uri' => call_uri,
32
+ 'mixer-name' => mixer_name,
33
+ 'direction' => direction,
34
+ 'media' => media
35
+ }
85
36
  end
86
- end # Join
87
- end # Command
88
- end # Punchblock
37
+ end
38
+ end
39
+ end
@@ -4,6 +4,6 @@ module Punchblock
4
4
  module Command
5
5
  class Mute < CommandNode
6
6
  register :mute, :core
7
- end # Mute
8
- end # Command
9
- end # Punchblock
7
+ end
8
+ end
9
+ end
@@ -7,45 +7,12 @@ module Punchblock
7
7
 
8
8
  include HasHeaders
9
9
 
10
- ##
11
- # Create a Rayo redirect command
12
- #
13
- # @param [Hash] options
14
- # @option options [String] :to redirect target
15
- # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
16
- # the new call. Can be either a hash of key-value pairs, or an array of
17
- # Header objects.
18
- #
19
- # @return [Command::Redirect] a formatted Rayo redirect command
20
- #
21
- # @example
22
- # Redirect.new(:to => 'tel:+14045551234').to_xml
23
- #
24
- # returns:
25
- # <redirect to="tel:+14045551234" xmlns="urn:xmpp:rayo:1"/>
26
- #
27
- def self.new(options = {})
28
- super().tap do |new_node|
29
- new_node.to = options[:to]
30
- new_node.headers = options[:headers]
31
- end
32
- end
33
-
34
- ##
35
10
  # @return [String] the redirect target
36
- def to
37
- read_attr :to
38
- end
39
-
40
- ##
41
- # @param [String] redirect_to redirect target
42
- def to=(redirect_to)
43
- write_attr :to, redirect_to
44
- end
11
+ attribute :to
45
12
 
46
- def inspect_attributes # :nodoc:
47
- [:to] + super
13
+ def rayo_attributes
14
+ {'to' => to}
48
15
  end
49
- end # Redirect
50
- end # Command
51
- end # Punchblock
16
+ end
17
+ end
18
+ end
@@ -9,67 +9,27 @@ module Punchblock
9
9
 
10
10
  VALID_REASONS = [:busy, :decline, :error].freeze
11
11
 
12
- ##
13
- # Create a Rayo reject command
14
- #
15
- # @param [Hash] options
16
- # @option options [Symbol] :reason for rejecting the call. Can be any one of VALID_REASONS. Defaults to :decline
17
- # @option options [Array[Header], Hash, Optional] :headers SIP headers to attach to
18
- # the call. Can be either a hash of key-value pairs, or an array of
19
- # Header objects.
20
- #
21
- # @return [Command::Reject] a formatted Rayo reject command
22
- #
23
- # @example
24
- # Reject.new(:reason => :busy).to_xml
25
- #
26
- # returns:
27
- # <reject xmlns="urn:xmpp:rayo:1"><busy/></reject
28
- #
29
- def self.new(options = {})
30
- super().tap do |new_node|
31
- case options
32
- when Nokogiri::XML::Node
33
- new_node.inherit options
34
- when Hash
35
- options.each_pair { |k,v| new_node.send :"#{k}=", v }
36
- end
37
- end
38
- end
39
-
40
- ##
41
- # @return [Symbol] the reason type for rejecting a call
42
- #
43
- def reason
44
- node = reason_node
45
- node ? node.name.to_sym : nil
46
- end
47
-
48
- ##
49
- # Set the reason for rejecting the call
50
- #
51
- # @param [Symbol] reject_reason Can be any one of :busy, :dclined or :error.
52
- #
12
+ # @return [Symbol] the reason type for rejecting a call. One of :busy, :dclined or :error.
53
13
  # @raises ArgumentError if reject_reason is not one of the allowed reasons
54
- #
14
+ attribute :reason, Symbol
55
15
  def reason=(reject_reason)
56
16
  if reject_reason && !VALID_REASONS.include?(reject_reason.to_sym)
57
17
  raise ArgumentError, "Invalid Reason (#{reject_reason}), use: #{VALID_REASONS*' '}"
58
18
  end
59
- children.each(&:remove)
60
- self << RayoNode.new(reject_reason) if reject_reason
19
+ super
61
20
  end
62
21
 
63
- def inspect_attributes # :nodoc:
64
- [:reason] + super
22
+ def inherit(xml_node)
23
+ if first_child = xml_node.at_xpath('*')
24
+ self.reason = first_child.name
25
+ end
26
+ super
65
27
  end
66
28
 
67
- private
68
-
69
- def reason_node
70
- node_children = children.select { |c| [Nokogiri::XML::Element, Niceogiri::XML::Node].any? { |k| c.is_a?(k) } }
71
- node_children.first
29
+ def rayo_children(root)
30
+ root.send reason if reason
31
+ super
72
32
  end
73
- end # Reject
74
- end # Command
75
- end # Punchblock
33
+ end
34
+ end
35
+ end