Skip to content

Commit

Permalink
[FEATURE] Support RubySpeech builtin grammars on Asterisk and FreeSWITCH
Browse files Browse the repository at this point in the history
  • Loading branch information
benlangfeld committed Sep 30, 2013
1 parent 12a753f commit 45f3cf7
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
@@ -1,4 +1,5 @@
# [develop](https://github.com/adhearsion/punchblock)
* Feature: Support RubySpeech builtin grammars on Asterisk and FreeSWITCH
* Bugfix: Reject commands against components which have finished on Asterisk, and garbage collect them

# [v2.0.1](https://github.com/adhearsion/punchblock/compare/v2.0.0...v2.0.1) - [2013-09-17](https://rubygems.org/gems/punchblock/versions/2.0.1)
Expand Down
26 changes: 25 additions & 1 deletion lib/punchblock/translator/dtmf_recognizer.rb
Expand Up @@ -3,14 +3,38 @@
module Punchblock
module Translator
class DTMFRecognizer
class BuiltinMatcherCache
include Singleton
include MonitorMixin

def get(uri)
cache[uri] ||= fetch(uri)
end

private

def fetch(uri)
grammar = RubySpeech::GRXML.from_uri(uri)
RubySpeech::GRXML::Matcher.new(grammar)
end

def cache
@cache ||= {}
end
end

def initialize(responder, grammar, initial_timeout = nil, inter_digit_timeout = nil, terminator = nil)
@responder = responder
self.initial_timeout = initial_timeout || -1
self.inter_digit_timeout = inter_digit_timeout || -1
@terminator = terminator
@finished = false

@matcher = RubySpeech::GRXML::Matcher.new RubySpeech::GRXML.import(grammar.to_s)
@matcher = if grammar.url
BuiltinMatcherCache.instance.get(grammar.url)
else
RubySpeech::GRXML::Matcher.new RubySpeech::GRXML.import(grammar.value.to_s)
end
@buffer = ""
end

Expand Down
4 changes: 2 additions & 2 deletions lib/punchblock/translator/input_component.rb
Expand Up @@ -8,7 +8,7 @@ def execute
setup_dtmf_recognizer
send_ref
start_timers
rescue OptionError => e
rescue OptionError, ArgumentError => e
with_error 'option error', e.message
end

Expand Down Expand Up @@ -52,7 +52,7 @@ def validate

def setup_dtmf_recognizer
@recognizer = DTMFRecognizer.new self,
input_node.grammars.first.value,
input_node.grammars.first,
(input_node.initial_timeout || -1),
(input_node.inter_digit_timeout || -1),
input_node.terminator
Expand Down
2 changes: 1 addition & 1 deletion punchblock.gemspec
Expand Up @@ -31,7 +31,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency %q<celluloid>, ["~> 0.14"]
s.add_runtime_dependency %q<ruby_ami>, ["~> 2.0"]
s.add_runtime_dependency %q<ruby_fs>, ["~> 1.1"]
s.add_runtime_dependency %q<ruby_speech>, ["~> 2.0"]
s.add_runtime_dependency %q<ruby_speech>, ["~> 2.3"]
s.add_runtime_dependency %q<virtus>
s.add_runtime_dependency %q<ruby_jid>, ["~> 1.0"]

Expand Down
54 changes: 54 additions & 0 deletions spec/punchblock/translator/asterisk/component/input_spec.rb
Expand Up @@ -127,6 +127,60 @@ def send_ami_events_for_dtmf(digit)
end
end

context 'with a builtin grammar' do
let(:original_command_opts) { { grammar: { url: 'builtin:dtmf/boolean' } } }

before do
subject.execute
expected_event
send_ami_events_for_dtmf 1
end

let :expected_nlsml do
RubySpeech::NLSML.draw do
interpretation confidence: 1 do
instance "true"
input "1", mode: :dtmf
end
end
end

let :expected_event do
Punchblock::Component::Input::Complete::Match.new nlsml: expected_nlsml
end

it "should use RubySpeech builtin grammar" do
reason.should be == expected_event
end
end

context 'with a parameterized builtin grammar' do
let(:original_command_opts) { { grammar: { url: 'builtin:dtmf/boolean?n=3;y=4' } } }

before do
subject.execute
expected_event
send_ami_events_for_dtmf 4
end

let :expected_nlsml do
RubySpeech::NLSML.draw do
interpretation confidence: 1 do
instance "true"
input "4", mode: :dtmf
end
end
end

let :expected_event do
Punchblock::Component::Input::Complete::Match.new nlsml: expected_nlsml
end

it "should use RubySpeech builtin grammar" do
reason.should be == expected_event
end
end

context 'with multiple grammars' do
let(:original_command_opts) { { :grammars => [{:value => grammar}, {:value => grammar}] } }
it "should return an error and not execute any actions" do
Expand Down
64 changes: 64 additions & 0 deletions spec/punchblock/translator/freeswitch/component/input_spec.rb
Expand Up @@ -123,6 +123,70 @@ def send_dtmf(digit)
end
end

context 'with a builtin grammar' do
let(:original_command_opts) { { grammar: { url: 'builtin:dtmf/boolean' } } }

before do
subject.execute
expected_event
send_dtmf 1
end

let :expected_nlsml do
RubySpeech::NLSML.draw do
interpretation confidence: 1 do
instance "true"
input "1", mode: :dtmf
end
end
end

let :expected_event do
Punchblock::Component::Input::Complete::Match.new nlsml: expected_nlsml
end

it "should use RubySpeech builtin grammar" do
reason.should be == expected_event
end
end

context 'with a parameterized builtin grammar' do
let(:original_command_opts) { { grammar: { url: 'builtin:dtmf/boolean?n=3;y=4' } } }

before do
subject.execute
expected_event
send_dtmf 4
end

let :expected_nlsml do
RubySpeech::NLSML.draw do
interpretation confidence: 1 do
instance "true"
input "4", mode: :dtmf
end
end
end

let :expected_event do
Punchblock::Component::Input::Complete::Match.new nlsml: expected_nlsml
end

it "should use RubySpeech builtin grammar" do
reason.should be == expected_event
end
end

context 'with a bad builtin grammar name' do
let(:original_command_opts) { { grammar: { url: 'builtin:dtmf/foobar' } } }

it "should return an error and not execute any actions" do
subject.execute
error = ProtocolError.new.setup 'option error', 'foobar is an invalid builtin grammar'
original_command.response(0.1).should be == error
end
end

context 'with multiple grammars' do
let(:original_command_opts) { { :grammars => [{:value => grammar}, {:value => grammar}] } }
it "should return an error and not execute any actions" do
Expand Down

0 comments on commit 45f3cf7

Please sign in to comment.