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 (:require
[ebird] [ebird]
[tailscale] [tailscale]
[taoensso.telemere :as tel]
[bling.core :as bling] [bling.core :as bling]
[bling.hifi] [bling.hifi]
[cheshire.core :as json] [cheshire.core :as json]
@ -22,23 +23,34 @@
(def nearby (atom {})) (def nearby (atom {}))
(def last-update (atom nil)) (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 now []
(java.time.LocalDateTime/now))
(def date-formatter
(java.time.format.DateTimeFormatter/ofPattern "dd MMM HH:mm"))
(defn get-nearby [species] (defn get-nearby [species]
(let [species (lower-case (species :latin)) (let [species (lower-case (species :latin))
nearby-info (@nearby species) nearby-info (@nearby species)
since (.minusDays (java.time.LocalDateTime/now) 1)] since (.minusDays (now) 1)]
(if (and nearby-info (.isBefore since (:time nearby-info))) (if (and nearby-info (.isBefore since (:time nearby-info)))
nearby-info nearby-info
(let [nearby-info (-> species (let [nearby-info (-> species
(ebird/get-recent) (ebird/get-recent)
(ebird/summarise-recent) (ebird/summarise-recent)
(assoc :time (java.time.LocalDateTime/now)))] (assoc :time (now)))]
(swap! nearby #(assoc % species nearby-info)) (swap! nearby #(assoc % species nearby-info))
nearby-info)))) nearby-info))))
(defn add-observation* [bird time certainty] (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 #{}}))) (swap! observations #(conj % {:bird bird :time time :certainty certainty :seen-by #{}})))
(defn add-observation [{bird-name :bird certainty :certainty} time] (defn add-observation [{bird-name :bird certainty :certainty} time]
@ -55,7 +67,7 @@
(defn post-observation [request] (defn post-observation [request]
(let [body (json/parse-stream (reader (:body request)) true) (let [body (json/parse-stream (reader (:body request)) true)
birds (:birds body) birds (:birds body)
now (java.time.LocalDateTime/now)] now (now)]
(reset! last-update now) (reset! last-update now)
(add-observations birds now) (add-observations birds now)
{:status 200})) {:status 200}))
@ -142,7 +154,9 @@
(let [observation-count (:observation-count nearby)] (let [observation-count (:observation-count nearby)]
[:li.closed [:li.closed
{:onclick "onExpand(this)" {: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)) [:span {:style (when (or (not observation-count) (= 0 observation-count))
"text-decoration-style:double;text-decoration-line:underline;text-decoration-skip-ink:all;")} "text-decoration-style:double;text-decoration-line:underline;text-decoration-skip-ink:all;")}
(or (get-in bird [:name :de]) (or (get-in bird [:name :de])
@ -173,7 +187,6 @@
0.5 (str "color:" (:light-orange colours) ";") 0.5 (str "color:" (:light-orange colours) ";")
nil)} (double (/ (math/round (* 10000 certainty)) 100.0))] nil)} (double (/ (math/round (* 10000 certainty)) 100.0))]
"&nbsp;%"]])) "&nbsp;%"]]))
(def date-formatter (java.time.format.DateTimeFormatter/ofPattern "dd MMM HH:mm"))
(defn filter-outdated [since obs] (defn filter-outdated [since obs]
(filter #(.isBefore since (:time %)) obs)) (filter #(.isBefore since (:time %)) obs))
@ -184,7 +197,7 @@
(into []))) (into [])))
(defn list-observation [{ip :remote-addr}] (defn list-observation [{ip :remote-addr}]
(let [since (.minusDays (java.time.LocalDateTime/now) 1) (let [since (.minusDays (now) 1)
whois (tailscale/whois ip) whois (tailscale/whois ip)
user-id (get-in whois [:user-profile :id]) user-id (get-in whois [:user-profile :id])
summary (summarise-observations (filter-outdated since @observations) user-id)] summary (summarise-observations (filter-outdated since @observations) user-id)]
@ -192,7 +205,8 @@
{:status 200 {:status 200
:headers {"charset" "utf-8" :headers {"charset" "utf-8"
"Content-Type" "text/html; charset=utf-8"} "Content-Type" "text/html; charset=utf-8"}
:body (str (html5 :body (str
(html5
(head) (head)
[:body [:body
{:style {:style
@ -212,7 +226,9 @@
"never"))]]] "never"))]]]
[:ul {:style "flex:1"} [:ul {:style "flex:1"}
(map template-observation summary)] (map template-observation summary)]
[:footer "(c) fey naomi, user: " [:i (get-in whois [:user-profile :display-name])]]]))})) [:footer
"(c) fey naomi, user: "
[:i (get-in whois [:user-profile :display-name])]]]))}))
(def router (def router
(wrap-with-logger (wrap-with-logger