adhearsion 0.7.6 → 0.7.7

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 (61) hide show
  1. data/.version +1 -1
  2. data/CHANGELOG +43 -25
  3. data/Rakefile +0 -5
  4. data/TODO +51 -2
  5. data/ahn +2 -1
  6. data/apps/default/Rakefile +16 -7
  7. data/apps/default/config/adhearsion.yml +22 -1
  8. data/apps/default/config/helpers/manager_proxy.yml +1 -0
  9. data/apps/default/config/helpers/micromenus/images/arrow-off.gif +0 -0
  10. data/apps/default/config/helpers/micromenus/images/arrow-on.gif +0 -0
  11. data/apps/default/config/helpers/micromenus/images/error.gif +0 -0
  12. data/apps/default/config/helpers/micromenus/images/folder-off.gif +0 -0
  13. data/apps/default/config/helpers/micromenus/images/folder-on.gif +0 -0
  14. data/apps/default/config/helpers/micromenus/images/folder.png +0 -0
  15. data/apps/default/config/helpers/micromenus/images/ggbridge.jpg +0 -0
  16. data/apps/default/config/helpers/micromenus/images/green.png +0 -0
  17. data/apps/default/config/helpers/micromenus/images/microbrowser.bg.gif +0 -0
  18. data/apps/default/config/helpers/micromenus/images/red.png +0 -0
  19. data/apps/default/config/helpers/micromenus/images/url-off.gif +0 -0
  20. data/apps/default/config/helpers/micromenus/images/url-on.gif +0 -0
  21. data/apps/default/config/helpers/micromenus/images/yellow.png +0 -0
  22. data/apps/default/config/helpers/micromenus/javascripts/animation.js +1341 -0
  23. data/apps/default/config/helpers/micromenus/javascripts/carousel.js +1238 -0
  24. data/apps/default/config/helpers/micromenus/javascripts/columnav.js +306 -0
  25. data/apps/default/config/helpers/micromenus/javascripts/connection.js +965 -0
  26. data/apps/default/config/helpers/micromenus/javascripts/container.js +4727 -0
  27. data/apps/default/config/helpers/micromenus/javascripts/container_core.js +2915 -0
  28. data/apps/default/config/helpers/micromenus/javascripts/dom.js +892 -0
  29. data/apps/default/config/helpers/micromenus/javascripts/dragdrop.js +2921 -907
  30. data/apps/default/config/helpers/micromenus/javascripts/event.js +1771 -0
  31. data/apps/default/config/helpers/micromenus/javascripts/yahoo.js +433 -0
  32. data/apps/default/config/helpers/micromenus/stylesheets/carousel.css +78 -0
  33. data/apps/default/config/helpers/micromenus/stylesheets/columnav.css +135 -0
  34. data/apps/default/config/helpers/micromenus/stylesheets/microbrowsers.css +42 -0
  35. data/apps/default/config/helpers/multi_messenger.yml +5 -1
  36. data/apps/default/config/migration.rb +10 -0
  37. data/apps/default/extensions.rb +1 -1
  38. data/apps/default/helpers/factorial.alien.c +3 -3
  39. data/apps/default/helpers/lookup.rb +2 -1
  40. data/apps/default/helpers/manager_proxy.rb +67 -15
  41. data/apps/default/helpers/micromenus.rb +173 -31
  42. data/apps/default/helpers/multi_messenger.rb +20 -3
  43. data/lib/adhearsion.rb +218 -88
  44. data/lib/constants.rb +1 -0
  45. data/lib/core_extensions.rb +15 -9
  46. data/lib/phone_number.rb +85 -0
  47. data/lib/rami.rb +3 -2
  48. data/lib/servlet_container.rb +47 -24
  49. data/lib/sexy_migrations.rb +70 -0
  50. data/test/asterisk_module_test.rb +9 -9
  51. data/test/specs/numerical_string_spec.rb +53 -0
  52. metadata +31 -11
  53. data/apps/default/config/helpers/micromenus/javascripts/builder.js +0 -131
  54. data/apps/default/config/helpers/micromenus/javascripts/controls.js +0 -834
  55. data/apps/default/config/helpers/micromenus/javascripts/effects.js +0 -956
  56. data/apps/default/config/helpers/micromenus/javascripts/prototype.js +0 -2319
  57. data/apps/default/config/helpers/micromenus/javascripts/scriptaculous.js +0 -51
  58. data/apps/default/config/helpers/micromenus/javascripts/slider.js +0 -278
  59. data/apps/default/config/helpers/micromenus/javascripts/unittest.js +0 -557
  60. data/apps/default/config/helpers/micromenus/stylesheets/firefox.css +0 -10
  61. data/apps/default/config/helpers/micromenus/stylesheets/firefox.xul.css +0 -44
