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.
Files changed (150) hide show
  1. data/CHANGELOG +3 -0
  2. data/LICENSE +456 -0
  3. data/Manifest.txt +149 -0
  4. data/README.txt +6 -0
  5. data/Rakefile +48 -0
  6. data/ahn_generators/component/USAGE +5 -0
  7. data/ahn_generators/component/component_generator.rb +57 -0
  8. data/ahn_generators/component/templates/configuration.rb +0 -0
  9. data/ahn_generators/component/templates/lib/lib.rb.erb +3 -0
  10. data/ahn_generators/component/templates/test/test.rb.erb +12 -0
  11. data/ahn_generators/component/templates/test/test_helper.rb +14 -0
  12. data/app_generators/ahn/USAGE +5 -0
  13. data/app_generators/ahn/ahn_generator.rb +76 -0
  14. data/app_generators/ahn/templates/.ahnrc +12 -0
  15. data/app_generators/ahn/templates/README +8 -0
  16. data/app_generators/ahn/templates/Rakefile +3 -0
  17. data/app_generators/ahn/templates/components/simon_game/configuration.rb +0 -0
  18. data/app_generators/ahn/templates/components/simon_game/lib/simon_game.rb +61 -0
  19. data/app_generators/ahn/templates/components/simon_game/test/test_helper.rb +14 -0
  20. data/app_generators/ahn/templates/components/simon_game/test/test_simon_game.rb +31 -0
  21. data/app_generators/ahn/templates/config/startup.rb +53 -0
  22. data/app_generators/ahn/templates/dialplan.rb +4 -0
  23. data/bin/ahn +28 -0
  24. data/bin/ahnctl +68 -0
  25. data/bin/jahn +32 -0
  26. data/lib/adhearsion/blank_slate.rb +5 -0
  27. data/lib/adhearsion/cli.rb +106 -0
  28. data/lib/adhearsion/component_manager.rb +277 -0
  29. data/lib/adhearsion/core_extensions/all.rb +9 -0
  30. data/lib/adhearsion/core_extensions/array.rb +0 -0
  31. data/lib/adhearsion/core_extensions/custom_daemonizer.rb +45 -0
  32. data/lib/adhearsion/core_extensions/global.rb +1 -0
  33. data/lib/adhearsion/core_extensions/guid.rb +5 -0
  34. data/lib/adhearsion/core_extensions/hash.rb +0 -0
  35. data/lib/adhearsion/core_extensions/metaprogramming.rb +17 -0
  36. data/lib/adhearsion/core_extensions/numeric.rb +4 -0
  37. data/lib/adhearsion/core_extensions/proc.rb +0 -0
  38. data/lib/adhearsion/core_extensions/pseudo_uuid.rb +11 -0
  39. data/lib/adhearsion/core_extensions/publishable.rb +73 -0
  40. data/lib/adhearsion/core_extensions/relationship_properties.rb +40 -0
  41. data/lib/adhearsion/core_extensions/string.rb +26 -0
  42. data/lib/adhearsion/core_extensions/thread.rb +13 -0
  43. data/lib/adhearsion/core_extensions/thread_safety.rb +7 -0
  44. data/lib/adhearsion/core_extensions/time.rb +0 -0
  45. data/lib/adhearsion/distributed/gateways/dbus_gateway.rb +0 -0
  46. data/lib/adhearsion/distributed/gateways/osa_gateway.rb +0 -0
  47. data/lib/adhearsion/distributed/gateways/rest_gateway.rb +9 -0
  48. data/lib/adhearsion/distributed/gateways/soap_gateway.rb +9 -0
  49. data/lib/adhearsion/distributed/gateways/xmlrpc_gateway.rb +9 -0
  50. data/lib/adhearsion/distributed/peer_finder.rb +0 -0
  51. data/lib/adhearsion/distributed/remote_cli.rb +0 -0
  52. data/lib/adhearsion/hooks.rb +57 -0
  53. data/lib/adhearsion/host_definitions.rb +63 -0
  54. data/lib/adhearsion/initializer/asterisk.rb +59 -0
  55. data/lib/adhearsion/initializer/configuration.rb +202 -0
  56. data/lib/adhearsion/initializer/database.rb +92 -0
  57. data/lib/adhearsion/initializer/drb.rb +25 -0
  58. data/lib/adhearsion/initializer/freeswitch.rb +22 -0
  59. data/lib/adhearsion/initializer/paths.rb +55 -0
  60. data/lib/adhearsion/initializer/rails.rb +40 -0
  61. data/lib/adhearsion/initializer.rb +217 -0
  62. data/lib/adhearsion/logging.rb +92 -0
  63. data/lib/adhearsion/services/scheduler.rb +5 -0
  64. data/lib/adhearsion/tasks/database.rb +5 -0
  65. data/lib/adhearsion/tasks/generating.rb +20 -0
  66. data/lib/adhearsion/tasks/lint.rb +4 -0
  67. data/lib/adhearsion/tasks/testing.rb +37 -0
  68. data/lib/adhearsion/tasks.rb +15 -0
  69. data/lib/adhearsion/version.rb +9 -0
  70. data/lib/adhearsion/voip/asterisk/agi_server.rb +78 -0
  71. data/lib/adhearsion/voip/asterisk/ami/actions.rb +238 -0
  72. data/lib/adhearsion/voip/asterisk/ami/machine.rb +871 -0
  73. data/lib/adhearsion/voip/asterisk/ami/machine.rl +109 -0
  74. data/lib/adhearsion/voip/asterisk/ami/parser.rb +262 -0
  75. data/lib/adhearsion/voip/asterisk/ami.rb +147 -0
  76. data/lib/adhearsion/voip/asterisk/commands.rb +1186 -0
  77. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +140 -0
  78. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +101 -0
  79. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +250 -0
  80. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +240 -0
  81. data/lib/adhearsion/voip/asterisk/config_manager.rb +71 -0
  82. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +80 -0
  83. data/lib/adhearsion/voip/asterisk.rb +4 -0
  84. data/lib/adhearsion/voip/call.rb +402 -0
  85. data/lib/adhearsion/voip/call_routing.rb +64 -0
  86. data/lib/adhearsion/voip/commands.rb +9 -0
  87. data/lib/adhearsion/voip/constants.rb +39 -0
  88. data/lib/adhearsion/voip/conveniences.rb +18 -0
  89. data/lib/adhearsion/voip/dial_plan.rb +205 -0
  90. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
  91. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -0
  92. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +27 -0
  93. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +124 -0
  94. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +75 -0
  95. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
  96. data/lib/adhearsion/voip/dsl/numerical_string.rb +117 -0
  97. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +48 -0
  98. data/lib/adhearsion/voip/freeswitch/event_handler.rb +58 -0
  99. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +129 -0
  100. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +38 -0
  101. data/lib/adhearsion/voip/freeswitch/oes_server.rb +195 -0
  102. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +80 -0
  103. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +123 -0
  104. data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +58 -0
  105. data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +149 -0
  106. data/lib/adhearsion.rb +31 -0
  107. data/script/destroy +14 -0
  108. data/script/generate +14 -0
  109. data/spec/fixtures/dialplan.rb +3 -0
  110. data/spec/initializer/test_configuration.rb +267 -0
  111. data/spec/initializer/test_loading.rb +162 -0
  112. data/spec/initializer/test_paths.rb +43 -0
  113. data/spec/silence.rb +10 -0
  114. data/spec/test_ahn_command.rb +149 -0
  115. data/spec/test_code_quality.rb +87 -0
  116. data/spec/test_component_manager.rb +97 -0
  117. data/spec/test_constants.rb +8 -0
  118. data/spec/test_drb.rb +104 -0
  119. data/spec/test_helper.rb +94 -0
  120. data/spec/test_hooks.rb +37 -0
  121. data/spec/test_host_definitions.rb +79 -0
  122. data/spec/test_initialization.rb +105 -0
  123. data/spec/test_logging.rb +80 -0
  124. data/spec/test_relationship_properties.rb +54 -0
  125. data/spec/voip/asterisk/ami_response_definitions.rb +23 -0
  126. data/spec/voip/asterisk/config_file_generators/test_agents.rb +253 -0
  127. data/spec/voip/asterisk/config_file_generators/test_queues.rb +325 -0
  128. data/spec/voip/asterisk/config_file_generators/test_voicemail.rb +306 -0
  129. data/spec/voip/asterisk/menu_command/test_calculated_match.rb +111 -0
  130. data/spec/voip/asterisk/menu_command/test_matchers.rb +98 -0
  131. data/spec/voip/asterisk/mock_ami_server.rb +176 -0
  132. data/spec/voip/asterisk/test_agi_server.rb +453 -0
  133. data/spec/voip/asterisk/test_ami.rb +227 -0
  134. data/spec/voip/asterisk/test_commands.rb +2006 -0
  135. data/spec/voip/asterisk/test_config_manager.rb +129 -0
  136. data/spec/voip/dsl/dispatcher_spec_helper.rb +45 -0
  137. data/spec/voip/dsl/test_dialing_dsl.rb +268 -0
  138. data/spec/voip/dsl/test_dispatcher.rb +82 -0
  139. data/spec/voip/dsl/test_parser.rb +87 -0
  140. data/spec/voip/freeswitch/test_basic_connection_manager.rb +39 -0
  141. data/spec/voip/freeswitch/test_inbound_connection_manager.rb +39 -0
  142. data/spec/voip/freeswitch/test_oes_server.rb +9 -0
  143. data/spec/voip/test_call_routing.rb +127 -0
  144. data/spec/voip/test_dialplan_manager.rb +372 -0
  145. data/spec/voip/test_numerical_string.rb +48 -0
  146. data/spec/voip/test_phone_number.rb +36 -0
  147. data/test/test_ahn_generator.rb +59 -0
  148. data/test/test_component_generator.rb +52 -0
  149. data/test/test_generator_helper.rb +20 -0
  150. 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
@@ -0,0 +1,3 @@
1
+ class <%= class_name %>
2
+
3
+ end
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + "/test_helper"
2
+
3
+ class Test<%= class_name %> < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @<%= name %> = <%= class_name %>.new
7
+ end
8
+
9
+ def test_truth
10
+
11
+ end
12
+ 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,5 @@
1
+ Description:
2
+
3
+
4
+ Usage:
5
+
@@ -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,12 @@
1
+ # Adhearsion Runtime Configuration.
2
+
3
+ paths:
4
+
5
+ # All paths are relative to this file's directory
6
+ init: config/startup.rb
7
+
8
+ dialplan: dialplan.rb
9
+
10
+ models:
11
+ directory: models
12
+ pattern: "*.rb"
@@ -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
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'adhearsion'
3
+ require 'adhearsion/tasks'
@@ -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__) + "/..")
@@ -0,0 +1,4 @@
1
+ adhearsion {
2
+ simon = new_simon_game
3
+ simon.start
4
+ }
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,5 @@
1
+ class BlankSlate
2
+ instance_methods.each do |method|
3
+ undef_method method unless method =~ /^__/ || method == 'instance_eval'
4
+ end
5
+ end
@@ -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