adhearsion 2.6.4 → 3.0.0.beta1

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 (242) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -9
  3. data/CHANGELOG.md +22 -7
  4. data/Gemfile +2 -0
  5. data/README.markdown +4 -5
  6. data/Rakefile +1 -2
  7. data/adhearsion.gemspec +19 -8
  8. data/features/cli_create.feature +19 -3
  9. data/features/step_definitions/cli_steps.rb +0 -11
  10. data/features/support/env.rb +3 -4
  11. data/lib/adhearsion.rb +48 -27
  12. data/lib/adhearsion/call.rb +34 -50
  13. data/lib/adhearsion/call_controller.rb +6 -12
  14. data/lib/adhearsion/call_controller/dial.rb +15 -53
  15. data/lib/adhearsion/call_controller/input.rb +39 -162
  16. data/lib/adhearsion/call_controller/input/ask_grammar_builder.rb +44 -0
  17. data/lib/adhearsion/call_controller/input/menu_builder.rb +136 -0
  18. data/lib/adhearsion/call_controller/input/prompt_builder.rb +78 -0
  19. data/lib/adhearsion/call_controller/input/result.rb +46 -0
  20. data/lib/adhearsion/call_controller/output.rb +48 -67
  21. data/lib/adhearsion/call_controller/output/abstract_player.rb +3 -3
  22. data/lib/adhearsion/call_controller/output/async_player.rb +3 -3
  23. data/lib/adhearsion/call_controller/output/player.rb +1 -1
  24. data/lib/adhearsion/call_controller/record.rb +23 -8
  25. data/lib/adhearsion/calls.rb +1 -1
  26. data/lib/adhearsion/cli_commands/ahn_command.rb +2 -65
  27. data/lib/adhearsion/cli_commands/thor_errors.rb +0 -6
  28. data/lib/adhearsion/configuration.rb +91 -39
  29. data/lib/adhearsion/core_ext/blather/stanza.rb +41 -0
  30. data/lib/adhearsion/core_ext/blather/stanza/presence.rb +13 -0
  31. data/lib/adhearsion/error.rb +5 -0
  32. data/lib/adhearsion/event.rb +21 -0
  33. data/lib/adhearsion/event/active_speaker.rb +11 -0
  34. data/lib/adhearsion/event/answered.rb +11 -0
  35. data/lib/adhearsion/event/asterisk.rb +10 -0
  36. data/lib/adhearsion/event/asterisk/ami.rb +34 -0
  37. data/lib/adhearsion/event/complete.rb +75 -0
  38. data/lib/adhearsion/event/dtmf.rb +11 -0
  39. data/lib/adhearsion/event/end.rb +22 -0
  40. data/lib/adhearsion/event/input_timers_started.rb +9 -0
  41. data/lib/adhearsion/event/joined.rb +17 -0
  42. data/lib/adhearsion/event/offer.rb +14 -0
  43. data/lib/adhearsion/event/ringing.rb +11 -0
  44. data/lib/adhearsion/event/started_speaking.rb +13 -0
  45. data/lib/adhearsion/event/stopped_speaking.rb +13 -0
  46. data/lib/adhearsion/event/unjoined.rb +17 -0
  47. data/lib/adhearsion/events.rb +47 -66
  48. data/lib/adhearsion/foundation.rb +0 -1
  49. data/lib/adhearsion/foundation/object.rb +0 -5
  50. data/lib/adhearsion/generators/app/app_generator.rb +4 -1
  51. data/lib/adhearsion/generators/app/templates/Gemfile.erb +2 -10
  52. data/lib/adhearsion/generators/app/templates/adhearsion.erb +9 -9
  53. data/lib/adhearsion/generators/app/templates/config.ru +7 -0
  54. data/lib/adhearsion/generators/app/templates/en.yml +4 -0
  55. data/lib/adhearsion/generators/app/templates/events.erb +2 -2
  56. data/lib/adhearsion/generators/app/templates/hello_world.wav +0 -0
  57. data/lib/adhearsion/generators/app/templates/simon_game.rb +2 -1
  58. data/lib/adhearsion/generators/app/templates/simon_game_spec.rb +2 -2
  59. data/lib/adhearsion/has_headers.rb +34 -0
  60. data/lib/adhearsion/http_server.rb +37 -0
  61. data/lib/adhearsion/initializer.rb +19 -153
  62. data/lib/adhearsion/logging.rb +6 -25
  63. data/lib/adhearsion/outbound_call.rb +5 -5
  64. data/lib/adhearsion/plugin.rb +1 -0
  65. data/lib/adhearsion/protocol_error.rb +26 -0
  66. data/lib/adhearsion/rayo.rb +30 -0
  67. data/lib/adhearsion/rayo/client.rb +62 -0
  68. data/lib/adhearsion/rayo/client/component_registry.rb +33 -0
  69. data/lib/adhearsion/rayo/command.rb +21 -0
  70. data/lib/adhearsion/rayo/command/accept.rb +16 -0
  71. data/lib/adhearsion/rayo/command/answer.rb +16 -0
  72. data/lib/adhearsion/rayo/command/dial.rb +57 -0
  73. data/lib/adhearsion/rayo/command/hangup.rb +16 -0
  74. data/lib/adhearsion/rayo/command/join.rb +43 -0
  75. data/lib/adhearsion/rayo/command/mute.rb +13 -0
  76. data/lib/adhearsion/rayo/command/redirect.rb +23 -0
  77. data/lib/adhearsion/rayo/command/reject.rb +40 -0
  78. data/lib/adhearsion/rayo/command/unjoin.rb +24 -0
  79. data/lib/adhearsion/rayo/command/unmute.rb +13 -0
  80. data/lib/adhearsion/rayo/command_node.rb +47 -0
  81. data/lib/adhearsion/rayo/component.rb +21 -0
  82. data/lib/adhearsion/rayo/component/asterisk.rb +13 -0
  83. data/lib/adhearsion/rayo/component/asterisk/agi.rb +14 -0
  84. data/lib/adhearsion/rayo/component/asterisk/agi/command.rb +46 -0
  85. data/lib/adhearsion/rayo/component/asterisk/ami.rb +14 -0
  86. data/lib/adhearsion/rayo/component/asterisk/ami/action.rb +61 -0
  87. data/lib/adhearsion/rayo/component/component_node.rb +90 -0
  88. data/lib/adhearsion/rayo/component/input.rb +186 -0
  89. data/lib/adhearsion/rayo/component/output.rb +471 -0
  90. data/lib/adhearsion/rayo/component/prompt.rb +53 -0
  91. data/lib/adhearsion/rayo/component/receive_fax.rb +26 -0
  92. data/lib/adhearsion/rayo/component/record.rb +165 -0
  93. data/lib/adhearsion/rayo/component/send_fax.rb +64 -0
  94. data/lib/adhearsion/rayo/component/stop.rb +11 -0
  95. data/lib/adhearsion/rayo/connection.rb +12 -0
  96. data/lib/adhearsion/rayo/connection/asterisk.rb +74 -0
  97. data/lib/adhearsion/rayo/connection/connected.rb +22 -0
  98. data/lib/adhearsion/rayo/connection/generic_connection.rb +22 -0
  99. data/lib/adhearsion/rayo/connection/xmpp.rb +198 -0
  100. data/lib/adhearsion/rayo/disconnected_error.rb +22 -0
  101. data/lib/adhearsion/{punchblock_plugin → rayo}/initializer.rb +19 -19
  102. data/lib/adhearsion/rayo/rayo_node.rb +127 -0
  103. data/lib/adhearsion/rayo/ref.rb +57 -0
  104. data/lib/adhearsion/statistics.rb +1 -1
  105. data/lib/adhearsion/tasks.rb +1 -2
  106. data/lib/adhearsion/tasks/configuration.rb +1 -1
  107. data/lib/adhearsion/tasks/environment.rb +0 -2
  108. data/lib/adhearsion/tasks/i18n.rb +49 -0
  109. data/lib/adhearsion/translator.rb +11 -0
  110. data/lib/adhearsion/translator/asterisk.rb +234 -0
  111. data/lib/adhearsion/translator/asterisk/agi_app.rb +17 -0
  112. data/lib/adhearsion/translator/asterisk/agi_command.rb +45 -0
  113. data/lib/adhearsion/translator/asterisk/ami_error_converter.rb +20 -0
  114. data/lib/adhearsion/translator/asterisk/call.rb +416 -0
  115. data/lib/adhearsion/translator/asterisk/channel.rb +43 -0
  116. data/lib/adhearsion/translator/asterisk/component.rb +88 -0
  117. data/lib/adhearsion/translator/asterisk/component/asterisk.rb +15 -0
  118. data/lib/adhearsion/translator/asterisk/component/asterisk/agi_command.rb +42 -0
  119. data/lib/adhearsion/translator/asterisk/component/asterisk/ami_action.rb +68 -0
  120. data/lib/adhearsion/translator/asterisk/component/composed_prompt.rb +76 -0
  121. data/lib/adhearsion/translator/asterisk/component/dtmf_recognizer.rb +137 -0
  122. data/lib/adhearsion/translator/asterisk/component/input.rb +34 -0
  123. data/lib/adhearsion/translator/asterisk/component/input_component.rb +90 -0
  124. data/lib/adhearsion/translator/asterisk/component/mrcp_native_prompt.rb +71 -0
  125. data/lib/adhearsion/translator/asterisk/component/mrcp_prompt.rb +55 -0
  126. data/lib/adhearsion/translator/asterisk/component/mrcp_recog_prompt.rb +165 -0
  127. data/lib/adhearsion/translator/asterisk/component/output.rb +233 -0
  128. data/lib/adhearsion/translator/asterisk/component/record.rb +101 -0
  129. data/lib/adhearsion/translator/asterisk/component/stop_by_redirect.rb +30 -0
  130. data/lib/adhearsion/translator/asterisk/unimrcp_app.rb +28 -0
  131. data/lib/adhearsion/uri_list.rb +21 -0
  132. data/lib/adhearsion/version.rb +1 -1
  133. data/spec/adhearsion/call_controller/dial_spec.rb +79 -1420
  134. data/spec/adhearsion/call_controller/input_spec.rb +1141 -237
  135. data/spec/adhearsion/call_controller/output/async_player_spec.rb +10 -10
  136. data/spec/adhearsion/call_controller/output/player_spec.rb +8 -8
  137. data/spec/adhearsion/call_controller/output_spec.rb +162 -215
  138. data/spec/adhearsion/call_controller/record_spec.rb +15 -16
  139. data/spec/adhearsion/call_controller_spec.rb +23 -40
  140. data/spec/adhearsion/call_spec.rb +123 -129
  141. data/spec/adhearsion/calls_spec.rb +3 -3
  142. data/spec/adhearsion/configuration_spec.rb +94 -108
  143. data/spec/adhearsion/event/answered_spec.rb +50 -0
  144. data/spec/adhearsion/event/asterisk/Find Results +402 -0
  145. data/spec/adhearsion/event/asterisk/ami_spec.rb +81 -0
  146. data/spec/adhearsion/event/complete_spec.rb +176 -0
  147. data/spec/adhearsion/event/dtmf_spec.rb +35 -0
  148. data/spec/adhearsion/event/end_spec.rb +85 -0
  149. data/spec/adhearsion/event/input_timers_started_spec.rb +19 -0
  150. data/spec/adhearsion/event/joined_spec.rb +53 -0
  151. data/spec/adhearsion/event/offer_spec.rb +106 -0
  152. data/spec/adhearsion/event/ringing_spec.rb +50 -0
  153. data/spec/adhearsion/event/started_speaking_spec.rb +37 -0
  154. data/spec/adhearsion/event/stopped_speaking_spec.rb +37 -0
  155. data/spec/adhearsion/event/unjoined_spec.rb +48 -0
  156. data/spec/adhearsion/event/untitled +0 -0
  157. data/spec/adhearsion/events_spec.rb +19 -45
  158. data/spec/adhearsion/initializer_spec.rb +12 -184
  159. data/spec/adhearsion/logging_spec.rb +5 -20
  160. data/spec/adhearsion/outbound_call_spec.rb +13 -13
  161. data/spec/adhearsion/plugin_spec.rb +3 -4
  162. data/spec/adhearsion/protocol_error_spec.rb +91 -0
  163. data/spec/adhearsion/rayo/client/component_registry_spec.rb +26 -0
  164. data/spec/adhearsion/rayo/client_spec.rb +134 -0
  165. data/spec/adhearsion/rayo/command/accept_spec.rb +63 -0
  166. data/spec/adhearsion/rayo/command/answer_spec.rb +73 -0
  167. data/spec/adhearsion/rayo/command/dial_spec.rb +156 -0
  168. data/spec/adhearsion/rayo/command/hangup_spec.rb +63 -0
  169. data/spec/adhearsion/rayo/command/join_spec.rb +158 -0
  170. data/spec/adhearsion/rayo/command/mute_spec.rb +32 -0
  171. data/spec/adhearsion/rayo/command/redirect_spec.rb +89 -0
  172. data/spec/adhearsion/rayo/command/reject_spec.rb +117 -0
  173. data/spec/adhearsion/rayo/command/unjoin_spec.rb +82 -0
  174. data/spec/adhearsion/rayo/command/unmute_spec.rb +32 -0
  175. data/spec/adhearsion/rayo/command_node_spec.rb +101 -0
  176. data/spec/adhearsion/rayo/component/asterisk/agi/command_spec.rb +111 -0
  177. data/spec/adhearsion/rayo/component/asterisk/ami/action_spec.rb +173 -0
  178. data/spec/adhearsion/rayo/component/component_node_spec.rb +110 -0
  179. data/spec/adhearsion/rayo/component/input_spec.rb +715 -0
  180. data/spec/adhearsion/rayo/component/output_spec.rb +1030 -0
  181. data/spec/adhearsion/rayo/component/prompt_spec.rb +171 -0
  182. data/spec/adhearsion/rayo/component/receive_fax_spec.rb +136 -0
  183. data/spec/adhearsion/rayo/component/record_spec.rb +497 -0
  184. data/spec/adhearsion/rayo/component/send_fax_spec.rb +144 -0
  185. data/spec/adhearsion/rayo/connection/asterisk_spec.rb +118 -0
  186. data/spec/adhearsion/rayo/connection/xmpp_spec.rb +449 -0
  187. data/spec/adhearsion/rayo/initializer_spec.rb +353 -0
  188. data/spec/adhearsion/rayo/ref_spec.rb +168 -0
  189. data/spec/adhearsion/rayo_spec.rb +7 -0
  190. data/spec/adhearsion/router/route_spec.rb +1 -1
  191. data/spec/adhearsion/statistics_spec.rb +2 -5
  192. data/spec/adhearsion/translator/asterisk/call_spec.rb +2047 -0
  193. data/spec/adhearsion/translator/asterisk/component/asterisk/agi_command_spec.rb +256 -0
  194. data/spec/adhearsion/translator/asterisk/component/asterisk/ami_action_spec.rb +151 -0
  195. data/spec/adhearsion/translator/asterisk/component/composed_prompt_spec.rb +257 -0
  196. data/spec/adhearsion/translator/asterisk/component/input_spec.rb +571 -0
  197. data/spec/adhearsion/translator/asterisk/component/mrcp_native_prompt_spec.rb +774 -0
  198. data/spec/adhearsion/translator/asterisk/component/mrcp_prompt_spec.rb +1244 -0
  199. data/spec/adhearsion/translator/asterisk/component/output_spec.rb +1850 -0
  200. data/spec/adhearsion/translator/asterisk/component/record_spec.rb +426 -0
  201. data/spec/adhearsion/translator/asterisk/component/stop_by_redirect_spec.rb +62 -0
  202. data/spec/adhearsion/translator/asterisk/component_spec.rb +83 -0
  203. data/spec/adhearsion/translator/asterisk_spec.rb +685 -0
  204. data/spec/adhearsion/uri_list_spec.rb +88 -0
  205. data/spec/adhearsion_spec.rb +89 -14
  206. data/spec/fixtures/locale/en.yml +13 -0
  207. data/spec/fixtures/locale/it.yml +13 -0
  208. data/spec/spec_helper.rb +18 -5
  209. data/spec/support/call_controller_test_helpers.rb +3 -2
  210. data/spec/support/initializer_stubs.rb +3 -1
  211. data/spec/support/punchblock_examples.rb +65 -0
  212. data/spec/support/punchblock_mocks.rb +12 -0
  213. metadata +412 -70
  214. data/features/cli_daemon.feature +0 -20
  215. data/features/cli_restart.feature +0 -52
  216. data/features/cli_stop.feature +0 -50
  217. data/lib/adhearsion/call_controller/menu_dsl.rb +0 -21
  218. data/lib/adhearsion/call_controller/menu_dsl/array_match_calculator.rb +0 -26
  219. data/lib/adhearsion/call_controller/menu_dsl/calculated_match.rb +0 -43
  220. data/lib/adhearsion/call_controller/menu_dsl/calculated_match_collection.rb +0 -45
  221. data/lib/adhearsion/call_controller/menu_dsl/fixnum_match_calculator.rb +0 -11
  222. data/lib/adhearsion/call_controller/menu_dsl/match_calculator.rb +0 -40
  223. data/lib/adhearsion/call_controller/menu_dsl/menu.rb +0 -207
  224. data/lib/adhearsion/call_controller/menu_dsl/menu_builder.rb +0 -92
  225. data/lib/adhearsion/call_controller/menu_dsl/range_match_calculator.rb +0 -60
  226. data/lib/adhearsion/call_controller/menu_dsl/string_match_calculator.rb +0 -25
  227. data/lib/adhearsion/call_controller/utility.rb +0 -77
  228. data/lib/adhearsion/foundation/custom_daemonizer.rb +0 -52
  229. data/lib/adhearsion/punchblock_plugin.rb +0 -63
  230. data/scripts/cloc-1.64.pl +0 -10483
  231. data/spec/adhearsion/call_controller/menu_dsl/array_match_calculator_spec.rb +0 -76
  232. data/spec/adhearsion/call_controller/menu_dsl/calculated_match_collection_spec.rb +0 -60
  233. data/spec/adhearsion/call_controller/menu_dsl/calculated_match_spec.rb +0 -61
  234. data/spec/adhearsion/call_controller/menu_dsl/fixnum_match_calculator_spec.rb +0 -39
  235. data/spec/adhearsion/call_controller/menu_dsl/match_calculator_spec.rb +0 -17
  236. data/spec/adhearsion/call_controller/menu_dsl/menu_builder_spec.rb +0 -165
  237. data/spec/adhearsion/call_controller/menu_dsl/menu_spec.rb +0 -420
  238. data/spec/adhearsion/call_controller/menu_dsl/range_match_calculator_spec.rb +0 -32
  239. data/spec/adhearsion/call_controller/menu_dsl/string_match_calculator_spec.rb +0 -40
  240. data/spec/adhearsion/call_controller/utility_spec.rb +0 -90
  241. data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +0 -356
  242. data/spec/adhearsion/punchblock_plugin_spec.rb +0 -59
