smsinabox 0.2.0

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,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