changeset 0:f53fab34ba78

Initial commit. Basic config file parsing is working.
author Brian Neal <bgneal@gmail.com>
date Tue, 15 May 2012 20:52:12 -0500
parents
children 479badee55ce
files .hgignore weighmail/__init__.py weighmail/config.py weighmail/main.py
diffstat 3 files changed, 99 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Tue May 15 20:52:12 2012 -0500
@@ -0,0 +1,4 @@
+syntax: glob
+*.swp
+*.pyc
+weighmail.ini
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weighmail/config.py	Tue May 15 20:52:12 2012 -0500
@@ -0,0 +1,86 @@
+import collections
+import re
+from ConfigParser import SafeConfigParser
+
+
+class ConfigError(Exception):
+    pass
+
+
+LIMIT_RE = re.compile(r'^(\d+)(GB|MB|KB)?$', re.IGNORECASE)
+
+KB = 1024
+MB = KB * KB
+GB = MB * MB
+
+SUFFIX_SIZES = {
+    None: 1,
+    'KB': KB,
+    'MB': MB,
+    'GB': GB
+}
+
+
+def parse_config_file(path):
+    """Parse INI file containing configuration details.
+
+    """
+    # Parse options file
+    defaults = dict(
+        username=None,
+        password=None,
+        host='imap.gmail.com',
+        ssl='True',
+        port='993',
+    )
+    parser = SafeConfigParser(defaults=defaults, allow_no_value=True)
+
+    with open(path, 'r') as fp:
+        parser.readfp(fp)
+
+    # Build a list of label named tuples
+    Label = collections.namedtuple('Label', 'name min max')
+
+    label_set = set(parser.sections()) - {'auth', 'connection'}
+    if not label_set:
+        raise ConfigError("please specify at least 1 label section")
+
+    labels = []
+    for label in label_set:
+        min_val = get_limit(parser.get(label, 'min'))
+        max_val = get_limit(parser.get(label, 'max'))
+
+        if (min_val is not None and max_val is not None and 
+                min_val > max_val):
+            raise ConfigError("min is > max for label %s" % label)
+
+        labels.append(Label(name=label, min=min_val, max=max_val))
+
+    # Build an options object and return it
+    fields = defaults.keys() + ['labels']
+    Options = collections.namedtuple('Options', fields)
+
+    opts = Options(
+        username=parser.get('auth', 'username'),
+        password=parser.get('auth', 'password'),
+        host=parser.get('connection', 'host'),
+        ssl=parser.getboolean('connection', 'ssl'),
+        port=parser.getint('connection', 'port'),
+        labels=labels,
+    )
+    return opts
+
+
+def get_limit(val):
+    """Turns a string limit (e.g. 3MB) into an integer"""
+
+    # An empty string is OK, it means no limit, which we translate to None
+    if val == '':
+        return None
+
+    match = LIMIT_RE.match(val)
+    if match is None:
+        raise ConfigError("invalid min/max value %s" % val)
+
+    return int(match.group(1)) * SUFFIX_SIZES[match.group(2).upper()]
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/weighmail/main.py	Tue May 15 20:52:12 2012 -0500
@@ -0,0 +1,9 @@
+from config import parse_config_file
+
+
+def main():
+    opts = parse_config_file('weighmail.ini')
+
+
+if __name__ == '__main__':
+    main()