first commit

This commit is contained in:
Simon Brooke 2026-09-27 15:34:12 +01:00
commit 79e51db335
6 changed files with 487 additions and 0 deletions

57
src/gaza_stats/core.clj Normal file
View file

@ -0,0 +1,57 @@
(ns gaza-stats.core
(:require [cljc.java-time.local-date :as ld]
[com.hypirion.clj-xchart :refer [xy-chart]]
[korma.core :refer [fields join select where]]
[korma.db :refer [defdb sqlite3]]))
;; create db
(defdb db (sqlite3
{:classname "org.sqlite.JDBC"
:subprotocol "sqlite"
:subname "resources/app.db"}))
(defmacro date? [x]
`(instance? java.time.LocalDate ~x))
(defn total-donations-by-weeks
"Return a list of pairs [java.time.LocalDate date, float amount] representing
the total of donations made between `start-date` and `end-date`. Arguments may
be supplied as `java.time.LocalDate` objects, or as strings in the format
`yyyy-mm-dd`. If `end-date` is not supplied, data for a single week will be
returned."
([start-date]
(let [sd (cond (date? start-date) start-date
(string? start-date) (ld/parse start-date))]
(total-donations-by-weeks sd (ld/plus-days sd 7))))
([start-date end-date]
(let [sd (cond (date? start-date) start-date
(string? start-date) (ld/parse start-date))
ed (cond (date? end-date) end-date
(string? end-date) (ld/parse end-date)
:else (ld/now))]
(loop [s sd
i (ld/plus-days sd 7)
r nil]
(let [r' (cons
[s (reduce +
(map :amount
(select 'campaign_donations
(fields :amount)
(where (and {:created_at [> s]}
{:created_at [<= i]})))))]
r)]
(if (ld/is-before ed i) (reverse r')
(recur i (ld/plus-days i 7) r')))))))
(defn chart-total-donations-by-weeks
"Create and return an XY chart of data on total donations made between
`start-date` and `end-date`. Arguments may be supplied as
`java.time.LocalDate` objects, or as strings in the format `yyyy-mm-dd`."
[start-date end-date]
(let [data (total-donations-by-weeks start-date end-date)]
(xy-chart {"Donations"
[(map #(java.util.Date/from
(.toInstant (.atStartOfDay (first %))
(java.time.ZoneOffset/ofHours 0)))
data)
(map #(nth % 1) data)]})))