smesser 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +79 -0
- data/Rakefile +11 -0
- data/bin/smesser +76 -0
- data/lib/smesser/provider.rb +81 -0
- data/lib/smesser/version.rb +3 -0
- data/lib/smesser.rb +116 -0
- data/providers/o2_ie.rb +50 -0
- data/providers/vodafone_ie.rb +65 -0
- data/smesser.gemspec +19 -0
- data/test/test_smesser.rb +16 -0
- metadata +90 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 JJ Buckley
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
# SMeSser
|
2
|
+
|
3
|
+
For using your provider's WebText programatically.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'smesser'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install smesser
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Smesser is generally supposed to be used as part of a more useful application,
|
22
|
+
for sending (free!) SMSs.
|
23
|
+
|
24
|
+
It does, however, come with a little command-line application (`smesser`). Try
|
25
|
+
`smesser -h` when it's installed.
|
26
|
+
|
27
|
+
## Configuration
|
28
|
+
|
29
|
+
You can program Smesser programatically, but it will also
|
30
|
+
have a look for some configuration files, and determine the
|
31
|
+
username/password/provider from there. These config files are loaded, in order,
|
32
|
+
if they exist:
|
33
|
+
|
34
|
+
* /etc/smesserrc
|
35
|
+
* /usr/local/etc/smesserrc
|
36
|
+
* ~/.smesserrc
|
37
|
+
|
38
|
+
*HINT*: If you're a command-line type of person (which I presume yuo are, as
|
39
|
+
you're reading this), then add a "contacts" hash to your configuration file.
|
40
|
+
These can be used as aliases instead of phone number.
|
41
|
+
|
42
|
+
Here's a sample configuration file, which you'd keep as ~/.smesserrc
|
43
|
+
|
44
|
+
```yaml
|
45
|
+
provider: o2.ie
|
46
|
+
username: "0861234567" # <-- Ensure a string, or the leading 0 could vanish!
|
47
|
+
password: secret
|
48
|
+
contacts:
|
49
|
+
mom: "+3538712345678"
|
50
|
+
dad: "+1123456788"
|
51
|
+
lisa: "08517171717"
|
52
|
+
```
|
53
|
+
|
54
|
+
## Providers
|
55
|
+
|
56
|
+
The core of Smesser is done by little [Mechanize][mechanize] agents, called
|
57
|
+
Providers, that know how to log in (as you) to a specific website, fill in a
|
58
|
+
form, and submit it.
|
59
|
+
|
60
|
+
The only requirements for a Provider is that it responds to `login` and `send`.
|
61
|
+
By subclassing Smesser::Provider, you get a couple of convenience methods to
|
62
|
+
help you create your own.
|
63
|
+
|
64
|
+
Have a look at bundled providers for info on how to write your own provider.
|
65
|
+
|
66
|
+
Currently, there's
|
67
|
+
|
68
|
+
* vodafone.ie
|
69
|
+
* o2.ie
|
70
|
+
|
71
|
+
## Contributing
|
72
|
+
|
73
|
+
1. Fork it
|
74
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
75
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
76
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
77
|
+
5. Create new Pull Request
|
78
|
+
|
79
|
+
[mechanize]: http://mechanize.rubyforge.org/
|
data/Rakefile
ADDED
data/bin/smesser
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../lib/smesser'))
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
$options = {}
|
6
|
+
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: smesser [options]"
|
9
|
+
|
10
|
+
opts.on('-c', '--config FILE', String, 'Use a specific config file') do |f|
|
11
|
+
if File.exists?
|
12
|
+
Smesser.config_files << f
|
13
|
+
else
|
14
|
+
puts "Can't open file #{f}"
|
15
|
+
exit 3
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
opts.on('-m', '--message MESSAGE', String, 'Your message. If blank, reads from STDIN.') do |m|
|
20
|
+
$options[:message] = m
|
21
|
+
end
|
22
|
+
|
23
|
+
opts.on('-P', '--provider PROVIDER', String, 'Choose a provider (list with --list)') do |p|
|
24
|
+
$options[:provider] = p
|
25
|
+
end
|
26
|
+
|
27
|
+
opts.on('-u', '--username USERNAME', String, 'Specify a username to log in with') do |u|
|
28
|
+
$options[:username] = u
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on('-p', '--password PASSWORD', String, 'Specify a password to log in with') do |p|
|
32
|
+
$options[:password] = p
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on('-L', '--list', 'Show all known providers, and exit') do
|
36
|
+
Smesser.print_providers
|
37
|
+
exit
|
38
|
+
end
|
39
|
+
|
40
|
+
opts.on('-v', '--verbose', 'Be more verbose') do
|
41
|
+
Smesser.log.level = Logger::INFO
|
42
|
+
end
|
43
|
+
|
44
|
+
opts.on('-d', '--debug', 'Debug the application') do
|
45
|
+
Smesser.log.level = Logger::DEBUG
|
46
|
+
end
|
47
|
+
|
48
|
+
opts.on('-n', '--dry-run', "Don't actually send the message") do
|
49
|
+
Smesser.configuration[:dryrun] = true
|
50
|
+
end
|
51
|
+
|
52
|
+
opts.on_tail('-h', '--help', 'Show this message') do
|
53
|
+
puts opts.to_s
|
54
|
+
exit
|
55
|
+
end
|
56
|
+
end.parse!(ARGV)
|
57
|
+
|
58
|
+
if ARGV.empty?
|
59
|
+
puts "You didn't enter any recipients!"
|
60
|
+
exit 1
|
61
|
+
end
|
62
|
+
$options[:recipients] = []
|
63
|
+
$options[:recipients] << ARGV.shift until ARGV.empty?
|
64
|
+
|
65
|
+
if $options[:message].nil?
|
66
|
+
print "Type your message below, and finish with ^D:\n> "
|
67
|
+
$options[:message] = ARGF.read.chomp
|
68
|
+
end
|
69
|
+
|
70
|
+
print "Sending... "
|
71
|
+
result = Smesser.send_message($options)
|
72
|
+
|
73
|
+
puts "#{result[:remaining]} remaining" if result[:remaining]
|
74
|
+
puts result[:message] if result[:message]
|
75
|
+
puts result[:status]
|
76
|
+
exit -1 unless result[:status] == "OK"
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'mechanize'
|
2
|
+
require 'smesser'
|
3
|
+
|
4
|
+
module Smesser
|
5
|
+
class Provider
|
6
|
+
class << self
|
7
|
+
attr_accessor :description
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_accessor :username, :password
|
11
|
+
|
12
|
+
def self.paths
|
13
|
+
@paths ||= [File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'providers'))]
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.load_all
|
17
|
+
Smesser.log.debug("Loading all provider files in #{paths.inspect}")
|
18
|
+
paths.each do |path|
|
19
|
+
Dir["#{path}/*.rb"].each do |f|
|
20
|
+
require f
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(username, password)
|
26
|
+
@username = username
|
27
|
+
@password = password
|
28
|
+
end
|
29
|
+
|
30
|
+
def get(address)
|
31
|
+
log.debug("Getting #{address}")
|
32
|
+
agent.get(address) unless agent.page and agent.page.uri == URI.parse(address)
|
33
|
+
log.debug("Got #{address} (#{page.code})")
|
34
|
+
page.code
|
35
|
+
end
|
36
|
+
|
37
|
+
def post_form(spec, &block)
|
38
|
+
spec = { :name => spec } if spec.is_a? String
|
39
|
+
log.debug("Looking for form with #{spec.inspect}")
|
40
|
+
form = page.form_with(spec)
|
41
|
+
raise "Form not found: #{spec.inspect} on #{page.uri} (forms: #{page.forms.map(&:name).inspect})" unless form
|
42
|
+
yield form
|
43
|
+
log.debug("Submitting form: #{form.action} #{form.request_data}")
|
44
|
+
form.submit
|
45
|
+
log.debug("Submitted #{form.action} (#{page.code})")
|
46
|
+
page.code
|
47
|
+
end
|
48
|
+
|
49
|
+
def click(spec)
|
50
|
+
spec = { :text => spec } if spec.is_a? String
|
51
|
+
log.debug("Looking for a form with #{spec.inspect}")
|
52
|
+
link = page.link_with(spec)
|
53
|
+
raise "Link not found: #{spec.inspect} on #{page.uri} (links: #{page.links.map(&:text).inspect})" unless link
|
54
|
+
log.debug("Clicking link #{link.text} => #{link.href}")
|
55
|
+
link.click
|
56
|
+
log.debug("Clicked link #{link.href} (#{page.code})")
|
57
|
+
page.code
|
58
|
+
end
|
59
|
+
|
60
|
+
def login
|
61
|
+
raise "You need to override #{this}#login"
|
62
|
+
end
|
63
|
+
|
64
|
+
def send(message, *recipients)
|
65
|
+
raise "You need to override #{this}#send"
|
66
|
+
end
|
67
|
+
|
68
|
+
def agent
|
69
|
+
@agent ||= Mechanize.new
|
70
|
+
end
|
71
|
+
|
72
|
+
def page
|
73
|
+
agent.page
|
74
|
+
end
|
75
|
+
|
76
|
+
def log
|
77
|
+
Smesser.log
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
data/lib/smesser.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'logger'
|
4
|
+
require "smesser/version"
|
5
|
+
|
6
|
+
module Smesser
|
7
|
+
autoload :Provider, 'smesser/provider'
|
8
|
+
|
9
|
+
def self.config_files
|
10
|
+
@configfiles ||= [
|
11
|
+
"/etc/smesserrc",
|
12
|
+
"/usr/local/etc/smesserrc",
|
13
|
+
"~/.smesserrc"
|
14
|
+
]
|
15
|
+
end
|
16
|
+
|
17
|
+
# The easiest way to send an SMS.
|
18
|
+
#
|
19
|
+
# Accepts the following options:
|
20
|
+
#
|
21
|
+
# provider:: The name of the provider to use (see `providers`)
|
22
|
+
# username:: The username to log in with
|
23
|
+
# password:: The password to log in with
|
24
|
+
# message:: The message
|
25
|
+
# recipients:: An array of recipients. If Smesser has `contacts` configured,
|
26
|
+
# then you can use aliases here.
|
27
|
+
# retry:: The number of times to attempt sending. Default is 1.
|
28
|
+
#
|
29
|
+
# If any are missing, Smesser's configuration will be checked for a suitable
|
30
|
+
# value.
|
31
|
+
#
|
32
|
+
# Returns a hash, with (at least)
|
33
|
+
#
|
34
|
+
# status:: 'OK' if all went well, 'Failed' otherwise
|
35
|
+
#
|
36
|
+
# ...and any additional provider specific return values. A common one might be
|
37
|
+
# `:remaining`, to indicate the number of free SMSs left with the provider.
|
38
|
+
def self.send_message(options = {})
|
39
|
+
options.dup.each { |k, v| options[k.to_sym] = options.delete(k) if k.is_a?(String) }
|
40
|
+
|
41
|
+
args = configuration.merge(options)
|
42
|
+
log.debug("Sending message: args = #{args.inspect}")
|
43
|
+
|
44
|
+
provider = providers[args[:provider]].new(args[:username], args[:password])
|
45
|
+
log.debug("Provider: #{provider.inspect}")
|
46
|
+
|
47
|
+
recipients = lookup_contacts(args[:recipients])
|
48
|
+
log.debug("Recipients: #{recipients.inspect}")
|
49
|
+
|
50
|
+
unless provider.logged_in?
|
51
|
+
log.debug("Logging in... (#{args[:username]})")
|
52
|
+
provider.login unless args[:dryrun]
|
53
|
+
end
|
54
|
+
|
55
|
+
log.info("Message: #{args[:message].inspect}")
|
56
|
+
|
57
|
+
result = {}
|
58
|
+
|
59
|
+
if args[:dryrun] or provider.send(args[:message], *recipients)
|
60
|
+
log.info "Message sent."
|
61
|
+
result[:code] = "OK"
|
62
|
+
result[:remaining] = provider.remaining if provider.respond_to?(:remaining)
|
63
|
+
elsif args[:retry] and args[:retry] > 0
|
64
|
+
log.info "Failed, trying again... (#{args[:retry]})"
|
65
|
+
args[:retry] -= 1
|
66
|
+
return send_message(args)
|
67
|
+
else
|
68
|
+
log.info "Failed!"
|
69
|
+
result[:code] = "Failed"
|
70
|
+
end
|
71
|
+
|
72
|
+
result
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.log
|
76
|
+
return @log if @log
|
77
|
+
@log = Logger.new(STDOUT)
|
78
|
+
@log.level = Logger::WARN
|
79
|
+
@log
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.configuration
|
83
|
+
@configuration ||= load_config!
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.providers
|
87
|
+
Provider.load_all
|
88
|
+
@providers ||= {}
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.load_config!
|
92
|
+
config = {}
|
93
|
+
config_files.each do |f|
|
94
|
+
if File.exists?(path = File.expand_path(f))
|
95
|
+
config.merge!(YAML.load(File.read(path)))
|
96
|
+
end
|
97
|
+
end
|
98
|
+
config.dup.each { |k, v| config[k.to_sym] = v if k.is_a?(String) }
|
99
|
+
config
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.lookup_contacts(recipients)
|
103
|
+
contacts = configuration[:contacts]
|
104
|
+
return recipients unless contacts
|
105
|
+
recipients.map do |r|
|
106
|
+
log.debug "#{r} => #{contacts[r]}" if contacts[r]
|
107
|
+
contacts[r] || r
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.print_providers(io = STDOUT)
|
112
|
+
providers.each do |k, v|
|
113
|
+
io.puts "#{k}: #{v.description || 'No description'}"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
data/providers/o2_ie.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'smesser/provider'
|
2
|
+
|
3
|
+
class O2Ie < Smesser::Provider
|
4
|
+
@@start_url = "http://www.o2online.ie/o2/"
|
5
|
+
@@send_action = "http://messaging.o2online.ie/smscenter_send.osp"
|
6
|
+
@@send_delay = 2
|
7
|
+
|
8
|
+
self.description = "www.o2.ie (400 free texts per month)"
|
9
|
+
|
10
|
+
def logged_in?
|
11
|
+
get @@start_url
|
12
|
+
!!page.link_with(:text => 'Logout of o2.ie')
|
13
|
+
end
|
14
|
+
|
15
|
+
def login
|
16
|
+
get(@@start_url)
|
17
|
+
click('Login to o2.ie')
|
18
|
+
post_form('o2login_form') do |form|
|
19
|
+
form["IDToken1"] = @username
|
20
|
+
form["IDToken2"] = @password
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def send(message, *recipients)
|
25
|
+
get_webtext_page
|
26
|
+
post_form('form_WebtextSend') do |form|
|
27
|
+
form["SMSTo"] = recipients.join(", ")
|
28
|
+
form["SMSText"] = message
|
29
|
+
form.action = @@send_action
|
30
|
+
sleep(@@send_delay)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def remaining
|
35
|
+
get_webtext_page
|
36
|
+
if span = page.at("#spn_WebtextFree")
|
37
|
+
span.inner_text
|
38
|
+
else
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_webtext_page
|
44
|
+
login unless logged_in?
|
45
|
+
get(@@start_url)
|
46
|
+
click('Send a webtext')
|
47
|
+
get(page.frames.first.href)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
Smesser.providers['o2.ie'] = O2Ie
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'smesser/provider'
|
2
|
+
|
3
|
+
class VodafoneIe < Smesser::Provider
|
4
|
+
@@start_url = "https://www.vodafone.ie/myv/index.jsp"
|
5
|
+
@@login_url = "https://www.vodafone.ie/myv/services/login/login.jsp"
|
6
|
+
@@webtext_url = "https://www.vodafone.ie/myv/messaging/webtext/index.jsp"
|
7
|
+
@@send_delay = 3 # Vodafone's servers don't like instantaneousness.
|
8
|
+
|
9
|
+
self.description = "www.vodafone.ie"
|
10
|
+
|
11
|
+
def logged_in?
|
12
|
+
log.debug("Checking if logged in")
|
13
|
+
get(@@start_url)
|
14
|
+
if page.uri == URI.parse(@@start_url)
|
15
|
+
log.debug("Logged in")
|
16
|
+
true
|
17
|
+
else
|
18
|
+
log.debug("Not logged in")
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def login
|
24
|
+
get(@@login_url)
|
25
|
+
post_form('Login') do |form|
|
26
|
+
form.username = @username
|
27
|
+
form.password = @password
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def send(message, *recipients)
|
32
|
+
get(@@webtext_url)
|
33
|
+
|
34
|
+
post_form('WebText') do |form|
|
35
|
+
form.message = message
|
36
|
+
recipients.each_with_index do |recipient, index|
|
37
|
+
form["recipients[#{index}]"] = recipient
|
38
|
+
end
|
39
|
+
sleep(@@send_delay)
|
40
|
+
end
|
41
|
+
|
42
|
+
log.debug("Looking for div#webtext-thankyou")
|
43
|
+
if !!page.at('div#webtext-thankyou')
|
44
|
+
log.debug("Found!")
|
45
|
+
true
|
46
|
+
else
|
47
|
+
log.warn("No matching element found!")
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def remaining
|
53
|
+
log.debug("Checking remaining texts...")
|
54
|
+
login unless logged_in?
|
55
|
+
get @@webtext_url unless page.uri == URI::parse(@@webtext_url)
|
56
|
+
if div = page.at("div.info-row.text-remaining strong")
|
57
|
+
log.debug("Found element")
|
58
|
+
div.inner_text
|
59
|
+
else
|
60
|
+
log.warn("No matching element found!")
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
Smesser.providers['vodafone.ie'] = VodafoneIe
|
data/smesser.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/smesser/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["JJ Buckley"]
|
6
|
+
gem.email = ["jj@bjjb.org"]
|
7
|
+
gem.description = %q{Send free text messages!}
|
8
|
+
gem.summary = %q{SMeSser helps you send SMSs using various mobile provider's websites. The gem comes with a binary, which helps you set up the details for your own provider, and with a library which you can integrate into nicer front-ends.}
|
9
|
+
gem.homepage = "http://jjbuckley.github.com/smesser"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "smesser"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Smesser::VERSION
|
17
|
+
gem.add_development_dependency 'rake'
|
18
|
+
gem.add_dependency 'mechanize', '~> 2.3'
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'smesser'
|
3
|
+
|
4
|
+
class TestSmesser < Test::Unit::TestCase
|
5
|
+
def test_provider_paths
|
6
|
+
assert Smesser::Provider.paths.include?(File.expand_path(File.join(File.dirname(__FILE__), '..', 'providers')))
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_config_files
|
10
|
+
assert Smesser.config_files.include?("/usr/local/etc/smesserrc")
|
11
|
+
assert Smesser.config_files.include?("/etc/smesserrc")
|
12
|
+
assert Smesser.config_files.include?("~/.smesserrc")
|
13
|
+
end
|
14
|
+
|
15
|
+
# TODO - loads more tests!
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: smesser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- JJ Buckley
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-10 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &76809390 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *76809390
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mechanize
|
27
|
+
requirement: &76788750 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.3'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *76788750
|
36
|
+
description: Send free text messages!
|
37
|
+
email:
|
38
|
+
- jj@bjjb.org
|
39
|
+
executables:
|
40
|
+
- smesser
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- LICENSE
|
47
|
+
- README.md
|
48
|
+
- Rakefile
|
49
|
+
- bin/smesser
|
50
|
+
- lib/smesser.rb
|
51
|
+
- lib/smesser/provider.rb
|
52
|
+
- lib/smesser/version.rb
|
53
|
+
- providers/o2_ie.rb
|
54
|
+
- providers/vodafone_ie.rb
|
55
|
+
- smesser.gemspec
|
56
|
+
- test/test_smesser.rb
|
57
|
+
homepage: http://jjbuckley.github.com/smesser
|
58
|
+
licenses: []
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
hash: 251797839
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
hash: 251797839
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 1.8.10
|
84
|
+
signing_key:
|
85
|
+
specification_version: 3
|
86
|
+
summary: SMeSser helps you send SMSs using various mobile provider's websites. The
|
87
|
+
gem comes with a binary, which helps you set up the details for your own provider,
|
88
|
+
and with a library which you can integrate into nicer front-ends.
|
89
|
+
test_files:
|
90
|
+
- test/test_smesser.rb
|