punchblock 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # develop
2
2
 
3
+ # v0.6.1
4
+ * Feature: Allow instructing the connection we are ready. An XMPP connection will send initial presence with a status of 'chat' to the rayo domain
5
+ * Bugfix: When running on Asterisk, two FullyBooted events will now trigger a connected event
6
+ * Bugfix: No longer ignore offers from the specified rayo domain on XMPP connections
7
+ * Feature: Tag all event objects with the XMPP domain they came from
8
+
3
9
  # v0.6.0
4
10
  * API change: Punchblock consumers now need to instantiate both a Connection and a Client (see the punchblock-console gem for an example)
5
11
  * Feature: Added a Connection for Asterisk, utilising RubyAMI to open an AMI connection to Asterisk, and allowing AMI actions to be executed. AMI events are handled by the client event handler.
@@ -4,6 +4,7 @@ module Punchblock
4
4
 
5
5
  autoload :Asterisk
6
6
  autoload :Connected
7
+ autoload :GenericConnection
7
8
  autoload :XMPP
8
9
  end
9
10
  end
@@ -2,13 +2,15 @@ require 'ruby_ami'
2
2
 
3
3
  module Punchblock
4
4
  module Connection
5
- class Asterisk
5
+ class Asterisk < GenericConnection
6
6
  attr_reader :ami_client, :translator
7
7
  attr_accessor :event_handler
8
8
 
9
9
  def initialize(options = {})
10
+ options[:logger] = options[:wire_logger]
10
11
  @ami_client = RubyAMI::Client.new options.merge(:event_handler => lambda { |event| translator.handle_ami_event! event })
11
12
  @translator = Translator::Asterisk.new @ami_client, self
13
+ super()
12
14
  end
13
15
 
14
16
  def run
@@ -8,6 +8,11 @@ module Punchblock
8
8
  def client=(other)
9
9
  nil
10
10
  end
11
+
12
+ def eql?(other)
13
+ other.is_a? self.class
14
+ end
15
+ alias :== :eql?
11
16
  end
12
17
  end
13
18
  end
@@ -0,0 +1,13 @@
1
+ module Punchblock
2
+ module Connection
3
+ class GenericConnection
4
+ def initialize
5
+ @event_handler = lambda { |event| raise 'No event handler set' }
6
+ end
7
+
8
+ def ready!
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -7,7 +7,7 @@
7
7
 
8
8
  module Punchblock
9
9
  module Connection
10
- class XMPP
10
+ class XMPP < GenericConnection
11
11
  include Blather::DSL
12
12
  attr_accessor :event_handler
13
13
 
@@ -37,9 +37,9 @@ module Punchblock
37
37
 
38
38
  @ping_period = options.has_key?(:ping_period) ? options[:ping_period] : 60
39
39
 
40
- @event_handler = lambda { |event| raise 'No event handler set' }
41
-
42
40
  Blather.logger = options.delete(:wire_logger) if options.has_key?(:wire_logger)
41
+
42
+ super()
43
43
  end
44
44
 
45
45
  def write(command, options = {})
@@ -91,15 +91,23 @@ module Punchblock
91
91
  client.connected?
92
92
  end
93
93
 
94
+ def ready!
95
+ status = Blather::Stanza::Presence::Status.new :chat
96
+ status.to = @rayo_domain
97
+ client.write status
98
+ super
99
+ end
100
+
94
101
  private
95
102
 
96
103
  def handle_presence(p)
97
- throw :pass unless p.rayo_event? && p.from.domain == @rayo_domain
104
+ throw :pass unless p.rayo_event?
98
105
  @logger.info "Receiving event for call ID #{p.call_id}" if @logger
99
106
  @callmap[p.call_id] = p.from.domain
100
107
  @logger.debug p.inspect if @logger
101
108
  event = p.event
102
109
  event.connection = self
110
+ event.domain = p.from.domain
103
111
  event_handler.call event
104
112
  end
105
113
 
@@ -7,7 +7,7 @@ module Punchblock
7
7
 
8
8
  class_attribute :registered_ns, :registered_name
9
9
 
10
- attr_accessor :call_id, :component_id, :connection, :client, :original_component
10
+ attr_accessor :call_id, :component_id, :domain, :connection, :client, :original_component
11
11
 
12
12
  # Register a new stanza class to a name and/or namespace
13
13
  #
@@ -18,6 +18,7 @@ module Punchblock
18
18
  def initialize(ami_client, connection)
19
19
  @ami_client, @connection = ami_client, connection
20
20
  @calls, @components = {}, {}
21
+ @fully_booted_count = 0
21
22
  end
22
23
 
23
24
  def register_call(call)
@@ -38,7 +39,15 @@ module Punchblock
38
39
 
39
40
  def handle_ami_event(event)
40
41
  return unless event.is_a? RubyAMI::Event
41
- connection.handle_event Event::Asterisk::AMI::Event.new(:name => event.name, :attributes => event.headers)
42
+ if event.name.downcase == "fullybooted"
43
+ @fully_booted_count += 1
44
+ if @fully_booted_count >= 2
45
+ connection.handle_event Connection::Connected.new
46
+ @fully_booted_count = 0
47
+ end
48
+ else
49
+ connection.handle_event Event::Asterisk::AMI::Event.new(:name => event.name, :attributes => event.headers)
50
+ end
42
51
  end