@@ -0,0 +1,198 @@
1
+ # encoding: utf-8
2
+
3
+ %w{
4
+ timeout
5
+ blather/client/dsl
6
+ adhearsion/core_ext/blather/stanza
7
+ adhearsion/core_ext/blather/stanza/presence
8
+ adhearsion/rayo/connection/generic_connection
9
+ }.each { |f| require f }
10
+
11
+ module Adhearsion
12
+ module Rayo
13
+ module Connection
14
+ class XMPP < GenericConnection
15
+ include Blather::DSL
16
+ attr_accessor :event_handler, :root_domain
17
+
18
+ ##
19
+ # Initialize the required connection attributes
20
+ #
21
+ # @param [Hash] options
22
+ # @option options [String] :username client JID
23
+ # @option options [String] :password XMPP password
24
+ # @option options [String] :rayo_domain the domain on which Rayo is running
25
+ # @option options [Numeric, Optional] :write_timeout for which to wait on a command response
26
+ # @option options [Numeric, Optional] :connection_timeout for which to wait on a connection being established
27
+ # @option options [Numeric, nil, Optional] :ping_period interval in seconds on which to ping the server. Nil or false to disable
28
+ #
29
+ def initialize(options = {})
30
+ raise ArgumentError unless (@username = options[:username]) && options[:password]
31
+
32
+ setup(*[:username, :password, :host, :port, :certs, :connection_timeout].map { |key| options.delete key })
33
+
34
+ @root_domain = Blather::JID.new(options[:root_domain] || options[:rayo_domain] || @username).domain
35
+
36
+ @joined_mixers = []
37
+
38
+ @ping_period = options.has_key?(:ping_period) ? options[:ping_period] : 60
39
+
40
+ Blather.logger = logger
41
+ Blather.default_log_level = :trace if Blather.respond_to? :default_log_level
42
+
43
+ register_handlers
44
+
45
+ super()
46
+ end
47
+
48
+ def write(command, options = {})
49
+ iq = prep_command_for_execution command, options
50
+ command.request!
51
+ client.write_with_handler iq do |response|
52
+ if response.result?
53
+ handle_iq_result response, command
54
+ elsif response.error?
55
+ handle_error response, command
56
+ end
57
+ end
58
+ end
59
+
60
+ def prep_command_for_execution(command, options = {})
61
+ command.connection = self
62
+ command.target_call_id ||= options[:call_id]
63
+ command.target_mixer_name ||= options[:mixer_name]
64
+ command.domain ||= options[:domain]
65
+ command.component_id ||= options[:component_id]
66
+ if command.is_a?(Command::Join) && command.mixer_name
67
+ @joined_mixers << command.mixer_name
68
+ end
69
+ create_iq(jid_for_command(command), command.request_id).tap do |iq|
70
+ command.to_rayo(iq)
71
+ end
72
+ end
73
+
74
+ def send_message(call_id, domain, body, options = {})
75
+ jid = Blather::JID.new(call_id, domain || root_domain).to_s
76
+ message = Blather::Stanza::Message.new(jid, body, :normal)
77
+ message.subject = options[:subject]
78
+ client.write message
79
+ end
80
+
81
+ ##
82
+ # Fire up the connection
83
+ #
84
+ def run
85
+ connect
86
+ end
87
+
88
+ def connect
89
+ begin
90
+ EM.run { client.run }
91
+ rescue Blather::Stream::ConnectionFailed, Blather::Stream::ConnectionTimeout, Blather::StreamError => e
92
+ raise DisconnectedError.new(e.class.to_s, e.message)
93
+ end
94
+ end
95
+
96
+ def stop
97
+ client.close if client.connected?
98
+ end
99
+
100
+ def connected?
101
+ client.connected?
102
+ end
103
+
104
+ def ready!
105
+ send_presence :chat
106
+ super
107
+ end
108
+
109
+ def not_ready!
110
+ send_presence :dnd
111
+ super
112
+ end
113
+
114
+ def new_call_uri
115
+ "xmpp:#{Adhearsion.new_uuid}@#{root_domain}"
116
+ end
117
+
118
+ private
119
+
120
+ def jid_for_command(command)
121
+ return root_domain if command.is_a?(Command::Dial)
122
+
123
+ if command.target_call_id
124
+ node = command.target_call_id
125
+ elsif command.target_mixer_name
126
+ node = command.target_mixer_name
127
+ end
128
+
129
+ Blather::JID.new(node, command.domain || root_domain, command.component_id).to_s
130
+ end
131
+
132
+ def send_presence(presence)
133
+ status = Blather::Stanza::Presence::Status.new presence
134
+ status.to = root_domain
135
+ client.write status
136
+ end
137
+
138
+ def handle_presence(p)
139
+ throw :pass unless p.rayo_event?
140
+ event = p.event
141
+ event.connection = self
142
+ event.domain = p.from.domain
143
+ event.transport = "xmpp"
144
+ if @joined_mixers.include?(p.call_id)
145
+ event.target_mixer_name = p.call_id
146
+ else
147
+ event.target_call_id = p.call_id
148
+ end
149
+ event_handler.call event
150
+ end
151
+
152
+ def handle_iq_result(iq, command)
153
+ command.response = iq.rayo_node.is_a?(Ref) ? iq.rayo_node : true
154
+ end
155
+
156
+ def handle_error(iq, command = nil)
157
+ e = Blather::StanzaError.import iq
158
+ protocol_error = ProtocolError.new.setup e.name, e.text, iq.call_id, iq.component_id
159
+ command.response = protocol_error if command
160
+ end
161
+
162
+ def register_handlers
163
+ # Push a message to the queue and the log that we connected
164
+ when_ready do
165
+ event_handler.call Connected.new
166
+ logger.info "Connected to XMPP as #{@username}"
167
+ @rayo_ping = EM::PeriodicTimer.new(@ping_period) { ping_rayo } if @ping_period
168
+ throw :pass
169
+ end
170
+
171
+ disconnected do
172
+ @rayo_ping.cancel if @rayo_ping
173
+ raise DisconnectedError
174
+ end
175
+
176
+ # Read/handle presence requests. This is how we get events.
177
+ presence do |msg|
178
+ handle_presence msg
179
+ end
180
+ end
181
+
182
+ def ping_rayo
183
+ client.write_with_handler Blather::Stanza::Iq::Ping.new(:get, root_domain) do |response|
184
+ begin
185
+ handle_error response if response.is_a? Blather::BlatherError
186
+ rescue ProtocolError => e
187
+ raise unless e.name == :feature_not_implemented
188
+ end
189
+ end
190
+ end
191
+
192
+ def create_iq(jid, id)
193
+ Blather::Stanza::Iq.new :set, jid, id
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ require 'adhearsion/error'
4
+
5
+ module Adhearsion
6
+ module Rayo
7
+ ##
8
+ # This exception may be raised if the connection to the server is interrupted.
9
+ class DisconnectedError < Error
10
+ attr_accessor :cause, :message
11
+
12
+ def initialize(cause = nil, message = nil)
13
+ @cause, @message = cause, message
14
+ end
15
+
16
+ def to_s
17
+ "#<#{self.class}: cause=#{cause.inspect} message=#{message.inspect}"
18
+ end
19
+ alias :inspect :to_s
20
+ end
21
+ end
22
+ end
@@ -4,7 +4,7 @@ require 'blather'
4
4
  require 'active_support/core_ext/class/attribute_accessors'
