|
@@ -0,0 +1,133 @@
|
|
|
+#!/usr/bin/python3
|
|
|
+
|
|
|
+import argparse
|
|
|
+import configparser
|
|
|
+import psycopg2
|
|
|
+import datetime
|
|
|
+import json
|
|
|
+import pprint
|
|
|
+
|
|
|
+# network imports
|
|
|
+import smtplib
|
|
|
+from email.mime.text import MIMEText
|
|
|
+from email.parser import Parser
|
|
|
+
|
|
|
+parser = argparse.ArgumentParser()
|
|
|
+parser.add_argument("selection", type=str,
|
|
|
+ choices=["send-reminders", "report"])
|
|
|
+parser.add_argument("-c", "--config", type=str,
|
|
|
+ default="/etc/fcntoolbox/config.ini",
|
|
|
+ help="specify a configuration file")
|
|
|
+
|
|
|
+args = parser.parse_args()
|
|
|
+
|
|
|
+conf = configparser.RawConfigParser()
|
|
|
+conf.sections()
|
|
|
+conf.read(args.config)
|
|
|
+confdoli = conf['dolibarr']
|
|
|
+remindConf = conf['reminder']
|
|
|
+
|
|
|
+s = smtplib.SMTP('localhost')
|
|
|
+
|
|
|
+conn = psycopg2.connect(database=confdoli['database'],
|
|
|
+ user=confdoli['user'], password=confdoli['password'])
|
|
|
+
|
|
|
+parsedate = lambda x : datetime.datetime.strptime(x, "%Y-%m-%d %H:%M:%S")
|
|
|
+
|
|
|
+reportAdherents = []
|
|
|
+reportBody = []
|
|
|
+
|
|
|
+def getLateMembers(reminder):
|
|
|
+ minKey = "%s_min" % reminder
|
|
|
+ maxKey = "%s_max" % reminder
|
|
|
+ if (not minKey in remindConf) or (not maxKey in remindConf):
|
|
|
+ print("Configuration missing for '%', skipping reminder" % reminder)
|
|
|
+ return list()
|
|
|
+
|
|
|
+ min = int(remindConf[minKey])
|
|
|
+ minabs = abs(min)
|
|
|
+ minsign = '+' if min >= 0 else '-'
|
|
|
+ max = int(remindConf[maxKey])
|
|
|
+ maxabs = abs(max)
|
|
|
+ maxsign = '+' if max >= 0 else '-'
|
|
|
+
|
|
|
+ rows = ["rowid", "firstname", "lastname", "datefin", "email"]
|
|
|
+ query = """SELECT {} FROM llx_adherent
|
|
|
+ WHERE (datefin {} interval '{} days' > 'now'
|
|
|
+ AND datefin {} interval '{} days' < 'now')
|
|
|
+ AND statut = 1 """
|
|
|
+
|
|
|
+ cur = conn.cursor()
|
|
|
+ cur.execute(query.format(",".join(rows), maxsign, maxabs, minsign, minabs))
|
|
|
+ members = cur.fetchall()
|
|
|
+ members = list(map(lambda member: dict(zip(rows, member)), members))
|
|
|
+ return members
|
|
|
+
|
|
|
+def sendReminders(reminder):
|
|
|
+ global reportAdherents
|
|
|
+ global reportBody
|
|
|
+ lateMembers = getLateMembers(reminder)
|
|
|
+
|
|
|
+ # Last reminder state
|
|
|
+ remindstate = laststate[reminder] if reminder in laststate else []
|
|
|
+
|
|
|
+ # New reminder state
|
|
|
+ state[reminder] = list(map(lambda x : int(x['rowid']), lateMembers))
|
|
|
+ adherents = list(filter(lambda x: not int(x['rowid']) in remindstate, lateMembers))
|
|
|
+
|
|
|
+ remindFormat = open('cotisation-%s.format' % reminder, 'r').read()
|
|
|
+
|
|
|
+ for adherent in adherents:
|
|
|
+ adherent['rowid'] = int(adherent['rowid'])
|
|
|
+# adherent['datefin'] = parsedate(adherent['datefin'])
|
|
|
+ rawemail = remindFormat.format(**adherent)
|
|
|
+ parsedemail = Parser().parsestr(rawemail)
|
|
|
+ body = parsedemail.get_payload()
|
|
|
+ msg = MIMEText(body)
|
|
|
+ for key, val in parsedemail.items():
|
|
|
+ msg[key] = val
|
|
|
+ msg['From'] = "tresoriers@listes.franciliens.net"
|
|
|
+ msg['To'] = adherent['email']
|
|
|
+ if not "Subject" in msg:
|
|
|
+ print("Error: no subject in template email")
|
|
|
+ break
|
|
|
+ if len(body.strip()) == 0:
|
|
|
+ print("Error: no body in template email")
|
|
|
+ break
|
|
|
+ s.send_message(msg)
|
|
|
+
|
|
|
+ if len(adherents) > 0:
|
|
|
+ reportAdherents += adherents
|
|
|
+ reportBody += [body]
|
|
|
+
|
|
|
+if args.selection == 'send-reminders':
|
|
|
+ # Read state
|
|
|
+ with open('cotisation-state.json', 'r') as statefp:
|
|
|
+ laststate = json.load(statefp)
|
|
|
+ state = laststate
|
|
|
+
|
|
|
+ reminders = ['reminder0', 'reminder1', 'reminder2', 'reminder3']
|
|
|
+
|
|
|
+ for reminder in reminders:
|
|
|
+ sendReminders(reminder)
|
|
|
+
|
|
|
+ reportFormat = open('cotisation-report.format', 'r').read()
|
|
|
+ pp = pprint.PrettyPrinter()
|
|
|
+
|
|
|
+ if len(reportAdherents) > 0:
|
|
|
+ body = reportFormat.format(adherents = pp.pformat(reportAdherents), template = "\n----------\n".join(reportBody))
|
|
|
+ msg = MIMEText(body)
|
|
|
+ msg['Subject'] = "Rapport des rappels de cotisation"
|
|
|
+ msg['From'] = "root@franciliens.net"
|
|
|
+ msg['To'] = "tresoriers@listes.franciliens.net"
|
|
|
+ s.send_message(msg)
|
|
|
+ s.quit()
|
|
|
+
|
|
|
+ # Save state
|
|
|
+ with open('cotisation-state.json', 'w') as statefp:
|
|
|
+ json.dump(state, statefp)
|
|
|
+
|
|
|
+elif args.selection == 'report':
|
|
|
+ lateMembers = getLateMembers('reminder3')
|
|
|
+ for member in lateMembers:
|
|
|
+ print(member)
|