Metadata-Version: 2.3
Name: colette
Version: 0.2.3
Summary: Manage rounds of coffee roulette
License: AGPL3
Author: David Horsley
Author-email: david.e.horsley@gmail.com
Requires-Python: >=3.10,<4.0
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Dist: Jinja2 (>=3.1,<4.0)
Requires-Dist: appscript (>=1.2.2,<2.0.0) ; sys_platform == "darwin"
Requires-Dist: mip (>=1.13,<2.0)
Requires-Dist: pywin32 (>=306,<307) ; sys_platform == "win32"
Requires-Dist: tomlkit (>=0.12.1,<0.13.0)
Project-URL: Homepage, https://github.com/dehorsley/colette
Project-URL: Repository, https://github.com/dehorsley/colette.git
Description-Content-Type: text/markdown

# Colette: Coffee Roulette — pair with a random person for coffee

Colette is a command-line tool for organising pairings withing an organisation
or community. 

Aimed at organisations that want to encourage cross-team
collaboration, or communities that want to encourage networking, it can be used
to organise coffee roulettes, mentoring, or any other pairings.

It is designed to be simple to use, and to minimise the number of times people
are paired with the same person as more rounds are run and can automatically
send templated email to participants via Outlook, Mail.app or SMTP.

The algorithm can avoids pairing players from the same organisation or group,
and it also has the concept or roles withing the pair. For example if you would
like one participant to organise the meet-up, and the other to buy the coffee. One
can also specify pairs that should be avoided, or that should be prioritized.
These functions are optional.

