agilisto-smartcall 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+