smsinabox 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
1
+ module Smsinabox
2
+ class DeliveryReport
3
+
4
+ class << self
5
+
6
+ # Generate a delivery report from a nokogiri response
7
+ def from_response( nokogiri_xml )
8
+ response = new
9
+
10
+ # basic send_info stuff
11
+ response.event_id = nokogiri_xml.xpath('/api_result/send_info/eventid/text()').to_s.to_i
12
+ response.credits = nokogiri_xml.xpath('/api_result/send_info/credits/text()').to_s.to_i
13
+ response.fail_count = nokogiri_xml.xpath('/api_result/send_info/msgs_failed/text()').to_s.to_i
14
+ response.success_count = nokogiri_xml.xpath('/api_result/send_info/msgs_success/text()').to_s.to_i
15
+
16
+ # failures
17
+ nokogiri_xml.xpath('/api_result/entries_failed').each do |node|
18
+ response.failures << {
19
+ :numto => node.xpath('./numto/text()').to_s,
20
+ :customerid => node.xpath('./customerid/text()').to_s,
21
+ :reason => node.xpath('./reason/text()').to_s
22
+ }
23
+ end
24
+
25
+ # successes
26
+ nokogiri_xml.xpath('/api_result/entries_success').each do |node|
27
+ response.successes << {
28
+ :numto => node.xpath('./numto/text()').to_s,
29
+ :customerid => node.xpath('./customerid/text()').to_s
30
+ }
31
+ end
32
+
33
+ response
34
+ end
35
+
36
+ end
37
+
38
+ attr_accessor :event_id, :credits, :fail_count, :success_count, :failures, :successes
39
+
40
+ def initialize
41
+ @fail_count = 0
42
+ @success_count = 0
43
+
44
+ @failures = []
45
+ @successes = []
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,9 @@
1
+ module Smsinabox
2
+
3
+ class MissingCredentialException < Exception
4
+ end
5
+
6
+ class MessageInvalid < Exception
7
+ end
8
+
9
+ end
@@ -0,0 +1,21 @@
1
+ module Smsinabox
2
+
3
+ class Message
4
+
5
+ attr_accessor :recipient
6
+ attr_accessor :body
7
+
8
+ def initialize( options = {} )
9
+ @recipient = options.delete(:recipient)
10
+ @body = options.delete(:body)
11
+ end
12
+
13
+ def valid?
14
+ !( @recipient.nil? || @body.nil? )
15
+ end
16
+
17
+ def body
18
+ @body.gsub( /\n/, '|' )
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ module Smsinabox
2
+ class Reply
3
+
4
+ class << self
5
+
6
+ # Generate a reply from the nokogiri response fragment
7
+ def from_response( nokogiri_xml )
8
+ reply = new
9
+
10
+ reply.id = nokogiri_xml.xpath('./replyid/text()').to_s.to_i
11
+ reply.event_id = nokogiri_xml.xpath('./eventid/text()').to_s.to_i
12
+ reply.from = nokogiri_xml.xpath('./numfrom/text()').to_s
13
+ reply.message = nokogiri_xml.xpath('./receiveddata/text()').to_s
14
+ reply.sent_id = nokogiri_xml.xpath('./sentid/text()').to_s.to_i
15
+ reply.original = nokogiri_xml.xpath('./sentdata/text()').to_s
16
+ reply.sent_customer_id = nokogiri_xml.xpath('./sentcustomerid/text()').to_s
17
+ reply.received = nokogiri_xml.xpath('./received/text()').to_s
18
+ reply.sent = nokogiri_xml.xpath('./sentdatetime/text()').to_s
19
+
20
+ reply
21
+ end
22
+ end
23
+
24
+ attr_accessor :id, :event_id, :from, :message, :sent_id, :original,
25
+ :sent_customer_id, :received, :sent
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ module Smsinabox
2
+ class SentMessage
3
+
4
+ class << self
5
+
6
+ # Generate a #SentMessage from a response xml fragment
7
+ def from_response( nokogiri_xml )
8
+ msg = new
9
+
10
+ msg.id = nokogiri_xml.xpath('./sentid/text()').to_s.to_i
11
+ msg.change_id = nokogiri_xml.xpath('./changeid/text()').to_s.to_i
12
+ msg.event_id = nokogiri_xml.xpath('./eventid/text()').to_s.to_i
13
+ msg.type = nokogiri_xml.xpath('./smstype/text()').to_s
14
+ msg.to = nokogiri_xml.xpath('./numto/text()').to_s
15
+ msg.message = nokogiri_xml.xpath('./data/text()').to_s
16
+ msg.flash = nokogiri_xml.xpath('./flash/text()').to_s == 'true'
17
+ msg.customer_id = nokogiri_xml.xpath('./customerid/text()').to_s
18
+ msg.status = nokogiri_xml.xpath('./status/text()').to_s
19
+ msg.status_date = nokogiri_xml.xpath('./statusdate/text()').to_s
20
+
21
+ msg
22
+ end
23
+ end
24
+
25
+ attr_accessor :id, :change_id, :event_id, :type, :to, :message, :flash,
26
+ :customer_id, :status, :status_date
27
+
28
+ def delivered?
29
+ @status == 'DELIVRD'
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,4 @@
1
+ module Smsinabox
2
+ class SMS < Message
3
+ end
4
+ 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/smsinabox.rb'}"
9
+ puts "Loading smsinabox 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,101 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{smsinabox}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["kenneth.kalmer@gmail.com"]
12
+ s.date = %q{2010-06-18}
13
+ s.description = %q{Ruby API for sending text messages via http://www.smsinabox.co.za}
14
+ s.email = %q{kenneth.kalmer@gmail.com}
15
+ s.executables = ["sms-credit", "sms-send", "sms-setup"]
16
+ s.extra_rdoc_files = [
17
+ "History.txt",
18
+ "PostInstall.txt",
19
+ "README.rdoc",
20
+ "TODO.txt"
21
+ ]
22
+ s.files = [
23
+ ".gitignore",
24
+ "History.txt",
25
+ "PostInstall.txt",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "TODO.txt",
29
+ "bin/sms-credit",
30
+ "bin/sms-send",
31
+ "bin/sms-setup",
32
+ "lib/smsinabox.rb",
33
+ "lib/smsinabox/configuration.rb",
34
+ "lib/smsinabox/delivery_report.rb",
35
+ "lib/smsinabox/exceptions.rb",
36
+ "lib/smsinabox/message.rb",
37
+ "lib/smsinabox/reply.rb",
38
+ "lib/smsinabox/sent_message.rb",
39
+ "lib/smsinabox/sms.rb",
40
+ "script/console",
41
+ "script/destroy",
42
+ "script/generate",
43
+ "smsinabox.gemspec",
44
+ "spec/delivery_report_spec.rb",
45
+ "spec/fixtures/sendparam_response.xml",
46
+ "spec/message_spec.rb",
47
+ "spec/reply_spec.rb",
48
+ "spec/sent_message_spec.rb",
49
+ "spec/smsinabox_spec.rb",
50
+ "spec/spec.opts",
51
+ "spec/spec_helper.rb",
52
+ "tasks/deployment.rake",
53
+ "tasks/environment.rake",
54
+ "tasks/rspec.rake",
55
+ "tasks/website.rake"
56
+ ]
57
+ s.homepage = %q{http://github.com/kennethkalmer/smsinabox}
58
+ s.post_install_message = %q{
59
+ For more information on smsinabox, see http://www.opensourcery.co.za/smsinabox
60
+
61
+ Setup your account by running sms-setup now. You can then use the following
62
+ commands to interact with SMS in a Box:
63
+
64
+ sms-send: Send SMS messages
65
+ sms-credit: Quick overview of the credit available
66
+ sms-replies: Quick access to your replies
67
+ sms-setup: To change the account details
68
+ }
69
+ s.rdoc_options = ["--charset=UTF-8"]
70
+ s.require_paths = ["lib"]
71
+ s.rubygems_version = %q{1.3.5}
72
+ s.summary = %q{Ruby API for sending text messages via http://www.smsinabox.co.za}
73
+ s.test_files = [
74
+ "spec/delivery_report_spec.rb",
75
+ "spec/message_spec.rb",
76
+ "spec/reply_spec.rb",
77
+ "spec/sent_message_spec.rb",
78
+ "spec/smsinabox_spec.rb",
79
+ "spec/spec_helper.rb"
80
+ ]
81
+
82
+ if s.respond_to? :specification_version then
83
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
84
+ s.specification_version = 3
85
+
86
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
87
+ s.add_runtime_dependency(%q<nokogiri>, [">= 1.3.3"])
88
+ s.add_development_dependency(%q<rspec>, [">= 0"])
89
+ s.add_development_dependency(%q<cucumber>, [">= 0"])
90
+ else
91
+ s.add_dependency(%q<nokogiri>, [">= 1.3.3"])
92
+ s.add_dependency(%q<rspec>, [">= 0"])
93
+ s.add_dependency(%q<cucumber>, [">= 0"])
94
+ end
95
+ else
96
+ s.add_dependency(%q<nokogiri>, [">= 1.3.3"])
97
+ s.add_dependency(%q<rspec>, [">= 0"])
98
+ s.add_dependency(%q<cucumber>, [">= 0"])
99
+ end
100
+ end
101
+
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Smsinabox::DeliveryReport do
4
+ before(:each) do
5
+ f = File.open( File.dirname(__FILE__) + '/fixtures/sendparam_response.xml' )
6
+ sample_response = Nokogiri::XML( f )
7
+
8
+ @report = Smsinabox::DeliveryReport.from_response( sample_response )
9
+ end
10
+
11
+ it "should have an event id" do
12
+ @report.event_id.should be(27105067)
13
+ end
14
+
15
+ it "should have credits" do
16
+ @report.credits.should be(39763)
17
+ end
18
+
19
+ it "should know how many failed" do
20
+ @report.fail_count.should be(1)
21
+ end
22
+
23
+ it "should know how many succeeded" do
24
+ @report.success_count.should be(3)
25
+ end
26
+
27
+ it "should have a list of failures" do
28
+ @report.failures.should_not be_empty
29
+
30
+ f = @report.failures.first
31
+ f.should == { :numto => '', :customerid => '', :reason => 'numto invalid' }
32
+ end
33
+
34
+ it "should have a list of successes" do
35
+ @report.successes.should_not be_empty
36
+
37
+ s = @report.successes.first
38
+ s.should == { :numto => '27832297941', :customerid => 'UnqiueValue1' }
39
+ end
40
+ end
@@ -0,0 +1,29 @@
1
+ <api_result>
2
+ <entries_failed>
3
+ <numto />
4
+ <customerid />
5
+ <reason>numto invalid</reason>
6
+ </entries_failed>
7
+ <entries_success>
8
+ <numto>27832297941</numto>
9
+ <customerid>UnqiueValue1</customerid>
10
+ </entries_success>
11
+ <entries_success>
12
+ <numto>27832297941</numto>
13
+ <customerid>UnqiueValue1</customerid>
14
+ </entries_success>
15
+ <entries_success>
16
+ <numto>27832297941</numto>
17
+ <customerid>d47e1efd-5e4f-4832-ba7f-07f35d8c10f9</customerid>
18
+ </entries_success>
19
+ <send_info>
20
+ <eventid>27105067</eventid>
21
+ <credits>39763</credits>
22
+ <msgs_success>3</msgs_success>
23
+ <msgs_failed>1</msgs_failed>
24
+ </send_info>
25
+ <call_result>
26
+ <result>True</result>
27
+ <error />
28
+ </call_result>
29
+ </api_result>
@@ -0,0 +1,47 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Smsinabox::Message do
4
+
5
+ it "should accept a recipient" do
6
+ message = Smsinabox::Message.new( :recipient => '5555555555' )
7
+ message.recipient.should eql('5555555555')
8
+
9
+ message = Smsinabox::Message.new
10
+ message.recipient = '5555555555'
11
+ message.recipient.should eql('5555555555')
12
+ end
13
+
14
+ it "should accept a body" do
15
+ message = Smsinabox::Message.new( :body => 'text' )
16
+ message.body.should eql('text')
17
+
18
+ message = Smsinabox::Message.new
19
+ message.body = 'text'
20
+ message.body.should eql('text')
21
+ end
22
+
23
+ it "should only be valid if both the recipient and body is set" do
24
+ message = Smsinabox::Message.new
25
+ message.should_not be_valid
26
+
27
+ message.recipient = '5555555555'
28
+ message.should_not be_valid
29
+
30
+ message.body = 'text'
31
+ message.should be_valid
32
+
33
+ message.recipient = nil
34
+ message.should_not be_valid
35
+ end
36
+
37
+ it "should replace newlines with pipe (|) characters" do
38
+ message = Smsinabox::Message.new
39
+ message.body = <<-EOF
40
+ This
41
+ needs
42
+ pipes
43
+ EOF
44
+
45
+ message.body.should match( /This|\s+needs|\s+pipes/ )
46
+ end
47
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe Smsinabox::Reply do
4
+ before(:each) do
5
+ xml = <<-EOF
6
+ <api_result>
7
+ <data>
8
+ <replyid>3903103</replyid>
9
+ <eventid>33368123</eventid>
10
+ <numfrom>27123456789</numfrom>
11
+ <receiveddata>Bar</receiveddata>
12
+ <sentid>339548269</sentid>
13
+ <sentdata>Foo</sentdata>
14
+ <sentcustomerid/>
15
+ <received>10/Aug/2009 00:09:46</received>
16
+ <sentdatetime>07/Aug/2009 13:51:48</sentdatetime>
17
+ </data>
18
+ </api_result>
19
+ EOF
20
+ @xml_reply = Nokogiri::XML( xml )
21
+ end
22
+
23
+ it "should parse from response data" do
24
+ reply = Smsinabox::Reply.from_response( @xml_reply.xpath('/api_result/data').first )
25
+
26
+ reply.id.should == 3903103
27
+ reply.event_id.should == 33368123
28
+ reply.from.should == '27123456789'
29
+ reply.message.should == 'Bar'
30
+ reply.sent_id.should == 339548269
31
+ reply.original.should == 'Foo'
32
+ reply.sent_customer_id.should == ''
33
+ reply.received.should == '10/Aug/2009 00:09:46'
34
+ reply.sent.should == '07/Aug/2009 13:51:48'
35
+ end
36
+ end