5
5
 
6
6
  module Adhearsion
7
- class PunchblockPlugin < Plugin
7
+ module Rayo
8
8
  class Initializer
9
9
  cattr_accessor :config, :client, :dispatcher, :attempts
10
10
 
@@ -12,10 +12,10 @@ module Adhearsion
12
12
 
13
13
  class << self
14
14
  def init
15
- self.config = Adhearsion.config[:punchblock]
15
+ self.config = Adhearsion.config.core
16
16
 
17
17
  username = self.config.username
18
- if (self.config.platform || :xmpp) == :xmpp
18
+ if (self.config.type || :xmpp) == :xmpp
19
19
  username = Blather::JID.new username
20
20
  username = Blather::JID.new username.node, username.domain, resource unless username.resource
21
21
  username = username.to_s
@@ -31,9 +31,9 @@ module Adhearsion
31
31
  :root_domain => self.config.root_domain
32
32
  }
33
33
 
34
- self.client = Punchblock.client_with_connection self.config.platform, connection_options
34
+ self.client = Adhearsion.client_with_connection self.config.type, connection_options
35
35
 
36
- # Tell the Punchblock connection that we are ready to process calls.
36
+ # Tell the connection that we are ready to process calls.
37
37
  Events.register_callback :after_initialized do
38
38
  connection.ready!
