changeset 3:1311f6533978

Load configuration from file specified on the command line
author Daniele Nicolodi <daniele@grinta.net>
date Wed, 25 Feb 2015 01:44:50 +0100
parents ad577744dd8e
children b4c2db70bbf2
files setup.py src/bnpparibas.py
diffstat 2 files changed, 54 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/setup.py	Tue Feb 24 17:23:39 2015 +0100
+++ b/setup.py	Wed Feb 25 01:44:50 2015 +0100
@@ -13,7 +13,7 @@
       package_dir={'': 'src'},
       include_package_data=False,
       zip_safe=False,
-      install_requires=[ 'Pillow', 'beautifulsoup4', 'requests', ],
+      install_requires=[ 'Pillow', 'beautifulsoup4', 'click', 'requests', ],
       entry_points={
           'console_scripts': [
               'bnpparibas = bnpparibas:main', ],
--- a/src/bnpparibas.py	Tue Feb 24 17:23:39 2015 +0100
+++ b/src/bnpparibas.py	Wed Feb 25 01:44:50 2015 +0100
@@ -1,4 +1,5 @@
 import email
+import imp
 import os.path
 import re
 import smtplib
@@ -17,11 +18,11 @@
 from urllib.parse import urljoin
 
 import bs4
+import click
 import requests
 
 from PIL import Image
 
-DB = 'bnpparibas.sqlite'
 
 # message template
 MESSAGE = """\
@@ -57,7 +58,20 @@
 
 
 # load configuration
-from config import *
+def loadconfig(filename):
+    module = imp.new_module('config')
+    module.__file__ = filename
+    try:
+        with open(filename) as fd:
+            exec(compile(fd.read(), filename, 'exec'), module.__dict__)
+    except IOError as e:
+        e.strerror = 'Unable to load configuration file (%s)' % e.strerror
+        raise
+    config = {}
+    for key in dir(module):
+        if key.isupper():
+            config[key] = getattr(module, key)
+    return config
 
 
 # GPG encrypted text is ascii and as such does not require encoding
@@ -147,7 +161,6 @@
         data = { field['name']: field['value'] for field in form('input') }
 
         # keyboard image url
-        src = ''
         tag = soup.find(attrs={'id': 'secret-nbr-keyboard'})
         for prop in tag['style'].split(';'):
             match = re.match(r'background-image:\s+url\(\'(.*)\'\)\s*', prop)
@@ -183,7 +196,7 @@
             raise ValueError(err.text)
 
 
-    def recent(self):
+    def recent(self, contract):
         data = {
             'BeginDate': '',
             'Categs': '',
@@ -191,7 +204,7 @@
             'EndDate': '',
             'OpTypes': '',
             'cboFlowName': 'flow/iastatement',
-            'contractId': CONTRACT,
+            'contractId': contract,
             'contractIds': '',
             'entryDashboard': '',
             'execution': 'e6s1',
@@ -355,12 +368,12 @@
 
 
 class Mailer:
-    def __init__(self):
-        self.server = SMTPSERVER
-        self.port = SMTPPORT
-        self.starttls = SMTPSTARTTLS
-        self.username = SMTPUSER
-        self.password = SMTPPASSWD
+    def __init__(self, config):
+        self.server = config.get('SMTPSERVER', 'localhost')
+        self.port = config.get('SMTPPORT', 25)
+        self.starttls = config.get('SMTPSTARTTLS', False)
+        self.username = config.get('SMTPUSER', '')
+        self.password = config.get('SMTPPASSWD', '')
 
     @contextmanager
     def connect(self):
@@ -381,25 +394,35 @@
             conn.sendmail(fromaddr, toaddr, str(message))
 
 
-def encrypt(message, sender, recipient):
-    sender = parseaddr(sender)[1]
-    recipient = parseaddr(recipient)[1]
-    cmd = [ "gpg", "--homedir", GNUPGHOME, "--batch", "--yes", "--no-options", "--armor",
-            "--local-user", sender, "--recipient", recipient, "--sign", "--encrypt"]
-    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-    encdata = p.communicate(input=message.encode('utf-8'))[0].decode('ascii')
-    return encdata
+class GPG:
+    def __init__(self, homedir):
+        self.homedir = homedir
+        
+    def encrypt(self, message, sender, recipient):
+        sender = parseaddr(sender)[1]
+        recipient = parseaddr(recipient)[1]
+        cmd = [ "gpg", "--homedir", self.homedir, "--batch", "--yes", "--no-options", "--armor",
+                "--local-user", sender, "--recipient", recipient, "--sign", "--encrypt"]
+        p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+        encdata = p.communicate(input=message.encode('utf-8'))[0].decode('ascii')
+        return encdata
 
 
-def main():
+@click.command()
+@click.argument('filename')
+def main(filename):
+    # load configuration
+    config = loadconfig(filename)
+        
     bnp = Site()
-    bnp.login(USERNAME, PASSWORD)
+    bnp.login(config['USERNAME'], config['PASSWORD'])
 
-    db = sqlite3.connect(DB)
+    db = sqlite3.connect(config['DATABASE'])
     db.execute('''CREATE TABLE IF NOT EXISTS messages (id TEXT PRIMARY KEY)''')
     db.execute('''CREATE TABLE IF NOT EXISTS transactions (id INTEGER PRIMARY KEY)''')
 
-    mailer = Mailer()
+    mailer = Mailer(config)
+    encrypt = GPG(config['GNUPGHOME']).encrypt
 
     ## unread messages
     messages = filter(lambda x: not x.read, bnp.messages())
@@ -415,10 +438,10 @@
 
         # compose and send message
         body = MESSAGE.format(id=m.id, sender=sender, date=m.date, subject=m.subject, body=body)
-        message = MIMEText(encrypt(body, MAILFROM, MAILTO), _charset='utf8 7bit')
+        message = MIMEText(encrypt(body, config['MAILFROM'], config['MAILTO']), _charset='utf8 7bit')
         message['Subject'] = 'BNP Paribas message'
-        message['From'] = MAILFROM
-        message['To'] = MAILTO
+        message['From'] = config['MAILFROM']
+        message['To'] = config['MAILTO']
         message['Date'] = format_datetime(localtime(m.date))
         mailer.send(message)
 
@@ -427,7 +450,7 @@
 
         
     ## transactions
-    transactions = bnp.recent()
+    transactions = bnp.recent(config['CONTRACT'])
     curs = db.cursor()
     lines = []
     for t in transactions:
@@ -442,10 +465,10 @@
         lines.insert(0, HEADER)
         lines.insert(1, '-' * len(HEADER))
         body = '\n'.join(lines)
-        message = MIMEText(encrypt(body, MAILFROM, MAILTO), _charset='utf8 7bit')
+        message = MIMEText(encrypt(body, config['MAILFROM'], config['MAILTO']), _charset='utf8 7bit')
         message['Subject'] = 'BNP Paribas update'
-        message['From'] = MAILFROM
-        message['To'] = MAILTO
+        message['From'] = config['MAILFROM']
+        message['To'] = config['MAILTO']
         message['Date'] = format_datetime(localtime())
         mailer.send(message)