Skip to content

Instantly share code, notes, and snippets.

@nhamilakis
Last active December 3, 2021 11:26
Show Gist options
  • Save nhamilakis/389c72f9d5fafb2e5db63022721a8f88 to your computer and use it in GitHub Desktop.
Save nhamilakis/389c72f9d5fafb2e5db63022721a8f88 to your computer and use it in GitHub Desktop.
Secret Santa

Secret Santa Script

pip install pandas Jinja2 tqdm

Gmail as smtp

$ python3 secret_santa.py

Google Sheet Structure needs to have the following columns [Nom, Prenom, Email]

import argparse
import json
import random
from datetime import date
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from smtplib import SMTP
from typing import Dict
import pandas as pd
from jinja2 import Template
from tqdm import tqdm
# Keep Pairs in backup.json in case issue with email happens
KEEP_BACKUP: bool = True
# run matchmaking without sending emails
TEST: bool = False
EMAIL_TEMPLATE = """
<p>
Hello <b>{{full_name}}</b> and welcome to the CoML secret santa {{year}} edition.
</p>
<p> You have to buy a gift for <b>{{target_name}}</b>. </p>
<p> The budget limit is {{budget}}€. </p>
"""
SUBJECT = 'CoML Secret Santa'
cfg = argparse.Namespace(**{
"sheet_id": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"sheet_name": "secret-santa",
"budget": 10,
"from_email": "email@addrr",
"smtp_server": "smtp.com",
"smtp_port": 587,
"smtp_username": "email@addrr",
"smtp_password": "passwd"
})
def build_email_body(person: Dict, budget: int):
""" Build email from template and person """
tm = Template(EMAIL_TEMPLATE)
return tm.render(
full_name=f"{person['Nom'].title()} {person['Prenom'].title()}",
year=f"{date.today().year}",
target_name=f"{person['gift_to']['Nom'].title()} {person['gift_to']['Prenom'].title()}",
budget=budget
)
def load_csv(sheet_id: str, sheet_name: str):
""" Load a google sheet """
url = f"https://docs.google.com/spreadsheets/d/{sheet_id}/gviz/tq?tqx=out:csv&sheet={sheet_name}"
return pd.read_csv(url)
def send_mail(email_cfg: argparse.Namespace, to_email: str, subject: str, body: str):
""" Function to send an email """
message = MIMEMultipart()
message['Subject'] = subject
message['From'] = email_cfg.from_email
message['To'] = to_email
message.attach(MIMEText(body, "html"))
msg_body = message.as_string()
# connect to smtp
server = SMTP(email_cfg.smtp_server, email_cfg.smtp_port)
server.starttls()
server.login(email_cfg.smtp_username, email_cfg.smtp_password)
# send email
server.sendmail(email_cfg.from_email, to_email, msg_body)
server.quit()
def make_pairs(data: pd.DataFrame):
""" Match each person in Dataframe with a random unique other person"""
givers = data.to_dict(orient="records")
takers = data.to_dict(orient="records")
for gv in givers:
choice = random.randrange(len(takers))
while gv["Email"] == takers[choice]['Email']:
choice = random.randrange(len(takers))
gv["gift_to"] = takers.pop(choice)
return givers
if __name__ == '__main__':
# load emails from google
df = load_csv(cfg.sheet_id, cfg.sheet_name)
# match people into pairs
people = make_pairs(df)
# backup people in case of issue
if KEEP_BACKUP:
with open('backup.log.json', 'w') as fp:
json.dump(people, fp)
# loop over people & send emails
for p in tqdm(people):
email_body = build_email_body(p, cfg.budget)
if TEST:
print(f'{p["Nom"]} {p["Prenom"]} --> {p["gift_to"]["Nom"]} {p["gift_to"]["Prenom"]}')
else:
send_mail(cfg, p['Email'], SUBJECT, email_body)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment