bougyman-freeswitcher 0.1.3 → 0.1.4
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/AUTHORS +13 -0
- data/CHANGELOG +1136 -0
- data/MANIFEST +101 -0
- data/README +66 -70
- data/Rakefile +31 -77
- data/examples/inbound_event_socket.rb +18 -0
- data/examples/inbound_socket_events.rb +25 -0
- data/examples/outbound_event_socket.rb +28 -0
- data/freeswitcher.gemspec +155 -0
- data/lib/fsr.rb +14 -4
- data/lib/fsr/listener/outbound.rb +21 -10
- data/lib/fsr/version.rb +3 -0
- data/spec/helper.rb +11 -6
- data/tasks/authors.rake +30 -0
- data/tasks/bacon.rake +66 -0
- data/tasks/changelog.rake +19 -0
- data/tasks/copyright.rake +21 -0
- data/tasks/gem.rake +23 -0
- data/tasks/gem_installer.rake +76 -0
- data/tasks/install_dependencies.rake +6 -0
- data/tasks/manifest.rake +4 -0
- data/tasks/rcov.rake +23 -0
- data/tasks/release.rake +52 -0
- data/tasks/reversion.rake +8 -0
- data/tasks/setup.rake +16 -0
- data/tasks/spec.rake +0 -59
- data/tasks/yard.rake +4 -0
- metadata +123 -106
- data/examples/oes_demo.rb +0 -21
- data/examples/play_and_get_test.rb +0 -35
- data/tasks/package.rake +0 -29
@@ -0,0 +1,155 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{freeswitcher}
|
5
|
+
s.version = "0.1.4"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Jayson Vaughn", "Michael Fellinger", "Kevin Berry", "TJ Vanderpoel"]
|
9
|
+
s.date = %q{2009-05-11}
|
10
|
+
s.description = %q{========================================================= FreeSWITCHeR Copyright (c) 2009 The Rubyists (Jayson Vaughn, Tj Vanderpoel, Michael Fellinger, Kevin Berry) Distributed under the terms of the MIT License. ========================================================== ABOUT ----- A ruby library for interacting with the "FreeSWITCH" (http://www.freeswitch.org) opensource telephony platform REQUIREMENTS ------------ - ruby (>= 1.8) - eventmachine (If you wish to use Outbound and Inbound listener) USAGE ----- An Outbound Event Listener Example that reads and returns DTMF input: -------------------------------------------------------------------- Simply just create a subclass of FSR::Listner::Outbound and all new calls/sessions will invoke the "session_initiated" callback method. * NOTE: FSR uses blocks within the 'session_inititated' method to ensure that the next "freeswich command" is not executed until the previous "Freeswitch command" has finished. This is kicked off by "answer do" require 'fsr' require 'fsr/listener/outbound' class OutboundDemo < FSR::Listener::Outbound def session_initiated exten = @session.headers[:caller_caller_id_number] FSR::Log.info "*** Answering incoming call from #{exten}" answer do FSR::Log.info "***Reading DTMF from #{exten}" read("/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav", 4, 10, "input", 7000) do FSR::Log.info "*** Updating session for #{exten}" update_session do FSR::Log.info "***Success, grabbed #{@session.headers[:variable_input].strip} from #{exten}" hangup #Hangup the call end end end end end FSR.start_oes! OutboundDemo, :port => 8084, :host => "127.0.0.1" An Inbound Event Socket Listener example using FreeSWITCHeR's hook system: -------------------------------------------------------------------------- require 'pp' require 'fsr' require "fsr/listener/inbound" # EXAMPLE 1 # This adds a hook on CHANNEL_CREATE events. You can also create a method to handle the event you're after. See the next example FSL::Inbound.add_event_hook(:CHANNEL_CREATE) {|event| FSR::Log.info "*** [#{event.content[:unique_id]}] Channel created - greetings from the hook!" } # EXAMPLE 2 # Define a method to handle CHANNEL_HANGUP events. def custom_channel_hangup_handler(event) FSR::Log.info "*** [#{event.content[:unique_id]}] Channel hangup. The event:" pp event end # This adds a hook for EXAMPLE 2 FSL::Inbound.add_event_hook(:CHANNEL_HANGUP) {|event| custom_channel_hangup_handler(event) } # Start FSR Inbound Listener FSR.start_ies!(FSL::Inbound, :host => "localhost", :port => 8021) An Inbound Event Socket Listener example using the on_event callback method instead of hooks: --------------------------------------------------------------------------------------------- require 'pp' require 'fsr' require "fsr/listener/inbound" class IesDemo < FSR::Listener::Inbound def on_event(event) pp event.headers pp event.content[:event_name] end end FSR.start_ies!(IesDemo, :host => "localhost", :port => 8021) An example of using FSR::CommandSocket to originate a new call in irb: ---------------------------------------------------------------------- irb(main):001:0> require 'fsr' => true irb(main):002:0> FSR.load_all_commands => [:sofia, :originate] irb(main):003:0> sock = FSR::CommandSocket.new => #<FSR::CommandSocket:0xb7a89104 @server="127.0.0.1", @socket=#<TCPSocket:0xb7a8908c>, @port="8021", @auth="ClueCon"> irb(main):007:0> sock.originate(:target => 'sofia/gateway/carlos/8179395222', :endpoint => FSR::App::Bridge.new("user/bougyman")).run => {"Job-UUID"=>"732075a4-7dd5-4258-b124-6284a82a5ae7", "body"=>"", "Content-Type"=>"command/reply", "Reply-Text"=>"+OK Job-UUID: 732075a4-7dd5-4258-b124-6284a82a5ae7"} SUPPORT ------- Home page at http://code.rubyists.com/projects/fs #rubyists on FreeNode}
|
11
|
+
s.email = %q{FreeSWITCHeR@rubyists.com}
|
12
|
+
s.files = [".gitignore", "AUTHORS", "CHANGELOG", "License.txt", "MANIFEST", "NEWS", "README", "Rakefile", "examples/bin/cmd_demo.rb", "examples/bin/dtmf_test.rb", "examples/bin/ies_demo.rb", "examples/bin/ies_demo_with_hook.rb", "examples/bin/oes_demo.rb", "examples/dtmf_test.rb", "examples/ies_demo.rb", "examples/ies_demo_with_hook.rb", "examples/inbound_event_socket.rb", "examples/inbound_socket_events.rb", "examples/outbound_event_socket.rb", "freeswitcher.gemspec", "lib/fsr.rb", "lib/fsr/app.rb", "lib/fsr/app/answer.rb", "lib/fsr/app/bridge.rb", "lib/fsr/app/conference.rb", "lib/fsr/app/fifo.rb", "lib/fsr/app/fs_break.rb", "lib/fsr/app/fs_sleep.rb", "lib/fsr/app/hangup.rb", "lib/fsr/app/limit.rb", "lib/fsr/app/log.rb", "lib/fsr/app/play_and_get_digits.rb", "lib/fsr/app/playback.rb", "lib/fsr/app/read.rb", "lib/fsr/app/set.rb", "lib/fsr/app/speak.rb", "lib/fsr/app/transfer.rb", "lib/fsr/app/uuid_dump.rb", "lib/fsr/app/uuid_getvar.rb", "lib/fsr/app/uuid_setvar.rb", "lib/fsr/cmd.rb", "lib/fsr/cmd/calls.rb", "lib/fsr/cmd/fsctl.rb", "lib/fsr/cmd/originate.rb", "lib/fsr/cmd/sofia.rb", "lib/fsr/cmd/sofia/profile.rb", "lib/fsr/cmd/sofia/status.rb", "lib/fsr/cmd/sofia_contact.rb", "lib/fsr/cmd/status.rb", "lib/fsr/command_socket.rb", "lib/fsr/database.rb", "lib/fsr/database/call_limit.rb", "lib/fsr/database/core.rb", "lib/fsr/database/sofia_reg_external.rb", "lib/fsr/database/sofia_reg_internal.rb", "lib/fsr/database/voicemail_default.rb", "lib/fsr/event_socket.rb", "lib/fsr/fake_socket.rb", "lib/fsr/listener.rb", "lib/fsr/listener/header_and_content_response.rb", "lib/fsr/listener/inbound.rb", "lib/fsr/listener/inbound/event.rb", "lib/fsr/listener/outbound.rb", "lib/fsr/listener/outbound.rb.orig", "lib/fsr/model/call.rb", "lib/fsr/version.rb", "tasks/authors.rake", "tasks/bacon.rake", "tasks/changelog.rake", "tasks/copyright.rake", "tasks/gem.rake", "tasks/gem_installer.rake", "tasks/install_dependencies.rake", "tasks/manifest.rake", "tasks/rcov.rake", "tasks/release.rake", "tasks/reversion.rake", "tasks/setup.rake", "tasks/spec.rake", "tasks/yard.rake", "spec/helper.rb", "spec/fsr/app.rb", "spec/fsr/app/bridge.rb", "spec/fsr/app/conference.rb", "spec/fsr/app/fifo.rb", "spec/fsr/app/hangup.rb", "spec/fsr/app/limit.rb", "spec/fsr/app/log.rb", "spec/fsr/app/play_and_get_digits.rb", "spec/fsr/app/playback.rb", "spec/fsr/app/set.rb", "spec/fsr/app/transfer.rb", "spec/fsr/cmd.rb", "spec/fsr/cmd/calls.rb", "spec/fsr/cmd/originate.rb", "spec/fsr/cmd/sofia.rb", "spec/fsr/cmd/sofia/profile.rb", "spec/fsr/listener.rb", "spec/fsr/listener/inbound.rb", "spec/fsr/listener/outbound.rb", "spec/fsr/loading.rb"]
|
13
|
+
s.homepage = %q{http://code.rubyists.com/projects/fs}
|
14
|
+
s.post_install_message = %q{=========================================================
|
15
|
+
FreeSWITCHeR
|
16
|
+
Copyright (c) 2009 The Rubyists (Jayson Vaughn, Tj Vanderpoel, Michael Fellinger, Kevin Berry)
|
17
|
+
Distributed under the terms of the MIT License.
|
18
|
+
==========================================================
|
19
|
+
|
20
|
+
ABOUT
|
21
|
+
-----
|
22
|
+
A ruby library for interacting with the "FreeSWITCH" (http://www.freeswitch.org) opensource telephony platform
|
23
|
+
|
24
|
+
REQUIREMENTS
|
25
|
+
------------
|
26
|
+
- ruby (>= 1.8)
|
27
|
+
- eventmachine (If you wish to use Outbound and Inbound listener)
|
28
|
+
|
29
|
+
USAGE
|
30
|
+
-----
|
31
|
+
|
32
|
+
An Outbound Event Listener Example that reads and returns DTMF input:
|
33
|
+
--------------------------------------------------------------------
|
34
|
+
|
35
|
+
Simply just create a subclass of FSR::Listner::Outbound and all
|
36
|
+
new calls/sessions will invoke the "session_initiated" callback method.
|
37
|
+
|
38
|
+
* NOTE: FSR uses blocks within the 'session_inititated' method to ensure
|
39
|
+
that the next "freeswich command" is not executed until the previous
|
40
|
+
"Freeswitch command" has finished. This is kicked off by "answer do"
|
41
|
+
|
42
|
+
require 'fsr'
|
43
|
+
require 'fsr/listener/outbound'
|
44
|
+
|
45
|
+
class OutboundDemo < FSR::Listener::Outbound
|
46
|
+
|
47
|
+
def session_initiated
|
48
|
+
exten = @session.headers[:caller_caller_id_number]
|
49
|
+
FSR::Log.info "*** Answering incoming call from #{exten}"
|
50
|
+
|
51
|
+
answer do
|
52
|
+
FSR::Log.info "***Reading DTMF from #{exten}"
|
53
|
+
read("/home/freeswitch/freeswitch/sounds/music/8000/sweet.wav", 4, 10, "input", 7000) do
|
54
|
+
FSR::Log.info "*** Updating session for #{exten}"
|
55
|
+
update_session do
|
56
|
+
FSR::Log.info "***Success, grabbed #{@session.headers[:variable_input].strip} from #{exten}"
|
57
|
+
hangup #Hangup the call
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
FSR.start_oes! OutboundDemo, :port => 8084, :host => "127.0.0.1"
|
67
|
+
|
68
|
+
|
69
|
+
An Inbound Event Socket Listener example using FreeSWITCHeR's hook system:
|
70
|
+
--------------------------------------------------------------------------
|
71
|
+
|
72
|
+
require 'pp'
|
73
|
+
require 'fsr'
|
74
|
+
require "fsr/listener/inbound"
|
75
|
+
|
76
|
+
# EXAMPLE 1
|
77
|
+
# This adds a hook on CHANNEL_CREATE events. You can also create a method to handle the event you're after. See the next example
|
78
|
+
FSL::Inbound.add_event_hook(:CHANNEL_CREATE) {|event| FSR::Log.info "*** [#{event.content[:unique_id]}] Channel created - greetings from the hook!" }
|
79
|
+
|
80
|
+
# EXAMPLE 2
|
81
|
+
# Define a method to handle CHANNEL_HANGUP events.
|
82
|
+
def custom_channel_hangup_handler(event)
|
83
|
+
FSR::Log.info "*** [#{event.content[:unique_id]}] Channel hangup. The event:"
|
84
|
+
pp event
|
85
|
+
end
|
86
|
+
|
87
|
+
# This adds a hook for EXAMPLE 2
|
88
|
+
FSL::Inbound.add_event_hook(:CHANNEL_HANGUP) {|event| custom_channel_hangup_handler(event) }
|
89
|
+
|
90
|
+
|
91
|
+
# Start FSR Inbound Listener
|
92
|
+
FSR.start_ies!(FSL::Inbound, :host => "localhost", :port => 8021)
|
93
|
+
|
94
|
+
|
95
|
+
An Inbound Event Socket Listener example using the on_event callback method instead of hooks:
|
96
|
+
---------------------------------------------------------------------------------------------
|
97
|
+
|
98
|
+
require 'pp'
|
99
|
+
require 'fsr'
|
100
|
+
require "fsr/listener/inbound"
|
101
|
+
|
102
|
+
|
103
|
+
class IesDemo < FSR::Listener::Inbound
|
104
|
+
|
105
|
+
def on_event(event)
|
106
|
+
pp event.headers
|
107
|
+
pp event.content[:event_name]
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
FSR.start_ies!(IesDemo, :host => "localhost", :port => 8021)
|
113
|
+
|
114
|
+
|
115
|
+
An example of using FSR::CommandSocket to originate a new call in irb:
|
116
|
+
----------------------------------------------------------------------
|
117
|
+
|
118
|
+
irb(main):001:0> require 'fsr'
|
119
|
+
=> true
|
120
|
+
|
121
|
+
irb(main):002:0> FSR.load_all_commands
|
122
|
+
=> [:sofia, :originate]
|
123
|
+
|
124
|
+
irb(main):003:0> sock = FSR::CommandSocket.new
|
125
|
+
=> #<FSR::CommandSocket:0xb7a89104 @server="127.0.0.1", @socket=#<TCPSocket:0xb7a8908c>, @port="8021", @auth="ClueCon">
|
126
|
+
|
127
|
+
irb(main):007:0> sock.originate(:target => 'sofia/gateway/carlos/8179395222', :endpoint => FSR::App::Bridge.new("user/bougyman")).run
|
128
|
+
=> {"Job-UUID"=>"732075a4-7dd5-4258-b124-6284a82a5ae7", "body"=>"", "Content-Type"=>"command/reply", "Reply-Text"=>"+OK Job-UUID: 732075a4-7dd5-4258-b124-6284a82a5ae7"}
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
SUPPORT
|
133
|
+
-------
|
134
|
+
Home page at http://code.rubyists.com/projects/fs
|
135
|
+
#rubyists on FreeNode
|
136
|
+
}
|
137
|
+
s.require_paths = ["lib"]
|
138
|
+
s.rubyforge_project = %q{freeswitcher}
|
139
|
+
s.rubygems_version = %q{1.3.1}
|
140
|
+
s.summary = %q{A library for interacting with the "FreeSWITCH":http://freeswitch.org telephony platform}
|
141
|
+
s.test_files = ["spec/fsr/app.rb", "spec/fsr/app/bridge.rb", "spec/fsr/app/conference.rb", "spec/fsr/app/fifo.rb", "spec/fsr/app/hangup.rb", "spec/fsr/app/limit.rb", "spec/fsr/app/log.rb", "spec/fsr/app/play_and_get_digits.rb", "spec/fsr/app/playback.rb", "spec/fsr/app/set.rb", "spec/fsr/app/transfer.rb", "spec/fsr/cmd.rb", "spec/fsr/cmd/calls.rb", "spec/fsr/cmd/originate.rb", "spec/fsr/cmd/sofia.rb", "spec/fsr/cmd/sofia/profile.rb", "spec/fsr/listener.rb", "spec/fsr/listener/inbound.rb", "spec/fsr/listener/outbound.rb", "spec/fsr/loading.rb"]
|
142
|
+
|
143
|
+
if s.respond_to? :specification_version then
|
144
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
145
|
+
s.specification_version = 2
|
146
|
+
|
147
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
148
|
+
s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
|
149
|
+
else
|
150
|
+
s.add_dependency(%q<eventmachine>, [">= 0"])
|
151
|
+
end
|
152
|
+
else
|
153
|
+
s.add_dependency(%q<eventmachine>, [">= 0"])
|
154
|
+
end
|
155
|
+
end
|
data/lib/fsr.rb
CHANGED
@@ -3,11 +3,15 @@ require 'socket'
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'pp'
|
5
5
|
|
6
|
+
# Author:: TJ Vanderpoel (mailto:bougy.man@gmail.com)
|
7
|
+
# Copyright:: Copyright (c) 2009 The Rubyists (Jayson Vaughn, TJ Vanderpoel, Michael Fellinger, Kevin Berry)
|
8
|
+
# License:: Distributes under the terms of the MIT License http://www.opensource.org/licenses/mit-license.php
|
9
|
+
|
10
|
+
## This module declares the namespace under which the freeswitcher framework
|
11
|
+
## Any constants will be defined here, as well as methods for loading commands and applications
|
6
12
|
module FSR
|
7
13
|
# Global configuration options
|
8
|
-
|
9
|
-
VERSION = '0.1.3'
|
10
|
-
FS_INSTALL_PATHS = ["/usr/local/freeswitch", "/opt/freeswitch", "/usr/freeswitch"]
|
14
|
+
FS_INSTALL_PATHS = ["/usr/local/freeswitch", "/opt/freeswitch", "/usr/freeswitch", "/home/freeswitch/freeswitch"]
|
11
15
|
DEFAULT_CALLER_ID_NUMBER = '8675309'
|
12
16
|
DEFAULT_CALLER_ID_NAME = "FSR"
|
13
17
|
|
@@ -48,8 +52,13 @@ module FSR
|
|
48
52
|
end
|
49
53
|
|
50
54
|
# Method to start EM for Inbound Event Socket
|
55
|
+
# @see FSR::Listener::Inbound
|
56
|
+
# @param [FSR::Listener::Inbound] klass An Inbound Listener class, to be started by EM.run
|
57
|
+
# @param [::Hash] args A hash of options, may contain
|
58
|
+
# <tt>:host [String]</tt> The host/ip to bind to (Default: "localhost")
|
59
|
+
# <tt>:port [Integer]</tt> the port to listen on (Default: 8021)
|
51
60
|
def self.start_ies!(klass, args = {})
|
52
|
-
port = args[:port] ||
|
61
|
+
port = args[:port] || 8021
|
53
62
|
host = args[:host] || "localhost"
|
54
63
|
EM.run do
|
55
64
|
EventMachine::connect(host, port, klass)
|
@@ -83,4 +92,5 @@ module FSR
|
|
83
92
|
FS_CONFIG_PATH = FS_DB_PATH = nil
|
84
93
|
end
|
85
94
|
end
|
95
|
+
require "fsr/version"
|
86
96
|
|
@@ -13,7 +13,13 @@ module FSR
|
|
13
13
|
include FSR::App
|
14
14
|
|
15
15
|
# Redefine the FSR::App methods to wrap sendmsg around them
|
16
|
-
SENDMSG_METHOD_DEFINITION =
|
16
|
+
SENDMSG_METHOD_DEFINITION = [
|
17
|
+
"def %s(*args, &block)",
|
18
|
+
" sendmsg super",
|
19
|
+
" @queue << block if block_given?",
|
20
|
+
"end"
|
21
|
+
].join("\n")
|
22
|
+
|
17
23
|
APPLICATIONS.each { |app, obj| module_eval(SENDMSG_METHOD_DEFINITION % app.to_s) }
|
18
24
|
|
19
25
|
# session_initiated is called when a @session is first created.
|
@@ -31,7 +37,6 @@ module FSR
|
|
31
37
|
# @param reply This HeaderAndContent instance will have the channel variables
|
32
38
|
# in #content, if the session has been updated
|
33
39
|
def receive_reply(reply)
|
34
|
-
FSR::Log.warn "#{self.class.name}#receive_reply not overwritten"
|
35
40
|
FSR::Log.debug reply.inspect
|
36
41
|
end
|
37
42
|
|
@@ -49,8 +54,9 @@ module FSR
|
|
49
54
|
|
50
55
|
# Update_session
|
51
56
|
|
52
|
-
def update_session
|
57
|
+
def update_session(&block)
|
53
58
|
send_data("api uuid_dump #{@session.headers[:unique_id]}\n\n")
|
59
|
+
@queue << block if block_given?
|
54
60
|
end
|
55
61
|
|
56
62
|
def next_step
|
@@ -61,19 +67,20 @@ module FSR
|
|
61
67
|
protected
|
62
68
|
def post_init
|
63
69
|
@session = nil # holds the session object
|
70
|
+
@queue = [] # Keep track of queue for state machine
|
64
71
|
send_data("connect\n\n")
|
65
72
|
FSR::Log.debug "Accepting connections."
|
66
73
|
end
|
67
74
|
|
68
75
|
# receive_request is called each time data is received by the event machine
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
76
|
+
# it will manipulate the received data into either a new session or a reply,
|
77
|
+
# to be picked up by #session_initiated or #receive_reply.
|
78
|
+
# If your listener is listening for events, this will also renew your @session
|
79
|
+
# each time you receive a CHANNEL_DATA event.
|
73
80
|
# @param header The header of the request, as passed by HeaderAndContentProtocol
|
74
81
|
# @param content The content of the request, as passed by HeaderAndContentProtocol
|
75
82
|
#
|
76
|
-
# @
|
83
|
+
# @return [HeaderAndContentResponse] An EventMachine HeaderAndContentResponse
|
77
84
|
def receive_request(header, content)
|
78
85
|
hash_header = headers_2_hash(header)
|
79
86
|
hash_content = headers_2_hash(content)
|
@@ -82,16 +89,20 @@ module FSR
|
|
82
89
|
if @session.nil?
|
83
90
|
@session = session_header_and_content
|
84
91
|
@step = 0
|
92
|
+
@state = [:uninitiated]
|
85
93
|
session_initiated
|
94
|
+
@state << :initiated
|
86
95
|
elsif session_header_and_content.content[:event_name] # If content includes an event_name, it must be a response from an api command
|
87
96
|
if session_header_and_content.content[:event_name].to_s.match(/CHANNEL_DATA/i) # Anytime we see CHANNEL_DATA event, we want to update our @session
|
88
97
|
session_header_and_content = HeaderAndContentResponse.new({:headers => hash_header.merge(hash_content.strip_value_newlines), :content => {}})
|
89
98
|
@session = session_header_and_content
|
90
|
-
@step += 1
|
99
|
+
@step += 1 if @state.include?(:initiated)
|
100
|
+
@queue.pop.call unless @queue.empty?
|
91
101
|
receive_reply(hash_header)
|
92
102
|
end
|
93
103
|
else
|
94
|
-
@step += 1
|
104
|
+
@step += 1 if @state.include?(:initiated)
|
105
|
+
@queue.pop.call unless @queue.empty?
|
95
106
|
receive_reply(session_header_and_content)
|
96
107
|
end
|
97
108
|
end
|
data/lib/fsr/version.rb
ADDED
data/spec/helper.rb
CHANGED
@@ -1,12 +1,17 @@
|
|
1
1
|
begin
|
2
2
|
require 'bacon'
|
3
3
|
rescue LoadError
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
EOS
|
9
|
-
|
4
|
+
begin
|
5
|
+
require "rubygems"
|
6
|
+
require "bacon"
|
7
|
+
rescue LoadError
|
8
|
+
puts <<-EOS
|
9
|
+
To run these tests you must install bacon.
|
10
|
+
Quick and easy install for gem:
|
11
|
+
gem install bacon
|
12
|
+
EOS
|
13
|
+
exit(0)
|
14
|
+
end
|
10
15
|
end
|
11
16
|
|
12
17
|
Bacon.summary_on_exit
|
data/tasks/authors.rake
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Once git has a fix for the glibc in handling .mailmap and another fix for
|
2
|
+
# allowing empty mail address to be mapped in .mailmap we won't have to handle
|
3
|
+
# them manually.
|
4
|
+
|
5
|
+
desc 'Update AUTHORS'
|
6
|
+
task :authors do
|
7
|
+
authors = Hash.new(0)
|
8
|
+
|
9
|
+
`git shortlog -nse`.scan(/(\d+)\s(.+)\s<(.*)>$/) do |count, name, email|
|
10
|
+
case name
|
11
|
+
when "bougyman"
|
12
|
+
name, email = "TJ Vanderpoel", "bougy.man@gmail.com"
|
13
|
+
when /riscfuture/i
|
14
|
+
name, email = "Tim Morgan", "riscfuture@gmail.com"
|
15
|
+
when "Michael Fellinger m.fellinger@gmail.com"
|
16
|
+
name, email = "Michael Fellinger", "m.fellinger@gmail.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
authors[[name, email]] += count.to_i
|
20
|
+
end
|
21
|
+
|
22
|
+
File.open('AUTHORS', 'w+') do |io|
|
23
|
+
io.puts "Following persons have contributed to #{GEMSPEC.name}."
|
24
|
+
io.puts '(Sorted by number of submitted patches, then alphabetically)'
|
25
|
+
io.puts ''
|
26
|
+
authors.sort_by{|(n,e),c| [-c, n.downcase] }.each do |(name, email), count|
|
27
|
+
io.puts("%6d %s <%s>" % [count, name, email])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/tasks/bacon.rake
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
desc 'Run all bacon specs with pretty output'
|
2
|
+
task :bacon => :install_dependencies do
|
3
|
+
require 'open3'
|
4
|
+
require 'scanf'
|
5
|
+
require 'matrix'
|
6
|
+
|
7
|
+
specs = PROJECT_SPECS
|
8
|
+
|
9
|
+
some_failed = false
|
10
|
+
specs_size = specs.size
|
11
|
+
len = specs.map{|s| s.size }.sort.last
|
12
|
+
total_tests = total_assertions = total_failures = total_errors = 0
|
13
|
+
totals = Vector[0, 0, 0, 0]
|
14
|
+
|
15
|
+
red, yellow, green = "\e[31m%s\e[0m", "\e[33m%s\e[0m", "\e[32m%s\e[0m"
|
16
|
+
left_format = "%4d/%d: %-#{len + 11}s"
|
17
|
+
spec_format = "%d specifications (%d requirements), %d failures, %d errors"
|
18
|
+
|
19
|
+
specs.each_with_index do |spec, idx|
|
20
|
+
print(left_format % [idx + 1, specs_size, spec])
|
21
|
+
|
22
|
+
Open3.popen3(RUBY, spec) do |sin, sout, serr|
|
23
|
+
out = sout.read.strip
|
24
|
+
err = serr.read.strip
|
25
|
+
|
26
|
+
# this is conventional, see spec/innate/state/fiber.rb for usage
|
27
|
+
if out =~ /^Bacon::Error: (needed .*)/
|
28
|
+
puts(yellow % ("%6s %s" % ['', $1]))
|
29
|
+
else
|
30
|
+
total = nil
|
31
|
+
|
32
|
+
out.each_line do |line|
|
33
|
+
scanned = line.scanf(spec_format)
|
34
|
+
|
35
|
+
next unless scanned.size == 4
|
36
|
+
|
37
|
+
total = Vector[*scanned]
|
38
|
+
break
|
39
|
+
end
|
40
|
+
|
41
|
+
if total
|
42
|
+
totals += total
|
43
|
+
tests, assertions, failures, errors = total_array = total.to_a
|
44
|
+
|
45
|
+
if tests > 0 && failures + errors == 0
|
46
|
+
puts((green % "%6d passed") % tests)
|
47
|
+
else
|
48
|
+
some_failed = true
|
49
|
+
puts(red % " failed")
|
50
|
+
puts out unless out.empty?
|
51
|
+
puts err unless err.empty?
|
52
|
+
end
|
53
|
+
else
|
54
|
+
some_failed = true
|
55
|
+
puts(red % " failed")
|
56
|
+
puts out unless out.empty?
|
57
|
+
puts err unless err.empty?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
total_color = some_failed ? red : green
|
64
|
+
puts(total_color % (spec_format % totals.to_a))
|
65
|
+
exit 1 if some_failed
|
66
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'time'
|
2
|
+
desc 'update changelog'
|
3
|
+
task :changelog do
|
4
|
+
File.open('CHANGELOG', 'w+') do |changelog|
|
5
|
+
`git log -z --abbrev-commit`.split("\0").each do |commit|
|
6
|
+
next if commit =~ /^Merge: \d*/
|
7
|
+
ref, author, time, _, title, _, message = commit.split("\n", 7)
|
8
|
+
ref = ref[/commit ([0-9a-f]+)/, 1]
|
9
|
+
author = author[/Author: (.*)/, 1].strip
|
10
|
+
time = Time.parse(time[/Date: (.*)/, 1]).utc
|
11
|
+
title.strip!
|
12
|
+
|
13
|
+
changelog.puts "[#{ref} | #{time}] #{author}"
|
14
|
+
changelog.puts '', " * #{title}"
|
15
|
+
changelog.puts '', message.rstrip if message
|
16
|
+
changelog.puts
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
desc "add copyright to all .rb files in the distribution"
|
2
|
+
task :copyright do
|
3
|
+
ignore = File.readlines('License.txt').
|
4
|
+
select{|line| line.strip!; File.exist?(line)}.
|
5
|
+
map{|file| File.expand_path(file)}
|
6
|
+
|
7
|
+
puts "adding copyright to files that don't have it currently"
|
8
|
+
puts PROJECT_COPYRIGHT
|
9
|
+
puts
|
10
|
+
|
11
|
+
Dir['{lib,test}/**/*{.rb}'].each do |file|
|
12
|
+
file = File.expand_path(file)
|
13
|
+
next if ignore.include? file
|
14
|
+
lines = File.readlines(file).map{|l| l.chomp}
|
15
|
+
unless lines.first(PROJECT_COPYRIGHT.size) == PROJECT_COPYRIGHT
|
16
|
+
puts "#{file} seems to need attention, first 4 lines:"
|
17
|
+
puts lines[0..3]
|
18
|
+
puts
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|