@@ -0,0 +1,135 @@
1
+ /*
2
+ * Copyright (c) 2007, David A. Lindquist (stringify.com)
3
+ * Some Rights Reserved
4
+ *
5
+ * This code is licensed under the Creative Commons Attribution 2.5 License
6
+ * (http://creativecommons.org/licenses/by/2.5/). Please maintain the above
7
+ * license and copyright statements when using this code.
8
+ *
9
+ * $Id: columnav.css 476 2007-02-20 23:43:22Z david $
10
+ */
11
+
12
+ /* DO NOT CHANGE ANYTHING IN THIS SECTION
13
+
14
+ Styles below override defaults in carousel.css and govern fundamental layout
15
+ and behavior.
16
+
17
+ ------------------------------------------------------------------------------*/
18
+
19
+ .carousel-component {
20
+ background: transparent;
21
+ color: black;
22
+ overflow: auto !important;
23
+ padding: 0;
24
+ }
25
+
26
+ .carousel-component ul.carousel-list li {
27
+ color: black;
28
+ font-family: inherit;
29
+ font-size: 1em;
30
+ text-align: left;
31
+ }
32
+
33
+ .carousel-component ul.carousel-list li div {
34
+ overflow: auto;
35
+ overflow-y: scroll;
36
+ position: relative;
37
+ }
38
+
39
+ .carousel-component ul.carousel-list li a {
40
+ display: block;
41
+ overflow-x: hidden;
42
+ position: relative;
43
+ }
44
+
45
+ .carousel-component ul.carousel-list li a span {
46
+ display: block;
47
+ position: relative;
48
+ }
49
+
50
+
51
+ /* CUSTOMIZE ANYTHING IN THIS SECTION
52
+
53
+ Styles below can be changed to customize colors, margins, padding, fonts,
54
+ etc., as well as the icons that appear before each item. At minimum, set the
55
+ width of .carousel-component and its list items, and the height of the div
56
+ it contains.
57
+
58
+ ------------------------------------------------------------------------------*/
59
+
60
+ .carousel-component {
61
+ }
62
+
63
+ .carousel-component ul.carousel-list li {
64
+ width: 348px;
65
+ }
66
+
67
+ .carousel-component ul.carousel-list li div {
68
+ height: 348px;
69
+ }
70
+
71
+ .carousel-component ul.carousel-list li a {
72
+ color: black;
73
+ cursor: default;
74
+ font-family: 'Lucida Grande', Helvetica, Arial, sans-serif;
75
+ font-size: 12px;
76
+ margin: 0 1px;
77
+ padding: 2px;
78
+ text-decoration: none;
79
+ }
80
+
81
+ .carousel-component ul.carousel-list li a.columnav-has-menu {
82
+ background-image: url(../images/arrow-off.gif);
83
+ background-position: right center;
84
+ background-repeat: no-repeat;
85
+ }
86
+
87
+ .carousel-component ul.carousel-list li a.columnav-active {
88
+ background-color: #3875d7;
89
+ }
90
+
91
+ /* IE6 cannot grok element selectors with chained class names */
92
+ html>body .carousel-component ul.carousel-list li a.columnav-has-menu.columnav-active {
93
+ background-image: url(../images/arrow-on.gif);
94
+ }
95
+
96
+ .carousel-component ul.carousel-list li a.columnav-error span {
97
+ background-image: url(../images/error.gif);
98
+ color: red;
99
+ }
100
+
101
+ .carousel-component ul.carousel-list li a span {
102
+ background-repeat: no-repeat;
103
+ background-position: 0px center;
104
+ margin-right: 14px;
105
+ padding-left: 20px;
106
+ }
107
+
108
+ .carousel-component ul.carousel-list li a.columnav-active span {
109
+ color: white;
110
+ }
111
+
112
+ .carousel-component ul.carousel-list li a.columnav-has-menu span {
113
+ background-image: url(../images/folder-off.gif);
114
+ }
115
+
116
+ /* IE6 cannot grok element selectors with chained class names */
117
+ html>body .carousel-component ul.carousel-list li a.columnav-has-menu.columnav-active span {
118
+ background-image: url(../images/folder-on.gif);
119
+ }
120
+
121
+ .prevButton { }
122
+ .prevButton a {
123
+ color: black;
124
+ font-family: 'Lucida Grande', Helvetica, Arial;
125
+ font-size: 10px;
126
+ line-height: 22px;
127
+ position: relative;
128
+ text-align: center;
129
+ text-decoration: none;
130
+ }
131
+
132
+ .prevButton a:hover {
133
+ background-color: #3875d7;
134
+ color: white;
135
+ }
@@ -0,0 +1,42 @@
1
+ body {
2
+ background: url(/images/ggbridge.jpg) top left no-repeat; }
3
+
4
+ div.microbrowser {
5
+ background: url(/images/microbrowser.bg.gif) top left no-repeat;}
6
+ div.microbrowser .hd {}
7
+ div.microbrowser .ft {
8
+ display: none; }
9
+ div.microbrowser h1 {
10
+ color: white;
11
+ text-shadow: black 0px 0px 5px;
12
+ margin: 0; padding: 6px 0;
13
+ text-align: center;
14
+ font-size: 20px; }
15
+
16
+ .yui-panel {
17
+ width: 400px;}
18
+
19
+ .yui-panel .hd {
20
+ padding:0;
21
+ border:none;
22
+ color:#000;
23
+ height:44px;
24
+ margin-left:33px;
25
+ margin-right:33px;
26
+ text-align:center;
27
+ overflow:visible; }
28
+
29
+ .yui-panel .hd .tl {
30
+ width:30px;
31
+ height:22px;
32
+ top: 4px;
33
+ left:10px;
34
+ position:absolute; }
35
+
36
+ .yui-panel .hd .tr {
37
+ width:30px;
38
+ height:22px;
39
+ line-height: 22px;
40
+ top:6px;
41
+ left:315px;
42
+ position:absolute; }
@@ -2,4 +2,8 @@
2
2
  # be any Jabber/XMPP account.
