# coding: utf-8 import subprocess from email.mime.text import MIMEText from collections import namedtuple import click import jinja2 import csv Member = namedtuple('Member', ['id', 'cn', 'email', 'membership_type', 'due', 'last_bank']) def sendmail(msg): p = subprocess.Popen(["/usr/sbin/sendmail", "-t"], stdin=subprocess.PIPE) p.communicate(msg.as_string()) @click.command() @click.option('--dry-run', '-n', is_flag=True, help='Just test') @click.option('--members', type=click.File('rb'), required=True, help='Members list CSV') @click.option('--template', type=click.File('rb'), required=True, help='Mailing template') @click.option('--limit', help='Only run for selected user') @click.option('--continue', 'cont', type=int, help='Start with selected user') @click.option('--from', 'from_', help='From field') @click.option('--target-remote/--target-local', help='Send to mailRoutingAddress or local mailbox') def mailer(dry_run, members, template, target_remote, limit=None, cont=None, from_=None): template = jinja2.Template(template.read().decode('utf-8')) for row in csv.reader(members): member = Member(*row) # FIXME id and due data type if limit and limit != member.id and limit != member.cn: click.echo(' == Ignoring {.cn}... '.format(member)) continue if cont and int(cont) > int(member.id): click.echo(' == Ignoring {.cn}...'.format(member)) continue click.echo(' ==== {0.id}: Sending mail to {0.cn} ...'.format(member)) msg = template.make_module({ 'subject': 'Mailing', 'member': member, }) mail = MIMEText(str(msg), "plain", "utf-8") mail['From'] = from_ mail['To'] = member.email if target_remote else '{.cn}@hackerspace.pl'.format(member) mail['Subject'] = getattr(msg, 'subject', 'Mailing') if not mail.get_payload(decode=True).strip(): click.echo(' == Empty message, ignoring...') continue if dry_run: for k, v in mail.items(): click.echo(u'{}: {}'.format(k, v)) click.echo('\n' + mail.get_payload(decode=True)) else: sendmail(mail) if __name__ == "__main__": mailer()