librevox 0.1
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.
- data/LICENSE +20 -0
- data/README.md +159 -0
- data/Rakefile +6 -0
- data/TODO +24 -0
- data/lib/librevox.rb +35 -0
- data/lib/librevox/applications.rb +127 -0
- data/lib/librevox/command_socket.rb +50 -0
- data/lib/librevox/commands.rb +53 -0
- data/lib/librevox/listener/base.rb +80 -0
- data/lib/librevox/listener/inbound.rb +19 -0
- data/lib/librevox/listener/outbound.rb +83 -0
- data/lib/librevox/response.rb +48 -0
- data/librevox.gemspec +37 -0
- data/spec/helper.rb +6 -0
- data/spec/librevox/listener.rb +130 -0
- data/spec/librevox/listener/spec_inbound.rb +21 -0
- data/spec/librevox/listener/spec_outbound.rb +221 -0
- data/spec/librevox/spec_applications.rb +142 -0
- data/spec/librevox/spec_command_socket.rb +111 -0
- data/spec/librevox/spec_commands.rb +68 -0
- data/spec/librevox/spec_response.rb +56 -0
- metadata +76 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require 'librevox/applications'
|
3
|
+
|
4
|
+
module ApplicationTest
|
5
|
+
include Librevox::Applications
|
6
|
+
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def execute_app(name, args=[], params={}, &block)
|
10
|
+
{
|
11
|
+
:name => name,
|
12
|
+
:args => args,
|
13
|
+
:params => params,
|
14
|
+
:block => block
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Librevox::Applications do
|
20
|
+
A = ApplicationTest
|
21
|
+
|
22
|
+
should "answer" do
|
23
|
+
app = A.answer
|
24
|
+
app[:name].should == "answer"
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "bind_meta_app" do
|
28
|
+
should "bind meta app" do
|
29
|
+
app = A.bind_meta_app :key => "2",
|
30
|
+
:listen_to => :a,
|
31
|
+
:respond_on => :s,
|
32
|
+
:application => "hangup"
|
33
|
+
|
34
|
+
app[:name].should == "bind_meta_app"
|
35
|
+
app[:args].should == "2 a s hangup"
|
36
|
+
end
|
37
|
+
|
38
|
+
should "bind meta app with parameters" do
|
39
|
+
app = A.bind_meta_app :key => "2",
|
40
|
+
:listen_to => :a,
|
41
|
+
:respond_on => :s,
|
42
|
+
:application => "execute_extension",
|
43
|
+
:parameters => "dx XML features"
|
44
|
+
|
45
|
+
app[:name].should == "bind_meta_app"
|
46
|
+
app[:args].should == "2 a s execute_extension::dx XML features"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
should "bridge" do
|
51
|
+
app = A.bridge('user/coltrane')
|
52
|
+
app[:name].should == "bridge"
|
53
|
+
app[:args].should == 'user/coltrane'
|
54
|
+
|
55
|
+
app = A.bridge('user/coltrane', 'user/davis')
|
56
|
+
app[:args].should == 'user/coltrane,user/davis'
|
57
|
+
end
|
58
|
+
|
59
|
+
should "hangup" do
|
60
|
+
app = A.hangup
|
61
|
+
app[:name].should == "hangup"
|
62
|
+
|
63
|
+
app = A.hangup("some cause")
|
64
|
+
app[:args].should == "some cause"
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "play_and_get_digits" do
|
68
|
+
should "have defaults" do
|
69
|
+
app = A.play_and_get_digits "please-enter", "wrong-try-again"
|
70
|
+
app[:name].should == "play_and_get_digits"
|
71
|
+
app[:args].should == "1 2 3 5000 # please-enter wrong-try-again read_digits_var \\d+"
|
72
|
+
app[:params][:read_var].should == "read_digits_var"
|
73
|
+
end
|
74
|
+
|
75
|
+
should "take params" do
|
76
|
+
app = A.play_and_get_digits "please-enter", "invalid-choice",
|
77
|
+
:min => 2,
|
78
|
+
:max => 3,
|
79
|
+
:tries => 4,
|
80
|
+
:terminators => "0",
|
81
|
+
:timeout => 10000,
|
82
|
+
:read_var => "other_var",
|
83
|
+
:regexp => "[125]"
|
84
|
+
|
85
|
+
app[:args].should == "2 3 4 10000 0 please-enter invalid-choice other_var [125]"
|
86
|
+
app[:params][:read_var].should == "other_var"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
should "playback" do
|
91
|
+
app = A.playback("uri://some/file.wav")
|
92
|
+
app[:name].should == "playback"
|
93
|
+
app[:args].should == "uri://some/file.wav"
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "read" do
|
97
|
+
should "read with defaults" do
|
98
|
+
app = A.read "please-enter.wav"
|
99
|
+
app[:name].should == "read"
|
100
|
+
app[:args].should == "1 2 please-enter.wav read_digits_var 5000 #"
|
101
|
+
app[:params][:read_var].should == "read_digits_var"
|
102
|
+
end
|
103
|
+
|
104
|
+
should "take params" do
|
105
|
+
app = A.read "please-enter.wav",
|
106
|
+
:min => 2,
|
107
|
+
:max => 3,
|
108
|
+
:terminators => "0",
|
109
|
+
:timeout => 10000,
|
110
|
+
:read_var => "other_var"
|
111
|
+
|
112
|
+
app[:args].should == "2 3 please-enter.wav other_var 10000 0"
|
113
|
+
app[:params][:read_var].should == "other_var"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "record" do
|
118
|
+
should "start recording" do
|
119
|
+
app = A.record "/path/to/file.mp3"
|
120
|
+
app[:name].should == "record"
|
121
|
+
app[:args].should == "/path/to/file.mp3"
|
122
|
+
end
|
123
|
+
|
124
|
+
should "start recording with time limit" do
|
125
|
+
app = A.record "/path/to/file.mp3", :limit => 15
|
126
|
+
app[:name].should == "record"
|
127
|
+
app[:args].should == "/path/to/file.mp3 15"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
should "set" do
|
132
|
+
app = A.set("foo", "bar")
|
133
|
+
app[:name].should == "set"
|
134
|
+
app[:args].should == "foo=bar"
|
135
|
+
end
|
136
|
+
|
137
|
+
should "transfer" do
|
138
|
+
app = A.transfer "new_extension"
|
139
|
+
app[:name].should == "transfer"
|
140
|
+
app[:args].should == "new_extension"
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require 'rr'
|
3
|
+
require 'mocksocket'
|
4
|
+
|
5
|
+
require 'librevox/command_socket'
|
6
|
+
|
7
|
+
class Bacon::Context
|
8
|
+
include RR::Adapters::RRMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module Librevox
|
12
|
+
module Commands
|
13
|
+
def sample_cmd(args="")
|
14
|
+
execute_cmd "sample_cmd", args
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe Librevox::CommandSocket do
|
20
|
+
before do
|
21
|
+
@socket, @server = MockSocket.pipe
|
22
|
+
stub(TCPSocket).open(anything, anything).times(any_times) {@socket}
|
23
|
+
|
24
|
+
@server.print "Content-Type: command/reply\nReply-Text: +OK\n\n"
|
25
|
+
end
|
26
|
+
|
27
|
+
# This should be tested with some mocks. How do we use rr + bacon?
|
28
|
+
describe ":connect => false" do
|
29
|
+
should "not connect" do
|
30
|
+
@cmd = Librevox::CommandSocket.new(:connect => false)
|
31
|
+
@server.should.be.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
should "connect when asked" do
|
35
|
+
@cmd.connect
|
36
|
+
@server.gets.should == "auth ClueCon\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "with auto-connect" do
|
41
|
+
before do
|
42
|
+
@cmd = Librevox::CommandSocket.new
|
43
|
+
end
|
44
|
+
|
45
|
+
should "authenticate" do
|
46
|
+
@server.gets.should == "auth ClueCon\n"
|
47
|
+
end
|
48
|
+
|
49
|
+
should "read header response" do
|
50
|
+
@server.print "Content-Type: command/reply\nSome-Header: Some value\n\n"
|
51
|
+
reply = @cmd.run_cmd "foo"
|
52
|
+
|
53
|
+
reply.class.should == Librevox::Response
|
54
|
+
reply.headers[:some_header].should == "Some value"
|
55
|
+
end
|
56
|
+
|
57
|
+
should "read command/reply responses" do
|
58
|
+
@server.print "Content-Type: api/log\nSome-Header: Old data\n\n"
|
59
|
+
|
60
|
+
@server.print "Content-Type: command/reply\nSome-Header: New data\n\n"
|
61
|
+
reply = @cmd.run_cmd "foo"
|
62
|
+
|
63
|
+
reply.headers[:some_header].should == "New data"
|
64
|
+
end
|
65
|
+
|
66
|
+
should "read api/response responses" do
|
67
|
+
@server.print "Content-Type: api/log\nSome-Header: Old data\n\n"
|
68
|
+
|
69
|
+
@server.print "Content-Type: api/response\nSome-Header: New data\n\n"
|
70
|
+
reply = @cmd.run_cmd "foo"
|
71
|
+
|
72
|
+
reply.headers[:some_header].should == "New data"
|
73
|
+
end
|
74
|
+
|
75
|
+
should "read content if present" do
|
76
|
+
@server.print "Content-Type: command/reply\nContent-Length: 3\n\n+OK\n\n"
|
77
|
+
reply = @cmd.run_cmd "foo"
|
78
|
+
|
79
|
+
reply.content.should == "+OK"
|
80
|
+
end
|
81
|
+
|
82
|
+
should "register command" do
|
83
|
+
@cmd.should.respond_to? :sample_cmd
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "registered" do
|
87
|
+
before do
|
88
|
+
2.times {@server.gets} # get rid of the auth message
|
89
|
+
end
|
90
|
+
|
91
|
+
should "send command" do
|
92
|
+
@server.print "Content-Type: command/reply\nContent-Length: 3\n\n+OK\n\n"
|
93
|
+
@cmd.sample_cmd
|
94
|
+
@server.gets.should == "api sample_cmd\n"
|
95
|
+
end
|
96
|
+
|
97
|
+
should "return response from command" do
|
98
|
+
@server.print "Content-Type: command/reply\nContent-Length: 3\n\n+OK\n\n"
|
99
|
+
response = @cmd.sample_cmd
|
100
|
+
response.class.should == Librevox::Response
|
101
|
+
response.content.should == "+OK"
|
102
|
+
end
|
103
|
+
|
104
|
+
should "pass arguments" do
|
105
|
+
@server.print "Content-Type: command/reply\nContent-Length: 3\n\n+OK\n\n"
|
106
|
+
@cmd.sample_cmd("foo bar")
|
107
|
+
@server.gets.should == "api sample_cmd foo bar\n"
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require 'librevox/commands'
|
3
|
+
|
4
|
+
module CommandTest
|
5
|
+
include Librevox::Commands
|
6
|
+
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def execute_cmd(name, args="", &block)
|
10
|
+
{
|
11
|
+
:name => name,
|
12
|
+
:args => args,
|
13
|
+
:block => block
|
14
|
+
}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Librevox::Commands do
|
19
|
+
C = CommandTest
|
20
|
+
|
21
|
+
should "status" do
|
22
|
+
cmd = C.status
|
23
|
+
cmd[:name].should == "status"
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "originate" do
|
27
|
+
should "originate url to extension" do
|
28
|
+
cmd = C.originate "user/coltrane", :extension => 4000
|
29
|
+
cmd[:name].should == "originate"
|
30
|
+
cmd[:args].should == "{}user/coltrane 4000"
|
31
|
+
end
|
32
|
+
|
33
|
+
should "send variables" do
|
34
|
+
cmd = C.originate 'user/coltrane',
|
35
|
+
:extension => 1234,
|
36
|
+
:ignore_early_media => true,
|
37
|
+
:other_option => "value"
|
38
|
+
|
39
|
+
cmd[:args].should.match %r|^\{\S+\}user/coltrane 1234$|
|
40
|
+
cmd[:args].should.match /ignore_early_media=true/
|
41
|
+
cmd[:args].should.match /other_option=value/
|
42
|
+
end
|
43
|
+
|
44
|
+
should "take dialplan and context" do
|
45
|
+
cmd = C.originate "user/coltrane",
|
46
|
+
:extension => "4000",
|
47
|
+
:dialplan => "XML",
|
48
|
+
:context => "public"
|
49
|
+
cmd[:name].should == "originate"
|
50
|
+
cmd[:args].should == "{}user/coltrane 4000 XML public"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
should "fsctl" do
|
55
|
+
cmd = C.fsctl :hupall, :normal_clearing
|
56
|
+
cmd[:name].should == "fsctl"
|
57
|
+
cmd[:args].should == "hupall normal_clearing"
|
58
|
+
end
|
59
|
+
|
60
|
+
should "huball" do
|
61
|
+
cmd = C.hupall
|
62
|
+
cmd[:name].should == "hupall"
|
63
|
+
|
64
|
+
cmd = C.hupall("some_cause")
|
65
|
+
cmd[:name].should == "hupall"
|
66
|
+
cmd[:args].should == "some_cause"
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec/helper'
|
2
|
+
require 'librevox/response'
|
3
|
+
|
4
|
+
include Librevox
|
5
|
+
|
6
|
+
describe Response do
|
7
|
+
should "parse headers to hash" do
|
8
|
+
response = Response.new("Header1:some value\nOther-Header:other value")
|
9
|
+
|
10
|
+
response.headers.should.include :header1
|
11
|
+
response.headers[:header1].should.equal "some value"
|
12
|
+
|
13
|
+
response.headers.should.include :other_header
|
14
|
+
response.headers[:other_header].should.equal "other value"
|
15
|
+
end
|
16
|
+
|
17
|
+
should "parse key-value content to hash" do
|
18
|
+
response = Response.new("", "Key:value\nOther-Key:other value")
|
19
|
+
|
20
|
+
response.content.class.should.equal Hash
|
21
|
+
response.content[:key].should.equal "value"
|
22
|
+
response.content[:other_key].should.equal "other value"
|
23
|
+
end
|
24
|
+
|
25
|
+
should "not parse regular content" do
|
26
|
+
response = Response.new("", "OK.")
|
27
|
+
|
28
|
+
response.content.class.should.equal String
|
29
|
+
response.content.should.equal "OK."
|
30
|
+
end
|
31
|
+
|
32
|
+
should "check for event" do
|
33
|
+
response = Response.new("Content-Type: command/reply", "Event-Name: Hangup")
|
34
|
+
response.event?.should.be.true
|
35
|
+
response.event.should == "Hangup"
|
36
|
+
|
37
|
+
response = Response.new("Content-Type: command/reply", "Foo-Bar: Baz")
|
38
|
+
response.event?.should.be.false
|
39
|
+
end
|
40
|
+
|
41
|
+
should "check for api response" do
|
42
|
+
response = Response.new("Content-Type: api/response", "+OK")
|
43
|
+
response.api_response?.should.be.true
|
44
|
+
|
45
|
+
response = Response.new("Content-Type: command/reply", "Foo-Bar: Baz")
|
46
|
+
response.api_response?.should.be.false
|
47
|
+
end
|
48
|
+
|
49
|
+
should "check for command reply" do
|
50
|
+
response = Response.new("Content-Type: command/reply", "+OK")
|
51
|
+
response.command_reply?.should.be.true
|
52
|
+
|
53
|
+
response = Response.new("Content-Type: api/response", "Foo-Bar: Baz")
|
54
|
+
response.command_reply?.should.be.false
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: librevox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Harry Vangberg
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-12-14 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: |-
|
17
|
+
EventMachine-based Ruby library for interacting with the
|
18
|
+
open source telephony platform FreeSwitch.
|
19
|
+
email: harry@vangberg.name
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
26
|
+
files:
|
27
|
+
- README.md
|
28
|
+
- LICENSE
|
29
|
+
- TODO
|
30
|
+
- Rakefile
|
31
|
+
- librevox.gemspec
|
32
|
+
- lib/librevox.rb
|
33
|
+
- lib/librevox/applications.rb
|
34
|
+
- lib/librevox/command_socket.rb
|
35
|
+
- lib/librevox/commands.rb
|
36
|
+
- lib/librevox/response.rb
|
37
|
+
- lib/librevox/listener/base.rb
|
38
|
+
- lib/librevox/listener/inbound.rb
|
39
|
+
- lib/librevox/listener/outbound.rb
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://github.com/ichverstehe/librevox
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 1.3.5
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: Ruby library for interacting with FreeSWITCH.
|
68
|
+
test_files:
|
69
|
+
- spec/helper.rb
|
70
|
+
- spec/librevox/listener.rb
|
71
|
+
- spec/librevox/spec_applications.rb
|
72
|
+
- spec/librevox/spec_command_socket.rb
|
73
|
+
- spec/librevox/spec_commands.rb
|
74
|
+
- spec/librevox/spec_response.rb
|
75
|
+
- spec/librevox/listener/spec_inbound.rb
|
76
|
+
- spec/librevox/listener/spec_outbound.rb
|