sevenscale-adhearsion 0.7.1000
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/CHANGELOG +3 -0
- data/LICENSE +456 -0
- data/Manifest.txt +149 -0
- data/README.txt +6 -0
- data/Rakefile +48 -0
- data/ahn_generators/component/USAGE +5 -0
- data/ahn_generators/component/component_generator.rb +57 -0
- data/ahn_generators/component/templates/configuration.rb +0 -0
- data/ahn_generators/component/templates/lib/lib.rb.erb +3 -0
- data/ahn_generators/component/templates/test/test.rb.erb +12 -0
- data/ahn_generators/component/templates/test/test_helper.rb +14 -0
- data/app_generators/ahn/USAGE +5 -0
- data/app_generators/ahn/ahn_generator.rb +76 -0
- data/app_generators/ahn/templates/.ahnrc +12 -0
- data/app_generators/ahn/templates/README +8 -0
- data/app_generators/ahn/templates/Rakefile +3 -0
- data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
- data/app_generators/ahn/templates/components/simon_game/lib/simon_game.rb +61 -0
- data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +14 -0
- data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +31 -0
- data/app_generators/ahn/templates/config/startup.rb +53 -0
- data/app_generators/ahn/templates/dialplan.rb +4 -0
- data/bin/ahn +28 -0
- data/bin/ahnctl +68 -0
- data/bin/jahn +32 -0
- data/lib/adhearsion/blank_slate.rb +5 -0
- data/lib/adhearsion/cli.rb +106 -0
- data/lib/adhearsion/component_manager.rb +277 -0
- data/lib/adhearsion/core_extensions/all.rb +9 -0
- data/lib/adhearsion/core_extensions/array.rb +0 -0
- data/lib/adhearsion/core_extensions/custom_daemonizer.rb +45 -0
- data/lib/adhearsion/core_extensions/global.rb +1 -0
- data/lib/adhearsion/core_extensions/guid.rb +5 -0
- data/lib/adhearsion/core_extensions/hash.rb +0 -0
- data/lib/adhearsion/core_extensions/metaprogramming.rb +17 -0
- data/lib/adhearsion/core_extensions/numeric.rb +4 -0
- data/lib/adhearsion/core_extensions/proc.rb +0 -0
- data/lib/adhearsion/core_extensions/pseudo_uuid.rb +11 -0
- data/lib/adhearsion/core_extensions/publishable.rb +73 -0
- data/lib/adhearsion/core_extensions/relationship_properties.rb +40 -0
- data/lib/adhearsion/core_extensions/string.rb +26 -0
- data/lib/adhearsion/core_extensions/thread.rb +13 -0
- data/lib/adhearsion/core_extensions/thread_safety.rb +7 -0
- data/lib/adhearsion/core_extensions/time.rb +0 -0
- data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
- data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
- data/lib/adhearsion/distributed/gateways/rest_gateway.rb +9 -0
- data/lib/adhearsion/distributed/gateways/soap_gateway.rb +9 -0
- data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +9 -0
- data/lib/adhearsion/distributed/peer_finder.rb +0 -0
- data/lib/adhearsion/distributed/remote_cli.rb +0 -0
- data/lib/adhearsion/hooks.rb +57 -0
- data/lib/adhearsion/host_definitions.rb +63 -0
- data/lib/adhearsion/initializer/asterisk.rb +59 -0
- data/lib/adhearsion/initializer/configuration.rb +202 -0
- data/lib/adhearsion/initializer/database.rb +92 -0
- data/lib/adhearsion/initializer/drb.rb +25 -0
- data/lib/adhearsion/initializer/freeswitch.rb +22 -0
- data/lib/adhearsion/initializer/paths.rb +55 -0
- data/lib/adhearsion/initializer/rails.rb +40 -0
- data/lib/adhearsion/initializer.rb +217 -0
- data/lib/adhearsion/logging.rb +92 -0
- data/lib/adhearsion/services/scheduler.rb +5 -0
- data/lib/adhearsion/tasks/database.rb +5 -0
- data/lib/adhearsion/tasks/generating.rb +20 -0
- data/lib/adhearsion/tasks/lint.rb +4 -0
- data/lib/adhearsion/tasks/testing.rb +37 -0
- data/lib/adhearsion/tasks.rb +15 -0
- data/lib/adhearsion/version.rb +9 -0
- data/lib/adhearsion/voip/asterisk/agi_server.rb +78 -0
- data/lib/adhearsion/voip/asterisk/ami/actions.rb +238 -0
- data/lib/adhearsion/voip/asterisk/ami/machine.rb +871 -0
- data/lib/adhearsion/voip/asterisk/ami/machine.rl +109 -0
- data/lib/adhearsion/voip/asterisk/ami/parser.rb +262 -0
- data/lib/adhearsion/voip/asterisk/ami.rb +147 -0
- data/lib/adhearsion/voip/asterisk/commands.rb +1186 -0
- data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +140 -0
- data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +101 -0
- data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +250 -0
- data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +240 -0
- data/lib/adhearsion/voip/asterisk/config_manager.rb +71 -0
- data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +80 -0
- data/lib/adhearsion/voip/asterisk.rb +4 -0
- data/lib/adhearsion/voip/call.rb +402 -0
- data/lib/adhearsion/voip/call_routing.rb +64 -0
- data/lib/adhearsion/voip/commands.rb +9 -0
- data/lib/adhearsion/voip/constants.rb +39 -0
- data/lib/adhearsion/voip/conveniences.rb +18 -0
- data/lib/adhearsion/voip/dial_plan.rb +205 -0
- data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
- data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -0
- data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +27 -0
- data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +124 -0
- data/lib/adhearsion/voip/dsl/dialplan/parser.rb +75 -0
- data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
- data/lib/adhearsion/voip/dsl/numerical_string.rb +117 -0
- data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +48 -0
- data/lib/adhearsion/voip/freeswitch/event_handler.rb +58 -0
- data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +129 -0
- data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +38 -0
- data/lib/adhearsion/voip/freeswitch/oes_server.rb +195 -0
- data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +80 -0
- data/lib/adhearsion/voip/menu_state_machine/matchers.rb +123 -0
- data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +58 -0
- data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +149 -0
- data/lib/adhearsion.rb +31 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/fixtures/dialplan.rb +3 -0
- data/spec/initializer/test_configuration.rb +267 -0
- data/spec/initializer/test_loading.rb +162 -0
- data/spec/initializer/test_paths.rb +43 -0
- data/spec/silence.rb +10 -0
- data/spec/test_ahn_command.rb +149 -0
- data/spec/test_code_quality.rb +87 -0
- data/spec/test_component_manager.rb +97 -0
- data/spec/test_constants.rb +8 -0
- data/spec/test_drb.rb +104 -0
- data/spec/test_helper.rb +94 -0
- data/spec/test_hooks.rb +37 -0
- data/spec/test_host_definitions.rb +79 -0
- data/spec/test_initialization.rb +105 -0
- data/spec/test_logging.rb +80 -0
- data/spec/test_relationship_properties.rb +54 -0
- data/spec/voip/asterisk/ami_response_definitions.rb +23 -0
- data/spec/voip/asterisk/config_file_generators/test_agents.rb +253 -0
- data/spec/voip/asterisk/config_file_generators/test_queues.rb +325 -0
- data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +306 -0
- data/spec/voip/asterisk/menu_command/test_calculated_match.rb +111 -0
- data/spec/voip/asterisk/menu_command/test_matchers.rb +98 -0
- data/spec/voip/asterisk/mock_ami_server.rb +176 -0
- data/spec/voip/asterisk/test_agi_server.rb +453 -0
- data/spec/voip/asterisk/test_ami.rb +227 -0
- data/spec/voip/asterisk/test_commands.rb +2006 -0
- data/spec/voip/asterisk/test_config_manager.rb +129 -0
- data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
- data/spec/voip/dsl/test_dialing_dsl.rb +268 -0
- data/spec/voip/dsl/test_dispatcher.rb +82 -0
- data/spec/voip/dsl/test_parser.rb +87 -0
- data/spec/voip/freeswitch/test_basic_connection_manager.rb +39 -0
- data/spec/voip/freeswitch/test_inbound_connection_manager.rb +39 -0
- data/spec/voip/freeswitch/test_oes_server.rb +9 -0
- data/spec/voip/test_call_routing.rb +127 -0
- data/spec/voip/test_dialplan_manager.rb +372 -0
- data/spec/voip/test_numerical_string.rb +48 -0
- data/spec/voip/test_phone_number.rb +36 -0
- data/test/test_ahn_generator.rb +59 -0
- data/test/test_component_generator.rb +52 -0
- data/test/test_generator_helper.rb +20 -0
- metadata +254 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
class ComponentGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
default_options :author => nil
|
4
|
+
|
5
|
+
attr_reader :name, :class_name
|
6
|
+
|
7
|
+
def initialize(runtime_args, runtime_options = {})
|
8
|
+
super
|
9
|
+
usage if args.empty?
|
10
|
+
@name = args.shift
|
11
|
+
@name = @name.underscore
|
12
|
+
@class_name = @name.camelize
|
13
|
+
extract_options
|
14
|
+
end
|
15
|
+
|
16
|
+
def manifest
|
17
|
+
record do |m|
|
18
|
+
# Ensure appropriate folder(s) exists
|
19
|
+
m.directory "components/#{name}/lib"
|
20
|
+
m.directory "components/#{name}/test"
|
21
|
+
|
22
|
+
# Create stubs
|
23
|
+
m.file "configuration.rb", "components/#{name}/configuration.rb"
|
24
|
+
m.template "lib/lib.rb.erb", "components/#{name}/lib/#{name}.rb"
|
25
|
+
m.template "test/test.rb.erb", "components/#{name}/test/test_#{name}.rb"
|
26
|
+
m.file "test/test_helper.rb", "components/#{name}/test/test_helper.rb"
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
def banner
|
33
|
+
<<-EOS
|
34
|
+
Creates a ...
|
35
|
+
|
36
|
+
USAGE: #{$0} #{spec.name} name"
|
37
|
+
EOS
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_options!(opts)
|
41
|
+
# opts.separator ''
|
42
|
+
# opts.separator 'Options:'
|
43
|
+
# For each option below, place the default
|
44
|
+
# at the top of the file next to "default_options"
|
45
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
46
|
+
# "Some comment about this option",
|
47
|
+
# "Default: none") { |options[:author]| }
|
48
|
+
# opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
49
|
+
end
|
50
|
+
|
51
|
+
def extract_options
|
52
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
53
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
54
|
+
# raw instance variable value.
|
55
|
+
# @author = options[:author]
|
56
|
+
end
|
57
|
+
end
|
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../../../../lib'
|
2
|
+
require 'adhearsion'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'flexmock/test_unit'
|
5
|
+
AHN_ROOT = Adhearsion::PathString.new(File.dirname(__FILE__) + '/../../..')
|
6
|
+
Adhearsion::ComponentManager.load
|
7
|
+
Adhearsion::ComponentManager.start
|
8
|
+
|
9
|
+
class Test::Unit::TestCase
|
10
|
+
Adhearsion::ComponentManager.components_with_call_context.each_pair do |component_class_name, component_configuration|
|
11
|
+
const_set(component_class_name, component_configuration.component_class)
|
12
|
+
const_get(component_class_name).send(:attr_accessor, :call_context)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class AhnGenerator < RubiGen::Base
|
2
|
+
|
3
|
+
DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
|
4
|
+
Config::CONFIG['ruby_install_name'])
|
5
|
+
|
6
|
+
default_options :author => nil
|
7
|
+
|
8
|
+
attr_reader :name, :component
|
9
|
+
|
10
|
+
def initialize(runtime_args, runtime_options = {})
|
11
|
+
super
|
12
|
+
usage if args.empty?
|
13
|
+
@destination_root = File.expand_path(args.shift)
|
14
|
+
@name = base_name
|
15
|
+
@component = 'simon_game'
|
16
|
+
extract_options
|
17
|
+
end
|
18
|
+
|
19
|
+
def manifest
|
20
|
+
record do |m|
|
21
|
+
# Ensure appropriate folder(s) exists
|
22
|
+
m.directory ''
|
23
|
+
BASEDIRS.each { |path| m.directory path }
|
24
|
+
|
25
|
+
m.file *[".ahnrc"]*2
|
26
|
+
|
27
|
+
m.file *["components/simon_game/configuration.rb"]*2
|
28
|
+
m.file *["components/simon_game/lib/simon_game.rb"]*2
|
29
|
+
m.file *["components/simon_game/test/test_helper.rb"]*2
|
30
|
+
m.file *["components/simon_game/test/test_simon_game.rb"]*2
|
31
|
+
|
32
|
+
m.file *["config/startup.rb"]*2
|
33
|
+
m.file *["dialplan.rb"]*2
|
34
|
+
m.file *["README"]*2
|
35
|
+
m.file *["Rakefile"]*2
|
36
|
+
|
37
|
+
m.dependency "install_rubigen_scripts", [destination_root, 'ahn', 'adhearsion', 'test_spec'],
|
38
|
+
:shebang => options[:shebang], :collision => :force
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
def banner
|
44
|
+
<<-EOS
|
45
|
+
Creates a ...
|
46
|
+
|
47
|
+
USAGE: #{spec.name} name"
|
48
|
+
EOS
|
49
|
+
end
|
50
|
+
|
51
|
+
def add_options!(opts)
|
52
|
+
opts.separator ''
|
53
|
+
opts.separator 'Options:'
|
54
|
+
# For each option below, place the default
|
55
|
+
# at the top of the file next to "default_options"
|
56
|
+
# opts.on("-a", "--author=\"Your Name\"", String,
|
57
|
+
# "Some comment about this option",
|
58
|
+
# "Default: none") { |options[:author]| }
|
59
|
+
opts.on("-v", "--version", "Show the #{File.basename($0)} version number and quit.")
|
60
|
+
end
|
61
|
+
|
62
|
+
def extract_options
|
63
|
+
# for each option, extract it into a local variable (and create an "attr_reader :author" at the top)
|
64
|
+
# Templates can access these value via the attr_reader-generated methods, but not the
|
65
|
+
# raw instance variable value.
|
66
|
+
# @author = options[:author]
|
67
|
+
end
|
68
|
+
|
69
|
+
# Installation skeleton. Intermediate directories are automatically
|
70
|
+
# created so don't sweat their absence here.
|
71
|
+
BASEDIRS = %w(
|
72
|
+
components/simon_game/lib
|
73
|
+
components/simon_game/test
|
74
|
+
config
|
75
|
+
)
|
76
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Start your new app with "ahn start /path/to/your/app"
|
2
|
+
|
3
|
+
If you wish to use Adhearsion to control Asterisk's dialplan,
|
4
|
+
change the contexts you wish to be affected in your
|
5
|
+
/etc/asterisk/extensions.conf file to the following:
|
6
|
+
|
7
|
+
[your_context_name]
|
8
|
+
exten => _X.,1,AGI(agi://1.2.3.4) ; This IP here
|
File without changes
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class SimonGame
|
2
|
+
add_call_context :as => :call_context
|
3
|
+
|
4
|
+
attr_accessor :number, :attempt
|
5
|
+
def initialize
|
6
|
+
initialize_number
|
7
|
+
initialize_attempt
|
8
|
+
end
|
9
|
+
|
10
|
+
def start
|
11
|
+
loop do
|
12
|
+
say_number
|
13
|
+
collect_attempt
|
14
|
+
verify_attempt
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def random_number
|
19
|
+
rand(10).to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_number
|
23
|
+
initialize_attempt
|
24
|
+
@number << random_number
|
25
|
+
end
|
26
|
+
|
27
|
+
def say_number
|
28
|
+
update_number
|
29
|
+
call_context.say_digits number
|
30
|
+
end
|
31
|
+
|
32
|
+
def collect_attempt
|
33
|
+
@attempt = call_context.input(number.size)
|
34
|
+
end
|
35
|
+
|
36
|
+
def verify_attempt
|
37
|
+
if attempt_correct?
|
38
|
+
call_context.play 'good'
|
39
|
+
else
|
40
|
+
call_context.play %W(#{number.size - 1} times wrong-try-again-smarty)
|
41
|
+
reset
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def attempt_correct?
|
46
|
+
attempt == number
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize_attempt
|
50
|
+
@attempt ||= ''
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize_number
|
54
|
+
@number ||= ''
|
55
|
+
end
|
56
|
+
|
57
|
+
def reset
|
58
|
+
@attempt, @number = '', ''
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + '/../../../../../lib'
|
2
|
+
require 'adhearsion'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'flexmock/test_unit'
|
5
|
+
AHN_ROOT = Adhearsion::PathString.new(File.dirname(__FILE__) + '/../../..')
|
6
|
+
Adhearsion::ComponentManager.load
|
7
|
+
Adhearsion::ComponentManager.start
|
8
|
+
|
9
|
+
class Test::Unit::TestCase
|
10
|
+
Adhearsion::ComponentManager.components_with_call_context.each_pair do |component_class_name, component_configuration|
|
11
|
+
const_set(component_class_name, component_configuration.component_class)
|
12
|
+
const_get(component_class_name).send(:attr_accessor, :call_context)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/test_helper"
|
2
|
+
|
3
|
+
class TestSimonGame < Test::Unit::TestCase
|
4
|
+
attr_reader :game
|
5
|
+
def setup
|
6
|
+
@game = SimonGame.new
|
7
|
+
@game.call_context = mock_call_context
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_game_executes_say_digits_when_asked_to_say_number
|
11
|
+
flexmock(game).should_receive(:random_number).and_return("2")
|
12
|
+
mock_call_context.should_receive(:say_digits).once.with('2')
|
13
|
+
@game.say_number
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
# Didn't get very far on this
|
18
|
+
def xtest_can_play_one_round_and_receive_the_players_score
|
19
|
+
flexmock(game).should_receive(:random_number).and_return("2")
|
20
|
+
assert_equal(3, 'x')
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def mock_call_context
|
25
|
+
@mock_call_context ||= flexmock("Mock Call Context")
|
26
|
+
end
|
27
|
+
|
28
|
+
def stub_random_number
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
unless defined? Adhearsion
|
2
|
+
if File.exists? File.dirname(__FILE__) + "/../adhearsion/lib/adhearsion.rb"
|
3
|
+
# If you wish to freeze a copy of Adhearsion to this app, simply place a copy of Adhearsion
|
4
|
+
# into a folder named "adhearsion" within this app's main directory.
|
5
|
+
require File.dirname(__FILE__) + "/../adhearsion/lib/adhearsion.rb"
|
6
|
+
else
|
7
|
+
require 'rubygems'
|
8
|
+
gem 'adhearsion', '>= 0.7.999'
|
9
|
+
require 'adhearsion'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
Adhearsion::Configuration.configure do |config|
|
14
|
+
|
15
|
+
# Supported levels (in increasing severity) -- :debug < :info < :warn < :error < :fatal
|
16
|
+
config.logging :level => :info
|
17
|
+
|
18
|
+
# Whether incoming calls be automatically answered. Defaults to true.
|
19
|
+
# config.automatically_answer_incoming_calls = false
|
20
|
+
|
21
|
+
# Whether the other end hanging up should end the call immediately. Defaults to true.
|
22
|
+
# config.end_call_on_hangup = false
|
23
|
+
|
24
|
+
# Whether to end the call immediately if an unrescued exception is caught. Defaults to true.
|
25
|
+
# config.end_call_on_error = false
|
26
|
+
|
27
|
+
# By default Asterisk is enabled with the default settings
|
28
|
+
config.enable_asterisk
|
29
|
+
# config.asterisk.enable_ami :host => "127.0.0.1", :username => "admin", :password => "password"
|
30
|
+
|
31
|
+
# To change the host IP or port on which the AGI server listens, use this:
|
32
|
+
# config.enable_asterisk :listening_port => 4574, :listening_host => "127.0.0.1"
|
33
|
+
|
34
|
+
# config.enable_drb
|
35
|
+
|
36
|
+
# Streamlined Rails integration! The first argument should be a relative or absolute path to
|
37
|
+
# the Rails app folder with which you're integrating. The second argument must be one of the
|
38
|
+
# the following: :development, :production, or :test.
|
39
|
+
|
40
|
+
# config.enable_rails :path => 'gui', :env => :development
|
41
|
+
|
42
|
+
# Note: You CANNOT do enable_rails and enable_database at the same time. When you enable Rails,
|
43
|
+
# it will automatically connect to same database Rails does and load the Rails app's models.
|
44
|
+
|
45
|
+
# Configure a database to use ActiveRecord-backed models. See ActiveRecord::Base.establish_connection
|
46
|
+
# for the appropriate settings here.
|
47
|
+
# config.enable_database :adapter => 'mysql',
|
48
|
+
# :username => 'joe',
|
49
|
+
# :password => 'secret',
|
50
|
+
# :host => 'db.example.org'
|
51
|
+
end
|
52
|
+
|
53
|
+
Adhearsion::Initializer.start_from_init_file(__FILE__, File.dirname(__FILE__) + "/..")
|
data/bin/ahn
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This is the main executable file.
|
4
|
+
|
5
|
+
# Adhearsion, open source collaboration framework
|
6
|
+
# Copyright (C) 2006,2007,2008 Jay Phillips
|
7
|
+
#
|
8
|
+
# This library is free software; you can redistribute it and/or modify it under
|
9
|
+
# the terms of the GNU Lesser General Public License as published by the Free
|
10
|
+
# Software Foundation; either version 2.1 of the License, or (at your option)
|
11
|
+
# any later version.
|
12
|
+
#
|
13
|
+
# This library is distributed in the hope that it will be useful, but WITHOUT
|
14
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
15
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
16
|
+
# details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Lesser General Public License along
|
19
|
+
# with this library; if not, write to the Free Software Foundation, Inc.,
|
20
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
+
|
22
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
23
|
+
|
24
|
+
require 'rubygems'
|
25
|
+
require 'adhearsion'
|
26
|
+
require 'adhearsion/cli'
|
27
|
+
|
28
|
+
Adhearsion::CLI::AhnCommand.execute!
|
data/bin/ahnctl
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# ahnctl - Adhearsion daemon controller
|
4
|
+
#
|
5
|
+
# Adhearsion, open source collaboration framework
|
6
|
+
# Copyright (C) 2006,2007,2008 Jay Phillips
|
7
|
+
#
|
8
|
+
# This library is free software; you can redistribute it and/or
|
9
|
+
# modify it under the terms of the GNU Lesser General Public
|
10
|
+
# License as published by the Free Software Foundation; either
|
11
|
+
# version 2.1 of the License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# This library is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
16
|
+
# Lesser General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Lesser General Public
|
19
|
+
# License along with this library; if not, write to the Free Software
|
20
|
+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
+
|
22
|
+
USAGE = "Usage: ahnctl start|stop|restart /path/to/adhearsion/app [--pid-file=/path/to/pid_file.pid]"
|
23
|
+
|
24
|
+
# Blow up if the CLI arguments are invalid
|
25
|
+
abort USAGE unless (2..3).include?(ARGV.size) && %w[start stop restart].include?(ARGV.first)
|
26
|
+
|
27
|
+
# By default, ahnctl will use the version of Adhearsion it was installed with.
|
28
|
+
|
29
|
+
pid_file = ARGV.pop if ARGV.size == 3
|
30
|
+
ahn_command = File.expand_path File.dirname(__FILE__) + "/ahn"
|
31
|
+
app_dir = File.expand_path ARGV.last
|
32
|
+
|
33
|
+
pid_file_path_regexp = /^--pid-file=(.+)$/
|
34
|
+
abort USAGE if pid_file && pid_file !~ pid_file_path_regexp
|
35
|
+
|
36
|
+
# If pid_file is not nil, let's extract the path specified.
|
37
|
+
pid_file &&= File.expand_path pid_file[pid_file_path_regexp,1]
|
38
|
+
|
39
|
+
# If there was no third argument and pid_file is still nil, let's use the default.
|
40
|
+
pid_file ||= app_dir + '/adhearsion.pid'
|
41
|
+
|
42
|
+
abort "Directory is not an Adhearsion application!" unless File.exists?(app_dir + "/.ahnrc")
|
43
|
+
|
44
|
+
def terminate(pid) `kill -s TERM #{pid} 2> /dev/null` end
|
45
|
+
def kill(pid) `kill -s KILL #{pid} 2> /dev/null` end
|
46
|
+
|
47
|
+
# Even if we're starting Adhearsion, we need to make sure to clean up after any stale
|
48
|
+
# pid files. In effect, start is the same as restart.
|
49
|
+
puts "Stopping Adhearsion app at #{app_dir}" if %w[stop restart].include? ARGV.first
|
50
|
+
|
51
|
+
if File.exists?(pid_file)
|
52
|
+
# An Adhearsion process may still be running. Let's kill the other one as cleanly as possible
|
53
|
+
pid = File.read(pid_file).to_i
|
54
|
+
|
55
|
+
# Time to spend waiting for Adhearsion to exit
|
56
|
+
waiting_timeout = Time.now + 15
|
57
|
+
|
58
|
+
terminate pid
|
59
|
+
sleep 0.25 until `ps -p #{pid} | sed -e '1d'`.strip.empty? || Time.now > waiting_timeout
|
60
|
+
kill pid
|
61
|
+
|
62
|
+
`rm -f #{pid_file}`
|
63
|
+
end
|
64
|
+
|
65
|
+
if ['start', 'restart'].include? ARGV.first
|
66
|
+
puts "Starting Adhearsion app at #{app_dir}"
|
67
|
+
`#{ahn_command} start daemon #{app_dir} --pid-file=#{pid_file}`
|
68
|
+
end
|
data/bin/jahn
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
#!/usr/bin/env jruby
|
2
|
+
|
3
|
+
# This "jahn" script is "ahn" for JRUBY!
|
4
|
+
|
5
|
+
# Adhearsion, open source collaboration framework
|
6
|
+
# Copyright (C) 2006,2007,2008 Jay Phillips
|
7
|
+
#
|
8
|
+
# This library is free software; you can redistribute it and/or modify it under
|
9
|
+
# the terms of the GNU Lesser General Public License as published by the Free
|
10
|
+
# Software Foundation; either version 2.1 of the License, or (at your option)
|
11
|
+
# any later version.
|
12
|
+
#
|
13
|
+
# This library is distributed in the hope that it will be useful, but WITHOUT
|
14
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
15
|
+
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
16
|
+
# details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU Lesser General Public License along
|
19
|
+
# with this library; if not, write to the Free Software Foundation, Inc.,
|
20
|
+
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21
|
+
|
22
|
+
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
23
|
+
|
24
|
+
require 'rubygems'
|
25
|
+
require 'adhearsion'
|
26
|
+
require 'adhearsion/cli'
|
27
|
+
|
28
|
+
# jahn will soon have JRuby-specific behavior such as creating a compiled .jar
|
29
|
+
# file from an app.
|
30
|
+
# require 'adhearsion/jruby'
|
31
|
+
|
32
|
+
Adhearsion::CLI::AhnCommand.execute!
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Adhearsion
|
4
|
+
module CLI
|
5
|
+
module AhnCommand
|
6
|
+
USAGE = <<USAGE
|
7
|
+
Usage:
|
8
|
+
ahn create /path/to/directory
|
9
|
+
ahn start [daemon] [directory]
|
10
|
+
ahn version|-v|--v|-version|--version
|
11
|
+
ahn help|-h|--h|--help|-help
|
12
|
+
|
13
|
+
Under development:
|
14
|
+
ahn create:projectname /path/to/directory
|
15
|
+
USAGE
|
16
|
+
|
17
|
+
def self.execute!
|
18
|
+
CommandHandler.send(*parse_arguments)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.parse_arguments(args=ARGV.clone)
|
22
|
+
action = args.shift
|
23
|
+
case action
|
24
|
+
when /^-?-?h(elp)?$/, nil then [:help]
|
25
|
+
when /^-?-?v(ersion)?$/ then [:version]
|
26
|
+
when /^create(:([\w_.]+))?$/
|
27
|
+
[:create, args.shift, $LAST_PAREN_MATCH || :default]
|
28
|
+
when 'start'
|
29
|
+
pid_file_regexp = /^--pid-file=(.+)$/
|
30
|
+
if args.size > 3
|
31
|
+
raise CommandHandler::UnknownCommand, "Too many arguments supplied!" if args.size > 3
|
32
|
+
elsif args.size == 3
|
33
|
+
raise CommandHandler::UnknownCommand, "Unrecognized final argument #{args.last}" unless args.last =~ pid_file_regexp
|
34
|
+
pid_file = args.pop[pid_file_regexp, 1]
|
35
|
+
else
|
36
|
+
pid_file = nil
|
37
|
+
end
|
38
|
+
|
39
|
+
if args.first == 'daemon' && args.size == 2
|
40
|
+
path = args.last
|
41
|
+
daemon = true
|
42
|
+
elsif args.size == 1
|
43
|
+
path, daemon = args.first, false
|
44
|
+
else
|
45
|
+
raise CommandHandler::UnknownCommand, "Invalid format for the start CLI command!"
|
46
|
+
end
|
47
|
+
[:start, path, daemon, pid_file]
|
48
|
+
when '-'
|
49
|
+
[:start, Dir.pwd]
|
50
|
+
else
|
51
|
+
[action, *args]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module CommandHandler
|
56
|
+
class << self
|
57
|
+
def create(path, project=:default)
|
58
|
+
raise UnknownProject.new(project) if project != :default # TODO: Support other projects
|
59
|
+
require 'rubigen'
|
60
|
+
require 'rubigen/scripts/generate'
|
61
|
+
source = RubiGen::PathSource.new(:application,
|
62
|
+
File.join(File.dirname(__FILE__), "../../app_generators"))
|
63
|
+
RubiGen::Base.reset_sources
|
64
|
+
RubiGen::Base.append_sources source
|
65
|
+
RubiGen::Scripts::Generate.new.run([path], :generator => 'ahn')
|
66
|
+
end
|
67
|
+
|
68
|
+
def start(path, daemon=false, pid_file=nil)
|
69
|
+
raise PathInvalid, path unless File.exists? path + "/.ahnrc"
|
70
|
+
Adhearsion::Initializer.new path, :daemon => daemon, :pid_file => pid_file
|
71
|
+
end
|
72
|
+
|
73
|
+
def version
|
74
|
+
puts "Adhearsion v#{Adhearsion::VERSION::STRING}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def help
|
78
|
+
puts USAGE
|
79
|
+
end
|
80
|
+
|
81
|
+
def method_missing(action, *args)
|
82
|
+
raise UnknownCommand, [action, *args] * " "
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class UnknownCommand < Exception
|
87
|
+
def initialize(cmd)
|
88
|
+
super "Unknown command: #{cmd}\n#{USAGE}"
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class UnknownProject < Exception
|
93
|
+
def initialize(project)
|
94
|
+
super "Application #{project} does not exist! Have you installed it?"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
class PathInvalid < Exception
|
99
|
+
def initialize(path)
|
100
|
+
super "Directory #{path} does not contain an Adhearsion project!"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|