adhearsion 0.7.7 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (179) hide show
  1. data/CHANGELOG +9 -42
  2. data/EVENTS +11 -0
  3. data/README.txt +5 -0
  4. data/Rakefile +94 -84
  5. data/adhearsion.gemspec +148 -0
  6. data/app_generators/ahn/USAGE +5 -0
  7. data/app_generators/ahn/ahn_generator.rb +87 -0
  8. data/app_generators/ahn/templates/.ahnrc +34 -0
  9. data/app_generators/ahn/templates/README +8 -0
  10. data/app_generators/ahn/templates/Rakefile +23 -0
  11. data/app_generators/ahn/templates/components/ami_remote/ami_remote.rb +15 -0
  12. data/app_generators/ahn/templates/components/disabled/HOW_TO_ENABLE +7 -0
  13. data/app_generators/ahn/templates/components/disabled/stomp_gateway/README.markdown +47 -0
  14. data/app_generators/ahn/templates/components/disabled/stomp_gateway/config.yml +12 -0
  15. data/app_generators/ahn/templates/components/disabled/stomp_gateway/stomp_gateway.rb +34 -0
  16. data/app_generators/ahn/templates/components/restful_rpc/README.markdown +11 -0
  17. data/app_generators/ahn/templates/components/restful_rpc/config.yml +34 -0
  18. data/app_generators/ahn/templates/components/restful_rpc/example-client.rb +48 -0
  19. data/app_generators/ahn/templates/components/restful_rpc/restful_rpc.rb +87 -0
  20. data/app_generators/ahn/templates/components/restful_rpc/spec/restful_rpc_spec.rb +263 -0
  21. data/app_generators/ahn/templates/components/simon_game/simon_game.rb +56 -0
  22. data/app_generators/ahn/templates/config/startup.rb +50 -0
  23. data/app_generators/ahn/templates/dialplan.rb +3 -0
  24. data/app_generators/ahn/templates/events.rb +32 -0
  25. data/bin/ahn +28 -0
  26. data/bin/ahnctl +68 -0
  27. data/bin/jahn +42 -0
  28. data/examples/asterisk_manager_interface/standalone.rb +51 -0
  29. data/lib/adhearsion.rb +35 -953
  30. data/lib/adhearsion/cli.rb +223 -0
  31. data/lib/adhearsion/component_manager.rb +208 -0
  32. data/lib/adhearsion/component_manager/component_tester.rb +55 -0
  33. data/lib/adhearsion/component_manager/spec_framework.rb +24 -0
  34. data/lib/adhearsion/events_support.rb +84 -0
  35. data/lib/adhearsion/foundation/all.rb +9 -0
  36. data/lib/adhearsion/foundation/blank_slate.rb +5 -0
  37. data/lib/adhearsion/foundation/custom_daemonizer.rb +45 -0
  38. data/lib/adhearsion/foundation/event_socket.rb +203 -0
  39. data/lib/adhearsion/foundation/future_resource.rb +36 -0
  40. data/lib/adhearsion/foundation/global.rb +1 -0
  41. data/lib/adhearsion/foundation/metaprogramming.rb +17 -0
  42. data/lib/adhearsion/foundation/numeric.rb +13 -0
  43. data/lib/adhearsion/foundation/pseudo_guid.rb +10 -0
  44. data/lib/adhearsion/foundation/relationship_properties.rb +42 -0
  45. data/lib/adhearsion/foundation/string.rb +26 -0
  46. data/lib/adhearsion/foundation/synchronized_hash.rb +96 -0
  47. data/lib/adhearsion/foundation/thread_safety.rb +7 -0
  48. data/lib/adhearsion/host_definitions.rb +67 -0
  49. data/lib/adhearsion/initializer.rb +373 -0
  50. data/lib/adhearsion/initializer/asterisk.rb +81 -0
  51. data/lib/adhearsion/initializer/configuration.rb +254 -0
  52. data/lib/adhearsion/initializer/database.rb +49 -0
  53. data/lib/adhearsion/initializer/drb.rb +31 -0
  54. data/lib/adhearsion/initializer/freeswitch.rb +22 -0
  55. data/lib/adhearsion/initializer/rails.rb +40 -0
  56. data/lib/adhearsion/logging.rb +92 -0
  57. data/lib/adhearsion/tasks.rb +16 -0
  58. data/lib/adhearsion/tasks/database.rb +5 -0
  59. data/lib/adhearsion/tasks/deprecations.rb +59 -0
  60. data/lib/adhearsion/tasks/generating.rb +20 -0
  61. data/lib/adhearsion/tasks/lint.rb +4 -0
  62. data/lib/adhearsion/tasks/testing.rb +37 -0
  63. data/lib/adhearsion/version.rb +9 -0
  64. data/lib/adhearsion/voip/asterisk.rb +4 -0
  65. data/lib/adhearsion/voip/asterisk/agi_server.rb +81 -0
  66. data/lib/adhearsion/voip/asterisk/commands.rb +1284 -0
  67. data/lib/adhearsion/voip/asterisk/config_generators/agents.conf.rb +140 -0
  68. data/lib/adhearsion/voip/asterisk/config_generators/config_generator.rb +101 -0
  69. data/lib/adhearsion/voip/asterisk/config_generators/queues.conf.rb +250 -0
  70. data/lib/adhearsion/voip/asterisk/config_generators/voicemail.conf.rb +240 -0
  71. data/lib/adhearsion/voip/asterisk/config_manager.rb +71 -0
  72. data/lib/adhearsion/voip/asterisk/manager_interface.rb +562 -0
  73. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rb +1754 -0
  74. data/lib/adhearsion/voip/asterisk/manager_interface/ami_lexer.rl.rb +286 -0
  75. data/lib/adhearsion/voip/asterisk/manager_interface/ami_messages.rb +78 -0
  76. data/lib/adhearsion/voip/asterisk/manager_interface/ami_protocol_lexer_machine.rl +87 -0
  77. data/lib/adhearsion/voip/asterisk/special_dial_plan_managers.rb +80 -0
  78. data/lib/adhearsion/voip/asterisk/super_manager.rb +19 -0
  79. data/lib/adhearsion/voip/call.rb +440 -0
  80. data/lib/adhearsion/voip/call_routing.rb +64 -0
  81. data/lib/adhearsion/voip/commands.rb +9 -0
  82. data/lib/adhearsion/voip/constants.rb +39 -0
  83. data/lib/adhearsion/voip/conveniences.rb +18 -0
  84. data/lib/adhearsion/voip/dial_plan.rb +218 -0
  85. data/lib/adhearsion/voip/dsl/dialing_dsl.rb +151 -0
  86. data/lib/adhearsion/voip/dsl/dialing_dsl/dialing_dsl_monkey_patches.rb +37 -0
  87. data/lib/adhearsion/voip/dsl/dialplan/control_passing_exception.rb +27 -0
  88. data/lib/adhearsion/voip/dsl/dialplan/dispatcher.rb +124 -0
  89. data/lib/adhearsion/voip/dsl/dialplan/parser.rb +71 -0
  90. data/lib/adhearsion/voip/dsl/dialplan/thread_mixin.rb +16 -0
  91. data/lib/adhearsion/voip/dsl/numerical_string.rb +117 -0
  92. data/lib/adhearsion/voip/freeswitch/basic_connection_manager.rb +48 -0
  93. data/lib/adhearsion/voip/freeswitch/event_handler.rb +58 -0
  94. data/lib/adhearsion/voip/freeswitch/freeswitch_dialplan_command_factory.rb +129 -0
  95. data/lib/adhearsion/voip/freeswitch/inbound_connection_manager.rb +38 -0
  96. data/lib/adhearsion/voip/freeswitch/oes_server.rb +195 -0
  97. data/lib/adhearsion/voip/menu_state_machine/calculated_match.rb +80 -0
  98. data/lib/adhearsion/voip/menu_state_machine/matchers.rb +123 -0
  99. data/lib/adhearsion/voip/menu_state_machine/menu_builder.rb +58 -0
  100. data/lib/adhearsion/voip/menu_state_machine/menu_class.rb +149 -0
  101. data/lib/theatre.rb +151 -0
  102. data/lib/theatre/README.markdown +64 -0
  103. data/lib/theatre/callback_definition_loader.rb +84 -0
  104. data/lib/theatre/guid.rb +23 -0
  105. data/lib/theatre/invocation.rb +121 -0
  106. data/lib/theatre/namespace_manager.rb +153 -0
  107. data/lib/theatre/version.rb +2 -0
  108. metadata +160 -140
  109. data/.version +0 -1
  110. data/TODO +0 -71
  111. data/ahn +0 -223
  112. data/apps/default/Rakefile +0 -65
  113. data/apps/default/config/adhearsion.sqlite3 +0 -0
  114. data/apps/default/config/adhearsion.yml +0 -95
  115. data/apps/default/config/database.rb +0 -50
  116. data/apps/default/config/database.yml +0 -12
  117. data/apps/default/config/helpers/drb_server.yml +0 -43
  118. data/apps/default/config/helpers/factorial.alien.c.yml +0 -1
  119. data/apps/default/config/helpers/growler.yml +0 -21
  120. data/apps/default/config/helpers/lookup.yml +0 -1
  121. data/apps/default/config/helpers/manager_proxy.yml +0 -8
  122. data/apps/default/config/helpers/micromenus.yml +0 -1
  123. data/apps/default/config/helpers/micromenus/collab.rb +0 -60
  124. data/apps/default/config/helpers/micromenus/images/arrow-off.gif +0 -0
  125. data/apps/default/config/helpers/micromenus/images/arrow-on.gif +0 -0
  126. data/apps/default/config/helpers/micromenus/images/error.gif +0 -0
  127. data/apps/default/config/helpers/micromenus/images/folder-off.gif +0 -0
  128. data/apps/default/config/helpers/micromenus/images/folder-on.gif +0 -0
  129. data/apps/default/config/helpers/micromenus/images/folder.png +0 -0
  130. data/apps/default/config/helpers/micromenus/images/ggbridge.jpg +0 -0
  131. data/apps/default/config/helpers/micromenus/images/green.png +0 -0
  132. data/apps/default/config/helpers/micromenus/images/microbrowser.bg.gif +0 -0
  133. data/apps/default/config/helpers/micromenus/images/red.png +0 -0
  134. data/apps/default/config/helpers/micromenus/images/tux.bmp +0 -0
  135. data/apps/default/config/helpers/micromenus/images/url-off.gif +0 -0
  136. data/apps/default/config/helpers/micromenus/images/url-on.gif +0 -0
  137. data/apps/default/config/helpers/micromenus/images/yellow.png +0 -0
  138. data/apps/default/config/helpers/micromenus/javascripts/animation.js +0 -1341
  139. data/apps/default/config/helpers/micromenus/javascripts/carousel.js +0 -1238
  140. data/apps/default/config/helpers/micromenus/javascripts/columnav.js +0 -306
  141. data/apps/default/config/helpers/micromenus/javascripts/connection.js +0 -965
  142. data/apps/default/config/helpers/micromenus/javascripts/container.js +0 -4727
  143. data/apps/default/config/helpers/micromenus/javascripts/container_core.js +0 -2915
  144. data/apps/default/config/helpers/micromenus/javascripts/dom.js +0 -892
  145. data/apps/default/config/helpers/micromenus/javascripts/dragdrop.js +0 -2958
  146. data/apps/default/config/helpers/micromenus/javascripts/event.js +0 -1771
  147. data/apps/default/config/helpers/micromenus/javascripts/yahoo.js +0 -433
  148. data/apps/default/config/helpers/micromenus/stylesheets/carousel.css +0 -78
  149. data/apps/default/config/helpers/micromenus/stylesheets/columnav.css +0 -135
  150. data/apps/default/config/helpers/micromenus/stylesheets/microbrowsers.css +0 -42
  151. data/apps/default/config/helpers/multi_messenger.yml +0 -9
  152. data/apps/default/config/helpers/weather.yml +0 -1
  153. data/apps/default/config/helpers/xbmc.yml +0 -2
  154. data/apps/default/config/migration.rb +0 -59
  155. data/apps/default/extensions.rb +0 -41
  156. data/apps/default/helpers/factorial.alien.c +0 -32
  157. data/apps/default/helpers/growler.rb +0 -53
  158. data/apps/default/helpers/lookup.rb +0 -44
  159. data/apps/default/helpers/manager_proxy.rb +0 -112
  160. data/apps/default/helpers/micromenus.rb +0 -514
  161. data/apps/default/helpers/multi_messenger.rb +0 -53
  162. data/apps/default/helpers/oscar_wilde_quotes.rb +0 -197
  163. data/apps/default/helpers/weather.rb +0 -85
  164. data/apps/default/helpers/xbmc.rb +0 -39
  165. data/apps/default/logs/adhearsion.log +0 -0
  166. data/apps/default/logs/database.log +0 -0
  167. data/lib/constants.rb +0 -24
  168. data/lib/core_extensions.rb +0 -180
  169. data/lib/drb_server.rb +0 -101
  170. data/lib/logging.rb +0 -85
  171. data/lib/phone_number.rb +0 -85
  172. data/lib/rami.rb +0 -823
  173. data/lib/servlet_container.rb +0 -174
  174. data/lib/sexy_migrations.rb +0 -70
  175. data/test/asterisk_module_test.rb +0 -14
  176. data/test/core_extensions_test.rb +0 -26
  177. data/test/dial_test.rb +0 -43
  178. data/test/specs/numerical_string_spec.rb +0 -53
  179. data/test/test_micromenus.rb +0 -0
