install_services.sh now symlinks five frontend files (index.html,
styles.css, apt.js, masks.json, dims.json) from avian/frontend/ into
the Caddy site root. Caddy serves index.html before index.php, so /
shows the collage and BirdNET-Pi's stock UI moves to /index.php
(still linked from the menu drawer).
API shims stay under /avian/api/. apt.js fetches them with
./avian/api/birdnet-api.php?action=X now that the frontend lives at
root instead of /avian/frontend/.
avian/index.html redirect file removed (no longer needed - / serves
the collage directly).
README + menu drawer updated to reflect / as the entry point and
/index.php as the stock-UI link.
Verified in Docker:
/ 200 text/html (collage, 4 tiles)
/masks.json 200 (276 KB)
/avian/api/... 200 (all PHP shims working)
Caddy serves index.html as default index, index.php still reachable
Restructures the install so users run ONE command. The fork's
newinstaller.sh clones this repo (instead of upstream Nachtzuster) and
runs BirdNET-Pi's installer. install_services.sh symlinks the avian/
overlay into the Caddy site root, so http://birdnet.local/avian/ comes
up after reboot with no Caddy config needed.
Reviewer-flagged fixes:
Frontend (avian/frontend/apt.js)
- Switch all API paths from /api/*.json (which didn't route) to relative
action-based URLs (./api/birdnet-api.php?action=recent etc.).
- Fetch ./masks.json + ./dims.json relatively (were /avian/*.json).
- Replace every innerHTML user-content sink with createElement +
textContent + setAttribute — species labels are user-editable in
BirdNET-Pi, so untrusted.
- Add esc() helper for the few remaining innerHTML attribute contexts.
- fetchJson throws on non-200 (was silently parsing 404 HTML as JSON).
- Defensive null-check in loadMask if MASKS hasn't loaded.
Backend (avian/api/*.php)
- birdnet-api.php now derives DB_PATH from dirname(__DIR__, 3) so any
BirdNET-Pi install user works (no hardcoded /home/birdnet).
- recording/spectrogram/cutout use getenv('HOME') for the same reason.
- cutout.php reworked as the canonical image resolver: bundled
illustration → bundled cutout → cached rembg → fresh
Wikipedia+rembg, with the binomial regex guard and atomic rename
on cache write. Wikipedia URL host pinned to wikimedia.org /
wikipedia.org to block SSRF.
- Stale 'X-BirdNET-Proxy-Token' auth claims removed everywhere.
Pregen (avian/scripts/pregen.py)
- Gemini key moved from URL query to x-goog-api-key header.
- Model bumped to gemini-2.5-flash-image-preview.
- Bounded retry on 429 + 5xx with Retry-After honoured.
- Default --sleep raised from 1s to 4s (under free-tier RPM).
- Unified parser handles |/_/comma in all three input modes.
- responseModalities now [TEXT, IMAGE] (was IMAGE-only).
- --poses validated against POSES keys.
- ASCII [ok]/[fail] markers (was ✓/✗ — Windows console crash).
- Surfaces finishReason + blockReason on safety blocks.
Prompt template
- 'Two placeholders' typo → three.
- 'warm paper' / 'transparent background' contradiction resolved.
Forwarding
- mqtt-bridge.py: paho-mqtt 2.x CallbackAPIVersion compat shim.
- avian-mqtt.service: dropped broken %i, set User=birdnet + %h path.
- forwarding/README.md uses the actual action-based URLs.
README
- One-line install via curl … newinstaller.sh.
- No more 'install BirdNET-Pi separately' step (our fork does it).
- License section uses absolute github.com links.
- bird.onethreenine.net replaces the not-yet-existent project writeup.
- docs/thumb.png replaced with the 24-bird Twitter capture.
Removed
- avian/caddy/ and avian/scripts/install.sh — no longer needed; the
overlay symlink in install_services.sh handles everything.
phpSysInfo (Tools -> System Info) requires the mbstring PHP extension.
Without it, the page shows:
checkForExtensions phpSysInfo requires the mbstring extension to php
in order to work properly.
Fixes#531
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update advanced.php
Added a checkbox in the Advanced Settings page to enable Automatic Update
* Update install_config.sh
The AUTOMATIC_UPDATE parameter needs to be created in the BirdNET-Pi configuration file.
* Update install_services.sh
Add a cron job to the system to performa automatic updates.
* Create automatic_update.cron
The line to be added to the cron table to check for need to perform automatic update.
* Create automatic_update.sh
Script to perform the automatic update if the flag is set in the configuration. Also, the services are restarted after the update.
* Update install_services.sh
* Update automatic_update.sh
* Update advanced.php
Correct typo
* Update update_birdnet_snippets.sh
Add the automatic_update.cron to the list of cron jobs
* Update update_birdnet_snippets.sh
* Update automatic_update.cron
Change automatic update to once a week on Sunday at 3AM
* Update update_birdnet_snippets.sh
Adjusted to add option to existing installations
* Update automatic_update.sh
Removed unnecessary call to restart_services.sh
* Update advanced.php
Cleaned up the Options section line spacing in the settings table
* Update templates/automatic_update.cron
Co-authored-by: Nachtzuster <Nachtzuster@users.noreply.github.com>
* Update scripts/update_birdnet_snippets.sh
Co-authored-by: Nachtzuster <Nachtzuster@users.noreply.github.com>
* Delete scripts/automatic_update.sh
* Update advanced.php
Modified the description of the Automatic Update feature on the Advanced Configuration tab.
* Update install_config.sh
---------
Co-authored-by: Nachtzuster <Nachtzuster@users.noreply.github.com>
I came across this in my console while trying to access Species Stats (Streamlit):

It seems that Streamlit collects telemetry data by default. An issue was raised in their GitHub repo (https://github.com/streamlit/streamlit/issues/4747), which details how it's illegal to collect data (even just the IP address) in Europe without explicit consent due to GDPR laws. The Streamlit founder then replied basically saying the onus is on the developers implementing Streamlit to deal with this themselves.
So I propose we disable sending data entirely, this PR does that.