3
3
  username: test@adhearsion.com
4
4
  password: password
5
- enabled: false
5
+ enabled: false
6
+
7
+ # Specify whether incoming subscription requests should
8
+ # be automatically accepted.
9
+ accept_subscriptions: false
@@ -47,3 +47,13 @@ class CreateGroups < ActiveRecord::Migration
47
47
  drop_table :groups
48
48
  end
49
49
  end
50
+
51
+
52
+ CreateUsers.up
53
+ CreateGroups.up
54
+
55
+ ### If you'd like to create any initial users, do it here by
56
+ ### requiring your database.rb file and performing your logic.
57
+ #
58
+ # require 'config/database.rb'
59
+ # User.create :name => "Jay Phillips", :extension => 123
@@ -7,7 +7,7 @@
7
7
  # your extensions.conf file for Adhearsion as so:
8
8
  #
9
9
  # [internal]
10
- # exten => _X.,1,AGI(agi://192.168.1.3)
10
+ # exten => _.,1,AGI(agi://192.168.1.3)
11
11
  #
12
12
  # then, when Adhearsion receives that call, it sees it came from
13
13
  # the "internal" context and invokes this.
@@ -24,9 +24,9 @@
24
24
  */
25
25
 
26
26
  int fast_factorial(int input) {
27
- int sum = 0, count = 1;
27
+ int prod = 1, count = 1;
28
28
  while(count <= input) {
29
- sum += count++;
29
+ prod *= count++;
30
30
  }
31
- return sum;
31
+ return prod;
32
32
  }
@@ -15,7 +15,8 @@ def lookup number
15
15
  if (results = doc.at "#results_single_listing") then
16
16
  # This div's h3 contains the name of the caller
17
17
  hash[:first_name], hash[:last_name] = results.at('h3').inner_html.split(/,\s*/).reverse
18
-
18
+ hash[:name] = hash[:first_name] + " " + hash[:last_name]
19
+
19
20
  # Now we just need the rest of the information contained in p's.
20
21
  meta = results/'p'
21
22
  meta.pop # Discard the useless p element
@@ -38,23 +38,75 @@ class PBX
38
38
  @@sip_users[:users]
39
39
  end
40
40
 