Colette is written in Python, and is available on [PyPI](https://pypi.org/project/colette/).

## Installation

Colette requires Python 3.10+, and some familiarity with the command line.

Python can be obtained from [official Python distribution](https://python.org), or
[Anaconda](https://www.anaconda.com/products/individual) but be aware of the
non-free licensing of the latter. You will need to add python to your PATH.

To install the package run the following code in the command line

    pip install colette

Check the installation by running the following command:

    colette --help

This should print the help message.

## Getting started 

Once installed, you will need to create a working directory for your coffee
roulette. 

The directory should contain the following files:

| File/Directory       | Description                                                                                                           |
|----------------------|-----------------------------------------------------------------------------------------------------------------------|
| `people.csv`          | List of participants, in format described in the [next section](#peoplecsv) |
| `round_*.toml`        | Configuration files for each round. Generated by Colette to specify preferences like player exclusions and overrides.  |
| `solution_*.csv`      | Pairings generated by Colette. Alternatively, manually created if importing an existing program.                       |
| `templates/`          | Directory containing email templates                                                                                  |
| `templates/subject.txt`| File containing the subject line of the email                                                                         |
| `templates/body.html` | File containing the body of the email (can be plain text or HTML)                                                      |
| `email.ini` (optional)| Configuration file for sending emails using SMTP. If absent, Colette uses the default mail client on your computer.    |


### People.csv
You will need a `people.csv` comma separated value file with the following header

    name,organisation,email,active

You can create one with your favourite spreadsheet, or text editor.
Each participating (or previously participating) player should be listed on an
individual row with the following comma separated values:

-  `name` &mdash;  the name of the player and is the only field that must non-empty
 
-  `organisation` &mdash; whatever grouping sense for your programme. Colette 
    will try to avoid pairing people from the same "organisation" value. This can
    be left blank if you don't want to use this functionality.

-  `email` &mdash; populated with the email address of each player
if you want to use the email functionality.

- `active` &mdash; 
Used mark players as no longer participating in the
roulette. Note you can also use round configuration files to temporarily remove
players from a round. (Discussed below.) Must have one of the following values:

  - `1`, `true` or empty == active,
  - `0` or `false` == inactive. 

Other columns in the CSV are ignored, and can have any format.

### Templates 

If you want to use the email functionality, you will need to create
templates for the email subject and body. These are plain text files, use
the Jinja2 templating language, and are stored in the `templates` directory.

For example, the `subject.txt` file could look like this:

    Coffee Roulette ({{ round_config.date.strftime('%b-%Y') }})

Which will print the month and year of the round in the subject line.
Eg. "Coffee Roulette (Jan-2021)"

In the `body.html`, you can either use plain text, or HTML, for example

```html
<html>
<head></head>
<body>
Hi {{primary.name.split()[0]}} and {{secondary.name.split()[0]}},
<p>
The most advanced AI south of Campbell Town has been thinking long and
hard, and it has decided that it would be optimal for you two to have a
coffee this month.

<p>
Feel free to reschedule the time as it suits you! (It's not that clever.)

<div>
Cheers, <br>
The Coffee Robot <br>
</div>
</body>

</html>
```

The `primary` and `secondary` variables are populated people from the
`people.csv` file. If you wish to assign particular meaning or roles to the
`primary` and `secondary` designations, you can do so here.

Note Colette will try to swap the `primary` and `secondary` roles for a player
in each round, so that each player has a turn at being the "organiser" and the
"buyer".


### email.ini

If using SMTP email, you will need to create an `email.ini` file.
If you want to use Outlook or Mail.app, you remove this file.
This needs the following format:

```ini
[email]
from = Joe Bloggs <email.name@emailprovider.com>
server = smtp.emailprovider.com
port = 587
ssl = true
username = email.name@emailprovider.com
password = thepasswordfortheaccount
```

### Round configuration files (`round_*.toml`) (generated)

Colette will generate a `round_*.toml` file for each round. 

At a minimum, this file will need to contain the round `number` and a nominal `date`
for the round &mdash; with Colette will used to determine the availabiliy for participants. For example:

```toml
number = 28
date = 2023-11-06
```

These files can be also be used to specify players that are temporarily removed
from the round, overrides, and other preferences. If you want to
temporarily remove a player from the round, you can add a `[[remove]]` block to
the file, with the `name` of the player and the date or round number they should
be removed until.

For example:


```toml
## By round number:
[[remove]]
name = "Mary Poppins"
until = 29
# Mary is on holiday until next round

## Or by date:
[[remove]]
name = "Joe Bloggs"
until = 2044-01-01 
# Joe is in jail for the next 20 years
```


You can also add overrides to the round configuration file. For example, if you
want to avoid pairing two people, you can add a `[[override]]` block to the
file, with the `pair` of players and a `weight` to add to the cost of pairing

For example:

```toml
[[override]]
pair = ["Mary Poppins", "Joe Bloggs"]
weight = 1000000
# Mary and Joe are mortal enemies
# Joe made Mary's umbrella fly away
# Mary made Joe's coffee fly away
# They should never be paired
```

The `weight` is added to the cost of pairing the two players. So if you want to
prioritise pairing two people, you can add a negative weight. For example:

```toml
[[override]]
pair = ["Joe Bloggs", "Jane Doe"]
weight = -1000000
# Joe and Jane are in love
# They should always be paired
```

You can also add a `[[override]]` block to the file, with the `name` of the
player and a `role` to assign them. For example:

### Solution files (`solution_*.csv`)

Colette will generate a `solution_*.csv` file for each round. This file will
contain the pairings for the round. It will have the following header:

    primary,secondary,caveat

Where `primary` and `secondary` are the names of the players, and `caveats` is
a semi-colon separated list of warnings about the pairing. For example:

    primary,secondary,caveat
    Joe Bloggs,Mary Poppins,paired before
    Jane Doe,Thomas Tank,paired before;same organisation

If you want to import an existing solution, you can create a `solution_*.csv`
file manually. The only requirement is that the header is present, and the 
`primary` and `secondary` columns are populated with the names of the players.

The ordering of `primary` and `secondary` are not important if you don't want to
assign roles in the pairings.

## Running the roulette

Once you have the files, your ready to create a round. In the command line,


    colette new

> [!NOTE]
> 
> You may need to add the path pip installed colette too to your PATH
> environment variable.
>
> Alternatively you can run colette as
>
>     python -m colette

This will generate a new round configuration file. Make any changes you want to
the file (see above), and then make a pairing by running:

    colette pair


Inspect the `solution_*.csv` file to make sure you are happy with the pairings.
If you want to make changes, you can edit the `round_*.toml` file and re-run
by deleting the `solution_*.csv` file and re-running `colette pair`.

Once you are happy with the pairings, you can send the emails by running:

    colette email

By default, this will preview the emails in your default mail client. If you
want to send the emails, you can add the `--no-preview` flag:

    colette email --no-preview


Happy rouletting! Any problems with program itself, file an issue
on the [Colette Github project](https://github.com/dehorsley/colette/issues). 


## Tips

### Start a `round_*.toml` early

It can be useful to start a `round_*.toml` file early, and use it to keep track
of people who are going to be away. 

As people let you know they are going to be away, add them to the `remove`
section. This can make things easier when you come to generate the round.


### Handling odd numbers
If you have an odd number of people, Colette will have to remove someone from
the round. 

This is flagged by marking them as pairing with themselves. If you would
like to prioritise who is removed, for example you the organiser, you can add an
override to the round configuration file (in `round_n.toml`).  Something like:

```toml
[override]
pair = ["organiser", "organiser"]
weight = -900
```

Overrides are additive and the default weight for removing a player is 1000. 
So the net weight for removing the organiser will be 100.


### Importing existing programmes

If you have an existing solution, you can import it by creating
`solution_*.csv` files in the data directory (eg.
    coffee_roulette/solution_000001.csv, 
    coffee_roulette/solution_000002.csv ...
). The only requirement is that the
header is present, and the `primary` and `secondary` columns are populated with
the names of the players.


### Upgrading from v0.1.x

If you are upgrading from v0.1.x, you will need to change your templates. The
`subject.txt` and `body.html` files should now be in the `templates` directory,
instead of the old `organiser.template`, `buyer.template` and
`excluded.template` files.

You will also need to update your old solution files. The `organiser` and
`buyer` names are now `primary` and `secondary` in the solution files. You will
need to change your templates to reflect this. You can do so with the following
`sed` command (backup first!) 

    sed -i 's/organiser/primary/g' solution_*.csv
    sed -i 's/buyer/secondary/g' solution_*.csv

