Permalink
Browse files

Reworked config, support per-engine config options

  • Loading branch information...
1 parent 289f8ef commit a4f272714c32713ed5db5b0163286238457027a1 @mludvig committed Feb 15, 2012
Showing with 49 additions and 31 deletions.
  1. +18 −11 Sms/Config.py
  2. +3 −0 Sms/Exceptions.py
  3. +13 −0 Sms/GenericSmsDriver.py
  4. +1 −1 Sms/GwClickatell.py
  5. +4 −8 Sms/GwGenericHttp.py
  6. +5 −7 Sms/Sender.py
  7. +5 −4 sms-cli
View
29 Sms/Config.py
@@ -11,16 +11,10 @@
class Config(object):
_instance = None
_parsed_files = []
+ _engine_options = {}
- sms_engine = "GwGenericHttp" ## Module must contain class SmsDriver
- sms_recipients = [ ]
- sms_url_pattern = ""
- sms_message = ""
- sms_timestamp_format = "%m/%d %H:%M"
- ## Example config for Clickatell:
- ## sms_engine = "GwClickatell"
- ## sms_url_pattern = "https://api.clickatell.com/http/sendmsg?api_id=APIID&user=USERNAME&password=PASSWORD&to=%(recipient)s&text=%(message)s"
- ## replace APIID, USERNAME and PASSWORD with the values of your Clickatell account
+ engine = "GwGenericHttp" ## Module must export class SmsDriver
+ timestamp_format = "%m/%d %H:%M"
profile = "default"
verbosity = logging.INFO
@@ -55,8 +49,10 @@ def option_list(self):
def read_config_file(self, configfile):
cp = ConfigParser(configfile, self.profile)
for option in self.option_list():
- self.update_option(option, cp.get(option))
+ self.update_option(option, cp.pop(option))
self._parsed_files.append(configfile)
+ self._engine_options = cp.get_all()
+ debug("Engine Options: %s" % self.engine_options())
def update_option(self, option, value):
if value is None:
@@ -84,6 +80,9 @@ def update_option(self, option, value):
else: # string
setattr(Config, option, value)
+ def engine_options(self):
+ return self._engine_options
+
class ConfigParser(object):
def __init__(self, cfgfile, section):
self.cfg = {}
@@ -137,8 +136,16 @@ def __getitem__(self, name):
def __setitem__(self, name, value):
self.cfg[name] = value
+ def get_all(self):
+ return self.cfg
+
def get(self, name, default = None):
- if self.cfg.has_key(name):
+ if name in self.cfg:
return self.cfg[name]
return default
+ def pop(self, name, default = None):
+ retval = self.get(name, default)
+ if name in self.cfg:
+ del self.cfg[name]
+ return retval
View
3 Sms/Exceptions.py
@@ -19,6 +19,9 @@ def _set_message(self, message):
self._message = message
message = property(_get_message, _set_message)
+class SmsError(SmsException):
+ pass
+
class SmsConfigError(SmsException):
pass
View
13 Sms/GenericSmsDriver.py
@@ -0,0 +1,13 @@
+from logging import debug, info
+from Exceptions import *
+
+class GenericSmsDriver(object):
+ def __init__(self, options = {}):
+ self.set_options(options)
+
+ def set_options(self, options):
+ debug("Setting options to: %r" % options)
+ self.options = options
+
+ def send(self, message, recipient):
+ raise SmsConfigError("GenericSmsDriver is not intended for direct use")
View
2 Sms/GwClickatell.py
@@ -1,5 +1,5 @@
from logging import debug, info
-from Sms.Sender import SmsError
+from Exceptions import SmsError
import Sms.GwGenericHttp
class SmsDriver(Sms.GwGenericHttp.SmsDriver):
View
12 Sms/GwGenericHttp.py
@@ -1,16 +1,12 @@
import urllib
import urllib2
-## Must be full path because this module is imported via __import__()
-from Config import Config
-from Sender import SmsError
-
-class SmsDriver(object):
- def __init__(self):
- self._url_pattern = Config().sms_url_pattern
+from Exceptions import *
+from GenericSmsDriver import GenericSmsDriver
+class SmsDriver(GenericSmsDriver):
def send(self, message, recipient):
- url = self._url_pattern.strip('"\'') % { 'message' : urllib.quote(message), 'recipient' : recipient }
+ url = self.options['url_pattern'].strip('"\'') % { 'message' : urllib.quote(message), 'recipient' : recipient }
u = urllib2.urlopen(url)
if u.code != 200:
raise SmsError("HTTP Return code = %d" % u.code)
View
12 Sms/Sender.py
@@ -1,14 +1,12 @@
from logging import debug, error
from Config import Config
-
-class SmsError(Exception):
- pass
+from Exceptions import *
class SmsSender(object):
- def __init__(self, recipients = [], **kwargs):
- debug("Importing engine: %s" % Config().sms_engine)
- driver_module = __import__("Sms." + Config().sms_engine, fromlist = ["Sms"])
- self._driver = driver_module.SmsDriver(**kwargs)
+ def __init__(self, recipients = [], engine_options = {}, **kwargs):
+ debug("Importing engine: %s" % Config().engine)
+ driver_module = __import__("Sms." + Config().engine, fromlist = ["Sms"])
+ self._driver = driver_module.SmsDriver(options = Config().engine_options(), **kwargs)
self._recipients = recipients
self._message = ""
View
9 sms-cli
@@ -29,7 +29,7 @@ optparser = OptionParser()
optparser.set_defaults(config=default_config_file)
optparser.set_defaults(verbosity = default_verbosity)
-optparser.add_option("-r", "--recipient", dest="sms_recipients", action="append", metavar="PHONE-NUM", help="Cell phone number of message recipient. Can be used multiple times.")
+optparser.add_option("-r", "--recipient", dest="recipients", action="append", metavar="PHONE-NUM", help="Cell phone number of message recipient. Can be used multiple times.")
optparser.add_option("-m", "--message", dest="message", action="store", metavar="MESSAGE", help="Message to send to given Recipient(s)")
optparser.add_option("-f", "--config", dest="config", metavar="FILE", help="Config file name. Optionally can include :PROFILE, e.g. --config=/etc/sms-cli.conf:clickatell or use --profile clickatell. Defaults to %default")
optparser.add_option("-p", "--profile", dest="profile", action="store", metavar="PROFILE", help="Config file profile / section to process. Defaults to [default]")
@@ -67,13 +67,14 @@ for option in cfg.option_list():
if getattr(options, option) != None:
debug("Updating %s -> %s" % (option, getattr(options, option)))
cfg.update_option(option, getattr(options, option))
+ delattr(options, option)
except AttributeError:
## Some Config() options are not settable from command line
pass
-if not options.message or not cfg.sms_recipients:
+if not options.message or not options.recipients:
sys.stderr.write('Message and at least one recipient must be set!\n')
sys.exit(1)
-sms = SmsSender(cfg.sms_recipients)
-sms.send(options.message)
+sms = SmsSender()
+sms.send(message = options.message, recipients = options.recipients)

0 comments on commit a4f2727

Please sign in to comment.