43
52
 
44
53
  def execute_command(command, options = {})
@@ -1,3 +1,3 @@
1
1
  module Punchblock
2
- VERSION = "0.6.0"
2
+ VERSION = "0.6.1"
3
3
  end
@@ -117,6 +117,7 @@ module Punchblock
117
117
  mock_event_handler.expects(:call).once.with do |event|
118
118
  event.should be_instance_of Event::Offer
119
119
  event.call_id.should == '9f00061'
120
+ event.domain.should == 'call.rayo.net'
120
121
  end
121
122
  handle_presence
122
123
  end
@@ -144,25 +145,6 @@ module Punchblock
144
145
  lambda { connection.__send__ :handle_presence, example_irrelevant_event }.should throw_symbol(:pass)
145
146
  end
146
147
  end
147
-
148
- describe "from someone other than the rayo domain" do
149
- let :irrelevant_xml do
150
- <<-MSG
151
- <presence to='16577@app.rayo.net/1' from='9f00061@jabber.org/fgh4590'>
152
- <complete xmlns='urn:xmpp:rayo:ext:1'>
153
- <success xmlns='urn:xmpp:tropo:say:complete:1' />
154
- </complete>
155
- </presence>
156
- MSG
157
- end
158
-
159
- let(:example_irrelevant_event) { import_stanza irrelevant_xml }
160
-
161
- it 'should not handle the event' do
162
- mock_event_handler.expects(:call).never
163
- lambda { connection.__send__ :handle_presence, example_irrelevant_event }.should throw_symbol(:pass)
164
- end
165
- end
166
148
  end
167
149
  end
168
150
 
@@ -144,6 +144,26 @@ module Punchblock
144
144
  subject.handle_ami_event :foo
145
145
  end
146
146
  end
147
+
148
+
149
+ describe 'with a FullyBooted event' do
150
+ let(:ami_event) { RubyAMI::Event.new 'FullyBooted' }
151
+
152
+ context 'once' do
153
+ it 'does not send anything to the connection' do
154
+ subject.connection.expects(:handle_event).never
155
+ subject.handle_ami_event ami_event
156
+ end
157
+ end
158
+
159
+ context 'twice' do
160
+ it 'sends a connected event to the event handler' do
161
+ subject.connection.expects(:handle_event).once.with Connection::Connected.new
162
+ subject.handle_ami_event ami_event
163
+ subject.handle_ami_event ami_event
164
+ end
165
+ end
166
+ end
147
167
  end
148
168
  end
149
169
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: punchblock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -15,7 +15,7 @@ date: 2011-11-08 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: niceogiri
18
- requirement: &2160733620 !ruby/object:Gem::Requirement
18
+ requirement: &2164783340 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: 0.0.4
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *2160733620
26
+ version_requirements: *2164783340
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: blather
29
- requirement: &2160732480 !ruby/object:Gem::Requirement
29
+ requirement: &2164802760 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: 0.5.7
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *2160732480
37
+ version_requirements: *2164802760
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: pry
40
- requirement: &2160730960 !ruby/object:Gem::Requirement
40
+ requirement: &2164801920 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: 0.8.3
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *2160730960
48
+ version_requirements: *2164801920
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: activesupport
51
- requirement: &2160729840 !ruby/object:Gem::Requirement
51
+ requirement: &2164800700 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: 2.1.0
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *2160729840
59
+ version_requirements: *2164800700
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: state_machine
62
- requirement: &2160729040 !ruby/object:Gem::Requirement
62
+ requirement: &2164799620 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: 1.0.1
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *2160729040
70
+ version_requirements: *2164799620
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: future-resource
73
- requirement: &2160728280 !ruby/object:Gem::Requirement
73
+ requirement: &2164798360 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: 0.0.2
79
79
  type: :runtime
80
80
  prerelease: false
81
- version_requirements: *2160728280
81
+ version_requirements: *2164798360
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: has-guarded-handlers
84
- requirement: &2160727760 !ruby/object:Gem::Requirement
84
+ requirement: &2164797820 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
@@ -89,10 +89,10 @@ dependencies:
89
89
  version: 0.1.0
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *2160727760
92
+ version_requirements: *2164797820
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: celluloid
95
- requirement: &2160727280 !ruby/object:Gem::Requirement
95
+ requirement: &2164797340 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ! '>='
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: 0.5.0
101
101
  type: :runtime
102
102
  prerelease: false
103
- version_requirements: *2160727280
103
+ version_requirements: *2164797340
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: ruby_ami
106
- requirement: &2160726780 !ruby/object:Gem::Requirement
106
+ requirement: &2164796840 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ! '>='
@@ -111,10 +111,10 @@ dependencies:
111
111
  version: 0.1.2
112
112
  type: :runtime
113
113
  prerelease: false
