punchblock 0.12.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # [develop](https://github.com/adhearsion/punchblock)
2
2
 
3
+ # [v1.0.0](https://github.com/adhearsion/punchblock/compare/v0.12.0...v1.0.0) - [2012-04-11](https://rubygems.org/gems/punchblock/versions/1.0.0)
4
+ * Stable release :D
5
+ * Bugfix: Any issue in compiling an output document into executable elements on Asterisk should return an unrenderable doc error
6
+
3
7
  # [v0.12.0](https://github.com/adhearsion/punchblock/compare/v0.11.0...v0.12.0) - [2012-03-30](https://rubygems.org/gems/punchblock/versions/0.12.0)
4
8
  * API Change: `#call_id` and `#mixer_name` attributes changed to `#target_call_id` and `#target_mixer_name`
5
9
  * API Change: `#other_call_id` attributes changed to `#call_id` to better align with Rayo
data/LICENSE.txt CHANGED
@@ -1,6 +1,4 @@
1
- Copyright (C) 2011 Ben Klang
2
- Copyright (C) 2011 Ben Langfeld
3
- Copyright (C) 2011 Jason Goecke
1
+ Copyright (C) 2012 Adhearsion Foundation Inc
4
2
 
5
3
  Permission is hereby granted, free of charge, to any person obtaining
