123 lines
4.1 KiB
Markdown
123 lines
4.1 KiB
Markdown
# 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 = '<username>@gmail.com'
|
|
PASSWORD = '<app 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?
|