The GardenDespatches from The Satyrs’ Forest

Posts tagged as “programming”

Introducing @towns.satyrs.eu

Hello! If any of my (beautiful and sexy) readers are on Bluesky, i thought they might like to know that i’ve made a bot on there. It’s called @towns.satyrs.eu, and it posts a random British/Irish town (or village, or hamlet, or city) on the hour, every hour, give or take a few minutes. Like so:

Screenshot of a Bluesky post showing a town name (with Welsh translation), its coördinates, and a four-picture grid showing a satellite image and three more boring photos

It’s inspired by the inimitable (okay, highly imitable) @townsusa.bsky.social, which does the same thing but for American towns. Here’s how i made it, in bullet-point form:

  • Place data
    • From the moment i had the idea, i knew i wanted to use historic counties as the basis, rather than local government areas or the post-1974 bastardisations. I thought this would be a big hurdle — but, thankfully, the most comprehensive permissively licensed database on British place names out there, the Gazetteer of British Place Names, is maintained by none other than… the Association of British Counties! So that was easier than i expected.
    • The Irish government maintains its own official dataset of population centres, including both Irish and English names. It’s a bit thinner than its British counterpart, but it serves nicely enough for our purposes. (I had wanted to use Logainm.ie, the even more comprehensive dataset of Irish-language place names, but there didn’t seem to be any kind of download button anywhere… alas!)
    • For crown dependencies and overseas territories, i scraped data from OpenStreetMap using the Overpass Turbo API. It comes with its own bespoke arcane query language, but thankfully it’s 2026 and you can just get your friendly local server farm to write your queries for you instead of learning it yourself for questionable future gain.
    • OpenStreetMap also sourced most of the Welsh, Cornish, Scots Gaelic, and Irish place names for the UK, where the ABC’s gazetteer was frustratingly thin on the ground.
  • Pretty pictures
    • The satellite images are sourced from Mapbox, whose API has a very generous free tier if you can stomach giving them your card information.
    • Wikimedia Commons, incredibly, lets you search images by geographical location. The bot asks for the fifty nearest photos in a one-kilometre radius, then picks three from that list at random. (This avoids naïvely picking the three nearest and thus ending up with three pictures of exactly the same thing.)
    • Descriptive alt text is generated for the above by Google’s Gemini 3 Flash. At about a fifth of a pence per post — £17.50 per year, otherwise put — i’m hoping it won’t burn too much of a hole in my pocket.
  • Posting
    • Posting goes through Bluesky’s native ATProto API, whose documentation even starts with a helpful tutorial for setting up your first bot. That’s nice of them.

Anyway, that’s all. Enjoy, and do give the bot a follow if you wish!

The pauper’s jQuery

Black and white film still of a man in thought surrounded by grimy computer wiring
Pic loosely-related, from Darren Aronofsky’s πJS makes me want to drill my brain out sometimes, too.

Javascript has come a long way since the days of marquee tags and spacer gifs. You can do a lot with the API they give you to mess around with your web page’s content — but alas, so many of the functions have such verbose names!

To solve this, while not having to deal with the heaving weight of jQuery’s ten billion lines of IE6 compatibility, i made my own little alternative, and carry it everywhere with me:

const $ = sel => document.querySelector(sel);
const $$ = sel => document.querySelectorAll(sel);

Element.prototype.$ = Element.prototype.querySelector;
Element.prototype.$$ = Element.prototype.querySelectorAll;

EventTarget.prototype.on = EventTarget.prototype.addEventListener;

const documentReady = fn => document.on("DOMContentLoaded", fn);

What it does, in a nutshell: Use $ to select something matching a CSS selector, and $$ to select an array of everything it matches. (This is already available in your browser’s dev tools!) You can also use it on an element to restrict your search to its children — say, $(".post").$$("aside"), or some other such fanciful chaining.

.on, meanwhile, lets you listen out for events like so: $("#my-button").on("click", () => { /* Your function here… */ })

Finally, documentReady is just a nicer name for the frankly obtuse “DOMContentLoaded”.

Enjoy. Or don’t, i suppose. Hopefully it makes your hypertext tinkering just a little nicer. :-)