wire2air 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "rspec", "~> 2.3.0"
10
+ gem "yard", "~> 0.6.0"
11
+ gem "bundler", "~> 1.0.0"
12
+ gem "jeweler", "~> 1.6.4"
13
+ gem "rcov", ">= 0"
14
+ end
15
+
16
+ group :test do
17
+ gem "trollop"
18
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.6.4)
7
+ bundler (~> 1.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ rake (0.9.2)
11
+ rcov (0.9.10)
12
+ rspec (2.3.0)
13
+ rspec-core (~> 2.3.0)
14
+ rspec-expectations (~> 2.3.0)
15
+ rspec-mocks (~> 2.3.0)
16
+ rspec-core (2.3.1)
17
+ rspec-expectations (2.3.0)
18
+ diff-lcs (~> 1.1.2)
19
+ rspec-mocks (2.3.0)
20
+ trollop (1.16.2)
21
+ yard (0.6.8)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ bundler (~> 1.0.0)
28
+ jeweler (~> 1.6.4)
29
+ rcov
30
+ rspec (~> 2.3.0)
31
+ trollop
32
+ yard (~> 0.6.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 David Miani
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,20 @@
1
+ = Wire2Air
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to wire2air:w
6
+
7
+
8
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
9
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
10
+ * Fork the project
11
+ * Start a feature/bugfix branch
12
+ * Commit and push until you are happy with your contribution
13
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
14
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2011 wire2air. See LICENSE.txt for
19
+ further details.
20
+
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "wire2air"
18
+ gem.homepage = "http://github.com/nanothief/wire2air"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Ruby interface to the wire2air sms and voice mail service}
21
+ gem.description = %Q{Allows sending sms and voice messages, checking and adding more credits, subscribing to keywords}
22
+ gem.email = "davidmiani@gmail.com"
23
+ gem.authors = ["David Miani"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'yard'
42
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/wire2air.rb ADDED
@@ -0,0 +1,226 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+
4
+ # Class for interacting with the TxtImpact sms sending and receiving service.
5
+ # Example usage:
6
+ # connection = TxtImpact.new(:username => 'your_username',
7
+ # :password => 'your password',
8
+ # :profile_id => 42,
9
+ # :short_code => 1111,
10
+ # :vasid => 12345)
11
+ # connection.send_sms()
12
+ class Wire2Air
13
+
14
+
15
+ class FailedAuthenticationError < StandardError; end
16
+ class NotEnoughCreditsError < StandardError; end
17
+ class KeywordIsTakenError < StandardError; end
18
+ class AccountUpdateError < StandardError; end
19
+ class CreditCardDeclinedError < StandardError; end
20
+
21
+
22
+ class JobId
23
+ def initialize(mobile_number, sms_id)
24
+ @mobile_number, @sms_id = mobile_number, sms_id
25
+ end
26
+ attr_reader :mobile_number, :sms_id
27
+ def self.from_s(str)
28
+ matches = str.match /^JOBID: (\d+):(\d+)/
29
+ JobId.new(matches[1], matches[2])
30
+ end
31
+ end
32
+
33
+
34
+ # Initializes a TxtImpact object with the common profile info needed
35
+ # for making connections.
36
+ # @param [Hash] opts The profile connection options
37
+ # @option opts [String] :username The user name to connect as
38
+ # @option opts [String] :password The password (in plain text) for connecting
39
+ # @option opts [Integer] :profile_id The id of the profile
40
+ # @options opts [Integer] :short_code The short code for the account
41
+ # @options opts [Integer] :vasid The vasid of the account
42
+ def initialize(opts)
43
+ valid_keys =[:username, :password, :profile_id, :short_code, :vasid]
44
+ if opts.keys.sort != valid_keys.sort
45
+ puts opts.keys
46
+ raise ArgumentError.new "The options must only have the keys #{valid_keys}"
47
+ end
48
+
49
+ opts.each do |key, value|
50
+ instance_variable_set("@#{key}", value)
51
+ end
52
+
53
+ end
54
+
55
+ attr_reader :username, :password, :vasid, :profile_id, :short_code
56
+
57
+ alias :userid :username
58
+
59
+ public
60
+ # sends an sms
61
+ # @param [String, Array<String>] to_number DESTINATION MOBILE NUMBER. [(country
62
+ # code) + mobile number] e.g 17321234567 (for
63
+ # US), 919810601000 (for India)
64
+ # @param [String] text The message text
65
+ # @param [String] batch_reference If sending to multiple numbers, is used to identify
66
+ # the send request used in reports
67
+ # @return [JobId, Integer] If a single sms is being sent, a JobId is returned. Otherwise
68
+ # an Integer for the BatchID is returned.
69
+ # @raise NotEnoughError Not enough credits to send the sms
70
+ # @raise FailedAuthenticationError some authentication details are wrong
71
+ def send_sms(to_number, text, batch_reference = "batched send")
72
+ params = common_options
73
+ params['VERSION'] = '2.0'
74
+ params['FROM'] = short_code
75
+ params['TEXT'] = text
76
+
77
+ batch_send = !(to_number.is_a? String)
78
+
79
+ if !batch_send
80
+ params['TO'] = to_number
81
+ else
82
+ params['TO'] = to_number.join(',')
83
+ params['BATCHNAME'] = batch_reference
84
+ end
85
+
86
+ p params
87
+
88
+ url = URI.parse('http://smsapi.wire2air.com/smsadmin/submitsm.aspx')
89
+ res = Net::HTTP.post_form(url, params).body
90
+ case res
91
+ when /^ERR: 301/
92
+ raise FailedAuthenticationError
93
+ when /^ERR: 305/
94
+ raise NotEnoughCreditsError
95
+ end
96
+ if (batch_send)
97
+ res.match(/BATCHID: \d+/)[1]
98
+ else
99
+ puts res
100
+ JobId.from_s(res)
101
+ end
102
+ end
103
+
104
+ # Adds some credits to the account
105
+ # @param [Integer] keyword_credits The number of credits to add
106
+ # @return [void]
107
+ def subscribe_credits(keyword_credits = 1)
108
+ url = URI.parse('http://mzone.wire2air.com/mserver/api/subscribekeywords.aspx')
109
+ res = Net::HTTP.post_form(url, {
110
+ 'USERID' => userid,
111
+ 'PASSWORD' => password,
112
+ 'KEYWORDREDITS' => keyword_credits
113
+
114
+ })
115
+ case res.body
116
+ when /^Err:70[34]/
117
+ raise ArgumentError.new "Missing username or password"
118
+ when /^Err:705/
119
+ raise KeywordIsTakenError
120
+ when /^Err:300/
121
+ raise FailedAuthenticationError
122
+ when /^Err:715/
123
+ raise AccountUpdateError
124
+ when /^Err:716/
125
+ raise CreditCardDeclinedError
126
+ end
127
+
128
+ end
129
+
130
+ # returns the number of credits available
131
+ # @return Integer the number of credits available
132
+ def credit_count
133
+ url = URI.parse('http://smsapi.wire2air.com/smsadmin/checksmscredits.aspx')
134
+ res = Net::HTTP.post_form(url, {
135
+ 'USERID' => userid,
136
+ 'PASSWORD' => password,
137
+ 'VASID' => vasid
138
+ }).body
139
+ raise FailedAuthenticationError if res =~ /ERR: 301/
140
+ res.to_i
141
+ end
142
+
143
+ # Checks whether the keyword can be registered.
144
+ # @return Boolean true if the keyword is available
145
+ def is_keyword_available?(keyword)
146
+ url = URI.parse('http://mzone.wire2air.com/shortcodemanager/api/checkkeywordapi.aspx')
147
+ response = Net::HTTP.post_form(url, {
148
+ 'USERID' => userid,
149
+ 'PASSWORD' => password,
150
+ 'VASID' => vasid,
151
+ 'SHORTCODEID' => short_code,
152
+ 'KEYWORD' => keyword
153
+ })
154
+
155
+ response.body.include? "Err:0:"
156
+
157
+
158
+ end
159
+
160
+
161
+ # registers a keyword
162
+ # @param opts Options for creating the keyword
163
+ # @option opts [String] :service_name Service name for the keyword
164
+ # @option opts [String] :keyword
165
+ # @option opts [String] :processor_url The url of the webserice
166
+ # @option opts [String] :help_msg Response for help message
167
+ # @option opts [String] :stop_msg Responce for opt-out message
168
+ # @return [Integer] The service id
169
+ # @raise ArgumentError If arguments are missing/invalid
170
+ # @raise KeywordIsTakenError
171
+ def register_keyword(opts)
172
+ url = URI.parse('http://mzone.wire2air.com/shortcodemanager/api/RegisterKeywordAPI.aspx')
173
+ params = common_options
174
+ params['SHORTCODEID'] = short_code
175
+ params['SERVICENAME'] = opts[:service_name]
176
+ params['KEYWORD'] = opts[:keyword]
177
+ params['PROCESSORURL'] = opts[:processor_url]
178
+ params['HELPMSG'] = opts[:help_msg]
179
+ params['STOPMSG'] = opts[:stop_msg]
180
+ params['ACTION'] = 'ADD'
181
+
182
+ res = Net::HTTP.post_form(url, params).body
183
+
184
+ case res
185
+ when /Err:70[012346789]/, /Err:71[0134]/
186
+ raise ArgumentError.new res
187
+ when /Err:705/
188
+ raise KeywordIsTakenError
189
+ when /Err:712/
190
+ raise "Sticky session is not allowed"
191
+ end
192
+
193
+ res.match(/SERVICEID:(\d+)/)[1].to_i
194
+
195
+ end
196
+
197
+ # deletes a service created with register_keyword.
198
+ # @param [Integer] service_id The id of the service to delete
199
+ # @param [String] keyword the keyword for the service
200
+ def delete_service(service_id, keyword)
201
+ url = URI.parse('http://mzone.wire2air.com/shortcodemanager/api/RegisterKeywordAPI.aspx')
202
+ params = common_options
203
+ params.delete 'PROFILEID'
204
+ params['SHORTCODEID'] = short_code
205
+ params['SERVICEID'] = service_id.to_s
206
+ params['KEYWORD'] = keyword
207
+ params['ACTION'] = 'DELETE'
208
+ p params
209
+ res = Net::HTTP.post_form(url, params)
210
+ raise StandardError.new res.body unless res.body.start_with? "SERVICEID"
211
+ end
212
+
213
+ private
214
+ def common_options
215
+ { 'USERID' => username,
216
+ 'PASSWORD' => password,
217
+ 'VASID' => vasid,
218
+ 'PROFILEID' => profile_id,
219
+ }
220
+
221
+ end
222
+
223
+
224
+ end
225
+
226
+
data/manual_tests.rb ADDED
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require 'bundler/setup'
5
+ require 'trollop'
6
+ require './lib/wire2air'
7
+ require 'rspec'
8
+
9
+
10
+ def prompt(string)
11
+ STDOUT.sync = true
12
+ print string
13
+ res = gets
14
+ STDOUT.sync = false
15
+ res
16
+ end
17
+
18
+ def true_false_prompt(string)
19
+ res = prompt(string + "(y/n)")
20
+ res[0].downcase != "n"
21
+ end
22
+
23
+ def fail_with_message(msg)
24
+ puts msg
25
+ exit 1
26
+ end
27
+
28
+ def test_section(section_name)
29
+ puts "testing #{section_name}"
30
+ res = yield
31
+ if res
32
+ puts "#{section_name} working correctly"
33
+ else
34
+ puts "FAILED: #{section_name}"
35
+ exit 1
36
+ end
37
+ end
38
+
39
+ opts = Trollop::options do
40
+ opt :username, "The username to log in as", :type => :string, :required => true
41
+ opt :password, "The password to log in as", :type => :string, :required => true
42
+ opt :profile_id, "The profile_id to log in as", :type => :string, :required => true
43
+ opt :short_code, "The short_code to log in as", :type => :string, :required => true
44
+ opt :vasid, "The vasid to log in as", :type => :string, :required => true
45
+ opt :test_number, "The mobile number to test with", :type => :string, :required => true
46
+
47
+ opt :dont_test_sending_sms, "Prevent the sending of sms from being tested"
48
+ end
49
+
50
+
51
+
52
+ connection_opts = opts.dup
53
+
54
+ connection_opts = { :username => opts[:username], :password => opts[:password],
55
+ :profile_id => opts[:profile_id], :short_code => opts[:short_code],
56
+ :vasid => opts[:vasid]
57
+ }
58
+ connection = Wire2Air.new connection_opts
59
+
60
+ describe "sms api" do
61
+ unless opts[:dont_test_sending_sms]
62
+ it "should send a single sms message" do
63
+ msg = "test message #{Time.now}"
64
+ puts connection.send_sms(opts[:test_number], msg)
65
+
66
+ true_false_prompt("Did a message with the text '#{msg}' get sent?").should be_true
67
+ end
68
+ end
69
+
70
+
71
+ it 'can add more credits to the account' do
72
+ current_credits = prompt "Enter the number of available credits currently: "
73
+
74
+ puts connection.subscribe_credits(4)
75
+ true_false_prompt("Are there now #{current_credits.to_i + 4} credits available?").should be_true
76
+ end
77
+
78
+ it 'can find if a keyword is available' do
79
+ connection.is_keyword_available?("testing_keyword_34551").should be_true
80
+ end
81
+
82
+ it "can register a keyword and unregister a keyword" do
83
+ service_name = "A service name"
84
+ service_keyword = 'testing_keyword'
85
+ service_id = connection.register_keyword(
86
+ :service_name => service_name,
87
+ :keyword => service_keyword,
88
+ :processor_url => 'http://example.com/processor',
89
+ :help_msg => "help message",
90
+ :stop_msg => "stop message"
91
+ )
92
+
93
+ true_false_prompt("Did a new service get registered with name '#{service_name}'").should be_true
94
+ connection.delete_service(service_id, service_keyword)
95
+ true_false_prompt("Did the service '#{service_name}' get deleted?").should be_true
96
+
97
+
98
+ end
99
+ end
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'txtimpact_sms'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "TxtimpactSms" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
data/wire2air.gemspec ADDED
@@ -0,0 +1,64 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{wire2air}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = [%q{David Miani}]
12
+ s.date = %q{2011-08-20}
13
+ s.description = %q{Allows sending sms and voice messages, checking and adding more credits, subscribing to keywords}
14
+ s.email = %q{davidmiani@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/wire2air.rb",
29
+ "manual_tests.rb",
30
+ "spec/spec_helper.rb",
31
+ "spec/txtimpact_sms_spec.rb",
32
+ "wire2air.gemspec"
33
+ ]
34
+ s.homepage = %q{http://github.com/nanothief/wire2air}
35
+ s.licenses = [%q{MIT}]
36
+ s.require_paths = [%q{lib}]
37
+ s.rubygems_version = %q{1.8.8}
38
+ s.summary = %q{Ruby interface to the wire2air sms and voice mail service}
39
+
40
+ if s.respond_to? :specification_version then
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
45
+ s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
46
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
47
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
48
+ s.add_development_dependency(%q<rcov>, [">= 0"])
49
+ else
50
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
51
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
52
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
53
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
54
+ s.add_dependency(%q<rcov>, [">= 0"])
55
+ end
56
+ else
57
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
58
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
59
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
60
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
61
+ s.add_dependency(%q<rcov>, [">= 0"])
62
+ end
63
+ end
64
+
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wire2air
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - David Miani
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-20 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &2165590560 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.3.0
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *2165590560
25
+ - !ruby/object:Gem::Dependency
26
+ name: yard
27
+ requirement: &2165590080 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.6.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2165590080
36
+ - !ruby/object:Gem::Dependency
37
+ name: bundler
38
+ requirement: &2165589600 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.0.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *2165589600
47
+ - !ruby/object:Gem::Dependency
48
+ name: jeweler
49
+ requirement: &2165589120 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.4
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *2165589120
58
+ - !ruby/object:Gem::Dependency
59
+ name: rcov
60
+ requirement: &2165588640 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *2165588640
69
+ description: Allows sending sms and voice messages, checking and adding more credits,
70
+ subscribing to keywords
71
+ email: davidmiani@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files:
75
+ - LICENSE.txt
76
+ - README.rdoc
77
+ files:
78
+ - .document
79
+ - .rspec
80
+ - Gemfile
81
+ - Gemfile.lock
82
+ - LICENSE.txt
83
+ - README.rdoc
84
+ - Rakefile
85
+ - VERSION
86
+ - lib/wire2air.rb
87
+ - manual_tests.rb
88
+ - spec/spec_helper.rb
89
+ - spec/txtimpact_sms_spec.rb
90
+ - wire2air.gemspec
91
+ homepage: http://github.com/nanothief/wire2air
92
+ licenses:
93
+ - MIT
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 1.8.8
113
+ signing_key:
114
+ specification_version: 3
115
+ summary: Ruby interface to the wire2air sms and voice mail service
116
+ test_files: []