agilisto-smartcall 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/History.txt +4 -0
- data/Manifest.txt +88 -0
- data/PostInstall.txt +6 -0
- data/README.rdoc +50 -0
- data/Rakefile +26 -0
- data/bin/smartcall +38 -0
- data/config/website.yml.sample +2 -0
- data/lib/smartcall.rb +30 -0
- data/lib/smartcall/soap/default.rb +147 -0
- data/lib/smartcall/soap/default_driver.rb +70 -0
- data/lib/smartcall/soap/smartcall_error.rb +9 -0
- data/lib/smartcall/soap/sms_ws_client.rb +108 -0
- data/lib/smartcall/utility.rb +6 -0
- data/lib/smartcall/utility/options.rb +91 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +71 -0
- data/test/test_helper.rb +3 -0
- data/test/test_smartcall.rb +11 -0
- data/website/index.html +78 -0
- data/website/index.txt +52 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +159 -0
- data/website/template.html.erb +50 -0
- metadata +92 -0
@@ -0,0 +1,108 @@
|
|
1
|
+
module Smartcall
|
2
|
+
module Soap
|
3
|
+
class SmsWSClient
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def no_authorisation_error
|
7
|
+
raise SmartcallError.new("SmsWSErrors: Unable to Login")
|
8
|
+
end
|
9
|
+
|
10
|
+
def invalid_token_error
|
11
|
+
raise SmartcallError.new("SmsWSErrors: Invalid Token")
|
12
|
+
end
|
13
|
+
|
14
|
+
def invalid_source_address_error
|
15
|
+
raise SmartcallError.new("SmsWSErrors: Invalid Source Address")
|
16
|
+
end
|
17
|
+
|
18
|
+
def invalid_number_error
|
19
|
+
raise SmartcallError.new("SmsWSErrors: InvalidNumber")
|
20
|
+
end
|
21
|
+
|
22
|
+
def not_implemented_error
|
23
|
+
raise SmartcallError.new("SmsWSErrors: Not Implemented")
|
24
|
+
end
|
25
|
+
|
26
|
+
def debug_mode=(value)
|
27
|
+
@@debug_mode = value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
@@debug_mode = false
|
32
|
+
|
33
|
+
RESPONSE_HANDLER = { 'Success' => true , 'InvalidSourceAddress' => Proc.new { SmsWSClient.invalid_source_address_error } ,
|
34
|
+
'InvalidToken' => Proc.new { SmsWSClient.invalid_token_error } , 'Failed' => false ,
|
35
|
+
'InvalidNumber' => Proc.new { SmsWSClient.invalid_number_error } }
|
36
|
+
|
37
|
+
DEFAULT_ENDPOINT = "http://www.smartcalltech.co.za/SmsWS/Service.asmx"
|
38
|
+
|
39
|
+
def initialize(username, password, campaign_id, reference)
|
40
|
+
@retry = true
|
41
|
+
@username, @password, @campaign_id, @reference = username, password, campaign_id, reference
|
42
|
+
@obj = SmsWSSoap.new(DEFAULT_ENDPOINT)
|
43
|
+
@obj.wiredump_dev = STDERR if @@debug_mode
|
44
|
+
end
|
45
|
+
|
46
|
+
def send_sms(cell , msg)
|
47
|
+
@cell = cell
|
48
|
+
@msg = msg
|
49
|
+
@token ||= self.login
|
50
|
+
if @token
|
51
|
+
s = SendSMS.new(@token , cell , msg , @reference , @campaign_id)
|
52
|
+
response = @obj.sendSMS(s)
|
53
|
+
return process_response(RESPONSE_HANDLER[response.sendSMSResult])
|
54
|
+
else
|
55
|
+
update_token
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def send_binary_sms(cell, header, part)
|
60
|
+
@cell = cell
|
61
|
+
@token ||= self.login
|
62
|
+
if @token
|
63
|
+
s = SendBinaryString.new(@token, cell, header + part, @reference, @campaign_id)
|
64
|
+
response = @obj.sendBinaryString(s)
|
65
|
+
result = process_response(RESPONSE_HANDLER[response.sendBinaryStringResult])
|
66
|
+
return result
|
67
|
+
else
|
68
|
+
update_token
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def send_wap_link(cell, href, msg)
|
73
|
+
@cell = cell
|
74
|
+
@msg = msg
|
75
|
+
@token ||= self.login
|
76
|
+
if @token
|
77
|
+
s = SendWAPLink.new(@token , cell , href, msg , @reference , @campaign_id)
|
78
|
+
response = @obj.sendWAPLink(s)
|
79
|
+
return process_response(RESPONSE_HANDLER[response.sendWAPLinkResult])
|
80
|
+
else
|
81
|
+
update_token
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
protected
|
86
|
+
|
87
|
+
def process_response(response_handler)
|
88
|
+
response_handler.class == Proc ? response_handler.call : response_handler
|
89
|
+
end
|
90
|
+
|
91
|
+
def update_token
|
92
|
+
@retry ? @token = self.login : ( raise no_authorisation_error )
|
93
|
+
@retry = false
|
94
|
+
end
|
95
|
+
|
96
|
+
def retry_sms
|
97
|
+
send_sms(@cell , @msg) if @retry
|
98
|
+
@retry = false
|
99
|
+
end
|
100
|
+
|
101
|
+
def login
|
102
|
+
l = Login.new(@username , @password)
|
103
|
+
response = @obj.login(l)
|
104
|
+
response.loginResult != 'false' ? @token = response.token : false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
module Smartcall
|
5
|
+
module Utility
|
6
|
+
class Options #:nodoc:
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def parse(args)
|
10
|
+
@options = self.default_options
|
11
|
+
parser = OptionParser.new do |opts|
|
12
|
+
opts.banner = "Usage: smartcall [options] recipient message"
|
13
|
+
opts.separator ""
|
14
|
+
opts.separator "Specific options:"
|
15
|
+
|
16
|
+
opts.on('-u', '--username USERNAME',
|
17
|
+
"Specify the smartcall username (overrides ~/.smartcall setting)") do |username|
|
18
|
+
@options.username = username
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on('-p', '--password PASSWORD',
|
22
|
+
"Specify the smartcall password (overrides ~/.smartcall setting)") do |password|
|
23
|
+
@options.password = password
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on('-c', '--campaign CAMPAIGN_ID',
|
27
|
+
"Specify the campaign key (overrides ~/.smartcall setting)") do |key|
|
28
|
+
@options.campaign_id = key
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on('-r', '--reference REFERENCE',
|
32
|
+
"Specify the reference (overrides ~/.smartcall setting)") do |reference|
|
33
|
+
@options.reference = reference
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on('-d', '--debug') do
|
37
|
+
Smartcall::Soap::SmsWSClient.debug_mode = true
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on_tail('-h', '--help', "Show this message") do
|
41
|
+
puts opts
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on_tail('-v', '--version') do
|
46
|
+
puts "Ruby Smartcall SMS Utility #{Smartcall::VERSION}"
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
parser.parse!(args)
|
52
|
+
@options.recipient = ARGV[-2]
|
53
|
+
@options.message = ARGV[-1]
|
54
|
+
|
55
|
+
if (@options.message.nil? || @options.recipient.nil?) && send_message?
|
56
|
+
puts "You must specify a recipient and message!"
|
57
|
+
puts parser
|
58
|
+
exit
|
59
|
+
end
|
60
|
+
|
61
|
+
return @options
|
62
|
+
|
63
|
+
rescue OptionParser::MissingArgument => e
|
64
|
+
switch_given = e.message.split(':').last.strip
|
65
|
+
puts "The #{switch_given} option requires an argument."
|
66
|
+
puts parser
|
67
|
+
exit
|
68
|
+
end
|
69
|
+
|
70
|
+
def default_options
|
71
|
+
options = OpenStruct.new
|
72
|
+
config_file = File.open(File.join(ENV['HOME'], '.smartcall'))
|
73
|
+
config = YAML.load(config_file)
|
74
|
+
options.username = config['username']
|
75
|
+
options.password = config['password']
|
76
|
+
options.campaign_id = config['campaign_id']
|
77
|
+
options.reference = config['reference']
|
78
|
+
return options
|
79
|
+
rescue Errno::ENOENT
|
80
|
+
return options
|
81
|
+
end
|
82
|
+
|
83
|
+
def send_message?
|
84
|
+
(@options.show_status.nil? &&
|
85
|
+
@options.show_balance.nil?)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
data/script/console
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# File: script/console
|
3
|
+
irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
|
4
|
+
|
5
|
+
libs = " -r irb/completion"
|
6
|
+
# Perhaps use a console_lib to store any extra methods I may want available in the cosole
|
7
|
+
# libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
|
8
|
+
libs << " -r #{File.dirname(__FILE__) + '/../lib/smartcall.rb'}"
|
9
|
+
puts "Loading smartcall gem"
|
10
|
+
exec "#{irb} #{libs} --simple-prompt"
|
data/script/destroy
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/destroy'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Destroy.new.run(ARGV)
|
data/script/generate
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubigen'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rubygems'
|
8
|
+
require 'rubigen'
|
9
|
+
end
|
10
|
+
require 'rubigen/scripts/generate'
|
11
|
+
|
12
|
+
ARGV.shift if ['--help', '-h'].include?(ARGV[0])
|
13
|
+
RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
|
14
|
+
RubiGen::Scripts::Generate.new.run(ARGV)
|
data/script/txt2html
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
load File.dirname(__FILE__) + "/../Rakefile"
|
4
|
+
require 'rubyforge'
|
5
|
+
require 'redcloth'
|
6
|
+
require 'syntax/convertors/html'
|
7
|
+
require 'erb'
|
8
|
+
|
9
|
+
download = "http://rubyforge.org/projects/#{$hoe.rubyforge_name}"
|
10
|
+
version = $hoe.version
|
11
|
+
|
12
|
+
def rubyforge_project_id
|
13
|
+
RubyForge.new.configure.autoconfig["group_ids"][$hoe.rubyforge_name]
|
14
|
+
end
|
15
|
+
|
16
|
+
class Fixnum
|
17
|
+
def ordinal
|
18
|
+
# teens
|
19
|
+
return 'th' if (10..19).include?(self % 100)
|
20
|
+
# others
|
21
|
+
case self % 10
|
22
|
+
when 1: return 'st'
|
23
|
+
when 2: return 'nd'
|
24
|
+
when 3: return 'rd'
|
25
|
+
else return 'th'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Time
|
31
|
+
def pretty
|
32
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def convert_syntax(syntax, source)
|
37
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
38
|
+
end
|
39
|
+
|
40
|
+
if ARGV.length >= 1
|
41
|
+
src, template = ARGV
|
42
|
+
template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
|
43
|
+
else
|
44
|
+
puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
|
45
|
+
exit!
|
46
|
+
end
|
47
|
+
|
48
|
+
template = ERB.new(File.open(template).read)
|
49
|
+
|
50
|
+
title = nil
|
51
|
+
body = nil
|
52
|
+
File.open(src) do |fsrc|
|
53
|
+
title_text = fsrc.readline
|
54
|
+
body_text_template = fsrc.read
|
55
|
+
body_text = ERB.new(body_text_template).result(binding)
|
56
|
+
syntax_items = []
|
57
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
|
58
|
+
ident = syntax_items.length
|
59
|
+
element, syntax, source = $1, $2, $3
|
60
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
61
|
+
"syntax-temp-#{ident}"
|
62
|
+
}
|
63
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
64
|
+
body = RedCloth.new(body_text).to_html
|
65
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
66
|
+
end
|
67
|
+
stat = File.stat(src)
|
68
|
+
created = stat.ctime
|
69
|
+
modified = stat.mtime
|
70
|
+
|
71
|
+
$stdout << template.result(binding)
|
data/test/test_helper.rb
ADDED
data/website/index.html
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
4
|
+
<head>
|
5
|
+
<link rel="stylesheet" href="stylesheets/screen.css" type="text/css" media="screen" />
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
7
|
+
<title>
|
8
|
+
smartcall
|
9
|
+
</title>
|
10
|
+
<script src="javascripts/rounded_corners_lite.inc.js" type="text/javascript"></script>
|
11
|
+
<style>
|
12
|
+
|
13
|
+
</style>
|
14
|
+
<script type="text/javascript">
|
15
|
+
window.onload = function() {
|
16
|
+
settings = {
|
17
|
+
tl: { radius: 10 },
|
18
|
+
tr: { radius: 10 },
|
19
|
+
bl: { radius: 10 },
|
20
|
+
br: { radius: 10 },
|
21
|
+
antiAlias: true,
|
22
|
+
autoPad: true,
|
23
|
+
validTags: ["div"]
|
24
|
+
}
|
25
|
+
var versionBox = new curvyCorners(settings, document.getElementById("version"));
|
26
|
+
versionBox.applyCornersToAll();
|
27
|
+
}
|
28
|
+
</script>
|
29
|
+
</head>
|
30
|
+
<body>
|
31
|
+
<div id="main">
|
32
|
+
|
33
|
+
<h1>smartcall</h1>
|
34
|
+
<div class="sidebar">
|
35
|
+
<div id="version" class="clickable" onclick='document.location = "http://rubyforge.org/projects/smartcall"; return false'>
|
36
|
+
<p>Get Version</p>
|
37
|
+
<a href="http://rubyforge.org/projects/smartcall" class="numbers">0.0.1</a>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
<h2>What</h2>
|
41
|
+
<p>Gem to send text messages through Smartcall Technology Solutions (South African aggregator). http://www.smartcalltech.co.za</p>
|
42
|
+
<h2>Installing</h2>
|
43
|
+
<p><pre class='syntax'><span class="ident">sudo</span> <span class="ident">gem</span> <span class="ident">install</span> <span class="ident">smartcall</span></pre></p>
|
44
|
+
<h2>The basics</h2>
|
45
|
+
<p><pre class='syntax'>
|
46
|
+
|
47
|
+
<span class="ident">require</span> <span class="punct">'</span><span class="string">smartcall</span><span class="punct">'</span>
|
48
|
+
|
49
|
+
<span class="ident">api</span> <span class="punct">=</span> <span class="constant">Smartcall</span><span class="punct">::</span><span class="constant">API</span><span class="punct">.</span><span class="ident">new</span><span class="punct">(<</span><span class="constant">USERNAME</span><span class="punct">>,</span> <span class="punct"><</span><span class="constant">PASSWORD</span><span class="punct">>,</span> <span class="punct"><</span><span class="constant">CAMPAIGN_ID</span><span class="punct">>,</span> <span class="punct"><</span><span class="constant">REFERENCE</span><span class="punct">>)</span>
|
50
|
+
<span class="ident">api</span><span class="punct">.</span><span class="ident">send_message</span><span class="punct">("</span><span class="string">0825559629</span><span class="punct">",</span> <span class="punct">"</span><span class="string">Hello World</span><span class="punct">")</span>
|
51
|
+
</pre></p>
|
52
|
+
<h2>Forum</h2>
|
53
|
+
<p><a href="http://groups.google.com/group/smartcall">http://groups.google.com/group/smartcall</a></p>
|
54
|
+
<p><span class="caps">TODO</span> – create Google Group – smartcall</p>
|
55
|
+
<h2>How to submit patches</h2>
|
56
|
+
<p>Read the <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/">8 steps for fixing other people’s code</a> and for section <a href="http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups">8b: Submit patch to Google Groups</a>, use the Google Group above.</p>
|
57
|
+
<ul>
|
58
|
+
<li>github: <a href="http://github.com/agilisto/smartcall/tree/master">http://github.com/agilisto/smartcall/tree/master</a></li>
|
59
|
+
</ul>
|
60
|
+
<pre>git clone git://github.com/agilisto/smartcall.git</pre>
|
61
|
+
<h3>Build and test instructions</h3>
|
62
|
+
<pre>cd smartcall
|
63
|
+
rake test
|
64
|
+
rake install_gem</pre>
|
65
|
+
<h2>License</h2>
|
66
|
+
<p>This code is free to use under the terms of the <span class="caps">MIT</span> license.</p>
|
67
|
+
<h2>Contact</h2>
|
68
|
+
<p>Comments are welcome. Send an email to <a href="mailto:armanddp@agilisto.com">Armand du Plessis</a> email via the <a href="http://groups.google.com/group/smartcall">forum</a></p>
|
69
|
+
<p class="coda">
|
70
|
+
<a href="FIXME email">FIXME full name</a>, 1st July 2009<br>
|
71
|
+
Theme extended from <a href="http://rb2js.rubyforge.org/">Paul Battley</a>
|
72
|
+
</p>
|
73
|
+
</div>
|
74
|
+
|
75
|
+
<!-- insert site tracking codes here, like Google Urchin -->
|
76
|
+
|
77
|
+
</body>
|
78
|
+
</html>
|
data/website/index.txt
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
h1. smartcall
|
2
|
+
|
3
|
+
|
4
|
+
h2. What
|
5
|
+
|
6
|
+
Gem to send text messages through Smartcall Technology Solutions (South African aggregator). http://www.smartcalltech.co.za
|
7
|
+
|
8
|
+
h2. Installing
|
9
|
+
|
10
|
+
<pre syntax="ruby">sudo gem install smartcall</pre>
|
11
|
+
|
12
|
+
h2. The basics
|
13
|
+
|
14
|
+
<pre syntax="ruby">
|
15
|
+
|
16
|
+
require 'smartcall'
|
17
|
+
|
18
|
+
api = Smartcall::API.new(<USERNAME>, <PASSWORD>, <CAMPAIGN_ID>, <REFERENCE>)
|
19
|
+
api.send_message("0825559629", "Hello World")
|
20
|
+
</pre>
|
21
|
+
|
22
|
+
|
23
|
+
h2. Forum
|
24
|
+
|
25
|
+
"http://groups.google.com/group/smartcall":http://groups.google.com/group/smartcall
|
26
|
+
|
27
|
+
TODO - create Google Group - smartcall
|
28
|
+
|
29
|
+
h2. How to submit patches
|
30
|
+
|
31
|
+
Read the "8 steps for fixing other people's code":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/ and for section "8b: Submit patch to Google Groups":http://drnicwilliams.com/2007/06/01/8-steps-for-fixing-other-peoples-code/#8b-google-groups, use the Google Group above.
|
32
|
+
|
33
|
+
* github: "http://github.com/agilisto/smartcall/tree/master":http://github.com/agilisto/smartcall/tree/master
|
34
|
+
|
35
|
+
<pre>git clone git://github.com/agilisto/smartcall.git</pre>
|
36
|
+
|
37
|
+
|
38
|
+
h3. Build and test instructions
|
39
|
+
|
40
|
+
<pre>cd smartcall
|
41
|
+
rake test
|
42
|
+
rake install_gem</pre>
|
43
|
+
|
44
|
+
|
45
|
+
h2. License
|
46
|
+
|
47
|
+
This code is free to use under the terms of the MIT license.
|
48
|
+
|
49
|
+
h2. Contact
|
50
|
+
|
51
|
+
Comments are welcome. Send an email to "Armand du Plessis":mailto:armanddp@agilisto.com email via the "forum":http://groups.google.com/group/smartcall
|
52
|
+
|