39
39
  end
@@ -49,25 +49,25 @@ module Adhearsion
49
49
  client.stop
50
50
  end
51
51
 
52
- # Handle events from Punchblock via events system
52
+ # Handle events from connection via events system
53
53
  self.client.register_event_handler do |event|
54
54
  handle_event event
55
55
  end
56
56
 
57
- Events.punchblock Punchblock::Connection::Connected do |event|
58
- logger.info "Connected to Punchblock server"
57
+ Events.rayo Adhearsion::Rayo::Connection::Connected do |event|
58
+ logger.info "Connected to Rayo server"
59
59
  self.attempts = 0
60
60
  end
61
61
 
62
- Events.punchblock Punchblock::Event::Offer do |offer|
62
+ Events.rayo Adhearsion::Event::Offer do |offer|
63
63
  dispatch_offer offer
64
64
  end
65
65
 
66
- Events.punchblock proc { |e| e.respond_to?(:source) }, :source do |event|
66
+ Events.rayo proc { |e| e.respond_to?(:source) }, :source do |event|
67
67
  event.source.trigger_event_handler event
68
68
  end
69
69
 
70
- Events.punchblock proc { |e| e.respond_to?(:target_call_id) }, :target_call_id do |event|
70
+ Events.rayo proc { |e| e.respond_to?(:target_call_id) }, :target_call_id do |event|
71
71
  dispatch_call_event event
