v_1.2
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# Birthday Manager
|
||||
|
||||
Self-hosted birthday reminder application that automatically e-mails people on their birthday.
|
||||
|
||||
© 2026 Martinhal IT - Joao Vaz - Version 1.2
|
||||
|
||||
## Features
|
||||
|
||||
**Page 1 — Dashboard**
|
||||
- Three panels at the top: **Yesterday's Birthdays**, **Today's Birthdays** (with the **Force Send** button to resend the e-mail) and **Tomorrow's Birthdays**
|
||||
- Add / remove birthday entries: First Name, Last Name, Date of Birth, Gender, E-mail address
|
||||
- Yearly calendar overview of all entries (hover a marked day to see the names; browse other years)
|
||||
|
||||
**Page 2 — Administration**
|
||||
- Add / remove application users
|
||||
- Every user can enable/disable MFA (TOTP — Google Authenticator, Authy, etc.) and change their own password
|
||||
- Full e-mail log: who received mail, at what date & time, and whether it succeeded
|
||||
- Setting for the time of day the automatic birthday e-mails are sent (applies immediately, no restart needed)
|
||||
- Two template zones: **E-mail Template Male** and **E-Mail Template Female**, with placeholders `{first_name}`, `{last_name}`, `{age}`
|
||||
- Image upload — select multiple files at once (15 MB total per upload); each image shows its ready-to-copy `<img src="/uploads/…">` command, and images are embedded inline in the outgoing e-mail
|
||||
|
||||
Automatic sending: a scheduler runs every day at `SEND_HOUR` (default 08:00) and e-mails everyone whose birthday it is, using the template matching their gender. Duplicates are avoided (one automatic mail per person per day); **Force Send** always resends. February 29 birthdays are celebrated on February 28 in non-leap years.
|
||||
|
||||
Every successfully sent e-mail is also copied to the mailbox's **Sent** folder via IMAP, so it shows up in your normal mail client.
|
||||
|
||||
## Mail provider
|
||||
|
||||
The app comes pre-configured for **Purelymail**:
|
||||
|
||||
| | Server | Port | Security |
|
||||
|---|---|---|---|
|
||||
| Outgoing (SMTP) | `smtp.purelymail.com` | `465` | SSL/TLS |
|
||||
| Incoming (IMAP, Sent-folder copy) | `imap.purelymail.com` | `993` | SSL/TLS |
|
||||
|
||||
You only need to fill in `SMTP_USER`, `SMTP_PASS` and `SMTP_FROM` with your Purelymail mailbox credentials. If your network only supports STARTTLS for SMTP, set `SMTP_PORT=587` and `SMTP_SECURITY=starttls` instead. Any other provider works too — just override the host/port variables.
|
||||
|
||||
## Quick start (Docker — recommended)
|
||||
|
||||
1. Edit `docker-compose.yml` and fill in your Purelymail credentials (`SMTP_USER`, `SMTP_PASS`, `SMTP_FROM`) plus a random `SECRET_KEY` and your timezone.
|
||||
2. Run:
|
||||
|
||||
```bash
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
3. Open http://localhost:8080 and log in with **admin / admin** — then change the password on the Administration page immediately.
|
||||
|
||||
All data (SQLite database + uploaded images) lives in `./data`, so back up that folder.
|
||||
|
||||
## Quick start (plain Python)
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Purelymail servers are the built-in defaults - only credentials are needed
|
||||
export SMTP_USER=you@yourdomain.com
|
||||
export SMTP_PASS=your-purelymail-password
|
||||
export SMTP_FROM=you@yourdomain.com
|
||||
export SEND_HOUR=8
|
||||
export SECRET_KEY=$(python -c "import secrets;print(secrets.token_hex(32))")
|
||||
|
||||
python app.py
|
||||
```
|
||||
|
||||
The app listens on port 8080 (`PORT` env var to change). Data is stored in `./data` (`DATA_DIR` env var to change).
|
||||
|
||||
## Environment variables
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `SMTP_HOST` | `smtp.purelymail.com` | SMTP server |
|
||||
| `SMTP_PORT` | `465` | SMTP port |
|
||||
| `SMTP_USER` | – | SMTP username / mailbox |
|
||||
| `SMTP_PASS` | – | SMTP password |
|
||||
| `SMTP_FROM` | `SMTP_USER` | From address |
|
||||
| `SMTP_SECURITY` | `ssl` | `ssl`, `starttls` or `none` |
|
||||
| `IMAP_HOST` | `imap.purelymail.com` | IMAP server for the Sent-folder copy |
|
||||
| `IMAP_PORT` | `993` | IMAP port (SSL/TLS) |
|
||||
| `IMAP_USER` | `SMTP_USER` | IMAP username |
|
||||
| `IMAP_PASS` | `SMTP_PASS` | IMAP password |
|
||||
| `IMAP_SENT_FOLDER` | `Sent` | Mailbox folder sent mail is stored in |
|
||||
| `SEND_HOUR` | `8` | Default hour for the daily send — the time picked on the Administration page overrides this |
|
||||
| `SECRET_KEY` | random | Flask session key — set it so logins survive restarts |
|
||||
| `PORT` | `8080` | HTTP port |
|
||||
| `DATA_DIR` | `./data` | Where the database and uploads are stored |
|
||||
|
||||
## Notes
|
||||
|
||||
- The e-mail address field on entries is required because it is where the birthday greeting is sent.
|
||||
- Failed sends (e.g. SMTP misconfigured) are also recorded in the e-mail log with the error as tooltip on the "Failed" status. If a mail is delivered but the IMAP copy to the Sent folder fails, the mail is still logged as Sent and the IMAP error appears as a tooltip.
|
||||
- Run behind a reverse proxy (nginx / Caddy / Traefik) with HTTPS if you expose it beyond your LAN.
|
||||
Reference in New Issue
Block a user