Play & Win prize picker for Geekway to the West. It pulls game copies and plays from the ruleslawyer-backend library API, filters down to eligible plays, randomly selects winners for each awardable game copy, and produces winner lists and printable labels.
A standalone Python tool — not part of the Docker stack — that ships with a Gooey GUI but can also run headless from the command line.
- Loads game copies and plays (from the API, or from local JSON files with
--local). - Keeps only awardable Play & Win copies and eligible plays (filtering out plays outside the allowed duration and players who don't want to win or are on the ineligible list).
- Awards each copy a winner using one of two methods:
old_school— shuffle the plays, then pick one eligible player per play until all copies are awarded (falls back tostandardif it runs out of plays).standard— pick winners weighted by number of plays (more plays = more chances).
- Writes the winners, printable labels, and any unawarded games to files.
- Anaconda/Miniconda (Python 3.12)
- Auth0 credentials with access to the Rules Lawyer API
- Python packages:
pylabels,reportlab,requests,gooey
Create and activate a conda environment named pnw:
conda create -n pnw python=3.12
conda env create -f environment.yaml # installs from conda_packages.txt
conda activate pnw
pip install pylabels reportlab requests gooeySee Anaconda Setup.txt for OS-specific notes (Ubuntu, Arch, macOS).
Create the output directories if they don't already exist:
mkdir -p data logAuthentication uses the Auth0 client_credentials grant. Copy .env.example to .env and fill in:
| Variable | Description |
|---|---|
AUTH0_CLIENT_ID |
Auth0 machine-to-machine client ID |
AUTH0_CLIENT_SECRET |
Auth0 machine-to-machine client secret |
The code reads these from the environment (it does not auto-load .env), so export them into your shell before running, e.g.:
set -a; source .env; set +aRunning the tool launches the Gooey GUI:
python pnw_picker.pyTo run headless from the command line, pass --ignore-gooey along with the arguments:
python pnw_picker.py --ignore-gooey winners --method old_school --ineligible_players_fn staff.tsv| Argument | Description |
|---|---|
output_fn_prefix |
(required) prefix for the output filenames |
--method |
old_school or standard |
--ineligible_players_fn |
TSV of ID, Player Name to exclude (e.g. staff and family) |
--duration_min |
minimum play duration in minutes for a play to count |
--duration_max |
maximum play duration in minutes for a play to count |
--local |
read from local JSON files instead of the API |
-g, --games_source |
local games JSON (used with --local) |
-p, --plays_source |
local plays JSON (used with --local) |
Files are named <prefix>.<suffix>.<ext>, where <suffix> is a timestamp unless you supply one.
<prefix>.<suffix>.tsv— winners and the games they won, sorted by winner name<prefix>.<suffix>.pdf— labels to stick on the won games (Avery 6460), sorted by game name<prefix>.<suffix>.unawarded.tsv— plays for games that couldn't be fully awardeddata/games.<suffix>.json,data/plays.<suffix>.json— raw API responses (API mode only)log/*.tsv— debug dumps (all games, P&W games, awardable plays, filtered plays)
pnw_picker.py— entry point: winner selection logic and CLI/GUIpnw.py— data model (Game,Copy,GameCheckout,Win) and parsing/output helperspnw_api.py— Auth0 authentication and Rules Lawyer API requestscreate_mock_plays.py— generates mock plays for testingtest_pnw.py,test_requests.py— unit testsSQL Scripts/— analytics queries against the database (play stats, hoarding reports, etc.)Random Scripts/— one-off analysis utilities (BGG comparisons, checkout-over-time)
python -m unittest test_pnw.pyLicensed under Creative Commons Attribution 4.0 International (CC BY 4.0).