diff --git a/src/core.clj b/src/core.clj index 17f7db1..a75499b 100644 --- a/src/core.clj +++ b/src/core.clj @@ -8,23 +8,23 @@ [clojure.java.io :refer [reader]] [bling.core :as bling] [bling.hifi] - [hiccup2.core :as h] + [hiccup.page :refer [html5]] [taoensso.telemere :as tel])) (def known-species (atom {})) (def observations (atom [])) -(defn add-observation* [bird time] - (swap! observations #(conj % {:bird bird :time time})) - (bling/callout {:type :info} (str "Saw bird " (get-in bird [:name :en])))) +(defn add-observation* [bird time certainty] + (swap! observations #(conj % {:bird bird :time time :certainty certainty})) + (bling/callout {:type :info} (str "Heard bird " (get-in bird [:name :en]) " (certainty " (* 100 certainty) "%)"))) -(defn add-observation [bird time] - (let [?species (@known-species bird)] +(defn add-observation [{bird-name :bird certainty :certainty} time] + (let [?species (@known-species bird-name)] (if (not ?species) - (let [species (wd/get-bird bird)] - (swap! known-species #(assoc % bird species)) - (add-observation* species time)) - (add-observation* ?species time)))) + (let [species (wd/get-bird bird-name)] + (swap! known-species #(assoc % bird-name species)) + (add-observation* species time certainty)) + (add-observation* ?species time certainty)))) (defn add-observations [birds time] (doseq [bird birds] (add-observation bird time))) @@ -36,17 +36,82 @@ (add-observations birds now) {:status 200})) +(defn head [] + [:head + [:link {:rel "preconnect" :href "https://fonts.googleapis.com"}] + [:link {:rel "preconnect" :href "https://fonts.gstatic" :crossorigin true}] + [:link {:rel "stylesheet" :href "https://fonts.googleapis.com/css2?family=B612+Mono:ital,wght@0,400;0,700;1,400;1,700&family=Cinzel:wght@400..900&display=swap"}] + [:title "Bird observations"]]) + +(defn summarise-species [s] + {:bird (:bird (first s)) + :certainty (apply max (map :certainty s)) + :count (count s) + :first-seen (apply min (map #(.toEpochSecond (.atZone (:time %) (java.time.ZoneId/of "Europe/Berlin"))) s))}) + +(defn summarise-observations [observations since] + (->> observations + (filter #(.isBefore since (:time %))) + (group-by #(get-in % [:bird :latin])) + (vals) + (map summarise-species) + (sort-by :first-seen))) + + + +(def colours {:text "#333e51" + :background "#edf0f5" + :brown "#614d49" + :orange "#fd6940" + :light-orange "#f89f27" + :yellow "#ffd42f" + :pale "#f4f190" + :green "#bccb88" + :dark-green "#528026" + :blue "#31A0C5"}) +(defn template-observation [{bird :bird certainty :certainty count :count}] + [:li + (get-in bird [:name :en]) + " " + [:span.latin + {:style (str + "font-variant: small-caps;" + "font-family: Cinzel;" + "font-weight: 600;" + "text-decoration-style: dashed;" + "text-decoration-line: underline;" + "color:" (:brown colours) ";")} + (:latin bird)] + [:br] + [:span.certainty + {:style (str + "font-size: 0.8em;" + "font-style: italic;" + )} + (str "Seen " count " times with maximum likelihood ") + [:span {:style (condp < certainty + 0.8 (str "color:" (:orange colours) ";") + 0.5 (str "color:" (:light-orange colours) ";") + nil)} certainty]]]) (defn list-observation [_] (let [since (.minusDays (java.time.LocalDateTime/now) 1) - observations (map first (vals (group-by #(get-in % [:bird :latin]) (filter #(.isBefore since (:time %)) @observations)))) - template-observation (fn [{bird :bird}] [:li (str (get-in bird [:name :en]) " (" (:latin bird) ")")])] + observations (summarise-observations @observations since)] {:status 200 - :body (str (h/html {:mode :html} - [:html [:body - [:section - [:h1 "Birds today"] - [:ul - (map template-observation observations)]]]]))})) + :body (str (html5 {:mode :html} + [:html + (head) + [:body + {:style + (str "max-width: 800px;" + "margin-left: auto;" + "margin-right: auto;" + "font-family: \"B612 Mono\";" + "background-color:" (:background colours) ";" + "color:" (:text colours) ";")} + [:section + [:h1 "Birds today"] + [:ul + (map template-observation observations)]]]]))})) (def router (wrap-with-logger diff --git a/todos.md b/todos.md new file mode 100644 index 0000000..f1c011a --- /dev/null +++ b/todos.md @@ -0,0 +1,6 @@ +- Add links to wikipedia +- Add button to remove low likelihood +- Send summary email in the morning +- Tidy memory periodically +- Split log and notification +- Get user for fun & profit