41
- def self.originate hash
42
- # This is an ugly hack to use until RAI's AMI work is ported in.
43
- h = {}
44
- h['Application'] = hash.delete :app
45
- hash.each { |k,v| h[k.to_s.titleize] = v }
46
- @@rami_client.originate h
47
- end
41
+ class << self
42
+
43
+ # An introduction connects two endpoints together. The first argument is
44
+ # the first person the PBX will call. When she's picked up, Asterisk will
45
+ # play ringing while the second person is being dialed.
46
+ #
47
+ # The first argument is the person called first. Pass this as a canonical
48
+ # IAX2/server/user type argument. Destination takes the same format, but
49
+ # comma-separated Dial() arguments can be optionally passed after the
50
+ # technology.
51
+ #
52
+ # TODO: Provide an example when this works.
53
+ def introduce src, dst, hash={}
54
+ cid = hash.delete(:callerid) || hash.delete(:cid)
55
+ options = hash.delete(:options) || hash.delete(:opts)
56
+ dst << "|" << options if options
57
+ call_and_exec src, "Dial", dst, cid
58
+ end
59
+
60
+ def call_and_exec channel, app, args=nil, callerid=nil
61
+ args = { :channel => channel
62
+ :application => app }
63
+ args[:data] = args if args
64
+ args[:callerid] = callerid if callerid
65
+ originate args
66
+ end
67
+
68
+ def overhear their_channel, your_channel
69
+
70
+ end
71
+
72
+
73
+ def call chan, code=nil, &block
74
+ raise "Cannot provide both a String and a block!" if code && block_given?
75
+ ip = 'localhost' # TODO: How to get this?!
76
+ originate :application => "AGI",
77
+ :data => "agi://#{ip}/?call_id=",
78
+ :channel => chan
79
+
80
+ # TODO: Initiate an origination that comes back
81
+ # into Adhearsion and runs either a certain block
82
+ # of code or eval()s a String of dialplan code.
83
+ end
84
+
85
+ def originate hash
86
+ # This is an ugly hack to use until RAI's AMI work is ported in.
87
+ h = {}
88
+ h['Application'] = hash.delete :app
89
+ hash.each { |k,v| h[k.to_s.titleize] = v }
90
+ @@rami_client.originate h
91
+ end
48
92
 
49
- def self.record hash={}, &block
50
- # TODO: Implement me!
51
- raise NotImplementedError
93
+ def record hash={}, &block
94
+ # TODO: Implement me!
95
+ raise NotImplementedError
52
96
 
53
- # defaults = {:file => "#{String.random(5)}", :folder => nil,
54
- # :channel => Thread.current[:VARS]['channel'], :format => 'wav', :mix => '1'}
55
- # defaults = defaults.merge hash
56
- # PBX.rami_client.... # TODO
97
+ # defaults = {:file => "#{String.random(5)}", :folder => nil,
98
+ # :channel => Thread.current[:VARS]['channel'], :format => 'wav', :mix => '1'}
99
+ # defaults = defaults.merge hash
100
+ # PBX.rami_client.... # TODO
101
+ end
102
+
103
+ # private
104
+ # CALL_BLOCK_CACHE = {}
105
+ # def handle_call_specifically expiration=3.minutes.from_now, &block
106
+ # # Find a random, unused id
107
+ # while CALL_BLOCK_CACHE[id = rand(1_073_741_823)]; end # 1073741823 is the Fixnum max
108
+ # CALL_BLOCK_CACHE[id] = [expiration, block]
109
+ # end
57
110
  end
58
111
 
59
-
60
112
  end
@@ -51,8 +51,8 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
51
51
 
52
52
  if route.empty?
53
53
  start "Error" do
54
- build_text "Bad URL!"
55
- build_text "Must point to a micromenu!"
54
+ build_text "Whoops!"
55
+ build_text "You forgot to include the target Micromenu in the URL path!"
56
56
  end
57
57
  return
58
58
  end
@@ -63,9 +63,10 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
63
63
  load_menu filename
64
64
  until route.empty?
65
65
  segment = route.shift
66
- broken = segment.match(/^([\w_.]+);?(\d*)$/)
67
- segment, id = broken[1], broken[2]
68
- id = nil if id.empty?
66
+ broken = segment.match(/^([\w_.]+)(;(\d*))?$/)
67
+
68
+ segment, id = broken[1], broken[3]
69
+ id = nil if id && id.empty?
69
70
 
70
71
  matches = @config.select do |x|
71
72
  x[:type] == :menu && x[:text].nameify == segment
@@ -111,13 +112,12 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
111
112
  end
112
113
  end
113
114
  end
114
-
115
115
  def load_menu filename
116
116
  @config.clear
117
117
  file = File.join('config','helpers', 'micromenus', filename + '.rb')
118
118
  unless File.readable? file
