- Python 95%
- Dockerfile 5%
| Containerfile | ||
| funding-scout.container | ||
| funding-scout.timer | ||
| funding_scout.py | ||
| README.md | ||
| requirements.txt | ||
| sources.yaml | ||
funding-scout
Weekly scan of ~16 funding-body websites (Vinnova, Formas, VR, Trafikverket,
K2, RJ, STINT, VREF, FIA Foundation, EU F&T Portal, COST, MSCA, ERC, TRB —
see sources.yaml) for opportunities relevant to transport safety, cycling
safety, active mobility and motonormativity research. Writes one Markdown
file into your Silverbullet space, in the same format every week.
How it works (and its limits)
There's no funding-search API key in this setup, so the script scrapes
public listing pages directly: it fetches each page (with a headless
Chromium via Playwright, since several of these sites are JS-rendered
single-page apps), pulls out every link plus its surrounding text, and
keeps anything matching a keyword list (transport, cycling, traffic
safety, mobility, motonormativity, etc. — see KEYWORDS in
funding_scout.py). It then tries to extract a deadline and an amount
from the surrounding text with regex + date parsing.
This is a best-effort heuristic, not a real integration. It will:
- occasionally mis-parse or miss a deadline (flagged with ⚠️ in the report)
- occasionally miss a call entirely if a site's HTML changes
- occasionally include a false positive
Treat the weekly file as a first pass to skim, not a source of truth —
always open the linked call page before acting on a date or amount.
Expect to spend 10–15 minutes every couple of months tuning
KEYWORDS/TYPE_RULES in funding_scout.py or fixing a URL in
sources.yaml when a source goes quiet.
Files
| File | Purpose |
|---|---|
funding_scout.py |
The scraper + Markdown renderer |
sources.yaml |
List of sites to scan — edit freely |
requirements.txt |
Python deps |
Containerfile |
Builds the image (Playwright + Chromium included) |
funding-scout.container |
Podman Quadlet unit (the "service") |
funding-scout.timer |
Plain systemd timer that runs it weekly |
One-time setup
1. Find your Silverbullet volume name.
podman volume ls
2. Build the image.
cd funding-scout/
podman build -t funding-scout:latest -f Containerfile .
3. Edit funding-scout.container: replace <SILVERBULLET_VOLUME> with
the volume name from step 1. Adjust the OUTPUT_PATH subfolder
(/output/spaces/jakub/funding/funding-radar.md) if you'd rather it land somewhere
else in your space.
4. Install the Quadlet + timer. For a rootless setup (most common for a home server):
cp funding-scout.container /etc/containers/systemd/
cp funding-scout.timer /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now funding-scout.timer
5. Test it manually before waiting a week:
systemctl start funding-scout.service
journalctl -u funding-scout.service -f
Need to restart silverbullet.services. Then check your Silverbullet space for spaces/jakub/funding/funding-radar.md afterwards.
Rebuilding after edits
Any time you change funding_scout.py or sources.yaml:
podman build -t funding-scout:latest -f Containerfile .
systemctl start funding-scout.service
No need to touch the Quadlet or timer files for a code change — only if you rename things or change the output path.