- Python 64.5%
- JavaScript 19%
- HTML 10.5%
- Shell 4.2%
- CSS 1.6%
- Other 0.2%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| app | ||
| migrations | ||
| presentations | ||
| scripts | ||
| tests | ||
| .gitignore | ||
| config.py | ||
| LICENSE | ||
| pytest.ini | ||
| README.md | ||
| requirements.txt | ||
| run.py | ||
Pickup Scheduler
A calendar-based scheduling tool for logistics teams to manage pickups and deliveries. Events display in a calendar view, export to iCalendar, and generate printable PDF tickets for drivers.
Features
- Calendar Overview — Monthly calendar grid with events, blocked days, and holidays color-coded for quick scanning
- Event Management — Create, edit, and delete pickup/delivery events with customer details (name, phone, address), item descriptions, and vehicle assignments
- PDF Tickets — Download printable PDF tickets per event for drivers (requires login)
- iCalendar Subscription — Per-user, revocable
.icssubscription link for importing the schedule into external calendar apps - Blocked Days — Mark date ranges as unavailable to prevent scheduling conflicts
- Holiday Calendar — Automatically sync public holidays from an iCal feed (refreshes every 30 days)
- Data Retention — Automatically anonymizes customer data on events older than
EVENT_RETENTION_DAYS, keeping only the timestamps - Role-Based Access — Four permission levels: viewer, editor, admin, and owner
- User Management — Admins can create, edit, and deactivate user accounts; registration can be toggled on/off
- Mobile-Friendly — Responsive layout switches to an agenda view on narrow screens
- Vehicle Tracking — Optionally assign vehicles to events (toggle via config)
Quick Start
Prerequisites
- Python 3.11+
- SQLite
Setup
git clone <repository-url>
cd pickup_scheduler
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Create a .env file:
FLASK_CONFIG=DevelopmentConfig
SECRET_KEY=<your-secret-key>
JWT_SECRET_KEY=<your-jwt-secret>
DATABASE_URL=sqlite:///app.db
OWNER_USERNAME=admin
OWNER_PASSWORD=<your-admin-password>
OWNER_NAME=Admin
REGISTRATION_ENABLED=true
SHOW_VEHICLES=true
HOLIDAY_CALENDAR_URL=https://www.thunderbird.net/media/caldata/autogen/SwedishHolidays.ics
EVENT_RETENTION_DAYS=365
TRUSTED_PROXIES=
EVENT_RETENTION_DAYS controls how long customer details (name, phone number, address) are kept after an event's effective end date. After this window, the personal data is scrubbed and only the timestamps, event type, and actor remain; set to 0 to disable.
When the app sits behind a reverse proxy (e.g. nginx/caddy), set TRUSTED_PROXIES to the proxy's IPs/CIDRs (comma-separated, e.g. 127.0.0.1,::1). The audit trail then records the real client IP from the leftmost X-Forwarded-For entry; otherwise the header is ignored and the socket peer IP is used. run_retention continues to check the raw socket IP only.
The retention sweep runs automatically when the app handles a request (at most once per day). For a guaranteed, deterministic sweep on an idle server, schedule a cron job that calls the local /run_retention endpoint:
# crontab (root or any user; the endpoint only accepts localhost by default)
@daily curl -fsS -X POST http://127.0.0.1:3000/run_retention >> /var/log/pickup_retention.log 2>&1
- The endpoint refuses requests from any IP outside
RETENTION_ALLOWED_IPS(default127.0.0.1,::1); add more IPs as a comma-separated list in.envif the app sits behind a reverse proxy on another host. curl -fexits non-zero on HTTP errors so cron mail/journal surfaces failures.- Response is JSON:
{"success": true, "anonymized": N}(or{"skipped": "retention disabled"}whenEVENT_RETENTION_DAYS=0).
Run migrations and start the server:
flask db upgrade
python run.py
Usage
| What you can do | How |
|---|---|
| View schedule | Open the app — events, blocked days, and holidays appear on the calendar |
| Add event | Click a date or use the "Nytt event" button |
| Block a date | Admin panel → "Blockerade dagar" tab → pick date(s) |
| Print driver ticket | Click an event → "PDF" button (requires login) |
| Export calendar | Use "Hämta ICS" for your subscription link; "Förnya kalenderlänk" revokes it |
| Manage users | Admin panel → "Användare" tab |
Deployment
sudo ./scripts/deploy.sh deploy
The deploy script also supports upgrade, start, stop, restart, and status commands.
Testing
pytest -v
License
MIT License — see LICENSE for details.