sads_xml 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/MIT-LICENSE +20 -0
- data/README +8 -0
- data/Rakefile +38 -0
- data/app/views/layouts/sads_xml.html.erb +9 -0
- data/app/views/sads_xml/sads.html.erb +126 -0
- data/lib/sads_xml/controller_additions.rb +61 -0
- data/lib/sads_xml/sads.rb +166 -0
- data/lib/sads_xml/version.rb +3 -0
- data/lib/sads_xml.rb +9 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/ussd/default_controller.rb +9 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/ussd/default_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config/application.rb +56 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +62 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +337 -0
- data/test/dummy/log/test.log +133 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/functional/ussd/default_controller_test.rb +9 -0
- data/test/dummy/test/unit/helpers/ussd/default_helper_test.rb +4 -0
- data/test/dummy/tmp/cache/assets/CB1/D30/sprockets%2F7b6a97d2209a681f2bebe34655163319 +0 -0
- data/test/dummy/tmp/cache/assets/CBF/3F0/sprockets%2F7bd700995054fc7f6e3dd46729840f41 +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CF8/240/sprockets%2Fa77e8c483f757a8dde25486509c30e49 +0 -0
- data/test/dummy/tmp/cache/assets/CFA/270/sprockets%2Fd02325a0101297b802b9d58bf528daad +0 -0
- data/test/dummy/tmp/cache/assets/D15/F00/sprockets%2Fecc50cf25fa3f5a19523f1167447499e +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D87/660/sprockets%2F1ae8d4faaefc28a0e004e1363156a41f +0 -0
- data/test/dummy/tmp/cache/assets/D9D/DE0/sprockets%2Fa9c151cfd3ded7726c52d078c35ac71f +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E43/620/sprockets%2Fa1fde4a5eaab0961220acbd9def065aa +0 -0
- data/test/sads_xml_test.rb +108 -0
- data/test/test_helper.rb +14 -0
- metadata +186 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2012 InnoHub, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'SadsXml'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
Bundler::GemHelper.install_tasks
|
27
|
+
|
28
|
+
require 'rake/testtask'
|
29
|
+
|
30
|
+
Rake::TestTask.new(:test) do |t|
|
31
|
+
t.libs << 'lib'
|
32
|
+
t.libs << 'test'
|
33
|
+
t.pattern = 'test/**/*_test.rb'
|
34
|
+
t.verbose = false
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
task :default => :test
|
@@ -0,0 +1,126 @@
|
|
1
|
+
<style type="text/css">
|
2
|
+
#ussd-info {
|
3
|
+
margin-top: 8px;
|
4
|
+
margin-bottom: 8px;
|
5
|
+
padding: 8px;
|
6
|
+
font-family: verdana;
|
7
|
+
background: green;
|
8
|
+
color: white;
|
9
|
+
}
|
10
|
+
|
11
|
+
#screen {
|
12
|
+
font-family: Menlo, Monaco, Consolas, Monospace;
|
13
|
+
font-size: 1em;
|
14
|
+
width: 360px;
|
15
|
+
background: #AAA;
|
16
|
+
padding: 8px;
|
17
|
+
float: left;
|
18
|
+
}
|
19
|
+
|
20
|
+
#sms {
|
21
|
+
font-family: Menlo, Monaco, Consolas, Monospace;
|
22
|
+
font-size: 1em;
|
23
|
+
width: 360px;
|
24
|
+
padding: 8px;
|
25
|
+
float: left;
|
26
|
+
float: left;
|
27
|
+
background: #DDD;
|
28
|
+
}
|
29
|
+
|
30
|
+
#forms {
|
31
|
+
margin-top: 8px;
|
32
|
+
margin-bottom: 8px;
|
33
|
+
padding: 8px;
|
34
|
+
font-family: verdana;
|
35
|
+
background: green;
|
36
|
+
color: white;
|
37
|
+
}
|
38
|
+
|
39
|
+
.clear { clear: both; }
|
40
|
+
</style>
|
41
|
+
|
42
|
+
<div id="ussd-info">
|
43
|
+
<table>
|
44
|
+
<tr>
|
45
|
+
<th>Length</th>
|
46
|
+
<th>Pages</th>
|
47
|
+
</tr>
|
48
|
+
<tr>
|
49
|
+
<td><%= @sads.ussd_length %></td>
|
50
|
+
<td>Not Implemented</td>
|
51
|
+
</tr>
|
52
|
+
</table>
|
53
|
+
</div>
|
54
|
+
|
55
|
+
<div id="phone-viewport">
|
56
|
+
<div id="screen">
|
57
|
+
<% unless @sads.title.blank? %>
|
58
|
+
<%= @sads.title %>:
|
59
|
+
<br />
|
60
|
+
<% end %>
|
61
|
+
|
62
|
+
<% if @sads.banner_position == :top and @sads.banner_targets.any? -%>
|
63
|
+
{Ad=[<%= @sads.banner_targets.join(',') %>]}
|
64
|
+
<br />
|
65
|
+
<% end -%>
|
66
|
+
|
67
|
+
<% @sads.messages.each do |key, message| -%>
|
68
|
+
<% if key != :bottom -%>
|
69
|
+
<%= raw message.gsub(/\r/, '<br />') -%>
|
70
|
+
<br />
|
71
|
+
<% end -%>
|
72
|
+
<% end -%>
|
73
|
+
<% @sads.navigations.each do |key,links| %>
|
74
|
+
<% links.each do |link| %>
|
75
|
+
|
76
|
+
<% link[:pageId] = link[:pageId] %>
|
77
|
+
<% if link[:pageId].index("?") %>
|
78
|
+
<% link[:pageId].sub!("?", "?abonent=#{CGI.escape(params[:abonent])}&") %>
|
79
|
+
<% else %>
|
80
|
+
<% link[:pageId] += "?abonent=#{CGI.escape(params[:abonent])}" %>
|
81
|
+
<% end %>
|
82
|
+
|
83
|
+
<%= link_to raw("#{link[:accesskey]}>#{link[:title]}"), link[:pageId] %>
|
84
|
+
<br />
|
85
|
+
<% end %>
|
86
|
+
<% end %>
|
87
|
+
<% @sads.messages.each do |key, message| %>
|
88
|
+
<% if key == :bottom %>
|
89
|
+
<%= raw message.gsub(/\r/, '<br />') %>
|
90
|
+
<br />
|
91
|
+
<% end %>
|
92
|
+
<% end %>
|
93
|
+
|
94
|
+
<% @sads.inputs.each do |input| %>
|
95
|
+
<%= input[:title] %>><br />
|
96
|
+
<% end %>
|
97
|
+
|
98
|
+
<% if @sads.banner_position == :bottom and @sads.banner_targets.any? %>
|
99
|
+
{Ad=[<%= @sads.banner_targets.join(',') %>]}
|
100
|
+
<% end %>
|
101
|
+
</div>
|
102
|
+
<div id="sms">
|
103
|
+
<% if not @sads.sms_message.blank? %>
|
104
|
+
<%= raw @sads.sms_message.gsub(/\r/, '<br />') %>
|
105
|
+
<% end %>
|
106
|
+
</div>
|
107
|
+
<div class="clear"></div>
|
108
|
+
|
109
|
+
<div id="forms">
|
110
|
+
Emulated (Not shown on Phone)
|
111
|
+
<% @sads.inputs.each do |input| %>
|
112
|
+
<% submit_page = @sads.submit_page %>
|
113
|
+
<% if submit_page.index("?") %>
|
114
|
+
<% submit_page.sub!("?", "?abonent=#{CGI.escape(params[:abonent])}&") %>
|
115
|
+
<% else %>
|
116
|
+
<% submit_page += "?abonent=#{CGI.escape(params[:abonent])}" %>
|
117
|
+
<% end %>
|
118
|
+
|
119
|
+
<%= form_tag submit_page do |f| %>
|
120
|
+
<label><%= input[:title] %>:</label> <%= text_field_tag input[:name], '' %>
|
121
|
+
<%= submit_tag 'Submit' %>
|
122
|
+
<% end %>
|
123
|
+
<hr />
|
124
|
+
<% end %>
|
125
|
+
</div>
|
126
|
+
</div>
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module SadsXml
|
2
|
+
module ControllerAdditions
|
3
|
+
def self.included(base)
|
4
|
+
base.extend ClassMethods
|
5
|
+
end
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def enable_sads
|
9
|
+
send :include, InstanceMethods
|
10
|
+
|
11
|
+
skip_before_filter :verify_authenticity_token
|
12
|
+
around_filter :process_sads_request
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
|
18
|
+
def process_sads_request
|
19
|
+
setup_sads_request
|
20
|
+
yield
|
21
|
+
|
22
|
+
# Check ActionController::Responder
|
23
|
+
# This doesn't work for now, see how to implement this
|
24
|
+
# for DRYing the methods in the controller
|
25
|
+
# respond_with_sads
|
26
|
+
end
|
27
|
+
|
28
|
+
def setup_sads_request
|
29
|
+
# Get WHOISD Parameters
|
30
|
+
if params[:format] == 'sads'
|
31
|
+
@whoisd = {}
|
32
|
+
request.headers.each {|k,v| @whoisd[k] = v if k.match(/^HTTP_WHOISD/) }
|
33
|
+
logger.info " WHOISD: #{@whoisd.inspect}"
|
34
|
+
end
|
35
|
+
|
36
|
+
# The code below tries to emulate a SADS request
|
37
|
+
# this assumes that both are blank
|
38
|
+
if params[:format] == 'html'
|
39
|
+
params[:abonent] = '639990000000' if params[:abonent].nil?
|
40
|
+
params[:protocol] = 'ussd' if params[:protocol].nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
@sads = Sads.new
|
44
|
+
end
|
45
|
+
|
46
|
+
def respond_with_sads
|
47
|
+
respond_to do |format|
|
48
|
+
format.html { render :template => 'sads_xml/sads', :layout => 'sads_xml' }
|
49
|
+
format.sads { render :xml => @sads.to_sads }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if defined? ActionController
|
58
|
+
ActionController::Base.class_eval do
|
59
|
+
include SadsXml::ControllerAdditions
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
# Examples
|
4
|
+
#<?xml version="1.0" encoding="UTF-8"?>
|
5
|
+
#<page version="2.0" xmlns:meta="http://whoisd.eyeline.com/sads/meta">
|
6
|
+
# <title id="">DPC Mobile: Search by Person</title>
|
7
|
+
# <div>Please enter name of Person</div>
|
8
|
+
# <navigation id="">
|
9
|
+
# <link accesskey="*" pageId="search_by_person_submit"></link>
|
10
|
+
# </navigation>
|
11
|
+
#</page>
|
12
|
+
#
|
13
|
+
#<?xml version="1.0" encoding="UTF-8"?>
|
14
|
+
#<page version="2.0" xmlns:meta="http://whoisd.eyeline.com/sads/meta">
|
15
|
+
#<title id="">DPC Mobile: Search by Person</title>
|
16
|
+
# <div>
|
17
|
+
# <input navigationId="submit" name="name_of_person" title="Please enter name of Person" />
|
18
|
+
# </div>
|
19
|
+
# <navigation id="submit">
|
20
|
+
# <link accesskey="1" pageId="search_by_person_submit">Ok</link>
|
21
|
+
# </navigation>
|
22
|
+
#</page>
|
23
|
+
|
24
|
+
module SadsXml
|
25
|
+
class Sads
|
26
|
+
attr_accessor :title, :messages, :navigations, :inputs, :submit_page, :sms_message,
|
27
|
+
:banner_targets, :banner_position, :request_attributes
|
28
|
+
|
29
|
+
DEFAULTS = {
|
30
|
+
:navigation => {
|
31
|
+
:type => 'nav'
|
32
|
+
}
|
33
|
+
}
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
@title = ''
|
37
|
+
@inputs = []
|
38
|
+
@navigations = { :default => [] }
|
39
|
+
@messages = {}
|
40
|
+
@banner_targets = []
|
41
|
+
@banner_position = :top
|
42
|
+
@request_attributes = []
|
43
|
+
end
|
44
|
+
|
45
|
+
def message=(message)
|
46
|
+
self.set_message(:default, message)
|
47
|
+
end
|
48
|
+
|
49
|
+
def submit_page=(page_link)
|
50
|
+
# workaround for SADS Absolute Path
|
51
|
+
#page_link.gsub!(/^\/yp_mobile\//, '') unless page_link.match(/\.html$/)
|
52
|
+
@submit_page = page_link
|
53
|
+
end
|
54
|
+
|
55
|
+
def ussd_length
|
56
|
+
counter = 0
|
57
|
+
counter += @title.length + 2 unless @title.blank?
|
58
|
+
|
59
|
+
@messages.each do |key, message|
|
60
|
+
counter += message.length + 1 unless message.blank?
|
61
|
+
end
|
62
|
+
|
63
|
+
@navigations.each do |key, links|
|
64
|
+
links.each do |link|
|
65
|
+
counter += link[:title].length + link[:accesskey].length + 2
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
@inputs.each do |input|
|
70
|
+
counter += input[:title].length + 2
|
71
|
+
end
|
72
|
+
|
73
|
+
counter -= 1
|
74
|
+
return counter
|
75
|
+
end
|
76
|
+
|
77
|
+
def one_ussd_message
|
78
|
+
ussd_length <= 160
|
79
|
+
end
|
80
|
+
|
81
|
+
def one_ussd_message_characters_left
|
82
|
+
160 - ussd_length
|
83
|
+
end
|
84
|
+
|
85
|
+
def add_navigation(link, navigation_id = :default)
|
86
|
+
@navigations[navigation_id] = [] if @navigations[navigation_id].nil?
|
87
|
+
|
88
|
+
# workaround for SADS Absolute Path
|
89
|
+
#link[:pageId].gsub!(/^\/yp_mobile\//, '') unless link[:pageId].match(/\.html$/)
|
90
|
+
|
91
|
+
@navigations[navigation_id]<< DEFAULTS[:navigation].merge(link)
|
92
|
+
end
|
93
|
+
|
94
|
+
def add_attribute(req_attribute)
|
95
|
+
@request_attributes<< req_attribute
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_message(id, message)
|
99
|
+
@messages[id.to_sym] = message
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_input(input)
|
103
|
+
@inputs<< input
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_sads
|
107
|
+
xml = Builder::XmlMarkup.new
|
108
|
+
xml.instruct!
|
109
|
+
xml.page :version => "2.0", "xmlns:meta" => "http://whoisd.eyeline.com/sads/meta" do
|
110
|
+
xml.title @title, :id => ''
|
111
|
+
|
112
|
+
if @banner_position == :top and @banner_targets.any?
|
113
|
+
xml.meta :banner, :target => @banner_targets.join(',')
|
114
|
+
end
|
115
|
+
|
116
|
+
@messages.each do |key, message|
|
117
|
+
object_hash = {}
|
118
|
+
object_hash[:id] = key.to_s unless key == :default
|
119
|
+
|
120
|
+
xml.div message, object_hash
|
121
|
+
end
|
122
|
+
|
123
|
+
xml.div @sms_message, :type => 'sms' unless sms_message.blank?
|
124
|
+
|
125
|
+
if @inputs.any?
|
126
|
+
xml.div do
|
127
|
+
@inputs.each do |input|
|
128
|
+
xml.input input
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
navigations.each do |key, links|
|
134
|
+
if links.any?
|
135
|
+
object_hash = {}
|
136
|
+
object_hash[:id] = key.to_s unless key == :default
|
137
|
+
|
138
|
+
xml.navigation object_hash do
|
139
|
+
links.each do |link| xml.link link[:title].strip, link.except(:title) end
|
140
|
+
end
|
141
|
+
end # eo if links.any?
|
142
|
+
|
143
|
+
if @inputs.any?
|
144
|
+
xml.navigation :id => 'submit' do
|
145
|
+
xml.link :accesskey => '1', :pageId => @submit_page
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
if @request_attributes.any?
|
151
|
+
xml.attributes do
|
152
|
+
@request_attributes.each do |attribute|
|
153
|
+
xml.attribute attribute
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
if @banner_position == :bottom and @banner_targets.any?
|
159
|
+
xml.meta :banner, :target => @banner_targets.join(',')
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|