119
- item "Bad URL!"
120
- item "File inexistent!"
119
+ item "Target Micromenu doesn't exist!"
120
+ item "Did you input the URL correctly?"
121
121
  else
122
122
  eval File.read(File.join('config','helpers', 'micromenus', filename + '.rb'))
123
123
  end
@@ -131,8 +131,49 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
131
131
  ((url[-1] == ?/) ? url : url + "/") + pages * '/'
132
132
  end
133
133
  end
134
-
135
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
+
136
177
 
137
178
  module PolycomPhone
138
179
 
@@ -176,7 +217,7 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
176
217
  @xml.br
177
218
  end
178
219
  end
179
-
220
+
180
221
  module XulUi
181
222
 
182
223
  include PolycomPhone
@@ -220,29 +261,122 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
220
261
  end
221
262
 
222
263
  end
223
-
224
-
225
- module FirefoxUi
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
226
300
 
227
- include PolycomPhone
228
-
229
301
  def start name='', &block
230
302
  @xml.html do
231
303
  @xml.head do
232
304
  @xml.title name
233
- @xml.link :rel => 'stylesheet', :media => 'all', :href => '/stylesheets/firefox.css'
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'
234
309
  end
235
310
  @xml.body do
236
- yield
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
237
351
  end
238
352
  end
239
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
+
240
377
  def build_call number, name=number
241
- # The tel:// UI doesn't do Firefox much good. Mexuar, maybe?
242
- @xml.a name, :href => "tel://#{number}"
243
- @xml.br
378
+ @xml.li { @xml.a name, :href => "javascript:call(#{number})" }
244
379
  end
245
-
246
380
  end
247
381
 
248
382
 
@@ -253,11 +387,9 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
253
387
  name += '.bmp' unless name.index ?.
254
388
  @config << {:type => :image, :text => name}
255
389
  end
256
-
257
- def refresh_every time
390
+ def refresh_every time
258
391
  @refresh = time
259
392
  end
260
-
261
393
  def heading str
262
394
  @config << {:type => :heading, :text => str}
263
395
  end
@@ -302,8 +434,7 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
302
434
  end
303
435
 
304
436
  USER_AGENT_MAP = {
305
- "Polycom" => MicromenuGenerator::PolycomPhone,
306
- "Firefox" => MicromenuGenerator::XulUi#FirefoxUi
437
+ "Polycom" => MicromenuGenerator::PolycomPhone
307
438
  }
308
439
 
309
440
  def do_GET(request, response)
@@ -311,6 +442,13 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
311
442
  log "Request from: " + request['User-Agent']
312
443
 
313
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
+
314
452
  if route.first == 'images'
315
453
  file = File.join(%w(config helpers micromenus images), route[1..-1])
316
454
  # TODO: Handle missing files
@@ -321,17 +459,21 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
321
459
  file = File.join %w(config helpers micromenus stylesheets), route[1..-1]
322
460
  response.content_type = 'text/css'
323
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
324
466
  else
325
- mg = MicromenuGenerator.new request, resolve_brand(request['User-Agent']), StringIO.new
467
+ mg = MicromenuGenerator.new request, handler || resolve_brand(request['User-Agent']), StringIO.new
326
468
  response.content_type = mg.content_type
327
469
  response['Expires'] = 2
328
470
 
329
471
  mg.process route
330
472
 
331
473
  refresh = mg.get_refresh
332
- response['Refresh'] = refresh if refresh
474
+ response['Refresh'] = refresh if refresh
333
475
 
334
- response.body = mg.io.string
476
+ response.body = mg.io.string
335
477
  end
336
478
  end
337
479
 
@@ -339,12 +481,12 @@ class MicromenusServlet < WEBrick::HTTPServlet::AbstractServlet
339
481
  USER_AGENT_MAP.each do |k,v|
340
482
  return v if useragent.index k
341
483
  end
342
- MicromenuGenerator::PolycomPhone # Polycom's the default since it's XHTML
484
+ MicromenuGenerator::ModernUi # Default to Class A browser
343
485
  end
344
486
  end
345
487
 
346
488
  $MICROMENUS_SERVER = Thread.new do
347
- micromenu_server = WEBrick::HTTPServer.new :Port => ($HELPERS.micromenus.port || 1337)
489
+ micromenu_server = WEBrick::HTTPServer.new :Port => ($HELPERS['micromenus']['port'] || 1337)
348
490
 
349
491
  micromenu_server.mount '/', MicromenusServlet
350
492
  $HUTDOWN.hook {