# README This is a Python script for running a secret Santa draw. This script: - Ingests participant data in JSON format, - Automates the randomised pairing of people to buy gifts for, - Includes information about preferences or restrictions for gifts that participants may have, - Automatically emails participants via GMail SMTP (requires external set-up), and - Creates an output file of gift pairings for troubleshooting later. The script only uses standard libraries that come bundled with Python distributions, and does not require installing any dependencies. ## Set Up ### GMail SMTP This app uses GMail as an SMTP provider. - This is because GMail accounts are free and easy to create, - The server is trusted by spam filters and is unlikely to be flagged as junk, and - The app can authenticate without using any external libraries. This means that there will be a few steps of external set up. - [ ] Create `secret.py` from a copy of `secret.py.bak`. - [ ] Log in to (or create) a GMail account (a standard, free account should suffice). - [ ] Enable two-factor authentication on the account. - [ ] Under the two-factor authentication section, generate an `App Password`. - [ ] Enter your GMail username and the generated app password in `secret.py`. `secret.py` ```py USERNAME = '@gmail.com' PASSWORD = '' ``` You can get more information on [how to do this in the GMail documentation](https://support.google.com/mail/answer/185833?hl=en-GB). #### Using a Different SMTP Server You can set up a different SMTP provider by editing the server information in `config.py` and providing the appropriate username and password in `secret.py`. ### Data The script ingests data as a JSON file. Create a file `data.json` (matching the file path in `config.py`) in the following format: `data.json` ```json { "name0": { "email": "string", "preference": "string" }, "name1": { "email": "string", "preference": "string" } } ``` > [!NOTE] > **Punctuation**: Comma after every entry, except the last entry. JSON syntax is very fragile and can break if not entered correctly. > [!TIP] > **Email Addresses**: If you have provided an `EMAIL_DOMAIN` value in `config.py`, then you do not need to add the full email address, and can just provide the username before the `@`. If you do provide a full email address for a participant in the data file, it will override the domain name given. ### Configuration You can configure the app to send the draw for the secret Santa, including the greeting and the sign-off used, via the values in `config.py`. You can also edit the files in the `./templates` directory to customise the email message to include any additional instructions or text as needed. The most important configurations, however, are the credentials in `secret.py` and the data in `data.json` ## Running the script Because this script should work using standard libraries in Python 3, you should be able to execute the script using whatever Python 3 interpreter you have. `PowerShell` ```powershell > python app.py ``` `Bash` ```bash $ python3 app.py ``` ## The Algorithm The algorithm I used for the secret santa draw is a very elegant one, as [illustrated by Prof Hannah Fry](https://www.youtube.com/watch?v=GhnCj7Fvqt0). - Randomise the order of participants. - Generate a derangement from the randomised order by shifting the top name to the bottom of the list. - Match participants between the randomised list and derangement to pair who is buying for whom. This ensures that: - People know whom they are buying for, but do not know who else is buying for whom, and - Everybody has an equal chance of buying for everybody else. - The person running the draw also does not know who is buying for them (unless they peek behind the curtain, as it were). ## Troubleshooting If you do need to see who is buying for whom, you can check the `output.json` file, or check the sent emails from the SMTP server. ## Isn't This an Over-Engineered Solution for a Trivial Problem? Of course it is. ## Why Not Use an Existing Site for This? Because where is the fun in that?