# HG changeset patch # User Daniele Nicolodi # Date 1424825090 -3600 # Node ID 1311f65339782aeccec551718eaf2079164105ac # Parent ad577744dd8e33f8a1ae44630c04ebc9a85b8bcf Load configuration from file specified on the command line diff -r ad577744dd8e -r 1311f6533978 setup.py --- 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', ], diff -r ad577744dd8e -r 1311f6533978 src/bnpparibas.py --- 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)