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.
@@ -0,0 +1,9 @@
1
+ module Smartcall
2
+ module Soap
3
+ class SmartcallError < StandardError
4
+ def initialize(message)
5
+ super(message)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -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,6 @@
1
+ module Smartcall
2
+ module Utility
3
+ end
4
+ end
5
+
6
+ require File.join(File.dirname(__FILE__), *%w[utility/options])
@@ -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
@@ -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"
@@ -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)
@@ -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)
@@ -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)
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/smartcall'
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestSmartcall < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -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">(&lt;</span><span class="constant">USERNAME</span><span class="punct">&gt;,</span> <span class="punct">&lt;</span><span class="constant">PASSWORD</span><span class="punct">&gt;,</span> <span class="punct">&lt;</span><span class="constant">CAMPAIGN_ID</span><span class="punct">&gt;,</span> <span class="punct">&lt;</span><span class="constant">REFERENCE</span><span class="punct">&gt;)</span>
50
+ <span class="ident">api</span><span class="punct">.</span><span class="ident">send_message</span><span class="punct">(&quot;</span><span class="string">0825559629</span><span class="punct">&quot;,</span> <span class="punct">&quot;</span><span class="string">Hello World</span><span class="punct">&quot;)</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> &#8211; create Google Group &#8211; 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&#8217;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>
@@ -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
+