#!/usr/bin/env python3 # -*- coding: utf-8 -*- ''' This script creates randoms pairs from a list of participants in a secret santa game and sends them an email to notify them who the person is that they should buy presents for. ''' # -*- encoding: utf-8 -*- from argparse import ArgumentParser from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.utils import formatdate, make_msgid import json import random import smtplib from typing import Literal import types def secret_santa_matching(participants: list) -> list: # create a copy of the list to make choosing a partner easier copy = list(enumerate(participants[:])) # choose a partner for each participant for i in range(len(participants)): # if the last participant has only themselves left to choose, make them # switch partners with another random participant if len(copy) == 1 and participants[i] == copy[0][1]: current = participants[i] participants.remove(current) partner = random.choice(participants) current['partner'] = partner['partner'] partner['partner'] = current['name'] + ' (' + current['mail']+')' participants.append(current) break # otherwise choose a random partner for each participant else: partner = random.choice(copy) while partner[0] == i: partner = random.choice(copy) participants[i]['partner'] = partner[1]['name'] + \ ' ('+partner[1]['mail']+')' copy.remove(partner) return participants def send_secret_santa_mails(participants: list, config: dict): # open smtp connection server = smtplib.SMTP(config['server'], config['port']) server.ehlo() server.starttls() server.ehlo() server.login(config['user'], config['pass']) # create emails for all participants and send them # change the text for the mail here if you want to for r in participants: msg = MIMEMultipart('alternative') msg['From'] = config['sender'] msg['To'] = r['mail'] msg['Subject'] = 'Wichteln 🎄' msg['Message-ID'] = make_msgid(domain=config['sender'] .split('@')[1] .strip('>')) msg['Date'] = formatdate(localtime=True) plain = f'''Lieb{r['gender']} {r['name']}! Du bist heuer Wichtel für {r['partner']}. Das Geschenk sollte nicht mehr als {config['price']} kosten. Frohe Weihnachten! — Dein Christkind 👼''' html = f'''

Lieb{r['gender']} {r['name']}!

Du bist heuer Wichtel für {r['partner']}.
Das Geschenk sollte nicht mehr als {config['price']} kosten.

Frohe Weihnachten!
— Dein Christkind 👼

''' msg.attach(MIMEText(plain, 'plain', 'utf-8')) msg.attach(MIMEText(html, 'html', 'utf-8')) print('Sending email to', r['name'], '...') server.sendmail(config['sender'], r['mail'], msg.as_string()) def main(): parser = ArgumentParser() parser.add_argument('-p', '--participants', dest='pFileLocation', default='participants.json', help='read list of participants from PARTICIPANTFILE', metavar='PARTICIPANTFILE') parser.add_argument('-c', '--config', dest='cFileLocation', default='config.json', help='read the configuration from CONFIGFILE', metavar='CONFIGFILE') args = parser.parse_args() matches = [] # load and prepare a list containing all participants with open(args.pFileLocation, 'r') as pFile: matches = secret_santa_matching(json.load(pFile)) # load mail server configuration with open(args.cFileLocation, 'r') as cFile: config = json.load(cFile) send_secret_santa_mails(matches, config) if __name__ == '__main__': main()