Skip to content

Instantly share code, notes, and snippets.

View simon-brooke's full-sized avatar
💭
Semper in faecibus sumus, sole profundam variat.

Simon Brooke simon-brooke

💭
Semper in faecibus sumus, sole profundam variat.
View GitHub Profile
@simon-brooke
simon-brooke / latest_version.clj
Last active June 9, 2024 14:23
Get the latest stable version of a Clojure (or Java) package
(ns latest-version
"Find the most current stable version identifier of a Clojure (and Java) package."
;; This builds on Yannick Scherer's [ancient-clj](https://github.com/xsc/ancient-clj),
;; which in turn builds on Chas Emerick's
;; [pomegranate](https://github.com/clj-commons/pomegranate/). It goes without saying
;; that I could not have done this without them.
;; Usage: (latest-stable-version 'org.jmonkeyengine/jme3-core)
@simon-brooke
simon-brooke / Downgrading Shotwell database.md
Created June 4, 2024 09:49
Downgrading Shotwell database from 23/0.31.5 to 20/0.30.17

Downgrading Shotwell database from 23/0.31.5 to 20/0.30.17

What this is about

I decided to move back from Ubuntu (23.04) to Debian (Bookworm), essentially because the Snap package management system just annoyed the hell out of me. The one significant thing that broke was Shotwell. Debian Stable is stable precisely because it's not at the bleeding edge, and the version of Shotwell it ships with is older than that in Ubuntu 23.04, to the extent that the databases are incompatible.

How I arrived at this fix

@simon-brooke
simon-brooke / getstarstar.clj
Created May 27, 2024 12:54
Getting multiple properties from a Java object: or, how not to do it.
(ns getstarstar
(:require [camel-snake-kebab.core :refer [->camelCase ->kebab-case-keyword]])
(:import [clojure.lang Keyword]
[java.io File]))
;; What this is about: Ertuğrul Çetin's [jme-clj](https://github.com/ertugrulcetin/jme-clj)
;; contains a very elegant `get*` macro which constructs the name of a java
;; gatter instance method on the fly and then calls that method. This allows you to get
;; an arbitrary instance value from a java 'bean'. It's very neat. But sometimes
;; you will want to get many instance values from the same object, and to return them as
@simon-brooke
simon-brooke / example-rss.html
Created July 16, 2023 10:48
Embed an RSS feed into a web page using only locally sourced JQuery
<script src="/blog/js/jquery-3.7.0.min.js" type="application/javascript"></script>
<div class="social-media">
<hr/>
<h4>Recent Mastodon posts</h4>
<ol id="mastodon"></ol>
<script type="text/javascript">
const RSS_URL = "https://mastodon.scot/@simon_brooke.rss";
function getRSSFeed(feed, target) {
@simon-brooke
simon-brooke / get_pid.clj
Created December 21, 2022 17:01
Getting the process id from Clojure
(def pid
"OK, this is hacky as fuck, but I hope it works. The problem is that the
way to get the process id has changed several times during the history
of Java development, and the code for one version of Java won't even compile
in a different version."
(let [java-version (read-string (apply str (take 2
(split
(System/getProperty "java.version")
#"[_\.]"))))
cmd (case java-version
@simon-brooke
simon-brooke / migrate.clj
Last active October 6, 2022 20:46
Convert leiningen project.clj into clojure.cli deps.edn
(ns migrate
"
## Leiningen to deps.edn migration tool
I'm as yet unpersuaded of the merits of `deps.edn` vis-a-vis leiningen.
Leiningen puts all the metadata about your project and how to build it
in one place in a clear, well understood and easily-extensible format.
The `deps.edn` format intentionally does not.
Worse, `clojure.cli` uses a subtly but significantly different algorithm
@simon-brooke
simon-brooke / bargraph.clj
Created January 26, 2022 15:51
Quick and dirty bargraph from Clojure frequencies
(defn bargraph
"Quick'n'dirty bargraph from these `freqs`, the output from the function
`clojure.core/frequencies`."
[freqs]
(let [u (/ (apply max (vals freqs)) 20)
p (/ (apply +' (vals freqs)) 100)]
(join "\n"
(map #(format "%7d : %s (%d %%)"
%
(apply str (take (/ (freqs %) u) (repeat "#")))
@simon-brooke
simon-brooke / COVID-19-geographic-disbtribution-worldwide.awk
Created July 28, 2020 21:23
Collect daily worldwide COVID 19 data from the European Centre for Disease Control, bung it into a local database, and report
#!/bin/awk -f
BEGIN {
FS=",";
OFS=", ";
print("delete from covid;");
}
NR > 1 {
$1 = gensub( /(.*)/, "'\\1'", 1, $1);
$7 = gensub( /(.*)/, "'\\1'", 1, $7);
@simon-brooke
simon-brooke / tag.clj
Created May 26, 2020 16:12
Tagging in Clojure
(ns walkmap.tag
"Code for tagging, untagging, and finding tags on objects. Note the use of
the namespaced keyword, `:walkmap.tag/tags`, denoted in this file `::tags`.
This is in an attempt to avoid name clashes with other uses of this key."
(:require [clojure.set :refer [difference union]]))
(defn tagged?
"True if this `object` is tagged with each of these `tags`."
[object & tags]
(if
@simon-brooke
simon-brooke / set-exif-date.sh
Created April 15, 2020 14:54
Set EXIF date of digital photographs to the current date
#!/bin/bash
# Set the timestamp of the JPEG files which are specified as arguments to the current
# date, if its timestamp is zero.
#
# Background: My Olympus E20p, which I like and still use, is so old that it has no
# clock, and doesn't timestamp photographs. In order that Shotwell should file them
# properly, I like them timestamped.
#
# Weirdly, although the timestamp appears in the EXIF as it comes off the camera as