punchblock 1.9.4 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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