@@ -1,514 +0,0 @@
1
- # Micromenus Adhearsion helper
2
- # Copyright 2006 Jay Phillips
3
- #
4
- # This program is free software; you can redistribute it and/or
5
- # modify it under the terms of the GNU General Public License
6
- # as published by the Free Software Foundation; either version 2
7
- # of the License, or (at your option) any later version.
8
- #
9
- # This program is distributed in the hope that it will be useful,
10
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- # GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License
15
- # along with this program; if not, write to the Free Software
16
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
-
18
- require 'rubygems'
19
- require 'builder'
20
- require 'webrick'
21
- require 'stringio'
22
-
23
- class WEBrick::HTTPRequest
24
- def ip() @peeraddr[3][/(\d{1,3}\.){3}\d{1,3}/] end
25
- end
26
-
27
- # Micromenu catchers are special hooks that allow integration
28
- # between micromenus and incoming calls (specifically, incoming
29
- # calls generated by the micromenus)
30
- $MICROMENU_CALL_HOOKS = []
31
- class << $MICROMENU_CALL_HOOKS
32
- def purge_expired!
33
- self.synchronize { |hooks| hooks.delete_if { |h| h.expiration < Time.now } }
34
- end
35
- end
36
-
37
- class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
38
-
39
- class MicromenuGenerator
40
-
41
- def initialize request, model, io=$stdout
42
- @request, @io, @config = request, io, []
43
- @xml = Builder::XmlMarkup.new(:target => @io, :indent => 3)
44
- self.extend model
45
- end
46
-
47
- attr_accessor :name, :io, :config, :request
48
-
49
- def process request
50
- route = request.dup
51
-
52
- if route.empty?
53
- start "Error" do
54
- build_text "Whoops!"
55
- build_text "You forgot to include the target Micromenu in the URL path!"
56
- end
57
- return
58
- end
59
-
60
- title = " Adhearsion Micromenus"
61
-
62
- filename = route.shift
63
- load_menu filename
64
- until route.empty?
65
- segment = route.shift
66
- broken = segment.match(/^([\w_.]+)(;(\d*))?$/)
67
-
68
- segment, id = broken[1], broken[3]
69
- id = nil if id && id.empty?
70
-
71
- matches = @config.select do |x|
72
- x[:type] == :menu && x[:text].nameify == segment
73
- end
74
- dest = matches[(id.simplify || 1) - 1]
75
-
76
-
77
- if dest then
78
- @config.clear
79
- title = dest[:text]
80
- dest[:block].call
81
- else
82
- start "Error" do
83
- item '404 Not found!'
84
- item "Req: #{request.inspect}"
85
- return
86
- end
87
- end
88
- end
89
-
90
- # Let any headers override the default title
91
- @config.each do |item|
92
- if item[:type] == :heading
93
- title = @config.delete(item)[:text]
94
- break
95
- end
96
- end
97
-
98
- start title do
99
- @config.each do |item|
100
- case item[:type]
101
- when :menu
102
- build_menu item[:text], item[:uri], request
103
- when :item
104
- build_text item[:text]
105
- when :heading
106
- build_header item[:text]
107
- when :image
108
- build_image item[:text]
109
- when :call
110
- build_call item[:number], item[:text]
111
- end
112
- end
113
- end
114
- end
115
- def load_menu filename
116
- @config.clear
117
- file = File.join('config','helpers', 'micromenus', filename + '.rb')
118
- unless File.readable? file
119
- item "Target Micromenu doesn't exist!"
120
- item "Did you input the URL correctly?"
121
- else
122
- eval File.read(File.join('config','helpers', 'micromenus', filename + '.rb'))
123
- end
124
- @config
125
- end
126
- def join_url url, *pages
127
- url *= '/' if url.is_a? Array
128
- '/' + if url.empty?
129
- pages * '/'
130
- else
131
- ((url[-1] == ?/) ? url : url + "/") + pages * '/'
132
- end
133
- end
134
- def get_refresh() @refresh end
135
-
136
-
137
- module AjaxResponse
138
-
139
- def content_type() "application/xml" end
140
-
141
- def start name='', &block
142
- @xml.ul do
143
- yield
144
- end
145
- end
146
-
147
- def build_menu str, uri, request
148
- #build_menu item[:text], item[:uri], request
149
- #request.flatten! if request.is_a? Array
150
- @xml.li do
151
- @xml.a str, :href => join_url('ajax', request, uri), :rel => 'ajax'
152
- end
153
- end
154
-
155
- def build_text str
156
- @xml.li { @xml.span str }
157
- end
158
-
159
- def build_prompt
160
-
161
- end
162
-
163
- def build_image filename, hash=nil
164
- @xml.img :src => "/images/#{filename}"
165
- end
166
-
167
- def build_header str
168
- @xml.li { @xml.h1 str }
169
- end
170
-
171
- def build_call number, name=number
172
- @xml.a name, :href => "javascript:dial(#{number})"
173
- @xml.br
174
- end
175
- end
176
-
177
-
178
- module PolycomPhone
179
-
180
- def content_type() "text/html" end
181
-
182
- def start name='', &block
183
- @xml.html do
184
- @xml.head do
185
- @xml.title name
186
- end
187
- @xml.body do
188
- yield
189
- end
190
- end
191
- end
192
-
193
- def build_menu str, uri, request
194
- #build_menu item[:text], item[:uri], request
195
- #request.flatten! if request.is_a? Array
196
- @xml.p { @xml.a str, :href => join_url(request, uri) }
197
- end
198
-
199
- def build_text str
200
- @xml.p str
201
- end
202
-
203
- def build_prompt
204
-
205
- end
206
-
207
- def build_image filename, hash=nil
208
- @xml.img :src => "/images/#{filename}"
209
- end
210
-
211
- def build_header str
212
- @xml.h1 str
213
- end
214
-
215
- def build_call number, name=number
216
- @xml.a name, :href => "tel://#{number}"
217
- @xml.br
218
- end
219
- end
220
-
221
- module XulUi
222
-
223
- include PolycomPhone
224
- def content_type() "application/vnd.mozilla.xul+xml" end
225
-
226
- def start name='', &block
227
- @xml.instruct!
228
- @xml.instruct! 'xml-stylesheet', :href => "chrome://global/skin/", :type => "text/css"
229
- @xml.instruct! 'xml-stylesheet', :href => "/stylesheets/firefox.xul.css", :type => "text/css"
230
- @xml.window :title => name,
231
- 'xmlns:html' => "http://www.w3.org/1999/xhtml",
232
- :xmlns => "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" do
233
- @xml.vbox :id => 'haupt' do
234
- #@xml.label name, :class => 'header'
235
- yield
236
- end
237
- end
238
- end
239
-
240
- def build_call number, name=number
241
- # The tel:// UI doesn't do Firefox much good. Mexuar, maybe?
242
- @xml.html:a, name, :href => "tel://#{number}"
243
- @xml.html:br
244
- end
245
-
246
- def build_menu str, uri, request
247
- @xml.html:a, str, :href => join_url(request, uri)
248
- end
249
-
250
- def build_text str
251
- @xml.description str
252
- @xml.html:br
253
- end
254
-
255
- def build_image filename, hash=nil
256
- @xml.html:img, :src => "/images/#{filename}"
257
- end
258
-
259
- def build_header str
260
- @xml.label str, :class => 'header'
261
- end
262
-
263
- end
264
- module ModernUi
265
-
266
- CSSs = %w"carousel columnav microbrowsers"
267
- JAVASCRIPTS = %w"yahoo event dom animation connection container dragdrop carousel columnav"
268
- INIT = %{
269
- try { document.execCommand('BackgroundImageCache', false, true); } catch(e) {}
270
- function init() {
271
- var cn_cfg = { prevElement: 'columnav-prev', source: document.getElementById('main') };
272
- var cn = new YAHOO.extension.ColumNav('columnav', cn_cfg);
273
-
274
- YAHOO.namespace("example.container");
275
-
276
- YAHOO.example.container.panel1 = new YAHOO.widget.Panel("unique", { width:"350px", visible:true, draggable:true, close:true } );
277
- YAHOO.example.container.panel1.render();
278
-
279
- /*
280
- YAHOO.example.container.panel2 = new YAHOO.widget.Panel("panel2", { width:"300px", visible:true, draggable:true, close:true } );
281
- YAHOO.example.container.panel2.setHeader("Panel #2 from Script");
282
- YAHOO.example.container.panel2.setBody("This is a dynamically generated Panel.");
283
- YAHOO.example.container.panel2.setFooter("End of Panel #2");
284
- YAHOO.example.container.panel2.render(document.body);
285
- */
286
-
287
- YAHOO.util.Event.addListener("show1", "click", YAHOO.example.container.panel1.show, YAHOO.example.container.panel1, true);
288
- YAHOO.util.Event.addListener("hide1", "click", YAHOO.example.container.panel1.hide, YAHOO.example.container.panel1, true);
289
-
290
- /*
291
- YAHOO.util.Event.addListener("show2", "click", YAHOO.example.container.panel2.show, YAHOO.example.container.panel2, true);
292
- YAHOO.util.Event.addListener("hide2", "click", YAHOO.example.container.panel2.hide, YAHOO.example.container.panel2, true);
293
- */
294
- }
295
- YAHOO.util.Event.addListener(window, 'load', init);
296
-
297
- }
298
-
299
- def content_type() "text/html" end
300
-
301
- def start name='', &block
302
- @xml.html do
303
- @xml.head do
304
- @xml.title name
305
- CSSs.each { |css| @xml.link :rel => 'stylesheet', :type => 'text/css', :href => "/stylesheets/#{css}.css"}
306
-
307
- JAVASCRIPTS.each { |script| @xml.script :type => 'text/javascript', :src => "/javascripts/#{script}.js" do end }
308
- @xml.script INIT, :type => 'text/javascript'
309
- end
310
- @xml.body do
311
-
312
- @xml.div :id => "unique", :class => 'microbrowser' do
313
-
314
- @xml.div :class => "hd" do
315
- @xml.div :class => "tl" do
316
- @xml.div :class => 'prevButton' do
317
- @xml.a "Back", :href => "javascript:void(0)", :id => "columnav-prev"
318
- end
319
- end
320
- @xml.h1 name
321
- @xml.div :class => 'tr' do
322
- @xml.span "Close", :class => "container-close"
323
- end
324
- end
325
-
326
- @xml.div :class => 'bd' do
327
- @xml.div :id => 'columnav', :class => "carousel-component" do
328
- @xml.div :class => "carousel-clip-region" do
329
- @xml.ul :class => "carousel-list" do end
330
- end
331
- end
332
-
333
- @xml.ul :id => 'main', :style => 'display:none' do
334
- yield
335
- # @xml << %{
336
- # <li><a href="/viewaddressbook">View Address book again</a>
337
- # <ul><li>
338
- # <a href="http://google.com">Jicksta.com</a>
339
- # </li></ul></li>
340
- # <li><a href='#'>Linking to Somewhere</a></li>
341
- # <li><strong>Not</strong> linking to somewhere</li>
342
- # }
343
- end
344
- end
345
-
346
- @xml.div :class => "ft" do
347
- @xml.hr
348
- end
349
-
350
- end
351
- end
352
- end
353
- end
354
-
355
- def build_menu str, uri, request
356
- #build_menu item[:text], item[:uri], request
357
- #request.flatten! if request.is_a? Array
358
- @xml.li { @xml.a str, :rel => 'ajax', :href => join_url('ajax', request, uri) }
359
- end
360
-
361
- def build_text str
362
- @xml.li { @xml.span str }
363
- end
364
-
365
- def build_prompt
366
-
367
- end
368
-
369
- def build_image filename, hash=nil
370
- @xml.li { @xml.img :src => "/images/#{filename}" }
371
- end
372
-
373
- def build_header str
374
- @xml.li { @xml.h1 str }
375
- end
376
-
377
- def build_call number, name=number
378
- @xml.li { @xml.a name, :href => "javascript:call(#{number})" }
379
- end
380
- end
381
-
382
-
383
- private
384
-
385
-
386
- def image name
387
- name += '.bmp' unless name.index ?.
388
- @config << {:type => :image, :text => name}
389
- end
390
- def refresh_every time
391
- @refresh = time
392
- end
393
- def heading str
394
- @config << {:type => :heading, :text => str}
395
- end
396
- alias header heading
397
-
398
- def item title, &block
399
- hash = {:text => title, :type => :item }
400
- if block_given?
401
- hash[:block], hash[:type], hash[:uri] = block, :menu, title.nameify
402
- collisions = @config.select { |c| c[:type] == :menu && c[:text].nameify == hash[:uri]}.length
403
- hash[:uri] += ";#{collisions + 1}" if collisions.nonzero?
404
- end
405
- @config << hash
406
- end
407
- def items array
408
- array.each { |x| item x }
409
- end
410
-
411
- def guess_sip_user
412
- return @guessed_user if @guessed_user
413
- selection = PBX.sip_users.select { |x| x[:ip] == request.ip }.first
414
- @guessed_user = selection ? selection.username : nil
415
- end
416
-
417
- def call number, name=number, &block
418
- instance = {:type => :call, :text => name, :number => number}
419
- if block_given?
420
- $MICROMENU_CALL_HOOKS.purge_expired!
421
- num = "555551337#{rand(8_999_999_999) + 1_000_000_000}"
422
- instance[:number] = num
423
- $MICROMENU_CALL_HOOKS.synchronize do |hooks|
424
- hooks << { :expiration => 90.seconds.from_now, :extension => num, :hook => block }
425
- end
426
- end
427
- @config << instance
428
- end
429
-
430
- def action title, &block
431
- # Just like menu() but without a submenu.
432
- # Useful for performing an action and refreshing.
433
- end
434
- end
435
-
436
- USER_AGENT_MAP = {
437
- "Polycom" => MicromenuGenerator::PolycomPhone
438
- }
439
-
440
- def do_GET(request, response)
441
- response.status = 200
442
- log "Request from: " + request['User-Agent']
443
-
444
- route = request.path[1..-1].split '/'
445
- handler = nil
446
-
447
- if route.first == 'ajax'
448
- handler = MicromenuGenerator::AjaxResponse
449
- route.shift
450
- end
451
-
452
- if route.first == 'images'
453
- file = File.join(%w(config helpers micromenus images), route[1..-1])
454
- # TODO: Handle missing files
455
- response.content_type = WEBrick::HTTPUtils::mime_type file, WEBrick::HTTPUtils::DefaultMimeTypes
456
- response.body = File.read file
457
-
458
- elsif route.first == 'stylesheets'
459
- file = File.join %w(config helpers micromenus stylesheets), route[1..-1]
460
- response.content_type = 'text/css'
461
- response.body = File.read file
462
- elsif route.first == 'javascripts'
463
- file = File.join %w(config helpers micromenus javascripts), route[1..-1]
464
- response.content_type = 'text/javascript'
465
- response.body = File.read file
466
- else
467
- mg = MicromenuGenerator.new request, handler || resolve_brand(request['User-Agent']), StringIO.new
468
- response.content_type = mg.content_type
469
- response['Expires'] = 2
470
-
471
- mg.process route
472
-
473
- refresh = mg.get_refresh
474
- response['Refresh'] = refresh if refresh
475
-
476
- response.body = mg.io.string
477
- end
478
- end
479
-
480
- def resolve_brand useragent
481
- USER_AGENT_MAP.each do |k,v|
482
- return v if useragent.index k
483
- end
484
- MicromenuGenerator::ModernUi # Default to Class A browser
485
- end
486
- end
487
-
488
- $MICROMENUS_SERVER = Thread.new do
489
- micromenu_server = WEBrick::HTTPServer.new :Port => ($HELPERS['micromenus']['port'] || 1337)
490
-
491
- micromenu_server.mount '/', MicromenusServlet
492
- $HUTDOWN.hook {
493
- micromenu_server.stop
494
- }
495
- micromenu_server.start
496
- end
497
-
498
- # This before_call hook is the magic behind the call() method in the micromenus.
499
- before_call :low do
500
- # PSEUDOCODE
501
- # Check extension for format. next unless it matches
502
- # Delete all expired hooks
503
- # Find first match in the collection of hooks
504
- # Pull the first match out of the collection
505
- # Execute that match's block finish
506
- extension = Thread.current[:VARS]['extension'].to_s
507
-
508
- next unless extension.length == 19 && extension.starts_with?("555551337")
509
- $MICROMENU_CALL_HOOKS.purge_expired!
510
- match = $MICROMENU_CALL_HOOKS.detect { |x| x.extension == extension }
511
- next unless match
512
- Thread.current[:VARS]['context'] = :interrupted
513
- +match.hook
514
- end