chore: initial commit

This commit is contained in:
Fey Naomi Schrewe 2025-09-06 23:23:57 +02:00
commit 19d3a19427
3 changed files with 110 additions and 0 deletions

20
deps.edn Normal file
View File

@ -0,0 +1,20 @@
{:deps {com.yetanalytics/flint {:mvn/version "0.3.0"
:exclusions [org.clojure/clojuresript]}
ring/ring {:mvn/version "1.14.2"}
ring-logger/ring-logger {:mvn/version "1.1.1"}
metosin/reitit {:mvn/version "0.9.1"}
org.babashka/http-client {:mvn/version "0.4.22"}
com.taoensso/telemere {:mvn/version "1.1.0"}
com.taoensso/telemere-slf4j {:mvn/version "1.1.0"}
hiccup/hiccup {:mvn/version "2.0.0"}
cheshire/cheshire {:mvn/version "6.1.0"}
io.github.paintparty/bling {:mvn/version "0.8.8"}}
:aliases {:repl/conjure
{:extra-deps {nrepl/nrepl {:mvn/version "1.0.0"}
cider/cider-nrepl {:mvn/version "0.42.1"}}
:main-opts ["--main" "nrepl.cmdline"
"--middleware" "[cider.nrepl/cider-middleware]"
"--interactive"]}
:uberdeps {:replace-deps {uberdeps/uberdeps {:mvn/version "1.4.0"}}
:replace-paths []
:main-opts ["-m" "uberdeps.uberjar"]}}}

61
src/core.clj Normal file
View File

@ -0,0 +1,61 @@
(ns core
(:require [wikidata :as wd]
[cheshire.core :as json]
[reitit.ring :as ring]
[ring.adapter.jetty]
[ring.middleware.reload]
[ring.logger :refer [wrap-with-logger]]
[clojure.java.io :refer [reader]]
[bling.core :as bling]
[bling.hifi]
[hiccup2.core :as h]
[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]
(let [?species (@known-species bird)]
(if (not ?species)
(let [species (wd/get-bird bird)]
(swap! known-species #(assoc % bird species))
(add-observation* species time))
(add-observation* ?species time))))
(defn add-observations [birds time]
(doseq [bird birds] (add-observation bird time)))
(defn post-observation [request]
(let [body (json/parse-stream (reader (:body request)) true)
birds (:birds body)
now (java.time.LocalDateTime/now)]
(add-observations birds now)
{:status 200}))
(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) ")")])]
{:status 200
:body (str (h/html {:mode :html}
[:html [:body
[:section
[:h1 "Birds today"]
[:ul
(map template-observation observations)]]]]))}))
(def router
(wrap-with-logger
(ring/ring-handler
(ring/router
[["/" {:get list-observation}]
["/observation" {:post post-observation}]])
(ring/create-default-handler))))
(ring.middleware.reload/wrap-reload (ring.adapter.jetty/run-jetty #'router {:port 8080}))

29
src/wikidata.clj Normal file
View File

@ -0,0 +1,29 @@
(ns wikidata
(:require [com.yetanalytics.flint :as f])
(:require [babashka.http-client :as http])
(:require [cheshire.core :as json]))
(def wikidata-query-url "https://query.wikidata.org/sparql")
(defn- query [latin]
(-> `{:prefixes {:wdt "<http://www.wikidata.org/prop/direct/>"
:wd "<http://www.wikidata.org/entity/>"
:bd "<http://www.bigdata.com/rdf#>"
:wikibase "<http://wikiba.se/ontology#>"}
:select [~'?name]
:where [[~'?bird :wdt/P31 :wd/Q16521]
[~'?bird :wdt/P225 ~latin]
[~'?bird :wdt/P1843 ~'?name]
[:service :wikibase/label [[:bd/serviceParam :wikibase/language "en,de,fr"]]]]
}
(f/format-query :pretty true)))
(defn get-bird [latin]
(let [bindings (-> (http/get wikidata-query-url {:query-params {:query (query latin) :format "json"}})
(:body)
(json/parse-string true)
(:results)
(:bindings))]
{:name (apply hash-map (flatten (map (fn [{name :name}] [(keyword (:xml:lang name)) (:value name)]) bindings))) :latin latin}))