114
- version_requirements: *2160726780
114
+ version_requirements: *2164796840
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: bundler
117
- requirement: &2160726080 !ruby/object:Gem::Requirement
117
+ requirement: &2164796320 !ruby/object:Gem::Requirement
118
118
  none: false
119
119
  requirements:
120
120
  - - ~>
@@ -122,10 +122,10 @@ dependencies:
122
122
  version: 1.0.0
123
123
  type: :development
124
124
  prerelease: false
125
- version_requirements: *2160726080
125
+ version_requirements: *2164796320
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: rspec
128
- requirement: &2160546520 !ruby/object:Gem::Requirement
128
+ requirement: &2164795840 !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
131
131
  - - ! '>='
@@ -133,10 +133,10 @@ dependencies:
133
133
  version: 2.5.0
134
134
  type: :development
135
135
  prerelease: false
136
- version_requirements: *2160546520
136
+ version_requirements: *2164795840
137
137
  - !ruby/object:Gem::Dependency
138
138
  name: ci_reporter
139
- requirement: &2160546040 !ruby/object:Gem::Requirement
139
+ requirement: &2164795280 !ruby/object:Gem::Requirement
140
140
  none: false
141
141
  requirements:
142
142
  - - ! '>='
@@ -144,10 +144,10 @@ dependencies:
144
144
  version: 1.6.3
145
145
  type: :development
146
146
  prerelease: false
147
- version_requirements: *2160546040
147
+ version_requirements: *2164795280
148
148
  - !ruby/object:Gem::Dependency
149
149
  name: yard
150
- requirement: &2160545300 !ruby/object:Gem::Requirement
150
+ requirement: &2164746600 !ruby/object:Gem::Requirement
151
151
  none: false
152
152
  requirements:
153
153
  - - ~>
@@ -155,10 +155,10 @@ dependencies:
155
155
  version: 0.6.0
156
156
  type: :development
157
157
  prerelease: false
158
- version_requirements: *2160545300
158
+ version_requirements: *2164746600
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: rcov
161
- requirement: &2160544240 !ruby/object:Gem::Requirement
161
+ requirement: &2164745540 !ruby/object:Gem::Requirement
162
162
  none: false
163
163
  requirements:
164
164
  - - ! '>='
@@ -166,10 +166,10 @@ dependencies:
166
166
  version: '0'
167
167
  type: :development
168
168
  prerelease: false
169
- version_requirements: *2160544240
169
+ version_requirements: *2164745540
170
170
  - !ruby/object:Gem::Dependency
171
171
  name: rake
172
- requirement: &2160543520 !ruby/object:Gem::Requirement
172
+ requirement: &2164744600 !ruby/object:Gem::Requirement
173
173
  none: false
174
174
  requirements:
175
175
  - - ! '>='
@@ -177,10 +177,10 @@ dependencies:
177
177
  version: '0'
178
178
  type: :development
179
179
  prerelease: false
180
- version_requirements: *2160543520
180
+ version_requirements: *2164744600
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: mocha
183
- requirement: &2160542900 !ruby/object:Gem::Requirement
183
+ requirement: &2164744080 !ruby/object:Gem::Requirement
184
184
  none: false
185
185
  requirements:
186
186
  - - ! '>='
@@ -188,10 +188,10 @@ dependencies:
188
188
  version: '0'
189
189
  type: :development
190
190
  prerelease: false
191
- version_requirements: *2160542900
191
+ version_requirements: *2164744080
192
192
  - !ruby/object:Gem::Dependency
193
193
  name: i18n
194
- requirement: &2160542320 !ruby/object:Gem::Requirement
194
+ requirement: &2164743260 !ruby/object:Gem::Requirement
195
195
  none: false
196
196
  requirements:
197
197
  - - ! '>='
@@ -199,10 +199,10 @@ dependencies:
199
199
  version: '0'
200
200
  type: :development
201
201
  prerelease: false
202
- version_requirements: *2160542320
202
+ version_requirements: *2164743260
203
203
  - !ruby/object:Gem::Dependency
204
204
  name: countdownlatch
205
- requirement: &2160541740 !ruby/object:Gem::Requirement
205
+ requirement: &2164742420 !ruby/object:Gem::Requirement
206
206
  none: false
207
207
  requirements:
208
208
  - - ! '>='
@@ -210,7 +210,7 @@ dependencies:
210
210
  version: '0'
211
211
  type: :development
212
212
  prerelease: false
213
- version_requirements: *2160541740
213
+ version_requirements: *2164742420
214
214
  description: Like Rack is to Rails and Sinatra, Punchblock provides a consistent API
215
215
  on top of several underlying third-party call control protocols.
216
216
  email: punchblock@adhearsion.com
@@ -265,6 +265,7 @@ files:
265
265
  - lib/punchblock/connection.rb
266
266
  - lib/punchblock/connection/asterisk.rb
267
267
  - lib/punchblock/connection/connected.rb
268
+ - lib/punchblock/connection/generic_connection.rb
268
269
  - lib/punchblock/connection/xmpp.rb
269
270
  - lib/punchblock/core_ext/blather/stanza.rb
270
271
  - lib/punchblock/core_ext/blather/stanza/presence.rb