11 KiB
gaza-stats
A Clojure library designed to explore donations data for people in Gaza whose accounts have been verified by the Gaza Verified volunteers.
Dependencies
Usage
This is a very experimental, unfinished and unpolished library designed for use with leiningen. To use, clone this repository, connect to the directory into which you cloned it, and type lein repl.
At present several useful functions are implemented:
gaza-stats.core
Functions to interrogate the gaza.onl database.
accounts-with-donations-by-date-range
(accounts-with-donations-by-date-range start-date end-date)
Return a list of maps, each representing one account from the gaza.onl database, with a key :donations, whose value is a float representing the total donations received by that account between the dates start-date (exclusive) and end-date (inclusive). Date arguments should be supplied as java.time.LocalDate objects, or as strings in the format yyyy-mm-dd.
active-accounts
(active-accounts date)
Return, as an integer, the number of accounts believed to have been active on this date, which should be supplied as java.time.LocalDate objects, or as strings in the format yyyy-mm-dd
average-donations-received-by-month
(average-donations-received-by-month start-date end-date)
Return data as a map keyed by the date of the first of each month between start-date and end-date; the values are maps with keys :average, :count and :total. Arguments should be supplied as java.time.LocalDate objects, or as strings in the format yyyy-mm-dd.
db
TODO: write docs
db-spec
Database specification in a format which can be used with either JDBC or Korma.
enhance-account-with-donations
(enhance-account-with-donations account-map sd ed)
Take this account_map, which must at least have a valid value for the key :campaign_url and return a similar map including the key :donations, whose value is a float representing the total donations received by that campaign URL between the dates sd (exclusive) and ed (inclusive). Date arguments should be supplied as java.time.LocalDate objects.
local-date->date
macro
(local-date->date x)
Construct and return a new java.util.Date object from a java.time.LocalDate object. As usual, doing anything with Java time/date stuff is a complete bureaucratic nightmare.
local-date?
macro
(local-date? x)
Is this x an instance of java.time.LocalDate?
normalise-date
macro
(normalise-date date default)
More messing around with Java’s bizarre mess of date/time classes. We want our default date representation to be java.time.LocalDate, except, of course, when we don’t.
total-donations-by-weeks
(total-donations-by-weeks start-date)``(total-donations-by-weeks start-date end-date)
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.
gaza-stats.chart
Produce charts from data functions in other namespaces.
chart-accounts-with-donations-by-months-in-range
(chart-accounts-with-donations-by-months-in-range start-date end-date)
Return a chart with one line for each calendar month covering from start-date (inclusive) to end-date (inclusive). Arguments should be supplied as java.time.LocalDate objects, or as strings in the format yyyy-mm-dd, showing donations as for chart-donations-by-accounts-in-date-range, q.v.
chart-average-donations-received-by-month
(chart-average-donations-received-by-month start-date end-date)
Return a chart comparing the average donations received per account with the total number of active accounts per month between start-date and end-date. Arguments should be supplied as java.time.LocalDate objects, or as strings in the format yyyy-mm-dd.
chart-donations-as-percentage-in-date-range
(chart-donations-as-percentage-in-date-range start-date end-date)
Return a chart of donations received by individual accounts between start-date (exclusive) and end-date (inclusive). Arguments should be supplied as java.time.LocalDate objects, or as strings in the format yyyy-mm-dd. Accounts are identified in the chart only by rank order.
chart-donations-by-accounts-in-date-range
(chart-donations-by-accounts-in-date-range start-date end-date)
Return a chart of donations received by individual accounts between start-date (exclusive) and end-date (inclusive). Arguments should be supplied as java.time.LocalDate objects, or as strings in the format yyyy-mm-dd. Accounts are identified in the chart only by rank order.
chart-donations-by-donor
(chart-donations-by-donor start-date end-date key)``(chart-donations-by-donor start-date end-date key exclude-anons)
Return a rank-ordered graph of the values of this key in the donations-by-donor data between this start-date and this end-date.
chart-donations-by-weeks
(chart-donations-by-weeks start-date end-date key)
Create and return an XY chart of data on field represented by key 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.
chart-number-donations-by-weeks
(chart-number-donations-by-weeks start-date end-date)
Create and return an XY chart of data on number 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.
chart-total-donations-by-weeks
(chart-total-donations-by-weeks start-date end-date)
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.
gaza-stats.donors
Statistics on donors.
donations-by-donor
(donations-by-donor start-date end-date)
Return a sequence of maps, one representing each donor who has donated between start-date and end-date, each with keys :count, :donor and :total
Viewing charts
In your REPL, invoke (require '[com.hypirion.clj-xchart :refer [view]]). You
can then invoke view on a chart returned by the above function, for example:
(view (chart-total-donations-by-weeks "2024-04-01" "2026-09-20"))
Saving charts as graphics files
Again, xchart provides facilities for saving charts as graphics files. To do this, in your REPL first invoke (require '[com.hypirion.clj-xchart :refer [spit]]). This will, obviously, over-ride clojure,core/spit. You can now save a chart as a graphic using, e.g.:
(spit (chart-accounts-with-donations-by-months-in-range "2025-01-01" "2025-12-31") "donations-by-months-2025.svg")
The graphics format will be taken from the file extension, and at least all of bmp, gif, jpg, png, and, most importantly, svg are supported. The SVG is properly constructed as a drawing rather than as a raster, although there is no semantic labelling of the nodes or edges, which is disappointing.
NOTE: Data
This code is designed to explore data in a SQLite database which it expects to be called app.db and find in its resources directory. This database is not included in this repository but may be downloaded from here.
NOTE: Currency of amount column
The campaign_donations table has a column amount. I don't have any documentation on what currency the column is denominated in, but by inspecting my own donations, which I know to be in Pounds Sterling, I infer the column is probably denominated in US Dollare.
NOTE: Use of SQL Korma
I used SQL Korma in this project because I know it and I like it, but it is no longer maintained and its website is no longer online. The last version I could find on the Internet Archive is here. The source code is on Github. It might be better to rewrite so as not to use it, especially given that (at present) the SQL usage is trivial.
License
Copyright © 2026 Simon Brooke.
This program and the accompanying materials are made available under the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version, with the GNU Classpath Exception which is available at https://www.gnu.org/software/classpath/license.html.
