feat: add uncertainty

This commit is contained in:
Fey Naomi Schrewe 2026-02-09 21:13:55 +01:00
parent 2ce1a3e8f2
commit d25f4925c0

View File

@ -2,6 +2,7 @@
(:require
[ebird]
[tailscale]
[taoensso.telemere :as tel]
[bling.core :as bling]
[bling.hifi]
[cheshire.core :as json]
@ -22,23 +23,34 @@
(def nearby (atom {}))
(def last-update (atom nil))
(def conservation-info (with-open [f (reader "./conservation.edn")] (parse-next (soy/reader f))))
(def conservation-info
(with-open [f (reader "./conservation.edn")] (parse-next (soy/reader f))))
(defn get-nearby [species]
(defn now []
(java.time.LocalDateTime/now))
(def date-formatter
(java.time.format.DateTimeFormatter/ofPattern "dd MMM HH:mm"))
(defn get-nearby [species]
(let [species (lower-case (species :latin))
nearby-info (@nearby species)
since (.minusDays (java.time.LocalDateTime/now) 1)]
since (.minusDays (now) 1)]
(if (and nearby-info (.isBefore since (:time nearby-info)))
nearby-info
(let [nearby-info (-> species
(ebird/get-recent)
(ebird/summarise-recent)
(assoc :time (java.time.LocalDateTime/now)))]
(assoc :time (now)))]
(swap! nearby #(assoc % species nearby-info))
nearby-info))))
(defn add-observation* [bird time certainty]
(bling/callout {:type :info} (str "Heard bird " (get-in bird [:name :en]) " (certainty " (* 100 certainty) "%)"))
(bling/callout {:colorway (condp < certainty
0.8 :warning
0.5 :positive
:subtle)
:label "Heard bird"}
(str (get-in bird [:name :en]) " (certainty " (* 100 certainty) "%)"))
(swap! observations #(conj % {:bird bird :time time :certainty certainty :seen-by #{}})))
(defn add-observation [{bird-name :bird certainty :certainty} time]
@ -55,7 +67,7 @@
(defn post-observation [request]
(let [body (json/parse-stream (reader (:body request)) true)
birds (:birds body)
now (java.time.LocalDateTime/now)]
now (now)]
(reset! last-update now)
(add-observations birds now)
{:status 200}))
@ -142,7 +154,9 @@
(let [observation-count (:observation-count nearby)]
[:li.closed
{:onclick "onExpand(this)"
:class [(if unseen :unseen :seen)]}
:class [(if unseen :unseen :seen)]
:data-certainty certainty}
[:span {:style (when (or (not observation-count) (= 0 observation-count))
"text-decoration-style:double;text-decoration-line:underline;text-decoration-skip-ink:all;")}
(or (get-in bird [:name :de])
@ -173,7 +187,6 @@
0.5 (str "color:" (:light-orange colours) ";")
nil)} (double (/ (math/round (* 10000 certainty)) 100.0))]
"&nbsp;%"]]))
(def date-formatter (java.time.format.DateTimeFormatter/ofPattern "dd MMM HH:mm"))
(defn filter-outdated [since obs]
(filter #(.isBefore since (:time %)) obs))
@ -184,7 +197,7 @@
(into [])))
(defn list-observation [{ip :remote-addr}]
(let [since (.minusDays (java.time.LocalDateTime/now) 1)
(let [since (.minusDays (now) 1)
whois (tailscale/whois ip)
user-id (get-in whois [:user-profile :id])
summary (summarise-observations (filter-outdated since @observations) user-id)]
@ -192,27 +205,30 @@
{:status 200
:headers {"charset" "utf-8"
"Content-Type" "text/html; charset=utf-8"}
:body (str (html5
(head)
[:body
{:style
(str "max-width: 800px;"
"margin-left: auto;"
"margin-right: auto;"
"font-family: \"B612 Mono\";"
"background-color:" (:background colours) ";"
"display: flex;"
"flex-direction: column;"
"min-height: 100vh;"
"color:" (:text colours) ";")}
[:header [:h1 "Birds today 🐦"
[:span {:style (str "font-size:0.3em;margin-left:3em;color:" (colours :brown))}
(str "last updated " (if @last-update
(.format @last-update date-formatter)
"never"))]]]
[:ul {:style "flex:1"}
(map template-observation summary)]
[:footer "(c) fey naomi, user: " [:i (get-in whois [:user-profile :display-name])]]]))}))
:body (str
(html5
(head)
[:body
{:style
(str "max-width: 800px;"
"margin-left: auto;"
"margin-right: auto;"
"font-family: \"B612 Mono\";"
"background-color:" (:background colours) ";"
"display: flex;"
"flex-direction: column;"
"min-height: 100vh;"
"color:" (:text colours) ";")}
[:header [:h1 "Birds today 🐦"
[:span {:style (str "font-size:0.3em;margin-left:3em;color:" (colours :brown))}
(str "last updated " (if @last-update
(.format @last-update date-formatter)
"never"))]]]
[:ul {:style "flex:1"}
(map template-observation summary)]
[:footer
"(c) fey naomi, user: "
[:i (get-in whois [:user-profile :display-name])]]]))}))
(def router
(wrap-with-logger