72
72
  end
73
73
  end
@@ -81,7 +81,7 @@ module Adhearsion
81
81
  m = Mutex.new
82
82
  blocker = ConditionVariable.new
83
83
 
84
- Events.punchblock Punchblock::Connection::Connected do
84
+ Events.rayo Adhearsion::Rayo::Connection::Connected do
85
85
  Adhearsion::Process.booted
86
86
  m.synchronize { blocker.broadcast }
87
87
  end
@@ -104,7 +104,7 @@ module Adhearsion
104
104
  def connect_to_server
105
105
  logger.info "Starting connection to server"
106
106
  client.run
107
- rescue Punchblock::DisconnectedError => e
107
+ rescue Adhearsion::Rayo::DisconnectedError => e
108
108
  # We only care about disconnects if the process is up or booting
109
109
  return unless [:booting, :running].include? Adhearsion::Process.state_name
110
110
 
@@ -121,7 +121,7 @@ module Adhearsion
121
121
  logger.error "Connection lost. Attempting reconnect #{self.attempts} of #{self.config.reconnect_attempts}"
122
122
  sleep self.config.reconnect_timer
123
123
  retry
124
- rescue Punchblock::ProtocolError => e
124
+ rescue Adhearsion::ProtocolError => e
125
125
  logger.fatal "The connection failed due to a protocol error: #{e.name}."