6
4
  a copy of this software and associated documentation files (the
data/README.markdown CHANGED
@@ -1,31 +1,34 @@
1
- PUNCHBLOCK
2
- ==========
1
+ # Punchblock
2
+ 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
3
 
4
- Punchblock is a middleware library for telephony applications. Like Rack is to
5
- Rails and Sinatra, Punchblock provides a consistent API on top of several
6
- underlying third-party call control protocols.
4
+ In the same spirit that inspired Rack, the Punchblock library is envisioned to be the single library for call control wiring. Frameworks and applications may take advantage of Punchblock's single API to write powerful code for managing calls. Punchblock is not and will not be an application framework; rather it only surfaces the various protocols and presents a consistent interface to its consumers.
7
5
 
8
- Design
9
- ------
6
+ ## Installation
7
+ gem install punchblock
10
8
 
11
- In the same spirit that inspired Rack, the Punchblock library is envisioned to
12
- be the single library for call control wiring. Frameworks and applications may
13
- take advantage of Punchblock's single API to write powerful code for managing
14
- calls. Punchblock is not and will not be an application framework; rather it
15
- only surfaces the various protocols and presents a consistent interface to its
16
- consumers.
9
+ ## Usage
17
10
 
18
- Supported Protocols
19
- -------------------
11
+ The best available usage documentation available for Punchblock is by example, in Adhearsion.
20
12
 
21
- Punchblock is still in very early stages so this list
22
- is what we plan to support:
13
+ ## Supported Protocols
23
14
 
24
- * Rayo (Tropo, Voxeo Prism)
25
- * AGI/AMI (Asterisk)
26
- * EventSocket (FreeSWITCH, maybe)
15
+ * Rayo
16
+ * Asterisk (AMI & AsyncAGI)
27
17
 
28
- Installation
29
- ------------
18
+ ## Links:
19
+ * [Source](https://github.com/adhearsion/punchblock)
20
+ * [Documentation](http://rdoc.info/github/adhearsion/punchblock/master/frames)
21
+ * [Bug Tracker](https://github.com/adhearsion/punchblock/issues)
30
22
 
31
- gem install punchblock
23
+ ## Note on Patches/Pull Requests
24
+
25
+ * Fork the project.
26
+ * Make your feature addition or bug fix.
27
+ * Add tests for it. This is important so I don't break it in a future version unintentionally.
28
+ * Commit, do not mess with rakefile, version, or history.
29
+ * If you want to have your own version, that is fine but bump version in a commit by itself so I can ignore when I pull
30
+ * Send me a pull request. Bonus points for topic branches.
31
+
32
+ ## Copyright
33
+
34
+ Copyright (c) 2012 Adhearsion Foundation Inc. MIT licence (see LICENSE for details).
data/lib/punchblock.rb CHANGED
@@ -43,7 +43,7 @@ module Punchblock
43
43
 
44
44
  ##
45
45
  # This exception may be raised if a transport error is detected.
46
- TransportError = Class.new StandardError
46
+ Error = Class.new StandardError
47
47
 
48
48
  BASE_RAYO_NAMESPACE = 'urn:xmpp:rayo'
49
49
  BASE_ASTERISK_NAMESPACE = 'urn:xmpp:rayo:asterisk'
@@ -3,7 +3,7 @@
3
3
  module Punchblock
4
4
  ##
5
5
  # This exception may be raised if a transport error is detected.
6
- class ProtocolError < StandardError
6
+ class ProtocolError < Error
7
7
  attr_accessor :name, :text, :call_id, :component_id
8
8
 
9
9
  def setup(name = nil, text = nil, call_id = nil, component_id = nil)
@@ -12,6 +12,8 @@ module Punchblock
12
12
  autoload :StopByRedirect
13
13
 
14
14
  class Component
15
+ OptionError = Class.new Punchblock::Error
16
+
15
17
  include Celluloid
16
18
 
17
19
  attr_reader :id, :call
@@ -18,10 +18,10 @@ module Punchblock
18
18
  initial_timeout = @component_node.initial_timeout || -1
19
19
  @inter_digit_timeout = @component_node.inter_digit_timeout || -1
20
20
 
21
- return with_error 'option error', 'A grammar document is required.' unless @component_node.grammar
22
- return with_error 'option error', 'A mode value other than DTMF is unsupported on Asterisk.' unless @component_node.mode == :dtmf
23
- return with_error 'option error', 'An initial timeout value that is negative (and not -1) is invalid.' unless initial_timeout >= -1
24
- return with_error 'option error', 'An inter-digit timeout value that is negative (and not -1) is invalid.' unless @inter_digit_timeout >= -1
21
+ raise OptionError, 'A grammar document is required.' unless @component_node.grammar
22
+ raise OptionError, 'A mode value other than DTMF is unsupported on Asterisk.' unless @component_node.mode == :dtmf
23
+ raise OptionError, 'An initial timeout value that is negative (and not -1) is invalid.' unless initial_timeout >= -1
24
+ raise OptionError, 'An inter-digit timeout value that is negative (and not -1) is invalid.' unless @inter_digit_timeout >= -1
25
25
 
26
26
  send_ref
27
27
 
@@ -42,6 +42,8 @@ module Punchblock
42
42
  component.process_dtmf! event['Digit'] if event['End'] == 'Yes'
43
43
  end
44
44
  end
45
+ rescue OptionError => e
46
+ with_error 'option error', e.message
45
47
  end
46
48
 
47
49
  def process_dtmf(digit)
@@ -9,6 +9,8 @@ module Punchblock
9
9
  class Output < Component
10
10
  include StopByRedirect
11
11
 
12
+ UnrenderableDocError = Class.new OptionError
13
+
12
14
  def setup
13
15
  @media_engine = @call.translator.media_engine
14
16
  end
@@ -16,30 +18,18 @@ module Punchblock
16
18
  def execute
17
19
  @call.answer_if_not_answered
18
20
 
19
- return with_error 'option error', 'An SSML document is required.' unless @component_node.ssml
20
-
21
- return with_error 'option error', 'An interrupt-on value of speech is unsupported.' if @component_node.interrupt_on == :speech
21
+ raise OptionError, 'An SSML document is required.' unless @component_node.ssml
22
+ raise OptionError, 'An interrupt-on value of speech is unsupported.' if @component_node.interrupt_on == :speech
22
23
 
23
24
  [:start_offset, :start_paused, :repeat_interval, :repeat_times, :max_time].each do |opt|
24
- return with_error 'option error', "A #{opt} value is unsupported on Asterisk." if @component_node.send opt
25
+ raise OptionError, "A #{opt} value is unsupported on Asterisk." if @component_node.send opt
25
26
  end
26
27
 
27
28
  case @media_engine
28
29
  when :asterisk, nil
29
- return with_error 'option error', "A voice value is unsupported on Asterisk." if @component_node.voice
30
-
31
- @execution_elements = @component_node.ssml.children.map do |node|
32
- case node
33
- when RubySpeech::SSML::Audio
34
- lambda { current_actor.play_audio! node.src }
35
- when String
36
- return unrenderable_doc_error if node.include?(' ')
37
- lambda { current_actor.play_audio! node }
38
- else
39
- return unrenderable_doc_error
40
- end
41
- end.compact
30
+ raise OptionError, "A voice value is unsupported on Asterisk." if @component_node.voice
42
31
 
32
+ @execution_elements = collect_executable_elements
43
33
  @pending_actions = @execution_elements.count
44
34
 
45
35
  send_ref
@@ -73,6 +63,26 @@ module Punchblock
73
63
  output_component.send_complete_event! success_reason
74
64
  end
75
65
  end
66
+ rescue UnrenderableDocError => e
67
+ with_error 'unrenderable document error', e.message
68
+ rescue OptionError => e
69
+ with_error 'option error', e.message
70
+ end
71
+
72
+ def collect_executable_elements
73
+ @component_node.ssml.children.map do |node|
74
+ case node
75
+ when RubySpeech::SSML::Audio
76
+ lambda { current_actor.play_audio! node.src }
77
+ when String
78
+ raise UnrenderableDocError, 'The provided document could not be rendered.' if node.include?(' ')
79
+ lambda { current_actor.play_audio! node }
80
+ else
81
+ raise UnrenderableDocError, 'The provided document could not be rendered.'
82
+ end
83
+ end.compact
84
+ rescue
85
+ raise UnrenderableDocError, 'The provided document could not be rendered.'
76
86
  end
77
87
 
78
88
  def process_playback_completion
@@ -99,10 +109,6 @@ module Punchblock
99
109
 
100
110
  private
101
111
 
102
- def unrenderable_doc_error
103
- with_error 'unrenderable document error', 'The provided document could not be rendered.'
104
- end
105
-
106
112
  def escaped_doc
107
113
  @component_node.ssml.to_s.squish.gsub(/["\\]/) { |m| "\\#{m}" }
108
114
  end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Punchblock
4
- VERSION = "0.12.0"
4
+ VERSION = "1.0.0"
5
5
  end
@@ -414,6 +414,18 @@ module Punchblock
414
414
  end
415
415
  end
416
416
 
417
+ context 'with a string (not SSML)' do
418
+ let :command_options do
419
+ { :text => 'Foo Bar' }
420
+ end
421
+
422
+ it "should return an unrenderable document error" do
423
+ subject.execute
424
+ error = ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered.'
425
+ original_command.response(0.1).should be == error
426
+ end
427
+ end
428
+
417
429
  context 'with multiple audio SSML nodes' do
418
430
  let(:audio_filename1) { 'http://foo.com/bar.mp3' }
419
431
  let(:audio_filename2) { 'http://foo.com/baz.mp3' }
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.12.0
4
+ version: 1.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-03-30 00:00:00.000000000 Z
14
+ date: 2012-04-11 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: niceogiri
18
- requirement: &2151918560 !ruby/object:Gem::Requirement
18
+ requirement: &2151853680 !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: *2151918560
26
+ version_requirements: *2151853680
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: blather
29
- requirement: &2151917300 !ruby/object:Gem::Requirement
29
+ requirement: &2151852020 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ! '>='
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: 0.5.12
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *2151917300
37
+ version_requirements: *2151852020
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: activesupport
40
- requirement: &2151916200 !ruby/object:Gem::Requirement
40
+ requirement: &2151864820 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: 2.1.0
46
46
  type: :runtime
47
47
  prerelease: false
48
- version_requirements: *2151916200
48
+ version_requirements: *2151864820
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: state_machine
51
- requirement: &2151915240 !ruby/object:Gem::Requirement
51
+ requirement: &2151861640 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: 1.0.1
57
57
  type: :runtime
58
58
  prerelease: false
59
- version_requirements: *2151915240
59
+ version_requirements: *2151861640
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: future-resource
62
- requirement: &2151926340 !ruby/object:Gem::Requirement
62
+ requirement: &2151860660 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
@@ -67,10 +67,10 @@ dependencies:
67
67
  version: 0.0.2
68
68
  type: :runtime
69
69
  prerelease: false
70
- version_requirements: *2151926340
70
+ version_requirements: *2151860660
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: has-guarded-handlers
73
- requirement: &2151923420 !ruby/object:Gem::Requirement
73
+ requirement: &2151875260 !ruby/object:Gem::Requirement
74
74
  none: false
75
75
  requirements:
76
76
  - - ! '>='
@@ -78,10 +78,10 @@ dependencies:
78
78
  version: 0.1.0
79
79
  type: :runtime
80
80
  prerelease: false
81
- version_requirements: *2151923420
81
+ version_requirements: *2151875260
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: celluloid
84
- requirement: &2151921440 !ruby/object:Gem::Requirement
84
+ requirement: &2151879400 !ruby/object:Gem::Requirement
85
85
  none: false
86
86
  requirements:
87
87
  - - ! '>='
@@ -89,10 +89,10 @@ dependencies:
89
89
  version: 0.9.0
90
90
  type: :runtime
91
91
  prerelease: false
92
- version_requirements: *2151921440
92
+ version_requirements: *2151879400
93
93
  - !ruby/object:Gem::Dependency
94
94
  name: ruby_ami
95
- requirement: &2151932640 !ruby/object:Gem::Requirement
95
+ requirement: &2152058520 !ruby/object:Gem::Requirement
96
96
  none: false
97
97
  requirements:
98
98
  - - ! '>='
@@ -100,10 +100,10 @@ dependencies:
100
100
  version: 0.1.3
101
101
  type: :runtime
102
102
  prerelease: false
103
- version_requirements: *2151932640
103
+ version_requirements: *2152058520
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: ruby_speech
106
- requirement: &2155995300 !ruby/object:Gem::Requirement
106
+ requirement: &2152083720 !ruby/object:Gem::Requirement
107
107
  none: false
108
108
  requirements:
109
109
  - - ! '>='
@@ -111,10 +111,10 @@ dependencies:
111
111
  version: 0.5.1
112
112
  type: :runtime
113
113
  prerelease: false
114
- version_requirements: *2155995300
114
+ version_requirements: *2152083720
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: bundler
117
- requirement: &2155999080 !ruby/object:Gem::Requirement
117
+ requirement: &2152086540 !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: *2155999080
125
+ version_requirements: *2152086540
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: rspec
128
- requirement: &2156017820 !ruby/object:Gem::Requirement
128
+ requirement: &2152093960 !ruby/object:Gem::Requirement
129
129
  none: false
130
130
  requirements:
131
131
  - - ~>
@@ -133,10 +133,10 @@ dependencies:
133
133
  version: 2.7.0
134
134
  type: :development
135
135
  prerelease: false
136
- version_requirements: *2156017820
136
+ version_requirements: *2152093960
137
137
  - !ruby/object:Gem::Dependency
138
138
  name: ci_reporter
139
- requirement: &2156036260 !ruby/object:Gem::Requirement
139
+ requirement: &2152106160 !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: *2156036260
147
+ version_requirements: *2152106160
148
148
  - !ruby/object:Gem::Dependency
149
149
  name: yard
150
- requirement: &2156029000 !ruby/object:Gem::Requirement
150
+ requirement: &2152101260 !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: *2156029000
158
+ version_requirements: *2152101260
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: rake
161
- requirement: &2156042480 !ruby/object:Gem::Requirement
161
+ requirement: &2151949040 !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: *2156042480
169
+ version_requirements: *2151949040
170
170
  - !ruby/object:Gem::Dependency
171
171
  name: mocha
172
- requirement: &2156036860 !ruby/object:Gem::Requirement
172
+ requirement: &2151961660 !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: *2156036860
180
+ version_requirements: *2151961660
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: i18n
183
- requirement: &2155891280 !ruby/object:Gem::Requirement
183
+ requirement: &2151959840 !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: *2155891280
191
+ version_requirements: *2151959840
192
192
  - !ruby/object:Gem::Dependency
193
193
  name: countdownlatch
194
- requirement: &2155887920 !ruby/object:Gem::Requirement
194
+ requirement: &2151958260 !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: *2155887920
202
+ version_requirements: *2151958260
203
203
  - !ruby/object:Gem::Dependency
204
204
  name: guard-rspec
205
- requirement: &2156050140 !ruby/object:Gem::Requirement
205
+ requirement: &2152122840 !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: *2156050140
213
+ version_requirements: *2152122840
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
@@ -359,7 +359,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
359
359
  version: '0'
360
360
  segments:
361
361
  - 0
362
- hash: -3649265375268061365
362
+ hash: -3970210055497843172
363
363
  required_rubygems_version: !ruby/object:Gem::Requirement
364
364
  none: false
365
365
  requirements: