Send answers with Biju and remove machine definition from the gem

master
Guillaume DOTT 2013-09-11 11:12:22 +02:00
parent 8543374046
commit eec4e58dd9
14 changed files with 177 additions and 49 deletions

View File

@ -1,4 +1,4 @@
# Smsd
# SMSd
TODO: Write a gem description
@ -18,7 +18,26 @@ Or install it yourself as:
## Usage
TODO: Write usage instructions here
```ruby
#!/usr/bin/env ruby
require 'smsd'
require 'net/http'
cli = SMSd::CLI.new(ARGV) do
machine = SMSd::AnsweringMachine.new(I18n.t(:default_answer))
machine.add_action(/hello/i, 'Hello !!')
machine.add_action(/what/i) do |from, to, message|
"The phone number #{from} sent '#{message}' to #{to}"
end
machine.add_action(/myip/i) do
Net::HTTP.get('icanhazip.com', '/').chomp
end
end
cli.run
```
## Contributing

View File

@ -1,5 +0,0 @@
#!/usr/bin/env ruby
require 'smsd'
SMSd::CLI.new(ARGV)

View File

@ -0,0 +1,20 @@
#!/usr/bin/env ruby
require 'smsd'
require 'net/http'
cli = SMSd::CLI.new(ARGV) do
machine = SMSd::AnsweringMachine.new(I18n.t(:default_answer))
machine.add_action(/ping/i, 'PONG')
machine.add_action(/free/i) do
`free`
end
machine.add_action(/myip/i) do
Net::HTTP.get('icanhazip.com', '/').chomp
end
machine
end
cli.run

17
examples/polite.rb 100755
View File

@ -0,0 +1,17 @@
#!/usr/bin/env ruby
require 'smsd'
cli = SMSd::CLI.new(ARGV) do
machine = SMSd::AnsweringMachine.new('I didn\'t understand your message.')
machine.add_action(/hello|hi/i, 'Ahoy !!')
machine.add_action(/what/i) do |from, to, message|
"The phone number #{from} wrote '#{message}' to #{to}"
end
machine
end
cli.run

View File

@ -5,14 +5,5 @@ require 'smsd/cli'
require 'smsd/cli/options'
require 'smsd/answering_machine'
require 'smsd/answering_machine/action'
module SMSd
def self.init_i18n
I18n.load_path = Dir[File.join(File.dirname(__FILE__),
'..', 'locale', '*.yml')]
end
def self.locale=(locale)
I18n.locale = locale
end
end
require 'smsd/util/multi_io'
require 'smsd/util/sms'

View File

@ -8,7 +8,7 @@ module SMSd
end
def add_action(regexp, answer = nil, &block)
self.actions << Action.new(regexp, answer, &block)
actions << Action.new(regexp, answer, &block)
end
def execute(from, to, message)

View File

@ -1,25 +1,74 @@
require 'biju'
require 'logger'
module SMSd
class CLI
attr_accessor :machine, :options
attr_accessor :machine
attr_reader :modem, :options, :logger
def initialize(args)
self.options = Options.parse(args)
def initialize(args = [], &block)
@options = Options.parse(args)
SMSd.init_i18n
SMSd.locale = options[:locale] || :fr
self.machine = yield block if block_given?
define_actions
puts machine.execute(ARGV[0], ARGV[1], ARGV[2])
init_logger
@modem = Biju::Hayes.new(options[:modem], pin: options[:pin])
end
def define_actions
self.machine = AnsweringMachine.new(I18n.t(:default_answer))
def run
catch_signals
Process.daemon if options[:daemonize]
machine.add_action(/bonjour/i, 'Bonjour !!')
machine.add_action(/quoi/i) do |from, to, message|
I18n.t(:what, from: from, to: to, message: message)
loop do
break if @terminate
modem.messages.each do |sms|
handle_message sms
end
sleep 5
end
modem.modem.close
end
private
def init_logger
@logger = Logger.new(
Util::MultiIO.new(STDOUT, File.open('debug.log', 'a')))
logger.formatter = proc do |severity, datetime, progrname, msg|
"#{datetime} [#{severity}] #{msg}\n"
end
end
def catch_signals
signal_term = proc { @terminate = true }
Signal.trap('SIGTERM', signal_term)
Signal.trap('SIGINT', signal_term)
end
def handle_message(sms)
if sms.valid?
send_answer(sms)
else
logger.warn "#{sms}: #{sms.errors.join(',')}"
end
modem.delete(sms.id)
end
def send_answer(sms)
message = machine.execute(sms.phone_number, nil, sms.message)
if message.nil? || message == ''
log = 'Empty answer'
else
modem.send(Biju::Sms.new(
phone_number: sms.phone_number, message: message))
log = message
end
logger.info "#{sms}: #{log}"
end
end
end

View File

@ -7,20 +7,24 @@ module SMSd
options = {}
parser = ::OptionParser.new do |opts|
opts.banner = "Usage: smsd [options]"
opts.banner = 'Usage: smsd [options] MODEM'
opts.separator ""
opts.separator "Specific options:"
opts.separator ''
opts.separator 'Specific options:'
opts.on('-l', '--locale LOCALE',
'Define the language of the script') do |locale|
options[:locale] = locale.to_sym
opts.on('-d', '--[no-]daemonize',
'Run in the background') do |daemon|
options[:daemonize] = daemon
end
opts.separator ""
opts.separator "Common options:"
opts.on('-p', '--pin PIN', 'Specify the SIM PIN') do |pin|
options[:pin] = pin
end
opts.on('-h', '--help', 'Show this message') do
opts.separator ''
opts.separator 'Common options:'
opts.on_tail('-h', '--help', 'Show this message') do
puts opts
exit
end
@ -31,7 +35,18 @@ module SMSd
end
end
parser.parse!(args)
begin
parser.parse!(args)
options[:modem] = args.first
raise OptionParser::MissingArgument,
'modem not specified' if options[:modem].nil?
rescue OptionParser::MissingArgument, OptionParser::InvalidOption => e
puts e.message
puts parser
exit
end
options
end
end

View File

@ -0,0 +1,15 @@
module SMSd::Util
class MultiIO
def initialize(*targets)
@targets = targets
end
def write(*args)
@targets.each { |t| t.write(*args) }
end
def close
@targets.each(&:close)
end
end
end

View File

@ -0,0 +1,12 @@
class Biju::Sms
attr_reader :errors
def valid?
@errors = []
@errors << 'Message too old' if datetime.to_time < Time.now - (5 * 60)
@errors << 'Phone number too short' if phone_number.length < 6
@errors.empty?
end
end

View File

@ -1,3 +1,3 @@
module SMSd
VERSION = "0.0.1"
VERSION = '0.0.1'
end

View File

@ -1,3 +0,0 @@
en:
default_answer: "I didn't understand your message"
what: 'The phone number %{from} wrote "%{message} to %{to}'

View File

@ -1,3 +0,0 @@
fr:
default_answer: "Je n'ai pas compris votre message"
what: 'Le numéro %{from} a écrit "%{message}" au numéro %{to}'

View File

@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_dependency 'biju'
spec.add_dependency 'i18n'
spec.add_development_dependency "bundler", "~> 1.3"