126
126
  raise e
127
127
  end
@@ -152,9 +152,9 @@ module Adhearsion
152
152
  end
153
153
 
154
154
  def handle_event(event)
155
- Events.trigger :punchblock, event
155
+ Events.trigger :rayo, event
156
156
  case event
157
- when Punchblock::Event::Asterisk::AMI::Event
157
+ when Adhearsion::Event::Asterisk::AMI
158
158
  Events.trigger :ami, event
159
159
  end
160
160
  end
@@ -173,6 +173,6 @@ module Adhearsion
173
173
  client.connection
174
174
  end
175
175
  end
176
- end # Punchblock
177
- end # Plugin
178
- end # Adhearsion
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,127 @@
1
+ # encoding: utf-8
2
+
3
+ require 'active_support/core_ext/class/attribute'
4
+ require 'virtus'
5
+
6
+ require 'adhearsion/rayo'
7
+
8
+ module Adhearsion
9
+ module Rayo
10
+ class RayoNode
11
+ include Virtus.model
12
+
13
+ @@registrations = {}
14
+
15
+ class_attribute :registered_ns, :registered_name
16
+
17
+ attribute :target_call_id
18
+ attribute :target_mixer_name
19
+ attribute :component_id
20
+ attribute :source_uri
21
+ attribute :domain
22
+ attribute :transport
23
+ attribute :timestamp, DateTime, default: ->(*) { DateTime.now }
24
+
25
+ attr_accessor :connection, :client, :original_component
26
+
27
+ # Register a new stanza class to a name and/or namespace
28
+ #
29
+ # This registers a namespace that is used when looking
30
+ # up the class name of the object to instantiate when a new
31
+ # stanza is received
32
+ #
33
+ # @param [#to_s] name the name of the node
34
+ # @param [String, nil] ns the namespace the node belongs to
35
+ def self.register(name, ns = nil)
36
+ self.registered_name = name.to_s
37
+ self.registered_ns = ns.is_a?(Symbol) ? RAYO_NAMESPACES[ns] : ns
38
+ @@registrations[[self.registered_name, self.registered_ns]] = self
39
+ end
40
+
41
+ # Find the class to use given the name and namespace of a stanza
42
+ #
43
+ # @param [#to_s] name the name to lookup
44
+ # @param [String, nil] xmlns the namespace the node belongs to
45
+ # @return [Class, nil] the class appropriate for the name/ns combination
46
+ def self.class_from_registration(name, ns = nil)
47
+ @@registrations[[name.to_s, ns]]
48
+ end
49
+
50
+ # Import an XML::Node to the appropriate class
51
+ #
52
+ # Looks up the class the node should be then creates it based on the
53
+ # elements of the XML::Node
54
+ # @param [XML::Node] node the node to import
55
+ # @return the appropriate object based on the node name and namespace
56
+ def self.from_xml(node, call_id = nil, component_id = nil, uri = nil, timestamp = nil)
57
+ ns = (node.namespace.href if node.namespace)
58
+ klass = class_from_registration(node.name, ns)
59
+ if klass && klass != self
60
+ klass.from_xml node, call_id, component_id
61
+ else
62
+ new.inherit node
63
+ end.tap do |event|
64
+ event.target_call_id = call_id
65
+ event.component_id = component_id
66
+ event.source_uri = uri
67
+ event.timestamp = timestamp if timestamp
68
+ end
69
+ end
70
+
71
+ def inherit(xml_node)
72
+ xml_node.attributes.each do |key, attr_node|
73
+ setter_method = "#{key.gsub('-', '_')}="
74
+ send setter_method, xml_node[key] if respond_to?(setter_method)
75
+ end
76
+ self
77
+ end
78
+
79
+ def inspect
80
+ "#<#{self.class} #{to_hash.map { |k, v| "#{k}=#{v.inspect}" }.compact * ', '}>"
81
+ end
82
+
83
+ def ==(o)
84
+ o.is_a?(self.class) && self.comparable_attributes == o.comparable_attributes
85
+ end
86
+
87
+ ##
88
+ # @return [RayoNode] the original command issued that lead to this event
89
+ #
90
+ def source
91
+ @source ||= client.find_component_by_uri source_uri if client && source_uri
92
+ @source ||= original_component
93
+ end
94
+
95
+ def rayo_attributes
96
+ {}
97
+ end
98
+
99
+ def rayo_children(root)
100
+ end
101
+
102
+ def to_rayo(parent = nil)
103
+ parent = parent.parent if parent.is_a?(Nokogiri::XML::Builder)
104
+ Nokogiri::XML::Builder.with(parent) do |xml|
105
+ xml.send(registered_name,
106
+ {xmlns: registered_ns}.merge(rayo_attributes.delete_if { |k,v| v.nil? })) do |root|
107
+ rayo_children root
108
+ end
109
+ end.doc.root
110
+ end
111
+
112
+ def to_xml
113
+ to_rayo.to_xml
114
+ end
115
+
116
+ alias :to_s :inspect
117
+
118
+ protected
119
+
120
+ def comparable_attributes
121
+ to_hash.tap do |hash|
122
+ hash.delete :timestamp
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end