Elektrine
Log in Register
Paige Chat Timeline Gallery Friends Email Drive DNS Private DNS Domains VPN Kairo Nerve
Remote

Terence Eden’s Blog

@blog@shkspr.mobi
  • Open on shkspr.mobi

Regular nonsense about tech and its effects 🙃
Published by @Edent@mastodon.social / @edent.tel

If you reply to these posts, your reply may appear as comments on my blog.

852 Followers
0 Following
43 Posts
Joined April 21, 1994
Blog:

https://shkspr.mobi/blog/

Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
The UK Government's Low Value Purchase System is a Waste of Time https://shkspr.mobi/blog/2026/05/the-uk-governments-low-value-purchase-system-is-a-waste-of-time/

It can be hard running a small business. If you want to sell to a large organisation like the UK Government, there are forms to fill in, checks to comply with, tenders to bid on, and a hundred other things.

Luckily, there's the RM6237 Low Value Purchase System to make everything better. If a department wants to buy something below a certain threshold, they can contact any of the registered suppliers and just buy it. No complicated paperwork, cheaper prices, win-win!

Except, there's on annoying bit of bureaucracy. Every month I have to tell the Government Commercial Agency what business I've done.

Hello Terence Eden, It’s time to report your management information to the Government Commercial Agency (GCA). If you didn’t do any business, you still need to use this service to let us know. 9 April 2026 is the deadline to report your March 2026 data You need to report for the following commercial agreement(s):-   RM6237 – Low Value Purchase System Report your management information If you don’t think you should be getting this reminder or there is a problem reporting, please email the support team: Regards, GCA MI collection team

Fair enough, I guess. Let them know how many paperclips I've sold to the Ministry of Administrative Affairs.

But there's a wrinkle. What if I've sold nothing? Well, I still have to log on, wait for an MFA code to be send, click through, and report "No Business".

Screenshot with a button to report no business.

I think that's a waste of time. But I wondered how much time it collectively wastes for the nation's small businesses.

So I filed a Freedom of Information request to see how many people have to sign in to let them know they haven't done any business. They replied quickly - although sent the data as a PDF rather than the requested machine-readable format.

Here's how much of a waste of time it is for everyone:

Date Total Returns Nil Return Percentage Mar-25 768 729 94.9% Apr-25 902 876 97.1% May-25 948 923 97.4% Jun-25 1,322 1,270 96.1% Jul-25 1,406 1,355 96.4% Aug-25 1,369 1,326 96.9% Sep-25 1,416 1,362 96.2% Oct-25 1,610 1,556 96.6% Nov-25 1,713 1,654 96.6% Dec-25 1,645 1,590 96.7% Jan-26 1,536 1,487 96.8% Feb-26 1,588 1,531 96.4%

Even if you assume that it only takes 2 minutes to fill in their form, that's over 2 days worth of time being wasted every month.

At best, 59 small businesses reported that they sold something via RM6237. Well over a thousand businesses are clicking on a button which, frankly, ought not to exist. Why isn't the onus on those buying using the system to report what they've spent and who they spent it with?

After clicking the button, I'm always asked to rate my experience using the service. I FoI'd that data as well but was told:

This information is not held. Feedback scores submitted are anonymised and only available as a service-wide view; consequently, we do not capture or hold results specific to RM6237

So the GCA are wasting everyone's time and do not track how annoying it is.

#FoI #government #rant #statistics
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Sneaky spam in conversational replies to blog posts https://shkspr.mobi/blog/2026/04/sneaky-spam-in-conversational-replies-to-blog-posts/

I'm grateful that my blog posts attract lots of engaged, funny, and challenging comments. But any popular post also attracts spammers. I use Antispam Bee to automatically eradicate a couple of hundred crappy comments per day.

Graph showing 272 comments blocked in a single day.

Nevertheless, some get through. Here's a particularly pernicious one - it appeared as three comments ostensibly in reply to each other.

First

At first glance these look like normal comments. They each address the content of the blog post albeit somewhat superficially. The first comment looks like it was from a social media post sharing my link - I get a lot of those as pingbacks, so it initially didn't trigger any suspicions from me.

The second is ostensibly a reply to the first and continues the conversation. Again, a bit shallow, but seems to be engaging in good faith.

The third looks like yet another reply. They all have unique email addresses, none of them have set their username to anything overly odd, and none of the users have filled out their URl.

But notice, in the second one, there's a link to a dodgy casino! There's no https:// so it didn't jump out as a link.

All three came from the same IP address in the Philippines, so easy to block for now.

Each reply is spaced exactly 3 minutes apart which, in retrospect, looks a little odd.

Re-reading them carefully, they all look like AI slop. A plausible sounding summary, written in a casual style, but with very little semantic content. Seeing them as replies to each other primed me to think they were genuine because I'm used to spam coming in individual replies. Having the spam in the middle comment made it easy to glaze over.

Remember, there are no technological solutions to social problems. Sticking more and more barriers in the way of commenting only discourages genuine replies while the profit motive incentivises spammers to work around them.

#blog #blogging #spam #WordPress
0
1
1
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
Using FourSquare's API to post location checkins to social media https://shkspr.mobi/blog/2026/06/using-foursquares-api-to-post-location-checkins-to-social-media/

What is this, 2016?

I like sharing my location with my pocket friends sometimes. If I'm in a cool bar that they know, perhaps they can recommend a drink. If they live nearby, maybe they want to come for dinner. Not everyone has FourSquare's SwarmApp, so it is handy to automatically share its updates with other people.

Of course, Swarm doesn't cross-post to social media because walled-gardens are the most profitable. This is my attempt to open it back up again.

Here's what they look like on BlueSky and Mastodon:

Checked in to Hamburger Fischmarkt, Große Elbstr. 9 (Fischmarkt), Germany Probably a *bit* early for a breakfast beer. See on Swarm

[image or embed]

— Terence Eden (@edent.tel) 24 May 2026 at 07:45
Post by @Edent@mastodon.social
View on Mastodon
tl;dr

You can get the SwarmToSocial code from my GitLab.

At the moment, developers get 10,000 API calls for free each month. That's probably more than enough for most personal uses.

Documentation

I was pleasantly surprised that FourSquare's CheckIn documentation was fairly easy to use and understand.

Once you've signed up for a developer account you can create an OAuth app. That will generate a Client ID (ABC123), Client Secret (XYZ789), and you supply a Project URL.

Once done you can follow the Authentication documentation. Or just visit:

https://foursquare.com/oauth2/authenticate
   client_id=ABC123
  &response_type=code
  &redirect_uri=https://example.com/

Sign in with your FourSquare account. It will redirect you to:

https://example.com/?code=456QWE

Use that code to construct the final URl:

https://foursquare.com/oauth2/access_token
   client_id=ABC123
  &client_secret=XYZ789
  &grant_type=authorization_code
  &redirect_uri=http://example.com/
  &code=456QWE

That will respond with the Access Token:

{
   "access_token":"asdfghjkl123456"
}

Hurrah! Posting a new checkin is relatively simple. POST to this URl with a header of accept: application/json

https://api.foursquare.com/v2/checkins/add
   v=20260223
  &venueId=13600425
  &shout=This%20is%20a%20test
  &oauth_token=asdfghjkl123456
  • v is, rather confusingly, a date. The versioning documentation has more details but, basically, set it to the date you deployed your app.
  • venuId you'll need to find yourself (more on that later).
  • shout is up to 140 characters (!) of URl encoded text.

That will send back rather a lot of JSON. Here are the important bits:

{
  "meta": {
    "code": 200,
    "requestId": "123456789"
  },
  "response": {
    "checkin": {
      "id": "987654321",
      "createdAt": 1771843820,
      "type": "checkin",
      "visibility": "closeFriends",
      "shout": "This is a test of the API",
      "timeZoneOffset": -300,
      "editableUntil": 1771930220000,
      "user": {
        "id": "56367",
        "firstName": "Terence",
        "lastName": "Eden",
        "relationship": "self",
        "displayName": "Terence Eden"
      },
      "venue": {
        "id": "QWERTYUIOP",
        "name": "My Birthday Party!",
        "contact": {},
        "location": {
          "isFuzzed": true,
          "lat": 39.123456789,
          "lng": -84.987654321,
          "cc": "US",
          "city": "Cincinnati",
          "state": "KY",
          "country": "United States",
          "formattedAddress": [
            "Cincinnati, KY",
            "United States"
          ]
        }
      },
      "checkinShortUrl": "https://swarmapp.com/user/56367/checkin/987654321?s=wRZ7ByNfCW1DNrOIpsRcytPZelE"
    }
  }
}

For my purposes, the shout and checkinShortUrl are the most important. You can view a sample check in:

https://swarmapp.com/user/56367/checkin/699c34b55bad6b7fb1695544?s=LA7jCaAtH-s9CwSpgQrQdHrP5-8

Venue ID

If you're already using a service like Untappd you might be able to get the venue ID from that.

If not, FourSquare provides 100 million points of interest for free - although with questionable data quality.

Alternatively, you can search by location:

curl --request GET \
     --url 'https://places-api.foursquare.com/places/search?ll=51.123%2C0.123&radius=1000&sort=POPULARITY' \
     --header 'X-Places-Api-Version: 2025-06-17' \
     --header 'accept: application/json' \
     --header 'authorization: Bearer ABC123'

As far as I can see, the Bearer Token only exists on the documentation page. I couldn't find it in my developer console. Weird!

That gets you back:

{
  "results": [
    {
      "fsq_place_id": "4be584ed2457a593ad8cab15",
      "latitude": 51.11783041264215,
      "longitude": 0.11219274871133413,
      "categories": [
        {
          "fsq_category_id": "4bf58dd8d48988d1fa941735",
          "name": "Farmers Market",
          "short_name": "Farmers Market",
          "plural_name": "Farmers Markets",
          "icon": {
            "prefix": "https://ss3.4sqi.net/img/categories_v2/shops/food_farmersmarket_",
            "suffix": ".png"
          }
        }
      ],
      "date_created": "2010-05-08",
      "date_refreshed": "2025-11-01",
      "distance": 970,
      "extended_location": {},
      "link": "/places/4be584ed2457a593ad8cab15",
      "location": {
        "address": "",
        "locality": "Hartfield",
        "region": "East Sussex",
        "postcode": "",
        "admin_region": "England",
        "country": "GB",
        "formatted_address": "Hartfield, East Sussex"
      },
      "name": "Perryhill Farm Shop",
      "placemaker_url": "https://foursquare.com/placemakers/review-place/4be584ed2457a593ad8cab15",
      "related_places": {},
      "social_media": {
        "twitter": ""
      },
      "tel": "",
      "website": "http://www.perryhillorchards.co.uk/index.php?sec=4"
    },
    {
      "fsq_place_id": "8896f77565e54a658585301d",
      "latitude": 51.11649,
      "longitude": 0.13131,
      "categories": [],
      "date_created": "2021-12-06",
      "date_refreshed": "2021-12-06",
      "distance": 909,
      "extended_location": {},
      "link": "/places/8896f77565e54a658585301d",
      "location": {
        "address": "Priory Park, Beech Green Lane",
        "locality": "Withyham",
        "region": "East Sussex",
        "postcode": "TN7 4DB",
        "admin_region": "England",
        "post_town": "Hartfield",
        "country": "GB",
        "formatted_address": "Priory Park, Beech Green Lane, Withyham, East Sussex, TN7 4DB"
      },
      "name": "Spectra Studios",
      "placemaker_url": "https://foursquare.com/placemakers/review-place/8896f77565e54a658585301d",
      "related_places": {},
      "social_media": {},
      "tel": "01892 487149"
    },
  ],
  "context": {
    "geo_bounds": {
      "circle": {
        "center": {
          "latitude": 51.123,
          "longitude": 0.1234
        },
        "radius": 1000
      }
    }
  }
}

You can manually check a place using the Placemaker site: https://foursquare.com/placemakers/review-place/64eca80f0398c97ab52298ec

Getting Existing Checkins

What if you've checked in to a place using the official Swarm app? How do you get your own recent checkin data?

Again, there is documentation on getting user checkins.

curl --request GET \
     --url 'https://api.foursquare.com/v2/users/self/checkins?v=20260223&limit=2&offset=0&oauth_token=asdfghjkl123456' \
     --header 'accept: application/json'

Where it says oauth_token it actually means the access_token.

The JSON that is returned is a bit verbose, so I've simplified it here:

{
  "meta": {
    "code": 200,
    "requestId": "699c6505b488565a31e315e3"
  },
  "response": {
    "checkins": {
      "count": 2344,
      "items": [
        {
          "id": "699c34b55bad6b7fb1695544",
          "createdAt": 1771844789,
          "type": "checkin",
          "visibility": "closeFriends",
          "entities": [],
          "shout": "Testing the API using an Untappd FourSquare ID.",
          "timeZoneOffset": 0,
          "editableUntil": 1771931189000,
          "venue": {
            "id": "64eca80f0398c97ab52298ec",
            "name": "Abbey Wood Fossil Pit",
            "contact": {},
            "location": {
              "lat": 51.487514,
              "lng": 0.13048041,
              "postalCode": "SE2 0AX",
              "cc": "GB",
              "country": "United Kingdom",
              "formattedAddress": [
                "SE2 0AX"
              ]
            },
            "createdAt": 1693231119
          },
        },

Annoyingly, there's no checkinShortUrl which means it can't easily be shared.

For that, you'll need to use the get-checkin-details API:

curl --request GET \
     --url 'https://api.foursquare.com/v2/checkins/699c34b55bad6b7fb1695544?v=20250202&oauth_token=asdfghjkl123456' \
     --header 'accept: application/json'

Which will return this (truncated for brevity):

{
  "meta": {
    "code": 200,
    "requestId": "699c67de5f5c0a0e8ab234db"
  },
  "response": {
    "checkin": {
      "id": "699c34b55bad6b7fb1695544",
      "createdAt": 1771844789,
      "type": "checkin",
      "shout": "Testing the API using an Untappd FourSquare ID.",
      "timeZoneOffset": 0,
      "checkinShortUrl": "https://swarmapp.com/user/56367/checkin/699c34b55bad6b7fb1695544?s=LA7jCaAtH-s9CwSpgQrQdHrP5-8",
Photos

If there's a photo with the checkin, it will be return in the JSON like this:

{
  "response": {
    "checkin": {
      "photos": {
        "count": 1,
        "items": [
          {
            "id": "699f3a9f96799c05c0f16c9c",
            "createdAt": 1772042911,
            "prefix": "https://fastly.4sqi.net/img/general/",
            "suffix": "/56367_5VYox4Y-hs66wURVsYc1NLgOokfwBfcWhtKQrOlMdD8.jpg",
            "width": 1008,
            "height": 1344,

The URl for the image is prefix width x height suffix - in this case https://fastly.4sqi.net/img/general/1008x1344/56367_5VYox4Y-hs66wURVsYc1NLgOokfwBfcWhtKQrOlMdD8.jpg

You can adjust the width and height if you want a thumbnail or some other resolution.

If there's no photo, the count will be 0.

Putting it all together

Every 15 minutes, the SwarmToSocial code does the following:

  1. Get the most recent checkin.
  2. Read a local file to get the previously seen checkin ID.
  3. If the checkin ID hasn't been seen before:
    1. Get the checkin details.
    2. Get the photo if it exists
    3. Post the checkin (plus photo) to Mastodon & BlueSky.
    4. Save the checkin ID to a file.

Enjoy!

#api #BlueSky #FourSquare #geolocation #MastodonAPI
shkspr.mobi

Why is it so hard to passively stalk my friends’ locations? – Terence Eden’s Blog

0
1
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
Which age-gates should be skill-gates and vice-versa? https://shkspr.mobi/blog/2026/05/which-age-gates-should-be-skill-gates-and-vice-versa/

In the UK, it is illegal to buy alcohol if you are under 18.

Similarly, in most countries, you cannot vote until you have reached a specific age.

These are age-gates. You do not need to prove your competence to drink, vote, smoke, or get married; you just need to be old enough.

Some things have skill-gates. If you want an amateur radio licence in the UK, you need to pass an exam. You can be any age0.

Similarly, most jurisdictions allow you to get a medical licence once you have passed the requisite tests1.

There are also activities which are dual-gated. You can only get a driving licence after passing a test, but you can only apply to take the test once you are a certain age.

Where should society swap age-gates and skill-gates?

Perhaps the big one is voting. The UK is preparing to extend the franchise to all 16 and 17 year olds - but why is there an age-gate at all?

Children are affected by politics, they pay tax on the goods they buy, they exist in the world. Why shouldn't they vote?

The usual argument is that they are too immature. But maturity isn't dependent on age. Idiots are allowed to vote. Centenarians with no stake in the consequences of their politics are allowed to vote. People who don't understand what powers a government has are allowed to vote.

Would it really be so bad to introduce a voting licence? Make people take a short quiz to ensure they understand what they're voting for and why they're voting. Perhaps there are concerns about disenfranchising eligible adults (but not mature children) or that the state will rig the test (when they could rig the election) or whatever. But if we're sticking with the fiction that some people aren't mature enough to vote then we must give disenfranchised people a chance to prove their maturity.

You could make the same argument about driving. If a 7 year old is able to demonstrate mastery and control of a vehicle, are they likely to be a better driver than a 90 year old who has never taken a modern test?

Alcohol is different. We realise that the drug is harmful and especially harmful to developing humans. So we age-gate it. But do people really understand the health risks? Should you have to pass a test in order to imbibe? We make the people selling alcohol pass somewhat rigorous skills assessments. Perhaps the burden of proof should be reversed?

Wait, do you really believe all this?

No, not necessarily.

I find it fascinating that different cultures set different limits on people's activities. I wouldn't like to live somewhere that allowed anyone to drive on the public roads. Similarly, I don't particularly want governments restricting who can vote based on an arbitrary assessment.

But where are the limits? Why is the legal driving age so variable? Why are some driving tests easier than others?

Do you want a teenage doctor diagnosing you - even if they are legally certified? Should you be able to use a radio without passing a test if you're a legal adult?

Which age-gates and skill-gates do you think should be flipped?


  1. OK, realistically you have to be old enough to read, write, and communicate. But there's no legal barrier to a precocious 3 year old taking and passing the exams. ↩︎

  2. As seen in the insightful documentary series "Doogie Howser, M.D." ↩︎

#politics #thoughts
0
3
0
1
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 2mo ago
Google Calendar "Unable to launch event" - caused by missing DTSTAMP https://shkspr.mobi/blog/2026/07/google-calendar-unable-to-launch-event-caused-by-missing-dtstamp/

For several years, Google's product help forums have been littered with people trying to download a .ics event from their email, only to receive the error "Unable to launch event" when trying to add it to Google Calendar. It doesn't happen with all iCal attachments, only some. Here's how to fix it.

Android toast error message.

I checked dozens of broken iCalendar invites using this iCal validator and they all had the same problem: "Missing DTSTAMP property".

Here's a typical broken file:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:abcdef-ghij-klmn-opqrs-tuvwxyz
BEGIN:VEVENT
DTSTART:20260713T093000Z
DTEND:20260713T103000Z
SUMMARY:Your Delivery (Order 123456789)
UID:83c510fa-1be4-48a2-8338-c5a2350ba6e5
END:VEVENT
END:VCALENDAR

If you read the specification or follow the flowchart you'll see:

Property Name: DTSTAMP

Conformance: This property MUST be included in the "VEVENT", "VTODO", "VJOURNAL", or "VFREEBUSY" calendar components.

Adding that to the above produces:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:abcdef-ghij-klmn-opqrs-tuvwxyz
BEGIN:VEVENT
DTSTAMP:20260713T093000Z
DTSTART:20260713T093000Z
DTEND:20260713T103000Z
SUMMARY:Your Delivery (Order 123456789)
UID:83c510fa-1be4-48a2-8338-c5a2350ba6e5
END:VEVENT
END:VCALENDAR

You can download them both to see if they work on your Android phone.

  • Broken calendar invite
  • Working calendar invite

That's all it takes! Add the missing DTSTAMP to broken files and Google Calendar is able to import them.

From my (unscientific) testing, the broken file works on all iOS devices and some Android calendars - but always breaks on Google's Calendar.

Post by @Edent@mastodon.social
View on Mastodon

The iCal specification is reasonably old, but it is fairly simple to understand. Annoyingly, Google's documentation about iCal is frustratingly vague. It says:

This is what an iCalendar file looks like. An iCalendar file can also have more information, but these are the parts that are required.

BEGIN:VCALENDAR

VERSION:2.0

PRODID:< [enter ID information here] >

BEGIN:VEVENT

(event details)

END:VEVENT

END:VCALENDAR

But it never actually describes what those "event details" are!

Is the spec needlessly verbose? Perhaps. Should Google Calendar be a bit more forgiving in what it receives? Probably!

There's no meaningful way to report a bug to Google's product teams. Instead, I've taken to emailing the organisations sending out these broken invites and pleading with them to fix their systems.

Computers, eh?

#android #bug #google #standards
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 69mo ago
The unreasonable effectiveness of simple HTML https://shkspr.mobi/blog/2021/01/the-unreasonable-effectiveness-of-simple-html/

I've told this story at conferences - but due to the general situation I thought I'd retell it here.

A few years ago I was doing policy research in a housing benefits office in London. They are singularly unlovely places. The walls are brightened up with posters offering helpful services for people fleeing domestic violence. The security guards on the door are cautiously indifferent to anyone walking in. The air is filled with tense conversations between partners - drowned out by the noise of screaming kids.

In the middle, a young woman sits on a hard plastic chair. She is surrounded by canvas-bags containing her worldly possessions. She doesn't look like she is in a great emotional place right now. Clutched in her hands is a games console - a PlayStation Portable. She stares at it intensely; blocking out the world with Candy Crush.

Or, at least, that's what I thought.

Walking behind her, I glance at her console and recognise the screen she's on. She's connected to the complementary WiFi and is browsing the GOV.UK pages on Housing Benefit. She's not slicing fruit; she's arming herself with knowledge.

The PSP's web browser is - charitably - pathetic. It is slow, frequently runs out of memory, and can only open 3 tabs at a time.

But the GOV.UK pages are written in simple HTML. They are designed to be lightweight and will work even on rubbish browsers. They have to. This is for everyone.

Not everyone has a big monitor, or a multi-core CPU burning through the teraflops, or a broadband connection.

The photographer Chase Jarvis coined the phrase "the best camera is the one that’s with you". He meant that having a crappy instamatic with you at an important moment is better than having the best camera in the world locked up in your car.

The same is true of web browsers. If you have a smart TV, it probably has a crappy browser.

Twitter's guest mode displayed on a TV.

My old car had a built-in crappy web browser.

The dashboard of a BMW i3 - there is a web browser on the central display.

Both are painful to use - but they work!

If your laptop and phone both got stolen - how easily could you conduct online life through the worst browser you have? If you have to file an insurance claim online - will you get sent a simple HTML form to fill in, or a DOCX which won't render?

What vital information or services are forbidden to you due to being trapped in PDFs or horrendously complicated web sites?

Are you developing public services? Or a system that people might access when they're in desperate need of help? Plain HTML works. A small bit of simple CSS will make look decent. JavaScript is probably unnecessary - but can be used to progressively enhance stuff. Add alt text to images so people paying per MB can understand what the images are for (and, you know, accessibility).

Go sit in an uncomfortable chair, in an uncomfortable location, and stare at an uncomfortably small screen with an uncomfortably outdated web browser. How easy is it to use the websites you've created?

I chatted briefly to the young woman afterwards. She'd been kicked out by her parents and her friends had given her the bus fare to the housing benefits office. She had nothing but praise for how helpful the staff had been. I asked about the PSP - a hand-me-down from an older brother - and the web browser. Her reply was "It's shit. But it worked."

I think that's all we can strive for.


Here are some stats on games consoles visiting GOV.UK

Matt Hobbs (@TheRealNooshu@hachyderm.io)

@TheRealNooshu
TwitterReplying to @TheRealNooshuInterestingly we have 3,574 users visiting GOV.UK on games consoles:
• Xbox - 2,062
• Playstation 4 - 1,457
• Playstation Vita - 25
• Nintendo WiiU - 14
• Nintendo 3DS - 16

20/22
❤️ 27💬 1🔁 010:45 - Mon 01 February 2021
#HTML5 #web #WeekNotes #work
twitter.com
0
2
2
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 6mo ago
I'm OK being left behind, thanks! https://shkspr.mobi/blog/2026/03/im-ok-being-left-behind-thanks/

Many years ago, someone tried to get me into cryptocurrencies. "They're the future of money!" they said. I replied saying that I'd rather wait until they were more useful, less volatile, easier to use, and utterly reliable.

"You don't want to get left behind, do you?" They countered.

That struck me as a bizarre sentiment. What is there to be left behind from? If BitCoin (or whatever) is going to liberate us all from economic drudgery, what's the point of "getting in early"? It'll still be there tomorrow and I can join the journey whenever it is sensible for me.

Part of the crypto grift was telling people to "Have Fun Staying Poor". That weaponisation of FOMO was an insidious way to get people to drop their scepticism.

I feel the same way about the current crop of AI tools. I've tried a bunch of them. Some are good. Most are a bit shit. Few are useful to me as they are now. I'm utterly content to wait until their hype has been realised. Why should I invest in learning the equivalent of WordStar for DOS when Google Docs is coming any-day-now?

If this tech is as amazing as you say it is, I'll be able to pick it up and become productive on a timescale of my choosing not yours.

I didn't use Git when it first came out. Once it was stable and jobs began demanding it, I picked it up. Might I be 7% more effective if I'd suffered through the early years? Maybe. But so what? I could just as easily have wasted my time learning something which never took off.

I wrote my MSc on The Metaverse. Learning to built VR stuff was fun, but a complete waste of time. There was precisely zero utility in having gotten in early.

Perhaps there are some things for which it is sensible to be on the cutting edge. I took part in a vaccine trial because I thought it might personally benefit me and, hopefully, humanity.

But I'm struggling to think of anyone who has earned anything more than bragging rights by being first. Some early investors made money - but an equal and opposite number lost money. For every HTML 2.0 you might have tried, you were just as likely to have got stuck in the dead-end of Flash.

There are a 16,000 new lives being born every hour. They're all starting with a fairly blank slate. Are you genuinely saying that they'll all be left behind because they didn't learn your technology in utero?

No. That's obviously nonsense.

It is 100% OK to wait and see if something is actually useful.

#AI #crypto #future #technology
0
47
3
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
UK Government Kicks Out Palantir https://shkspr.mobi/blog/2026/05/uk-government-kicks-out-palantir/

The UK Government, for all its faults, is pretty good at publishing contracts it has awarded. That's why I get depressed when I see rage-bait nonsense about how companies have been award "Top Secret" deals.

Right now you can go to https://www.contractsfinder.service.gov.uk and search for whichever bête noire has you riled up. You might want to argue that the company is corrupt, incompetent, or overpriced - but you can't argue that its contract is secret. There's no conspiracy. There's no secrecy. There's not even "beware of the leopard" shenanigans. It's all out in the open0.

The Government says who it paying money to.

But, of course, there are some things the Government can't say. It's rare for them to publicly disagree with a supplier, or call out how crappy they were. They need to maintain cordial relations with people1. They don't want to scare off new suppliers who can't risk being publicly humiliated. When contracts are cancelled or ended, it is usually done quietly.

So you need to learn to read between the lines.

Let's take this excellent blog post from the Ministry of Housing Communities and Local Government2

"From emergency to sustainability: creating Share Homes for Ukraine data".

It's exactly the sort of blog post that some Civil Servants excel at writing. It clearly sets out how an ambitious and technically challenging project was delivered, why it is important, and who it benefits.

The blog post describes how the team…

exited our contract with our supplier.

And that:

Moving to this in-house model is already saving MHCLG millions of pounds a year in running costs.

They show user feedback for their new system saying:

It’s easier to navigate than the previous system

Of course, what they don't say is who supplied the previous system which was so costly and hard to use.

It was, of course, Palantir.

The original contract (CPD4124104) wasn't secret - although it was mired in some controvery as an urgent exemption to normal procurement rules3.

In 2023, the National Audit Office reported on the scheme - including Palanitr's software. They said:

The initial arrangement was put in place to help get the scheme up and running quickly. Consequently, the system did not undergo the usual research and testing that would be involved for the roll-out of a new digital system. There were initial issues such as the way it presented duplicated application data received from Home Office systems, and confusion from local authorities as to how to engage with the main data system.

How bad was Palantir's software? I've sent in a Freedom of Information request to find out. But we can tell that it was bad enough to convince MHCLG to rewrite it themselves.

A lean Civil Service may not have the in-house capability to rapidly create a new service. But, as their blog post shows, when given suitable resources Civil Servants can often outperform the private sector. More importantly, the new software is under the Ministry's direct control. This open source code is a triumph for sovereign technology.

MHCLG have shown the door to Palantir. They've built something better, easier to use, and cheaper.

I don't want to oversell this as the first victory in the war against this abominable company - but I hope where MHCLG leads, others will follow.


You can read more about this story on BBC News.


  1. Yes, there occasionally delays and some things are redacted either for privacy, security, or confidentiality. But, in the main, if the Government has spent money on it, it'll be published somewhere. ↩︎

  2. Yes, I know it would cathartic to have a YouTube Shocked Face "Government SLAMS woeful supplier!!" but the long-term consequences make it unlikely. ↩︎

  3. MHCLG is literally the worst acronym in a sea of unpronounceable alphabetti spaghetti. At least MOJ can be pronounced "Modge"! ↩︎

  4. My boring centrist dad position is that sometimes it makes sense to buy off-the-shelf in an emergency. If you find yourself abandoned after a night out, you order a taxi - you don't take up driving lessons. ↩︎

#government #OpenSource
0
1
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Cheapest way to keep a UK mobile number using an eSIM https://shkspr.mobi/blog/2026/04/cheapest-way-to-keep-a-uk-mobile-number-using-an-esim/

I have an old mobile phone number that I'd like to keep. I think it is registered with a bunch of services for 2FA by SMS, but I can't be sure. So I want to keep it for a couple of years just in case I need it to log on to something.

I don't want to faff around with physical SIMs, so I went looking for the cheapest way to keep my number for the longest time. There are a whole bunch of providers out there who will do low-cost monthly contracts (like Spusu), which I don't want. Similarly, there are some pure PAYG providers who require you to top-up with £10 every few months (like 1pmobile).

In the end, I went with Lyca Mobile (affiliate link). Total cost was £10 which should last indefinitely.

The process isn't particularly straightforward. Here's how it works:

First, add a PAYG SIM to your basket and select "eSIM"

Screen with a £6 SIM in the basket.

Next, click the Bin icon (🗑) in the top right. You'll get this pop-up:

Screen saying are you sure and offering other choices.

Select "Discard plan & add credit" - you'll return to this screen:

A screen letting you add a top up.

The minimum top-up is a tenner, so select that. From there, you can add details of your old number, its porting code, and when you want the port to take place. Then pay.

Done! You'll receive your eSIM instantly. Scan it with your phone and you'll be up and running. The phone number porting will take as long as it takes.

OK, but will Lyca let you keep a number indefinitely? Here's what they say:

How long can I keep my number for if I don’t use any of Lyca Mobile’s services?

Normally we will keep your number for 120 days if you do not use our service. However, you may also keep your Lycamobile number for up to 1 year without using our service. Just dial *139*9999# from your Lycamobile and follow the instructions on the screen. Please be aware that there will be a fixed annual fee of £15 which will be deducted from your balance.

Source

Note, their chatbot says the fixed fee is a fiver. Like all half-baked AI systems, it is wrong.

So, what does "using" consist of? This is hard to find out! I think is any chargeable event. Based on their current PAYG pricing the cheapest options are:

  • Send an SMS for 23p
  • Use 1MB of data for 15p.

If I'm right, you could use 1MB of data every 120 days. That would deplete your credit in about 22 years. More than long enough for me!

There you have it, I'm pretty sure that's the cheapest way to keep a UK mobile number on an eSIM. You can keep it switched off for 119 days, flick it on, send a quick message, then shut it down again.

Click the referral link to join Lyca Mobile

#eSIM #mobile #phone #sim
0
6
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
There's still no point in gigabit broadband https://shkspr.mobi/blog/2026/06/theres-still-no-point-in-gigabit-broadband/

Six years ago, I nearly got my ISP to upgrade our fibre connection to 1Gbps. As I said at the time:

This is a curmudgeonly post which is going to look ridiculously outdated in a few years.

What's the point of Gigabit broadband?

Well, it's a few years later and Virgin Media have just given me their Gig1 package for £30 per month. Nice! With all the inflation related price rises, it's great to get more for less.

But I'm still left wondering if this is massive overkill.

What can you actually do with their promised 1,130Mbps?

Online video calling isn't that intensive. All the 4K streaming services recommend 25Mbps - so I guess I could ask 40 friends to come round and stream simultaneously. Downloading Linux ISOs is pretty speedy on a connection half as fast - and is usually limited by the upstream. Same for game updates.

I've wired most of my house with Cat6 Ethernet - but most of my switches and ports are 1G rather than 2.5G, so the max bandwith isn't likely to get to any single device. The best I've got directly is around 940Mbps which is about what I'd expect from a gigabit port.

All my WiFi devices are limited by the reality of radio physics in a noisy environment - so about 450Mbps when close to the router. Some of my rooms are hard to reach, so they have HomePlugs beaming data across our electrical wiring. Again, physics dictates a fairly modest speed there.

I've got a VR headset - but haven't found anything that taxes its download speed. Especially given that it uses WiFi.

My 4K Fire Stick has a wired Ethernet connection. Its built in speed test maxes out around 80Mbps. In fact, most of the online speed tests I tried couldn't saturate the pipe - tapping out at around 700Mbps.

Some AI models and training sets are multiple terrabytes. But are they really likely to be downloaded multiple times per day? If they are, is there a real difference in waiting 7 minutes rather than 3.5?

Everyone jokes about website bloat, but the reality is much more prosaic. Latency to a CDN is a bigger contributor to the perceived slowness than the limits of a home connection.

So what about upload speed. The Internet is an inherently sucky medium; people download far more than they upload. In this case, upload is limited to "only" 110Mbps. Even if both of the people in this house were full-time Twitch streamers, I doubt we'd saturate that.

It's 2026 and I can barely recommend 500Mbps broadband. For most domestic uses, including working from home, it's rare to need more than 100Mbps. Sure, faster is always nicer and cheaper is always preferable, but what am I actually going to do with this speed?

Back in 2012, it was reasoned that the fastest legal use of the Internet was 2.5Mbps. We've blown past that limit thanks to video streaming and calling. But, on the assumption I'm not going to be using my connection to mirror Linux ISOs, what can I do with it?

I guess I can run a personal VPN from home. Handy if I want to stream geolocked content when I'm out of the country. But, again, 1Gbps is overkill for that - especially as I'm likely to be either on a mobile hotspot or hotel WiFi.

I could livestream all my security cameras 24/7 to a secure back-up vault. That isn't going to touch the sides of my upload speed.

Perhaps I could self-host all my stuff? Again, for personal use I'm limited to whatever speed my laptop or phone can get on a public connection. Given the risk of botnets, DDoS, hacking & the like, I'm not sure I'd want much public-facing stuff on my residential IP address.

To be clear, I think it is a great thing that the UK Government is pushing ISPs to deploy gigabit everywhere. It isn't at all useful now, but will probably be crucial in the future.

So if you have any ideas for what I can do to saturate this connection, please drop a comment in the box.

In the meantime, if you join Virgin Media using this link we will both get £50 bill credit.

#broadband #virgin
0
3
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 170mo ago
The Unintended Consequences of Gamification https://shkspr.mobi/blog/2012/10/the-unintended-consequences-of-gamification/

This is a necropost - resurrected from the now defunct blog of a previous employer. Sadly, most of the screenshots have fallen down the memory hole. So use your imagination. We'd launched Drive To Improve which put a "blackbox" in drivers' cars and gamified their safe driving.

I’ve recently taken part in the DriveToImprove Beta. My car now has a small device installed in it, which measures my driving. It reports back to me my location, whether I was speeding, and if I’m braking or accelerating too harshly. It also gives me a great little dashboard showing how well I’m doing and how I compare to others.

Dashboard showing various driving scores.

Bringing “high scores” to real life is part of a trend known as “gamification“.

DriveToImprove has the usual aspects of modern gamification – badges, a leaderboard, and the ability to track your progress.

As I was driving home one day last week, a child ran out in front of my car. I had only a split second to react – slam on the brakes and risk losing points for “Harsh Braking” or continue on, risk hitting the child, but maintain my perfect score…

It’s a real dilemma – safety vs score.

Of course, no one would think like that, would they? I certainly didn’t!

But gaming incentives have a funny effect on our brain. Games are fun – and that makes them highly emotionally manipulative.

That use of scores, rewards, and fun can manipulate us in all sorts of negative ways. Games can encourage us to hate, to harm our bodies, to join a cult, it can cause you to annoy your friends – in some extreme cases, the pleasure associated with playing a game can take over someone’s life until they literally play themselves to death.

So, when designing systems which utilise gamification, we have to be aware that the human brain is susceptible to all sorts of tricks – and we have to be really careful when we subvert them.

We know from feedback on our community that sometimes rapid acceleration is necessary. So is it always a good idea to penalise users for it?

Although we work hard to make sure that the game aspect of the products we create never take priority over safety, it’s impossible to predict what effect our stimulating of the brain’s pleasure centres will have. After all, earning rewards in a game can have the same effect on the brain as cocaine!

What’s great about the test-and-learn approach we take at The Lab is that it gives us time to see the consequences of our developments. We can remain focussed on adding value to our applications, while remaining aware of any unintended side-effects.

I found this video from Eran May-raz and Daniel Lazo a startling and amusing look at what may happen if we let gamification run away with itself.

#gaming #necropost
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Book Review: Up - A scientist's guide to the magic above us by Dr Lucy Rogers https://shkspr.mobi/blog/2026/04/book-review-up-a-scientists-guide-to-the-magic-above-us-by-dr-lucy-rogers/ Book cover featuring butterflies and clouds.

My mate Dr Lucy Rogers has written a book! This is a charming and thought provoking exploration of everything that goes on above our heads. This isn't an impersonal and imperious manuscript, it's a deeply personal and joyful book filled with science, anecdotes, and the thrill of discovery.

It's spectacularly accessible. Written in a relaxed and casual tone, it encourages domestic science. I don't mean bakery, I mean the sorts of observations you can do at home without access to a multi-million pound laboratory. The afterword of the book contains dozens of resources for people who want to get involved in science. Dr Rogers eloquently makes the case that you don't need to dedicate yourself full time - it's perfectly acceptable to engage with it on your own terms.

What I liked most about it was that she gets her hands dirty. It would have been easy to write a literature review from the comfort of a safe and dry office. Instead we get a travelogue of all the places she's been - each trek through the forest, every laboratory, and all the foreign festivals are brilliantly recounted. It's a proper adventure from America's tornado alley down to the Vatican Archives.

I find it remarkable how slow some modern science is. As she points out, "there have been only eight transits of Venus since the telescope was invented" - our knowledge rests on the shoulders of giants, but they can be slow, lumbering beasts.

If, like me, you only have a hazy memory of the science you learned at school, this book will top up your knowledge (and vocabulary). It will reignite your passion and curiosity about the world around you - and make you want to buy a round the world ticket to chase solar eclipses!

#BookReview #science
shkspr.mobi

Why is it so hard to passively stalk my friends’ locations? – Terence Eden’s Blog

0
45
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
Who are the actors in the UK's 2015 passport? https://shkspr.mobi/blog/2026/05/who-are-the-actors-in-the-uks-2015-passport/

I got nerdsniped by a bloody Reddit post!

In 2015, the UK Government launched a new passport design. It immediately attracted negative press for its designers' "sexist" decision to feature more men than women.

The government has been accused of sexism over the new UK passport design, which commemorates the achievements of two women but seven men.

It's true that there are only two named women - but there is another unnamed woman on the passport! Here's the "Performing Arts" page:

Passport page, richly illustrated, featuring Shakespeare's Globe. There are three actors in the corner.

Shakespeare stares down at his Wooden O. Half the page is a stage, and the men and woman merely players.

Here they are in a bit more detail:

Close up of the actors. They are dressed in period costume and are emoting.

Who are they? They look like reasonably modern photos rather than portraits. They're not obviously famous. None of the press at the time mentioned who they were. No stock photography library had anything similar that I could see. Your favourite AI thought one of them was Doctor Who and the other a Congressman from Nantucket.

The official document describing the design simply says:

On the left hand side there is an image of the interior of the theatre, with a play in progress.

I scanned in an old passport to get the faces in as much detail as possible. All three of them look like jobbing actors who you probably saw in a schools' production of Twelfth Night, don't they? Three faces in a row.

I couldn't find anything about them online. I asked my investigative-minded friends but they drew a blank.

I even sent a Freedom of Information request to the Passport Office.

They refused on grounds of GDPR, but they did say:

However, we can disclose the photographs of the individuals appearing on the passport page captured by a photographer employed by a supplier contracted to HM Passport Office.

So, if you're one of the actors / models - or know who they are - please drop a note in the box below!

#FoI #government #sexism #shakespeare
reddit.com
0
3
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Better TTS on Linux https://shkspr.mobi/blog/2026/04/better-tts-on-linux/

The venerable eSpeak is a mainstay of Linux distributions. It is a clever Text-To-Speech (TTS) program which will read aloud the written word using a phenomenally wide variety of languages and accents.

The only problem is that it sounds robotic. It has the same vocal fidelity as a 1980s Speak 'n' Spell toy. Monotonous, clipped, and painful to listen to. For some people, this is a feature, not a bug. I have blind friends who are so used to eSpeak that they can crank it up to hundreds of words per minute and navigate through complex documents with ease.

For the rest of us, it is a steep and unpleasant learning curve.

There are lots of modern TTS programs using all sorts of advanced AI. Many of them are paywalled or require you to post your text to a webserver - with all the privacy and latency problems that causes. Some are restricted to high-powered GPUs or other expensive equipment.

Piper is different. It is local first, runs quickly on modest hardware, and is open source.

The easiest way to install it on Linux is to use Pied - a simple GUI which allows you to select languages, listen to accents, and then install them.

GUI showing various British English languages.

It will change your speech-dispatcher to use the new Piper voice. That means it is immediately available to your Linux DE's accessibility service and to apps like Firefox.

I now have a reassuring Scottish lady speaking out everything on my computer.

#accessibility #firefox #linux #tts
0
1
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Does Mythos mean you need to shut down your Open Source repositories? https://shkspr.mobi/blog/2026/04/does-mythos-mean-you-need-to-shut-down-your-open-source-repos/

Much Sturm und Drang in the world of Open Source with the announcement that the "Mythos" AI is now the ultimate hacker and is poised to unleash havoc on every code base.

So should you close all your Open Source projects to make them safe?

No.

Firstly, all your Open Source code has already been slurped up.

It was all ingested for "training purposes" years ago. If it was moderately interesting then it was backed-up by a digital hoarder. It has been archived by various digital libraries. Anyone who wants to do research on your code base can.

Closing now doesn't meaningfully protect you.

Secondly, most of the security holes in your systems are probably not in your code. Vulnerabilities exist throughout your supply chain. All the dependencies - your OS, libraries, and even hardware - are all richer targets for hackers. Finding a CVE in a popular library is almost certainly more worthwhile than investigating your Open Source code.

The bigger risk comes not from subtle logic bugs but from phishers, poor password hygiene, and insider threats. Securing your existing systems provides more protection than rushing to close-source your code.

Finally, closing the source of something doesn't protect you. These new AI models can easily investigate and your closed source systems and potentially penetrate them. It has always been possible to analyse websites and binaries. AI doesn't change that - although it might accelerate it.

Open Source does have risks but AI doesn't upend decades of evidence that closed-source is just as vulnerable to attackers.

In cases where the state creates code using public money, it has a responsibly to share that code. Automated threat analysis - even by hypercapabe AI - doesn't change that.

I would strongly recommend reading the UK's AI Safety Institute's evaluation of Claude Mythos Preview’s cyber capabilities and the NCSC's advice. Neither of them recommend closing down Open Source code.

#AI #OpenSource
0
46
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 2mo ago
Public Transport - Don't Make Me Think! https://shkspr.mobi/blog/2026/07/public-transport-dont-make-me-think/

In the last year, I've been through over a dozen cities and used public transport in all of them.

It is wild just how confusing and complex buying a ticket can be. While some cities obviously take a user-centred approach to ticketing, others appear to take a Kafkaesque delight in a bureaucratic maze of zones, apps, and intricate restrictions.

One of the seminal texts in computer systems design is "Don't Make Me Think". Every time a service forces the user into making a decision, it is placing a cognitive burden on them. Computers' jobs are to make things easier for us fleshy meatbags.

There are some intractable problems with navigating unfamiliar spaces (looking at you Kyoto Station!) and a transport authority can't publish signs and make announcements in every conceivable language, but there's one thing they can control - ticketing.

Let me take you through some of the public transport ticket experiences I had - and explain how easy or hard they were to use.

Basel, Switzerland - free

Upon checking in to our hotel I was given a free Basel Card. It entitled me to free public transport across the city.

Zero extra cost. I didn't have to remember to take a physical card with me - the details were emailed as a PDF directly from the hotel on check-in.

I didn't have to show the bus driver when I entered a tram. If a ticket inspector was present, they could have asked to scan it.

This is close to the platonic ideal of "Don't Make Me Think" public transport. I didn't have to work out zones, fares, or timings. I didn't need to interact with people or machines. I didn't worry that I was somehow doing it wrong and was going to get shouted at.

Milano, Italy - contactless

I tapped my credit card on the reader. Whether it was a bus, tram, or metro the process was the same. Tap, wait a few milliseconds, beep. On the metro the gates opened automatically. On the tram, I just sat down after the beep.

The fares have a bit of complexity based on how frequently you travel. If you catch another bus within 90 minutes it only counts as one fare.

I didn't care because the daily price was capped.

Once I'd taken a few journeys it wasn't going to cost me any more. With a fee-free credit card it was simplicity itself.

If I had been on an extremely tight budget, I might have done some thinking - but as the daily cap was less than the price of a cocktail, I didn't bother.

Warsaw - paper ticket validation

I walked up to a touchscreen kiosk, selected the 🇬🇧 flag, and bought a 3 day paper ticket for a few € using contactless. The machine spat out a small paper ticket.

I hopped onto a tram, shoved the ticket in a slot and the machine printed a timestamp on it. Well, in theory. It didn't work the first few times for inscrutable reasons.

From then on, I didn't have to do anything. I jumped on whatever public transport I wanted. Only once did a ticket inspector come round demanding to see everyone's proof of validity.

The ticket was a slightly inconvenient size for my wallet - being much smaller than a credit card - and I think the kiosk should have validated it automatically. But, for general transport purposes, it was great at not forcing me to think.

Tallinn - scan the app

Install an app, choose ticket type, pay, done.

Every time I entered public transport, open the app, click the ticket, wave the resultant QR over a scanner.

Obviously choosing a ticket type is a little thinky. Do I want a single ticket, a day pass, something longer?

I'm not averse to installing an app when necessary. Thankfully, this transit app worked on GrapheneOS. There was an optional registration step which I skipped because I was unlikely to come back any time soon.

Riga - scan the bus

OK, this was just weird!

Much like above, install app, choose ticket, pay.

Despite buying an all-you-can-eat ticket, I still had to register on every bus/tram I got on. That meant hopping on, finding a QR code, opening the app, and trying to scan it while the driver attempted a new land-speed record.

Paris - ridiculous

Fuck Paris. The only way to buy a metro ticket is to download an app. Fair enough. But, after downloading the app it tells you to install another app!

Navigo app saying I have to install another app.

What the actual fuck? A convoluted, messy, and frustrating situation which has resulted in awful reviews for them.

Trains and metro travel require separate tickets at different prices. You can't easily hop from one to another. You need to think carefully about the route you're taking. A more convoluted route may be significantly cheaper because it doesn't involve swapping between services.

Madness!

The ticket readers use your phone's NFC chip to validate. So there's no technical reason why they can't just use contactless payment cards.

To be fair, change is coming… in 2030!

So what's best?

In an ideal world, all public transport would be free and plentiful. In our less-than-ideal reality, it seems obvious to me that public transport should above all be simple.

Tourists don't want to grapple with the complexities of zones, split tickets, random charges, and a different app for each city.

Regular travellers don't want yet another piece of plastic tat in their wallets, or to work out in advance what precise combination of journeys they need to take in order to optimise their spending.

One app is fine. Having to install a different app for each city you visit - even within the same country! - is infuriating.

Visitors should not have to think about how, where, when, or why they need to validate their tickets. Nor should anyone need to figure out which modes of transport are inclusive or not.

For the casual visitor, contactless payment with a daily / weekly cap is the simplest possible charging mechanism. It's cheaper for the cities to not have to build, develop, and support apps.

If you've come across a better public transport ticketing system - please let me know in the comments.

#usability
0
3
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 2mo ago
Book Review: Dungeon Crawler Carl by Matt Dinniman https://shkspr.mobi/blog/2026/07/book-review-dungeon-crawler-carl-by-matt-dinniman/ Book Cover.

To call this derivative is an understatement. But that's what this genre demands; rehash all your favourite media properties into something new. It's the literary equivalent of having your Transformers™ fight your He-Man© toys.

The plot, such as it is, features the Vogon Constructor Fleet destroying Earth due to a late beurecratic appeal, forcing people to play The Hunger Games, while a Twitch streamer narrates the action.

The protagonists in Andy Weir's books are boys who know enough science to save the day. The ones in Scalzi's books have enough pop-culture knowledge to save the day. Dinniman's has played enough loot-box gatcha RPGs to save the day.

It is mostly pretty good fun. The tropes are goofy, the gore is splattertastic and only rarely ventures into torture porn, the villains are suitably campy, and the wisecracking sidekick doesn't become too annoying.

But the prose…

Here's a classic scene from Red Dwarf which exemplifies the major problem I had with this book.

There's only so many times you can read "Then I severed a +3 damage with poison debuff while he raised a +1 shield and used his armour of holding to neutralise the attack". I find opening endless lootboxen a chore when I'm playing a game - reading 150 instances of "I got a bronze box with a cauldron of Mafeking, then a gold box with an enchanted ring, then…" just becomes tiresome.

I tried listening to the audiobook of the sequel and I just couldn't get past the endless recitation of lists about +5 to elbows and -6 to arseholes. Just unbearably tedious.

Look, I've never written a novel and doubt I could do any better. This has obviously found its fanbase but, regrettably, I'm not one. It was a fun enough read, but I'm not sure I can be bothered with a dozen more sequels of recycled plots and repetitive squishing of cackling enemies.

#BookReview
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Android now stops you sharing your location in photos https://shkspr.mobi/blog/2026/04/android-now-stops-you-sharing-your-location-in-photos/

My wife and I run OpenBenches. It's a niche little site which lets people share photos of memorial benches and their locations. Most modern phones embed a geolocation within the photo's metadata, so we use that information to put the photos on a map.

Google's Android has now broken that.

On the web, we used to use:


That opened the phone's photo picker and let the use upload a geotagged photo. But a while ago Google deliberately broke that.

Instead, we were encourage to use the file picker:


That opened the default file manager. This had the unfortunate side-effect of allowing the user to upload any file, rather than just photos. But it did allow the EXIF metadata through unmolested. Then Google broke that as well.

Using a "Progressive Web App" doesn't work either.

So, can users transfer their photos via Bluetooth or QuickShare? No. That's now broken as well.

You can't even directly share via email without the location being stripped away.

Literally the only way to get a photo with geolocation intact is to plug in a USB cable, copy the photo to your computer, and then upload it via a desktop web browser?

Why?!?!?

Because Google run an anticompetitive monopoly on their dominant mobile operating system.

Privacy.

There's a worry that users don't know they're taking photos with geolocation enabled. If you post a cute picture of your kid / jewellery / pint then there's a risk that a ne’er-do-well could find your exact location.

Most social media services are sensible and strip the location automatically. If you try to send a geotagged photo to Facebook / Mastodon / BlueSky / WhatsApp / etc, they default to not showing the location. You can add it in manually if you want, but anyone downloading your photo won't see the geotag.

And, you know, I get it. Google doesn't want the headline "Stalkers found me, kidnapped my baby, and stole my wedding ring - how a little known Android feature puts you in danger!"

But it is just so tiresome that Google never consults their community. There was no advance notice of this change that I could find. Just a bunch of frustrated users in my inbox blaming me for breaking something.

I don't know what the answer is. Perhaps a pop up saying "This website wants to see the location of your photos. Yes / No / Always / Never"? People get tired of constant prompts and the wording will never be clear enough for most users.

It looks like the only option available will be to develop a native Android app (and an iOS one?!) with all the cost, effort, and admin that entails. Android apps have a special permission for accessing geolocation in images.

If anyone has a working way to let Android web-browsers access the full geolocation EXIF metadata of photos uploaded on the web, please drop a comment in the box.

In the meantime, please leave a +1 on this HTML Spec comment.

#android #geolocation #geotagging #google #OpenBenches
0
2
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 2mo ago
Book Review: Foreign Fruit - A Personal History of the Orange by Katie Goh https://shkspr.mobi/blog/2026/07/book-review-foreign-fruit-a-personal-history-of-the-orange-by-katie-goh/ Book cover.

I didn't care for this book. It attempts to interweave botanical and cultural history with an autobiography and ends up doing neither particularly well.

For every dose of poetry about the far-flung and exotic journey of the fruit, there's a dull recitation of facts from Wikipedia. Occasionally various origin myths of citrus varieties are presented - there's no attempt to engage with them, seek out the truth, or comment on what they might mean.

Instead, the author seems more interested in inserting herself into the narrative. It's all rather uneasy. She spends a lots of times talking about hard it is for immigrants and their children. But her dad was a doctor who chose to stay in his new country, she's a fairly prominent journalist, and they spend a lot of time jetting across the world.

I know we're all fighting a battle no one else can see, but this isn't the story of someone's struggle against insurmountable odds.

There's an excruciating passage where she tries to rail against the evils of colonialism and expects her family, who grew up under colonial rule, to support her:

She set down her cup with a steady hand. ‘The British did some good things and they did some bad things,’ she said. ‘But what they did is in the past lah.’ She shrugged and picked her cup back up. ‘In Malaysia we need to think about the future.’

The author is utterly dismissive of other people's lived experience. She and I probably both agree that colonialism was a blunt and savage crime against people. But she can't let go of the fact that some people seem rather nonchalant about it.

I once asked my aunt about her colonial education, and she called it a gift.

It sort of feels like a privileged kid seething that no-one understands how hard it is to be her. I found the solipsism rather distasteful, and the lack of rigour in the botanic history left a bitter taste in my mouth.

#BookReview
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
NHS Goes To War Against Open Source https://shkspr.mobi/blog/2026/05/nhs-goes-to-war-against-open-source/

The NHS is preparing to close nearly all of its Open Source repositories.

Throughout my time working for the UK Government - in GDS, NHSX, i.AI, and others - I championed Open Source. I spoke to dozens of departments about it, wrote guidance still in use today, and briefed Ministers on why it was so important.

That's why I'm beyond disappointed at recent moves from NHS England to backtrack on all the previous commitments they've made about the value of open source to the UK's health service.

It's rare that multiple people leak the same story to me, but that's what gives me confidence that lots of people within the NHS are aghast at this news.

A few days ago, I was sent this quote which was attributed to a senior technical person in NHS England.

We are obviously looking at things like Mythos, which is more sophisticated at finding vulnerabilities. In the next week or so, we will be changing our tack on coding the open and making our code public until we're on top of that risk.

Most of our repos, unless they're essential, will be removed for security reasons.

As I've written before, this is not the correct response to the purported threat by Mythos. Neither the AI Safety Institute nor the NCSC recommend this action. While there may be some increase in risk from AI security scanners, to shutter everything would be a gross overreaction.

Nevertheless, that's what the NHS is preparing to do.

On the 29th of April, guidance note SDLC-8 was sent out. Here's what it says:

All source code repositories must be private by default. Repositories may be internal where there is a legitimate need for visibility within the enterprise. Repositories must not be public unless there is an explicit and exceptional need, and public access has been formally approved by the Engineering Board. Purpose Public repositories materially increase the risk of unintended disclosure of source code, architectural decisions, configuration detail, and contextual information that may be exploited — particularly given rapid advancements in Al models capable of large-scale code ingestion, inference, and reasoning (e.g. developments such as the Mythos model). This red line establishes a default-closed posture for code while the organisation assesses the impact of these changes and ensures that any public publication of code is a deliberate, reviewed, and justified decision. • For P&P Public repositories we will switch to Private on Monday the 11th May 2026 • Teams that have a need for an exemption need to declare this to the Engineering mailbox by COP Wednesday 6th May 2026 • Teams can change to private at any time ahead of this • Central tracking of public repositories: NHSE public repositories.xlsx

The majority of code repos published by the NHS are not meaningfully affected by any advance in security scanning. They're mostly data sets, internal tools, guidance, research tools, front-end design and the like. There is nothing in them which could realistically lead to a security incident.

When I was working at NHSX during the pandemic, we were so confident of the safety and necessity of open source, we made sure the Covid Contact Tracing app was open sourced the minute it was available to the public. That was a nationally mandated app, installed on millions of phones, subject to intense scrutiny from hostile powers - and yet, despite publishing the code, architecture and documentation, the open source code caused zero security incidents.

Furthermore, this new guidance is in direct contradiction to the UK's Tech Code of Practice point 3 "Be open and use open source" which insists on code being open.

Similarly, the Service Standard says:

There are very few examples of code that must not be published in the open.

The main reason for code to be closed source is when it relates to policy that has not yet been announced. In this case, you must make the code open as soon as possible after the policy is published.

You may also need to keep some code closed for security reasons, for example code that protects against fraud. Follow the guidance on code you should keep closed and security considerations for open code.

There's also the DHSC policy "Data saves lives: reshaping health and social care with data":

Commitment 601 – completed May 2022

We will publish a digital playbook on how to open source your code for health and care organisations

And, here's NHS Digital's stance on open source in their Software Engineering Quality Framework:

The position of all three of these documents is that we should code in the open by default.

All of which is reflected in the NHS service standard:

Public services are built with public money. So unless there's a good reason not to, the code they're based should be made available for other people to reuse and build on.

All of which is to say - open source should be baked into the DNA of the NHS by now. There are thousands of NHS repositories on GitHub. The work undertaken to assess all of them and then close them will be massive. And for what?

Even if we ignore the impracticality of closing all the code - it is too late! All that code has already been slurped up. If Mythos really is the ultimate hacker, hiding the code now does nothing. It has likely already retained copies of the repositories.

And if it were both practical and effective to hide source code - that doesn't matter. These AI tools are just as effective against closed-source. They can analyse binaries and probe websites with ease.

There are tens of thousands of NHS website pages which refer to their GitHub repos - will they all need to be updated? What's the cost of that?

I've no idea what led to NHS England making this retrograde decision - so I've send a Freedom of Information request to find out.

I am convinced that closing all their excellent open source work is the wrong move for the NHS. I hope they see sense and reverse course.

Until then, I've helped make sure that every single NHS repository has been backed up and, because the software licence permits it, can be re-published if the original is closed.

In the meantime, you should email your MP and tell them that the NHS is wrong to shutter its world-leading open source repositories.

Don't let them take away your right to see the code which underpins our nation's healthcare.


Further Reading
  • I'm quoted in this article from The New Scientist.
#government #nhs #OpenSource #politics
0
4
7
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 15mo ago
Get the location of the ISS using DNS https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/

I love DNS esoterica. Weird little things that you can shove in the global directory to be distributed around the world instantly(ish).

Domain names, like www.example.com usually resolve to servers. As much as we think of "the cloud" as being some intangible morass of ethereal Turing-machines floating in probability space, the more prosaic reality is that they're just boxen in data centres. They have a physical location.

Got a tricky machine which is playing silly-buggers? Wouldn't it be nice to know exactly where it is? That way you can visit and give it some percussive maintenance.

Enter the DNS LOC record!

The snappily titled RFC 1876 is an experimental standard. It allows you to create a DNS record which specifies the latitude and longitude of your server. Of course, some data-centres are very tall and some are underground. So it also contains an altitude parameter.

The standard allows for a minimum altitude of -100,000 metres - deep enough for any bunker! The maximum altitude is 42,849,672 metres which is high enough to allow it to be used on satellites in geostationary orbit.

So, as a bit of fun, I decided to create where-is-the-iss.dedyn.io

It isn't a website. You can't ping it. There's no way to interact with it except by using DNS. Yup! You can use a DNS query to get the (approximate) location of the International Space Station!

Linux and Mac users0 can run:

dig where-is-the-iss.dedyn.io LOC

And receive back the latest position of the ISS:

 ;; ANSWER SECTION:
where-is-the-iss.dedyn.io. 1066 IN  LOC 47 24 53.500 N 66 12 12.070 W 430520m 10000m 10000m 10000m

The DNS records are updated every 15 minutes on a best-effort basis1.

How

The lovely people at N2YO have a website which allows you to track loads of objects in orbit. They also have an easy to use API with a generous free tier.

Calling https://api.n2yo.com/rest/v1/satellite/positions/25544/0/0/0/1/&apiKey=_____ gets back the latest position:

 JSON{
    "info": {
        "satname": "SPACE STATION",
        "satid": 25544,
        "transactionscount": 7
    },
    "positions": [
        {
            "satlatitude": -21.25409321,
            "satlongitude": 140.3335763,
            "sataltitude": 420.09,
            "azimuth": 292.92,
            "elevation": -70.95,
            "ra": 202.69300845,
            "dec": -32.16097472,
            "timestamp": 1751366048,
            "eclipsed": true
        }
    ]}

Note that the altitude is in Km, whereas the LOC format requires m.

The latitude and longitude are in decimal format - they need to be converted to Degrees, Minutes, and Seconds.

There were only a few free domain name providers who offer an API for updating LOC records. I went for deSEC a charity from Berlin. They have comprehensive API documentation.

Adding the initial LOC record is done with:

 Bashcurl https://desec.io/api/v1/domains/where-is-the-iss.dedyn.io/rrsets/ \
    --header "Authorization: Token _______" \
    --header "Content-Type: application/json" --data @- <<< \
    '{"type": "LOC", "records": ["40 16 25.712 S 29 32 36.243 W 427550m 0.00m 10000m 10m"], "ttl": 900}'

However, updating the record is a little trickier. it needs to be sent as an HTTP PATCH to a subtly different URl. The PATCH only needs to send the data which have changed.

 Bashcurl -X PATCH https://desec.io/api/v1/domains/where-is-the-iss.dedyn.io/rrsets/@/LOC/ \
    --header "Authorization: Token _______" \
    --header "Content-Type: application/json" --data @- <<< \
    '{"records": ["40 16 25.712 S 29 32 36.243 W 427550m 0.00m 10000m 10m"]}'

I set the Time To Live at 900 seconds. Every 15 minutes my code runs to update the record2. That keeps me well within the API limits for both services. I could add TXT records showing when it was last updated, or other sorts of unstructured data, but I think this is enough for a quick proof-of-concept.

There you have it! A complex and silly way to demonstrate how DNS can be used to hold the most unlikely of records3. Say, I wonder how you'd represent the co-ordinates of the Mars Rover…?

Further Reading

For more DNS weirdness, please see my other posts:

  • BIMI - SVG in DNS TXT WTF?!
  • Why you can't dig Switzerland

  1. I don't think there's a way for Windows users to look up LOC records using PowerShell or the Command Prompt. ↩︎

  2. Look, I'm not NASA, OK? If you're using this to help you dock then I cannot be held responsible. ↩︎

  3. I suppose you could build an API with unlimited request limits by distributing data via DNS TXT records. Would best suit static or infrequently updating data. Push it once to DNS and let everyone query it semi-locally. ↩︎

  4. See if you can find the other interesting record I've added to DNS! ↩︎

#dns #internet #trivia
shkspr.mobi

Better TTS on Linux – Terence Eden’s Blog

0
5
1
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 2mo ago
Gadget Review: Thermal Master DV2 - Infrared Birdwatching Scope https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/

The good folks at Thermal Master have sent me their DV2 camera to review. As their name suggests, this is a thermal / infrared camera - they've specifically designed this for bird watching and animal spotting. Let's put it through its paces and see how it compares to the competition!

A handheld camera with a pivoted screen.

Straight away you can see it is different from normal IR cameras - they tend to have a small fixed screen and a rubber button interface. This has a lush touchscreen which displays the thermal image and is used to control the camera. The screen can go bright enough to be easily visible in full daylight, and you can dim it down to something more appropriate for night-time viewing.

OK, enough waffle, time to get snapping!

Photos

Here are some shots from the camera of various bits of wildlife near me. I haven't edited these images, they're exactly what you get from the camera.

A cat walking away from the camera.

The resolution is 512x384. There's no EXIF metadata - so no location information.

A bird in the tree.

There's also no in-picture thermal gradient so you can't see the exact temperature of an object. This is designed for spotting animals, not working out how hot your electronics are. The datetime is burned in to the image but can be turned off.

It has the ability to almost totally remove the background "noise" of the sky - making it excellent for spotting things on the wing.

A white object silhouetted against the sky.

Filesize is about 20KB per photo. So you can fit will over a million images on the ~32GB internal storage. Digital zoom goes up to 8X.

Videos

The static images don't really do it justice. It's also possible to shoot video. This gives you a reasonable idea of what you'll see on the touchscreen.

Video resolution is the same as the photos - 512x384 - and runs at 30fps. File size is around 40MB per minute. So about 12 hours of footage can be stored. I've re-encoded these videos to be smaller while keeping the same quality.

Here's a friendly fox I found - I've cycled through the various settings so you can see how they work.

https://shkspr.mobi/blog/wp-content/uploads/2026/07/Fox1.mp4

Again, as with the photos, there's no metadata and the datetime is burned in. Here are a couple of cats playing around in the park.

https://shkspr.mobi/blog/wp-content/uploads/2026/07/Cat1.mp4

Twisting the lens allows you to adjust the focus - it is really impressive the amount of detail it can pick up.

https://shkspr.mobi/blog/wp-content/uploads/2026/07/Cat2-Focus.mp4

There's no video stabilisation (use the tripod mount if you need it) and there's no audio.

RTSP

You can also stream the video to a computer, VLC, or anything else which will take an RTSP stream.

The URl will be rtsp://[IP Address]:8554/ch0 - that will get you a 20fps stream of exactly what the camera is seeing.

Range and Detection

It reckons it'll detect a human's heat signature from around 900 metres away.

There are several modes which will let you see more or less detail. That's particularly important if you're just interested in the hottest part of the image, or if you need to photograph something against a relatively warm background.

The App

This'll pair with your Android phone using the Thermal Masters app. It's a bit of a beast - around 200MB. That's because it's the same app for all their cameras and contains PDFs for several different models. Despite the relatively high download numbers, it has zero reviews.

Like lots of software from hardware manufacturers, the app is basic but serviceable. It connects to your DV2 via WiFi. You can either be on the same network or connect the camera to your phone's hotspot.

Looking through the app's code, it appears to use OpenCV, ffmpeg, and some other popular Open Source libraries. Sadly, the required attribution is missing.

The app is great for monitoring the camera, you can zoom in on the image and fiddle with some of the settings. But you can't actually trigger a photo or video recording! That's a bit annoying.

Linux

For our penguin powered friends, this shows up as 1f3a:1000 "Allwinner Technology Prestigio PER3464B ebook reader (Mass storage mode)". It's a basic drive which lets you copy the media back to your computer via USB-C. Easy as.

Comparison

So how does it compare to the Topdon TS004 Thermal Camera? The Topdon is also marketed at the bird-spotting crowd and, on the surface, has fairly similar features.

The most obvious difference is the user interface. The TS004 is a Monocular - so you need to shove your eye into the end to see anything.

Photo of a dark green tube with various buttons on it. It fits snugly in the hand.

With the DV2, you've got a big screen to look at - which is generally much more pleasant. That display of the DV2 is a touchscreen which makes it pretty easy to interact with - whereas with the TS004 you have to repeatedly mash buttons to change any settings.

In terms of resolution, both have a standard 256×192 sensor. The upscaling on the DV2 is good - but doesn't fundamentally change how much thermal information there is.

But it is the thoughtful little extras which make the DV2 useful. There's a built-in laser pointer which is useful for working out exactly what you're aiming at. At the bottom is a standard tripod mount, so you can rig it up somewhere to monitor an area.

Slightly bizarrely, it comes with an optional Picatinny Rail adaptor. That screws into the side of your DV2 and allows you to add firearm accessories! So if you ever wanted to add a sniper scope to your thermal camera…

Camera with a range finder attachment.

Alright, a regular range-finder will also attach to it 😆

The battery is a bit of an odd one. You can physically remove the battery and place it in its own USB charger. The battery is a 1INR22/71 which is a chunky beast. The charger comes with two slots (although only one battery is included) so you can quick-swap to a full battery if you need to. There is a USB-C port on the bottom, if you want to charge it the normal way.

With the TS004, the only way to stream video was via the app. The DV2 will connect to any WiFi network and present an RTSP stream. The built in WiFi is useful for grabbing firmware updates.

The DV2 also suffers a little from the lack of a trigger button for taking photos. When held in the hand, it feels natural to click the button under the thumb finger - instead, that toggles the laser. Taking a photo means tapping away on the screen to get to a sub-menu. Annoyingly, your phone can't be used as a remote control.

One thing in the TS004's advantage - it's lens cap is attached to the body of the unit. The DV2's is a separate rubber cap which comes off completely. Best remember to stick it in the supplied carrying case, eh?

The TS004 also has built-in animal recognition. It can detect heat signatures and tell you if they're a bird or a human. However, it always misidentified English foxes as Wild Boars! So was of limited use.

Thermal image. A dog-shaped object glows. It is labelled

The DV2 uses AI to upscale the quality of the images rather than trying to detect what it is actually looking at.

In general, the DV2 is easier to use and produces seemingly better quality media. But having to tap the screen multiple times to take a photo or video is slightly annoying.

Price

All the infrared cameras I've reviewed have been expensive. This one is no different. At the moment it is in stock for £459.

You can use the code THERMBIRD10 for 10% off at the official store or from Amazon.com.

That's a chunk of change - but you do get a lot of tech for the price. This isn't designed for finding hotspots in your home, it's excels at picking out wildlife - and the screen is big enough for several people to gather round to see what you've spotted.

Final Thoughts

This is one of the better thermal imaging devices that I've reviewed. The large touchscreen makes it so much easier to control than anything else on the market - all the others have squishy rubber buttons. It is mostly a delight to use, if you can put up with the slightly strange process of taking a photo.

Thermal cameras are still very expensive - the sensors are low resolution and sometimes flaky. The DV2 does a great job of producing a usable images and videos.

The app is no worse than the competition. It really ought to inform users about the use of Open Source code though.

The addition of the laser pointer isn't as gimmicky as I'd thought. I've no use for the Picatinny attachment, but I can see how it could be useful.

If you want to go wildlife spotting, this is probably the device to get. It captures an incredible amount of detail and is excellent at picking up the faintest heat signatures.

#camera #gadget #infrared #review #thermal #usbC
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
Book Review: Accessible Communications by Lisa Riemers and Matisse Hamel-Nelis https://shkspr.mobi/blog/2026/06/book-review-accessible-communications-by-lisa-riemers-and-matisse-hamel-nelis/ Book cover featuring multiple speech bubbles.

My mate Lisa has written a book!

Along with her pal Matisse, she takes us through the practicalities of publishing communications which are accessible to all. This isn't just about the theory - it takes us across multiple legal jurisdictions, ethical frameworks, and business cases. Once it is done convincing you of the necessity of the work, it begins to explain how to actually create useful and accessible comms.

Some stuff you may have heard before. Everyone knows to add alt text, right? But this goes in for a slightly deeper dive, explaining how different publishing tools expose it, how to get the most out of it, and where it can all go wrong.

Usually books like this focus only on HTML. That's great - but there is a world outside the Web. So this goes through the steps to make PDFs accessible (a necessary evil!) and other tools which comms professionals may be regularly using.

It also doesn't just focus on the US hegemony. Instead there are statistics and case studies from dozens of different countries and cultures. It also looks through the youth lens - are TikTok's bouncing subtitles good for accessibility? For situational stuff like not having headphones, probably but for people with cognitive impairments probably not.

Each chapter ends with "Key Takeaways" and a decent summary of what you've learned. You probably won't read this cover to cover, but it is worth diving in to the chapters which meet your needs. Some of the stuff was intimately familiar to me - but I had no idea about how to make Podcasts accessible.

There's a bit of AI stuff splashed through, as is de rigueur, but it is realistic about its current limitations and how harmful it can be if misapplied.

The book ends with a chunky checklist. I suggest printing it out and stapling it to anyone in your organisation who says accessibility is a waste of time.

#a11y #accessibility #BookReview
0
0
1
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Theatre Review: Hadestown https://shkspr.mobi/blog/2026/04/theatre-review-hadestown/

Poster for Hadestown featuring a hand holding a budding flower. Anaïs Mitchell has created something magical. I felt like giving a standing ovation after every song. Just pure theatrical joy delivered by a cast who know how to squeeze every drop of emotion from an audience.

Perhaps it was sitting right at the front of the stalls, but the opening of Hadestown feels like dinner theatre; almost cosy in its intimacy. The first act is so busy - there are a hundred-and-one things happening on stage that it occasionally becomes overwhelming. The second act is slightly more intimate, but no less dazzling.

Having the musicians on stage lends to the feel of being in a nightclub. The stereo separation makes it easier to pick out the various musical threads and brings a lovely texture to the songs. Also, who knew a trombone could steal a show?

Lots of the cast sing in their natural accents. A roaring northern Hades versus a Mancunian Orpheus makes for quite the thrilling combination. Having subsequently listened to the Broadway cast recording, it is amazing what a positive difference it makes.

And, yes, the obligatory revolve spins the performers on a near-constant merry-go-round. When I am King of the West End, the revolve will be banned for the laze cliché that it is!

A stunning show with a killer soundtrack and a delightful set of performers.

I've written before about how the pre-show and post-show experience shapes an event. The Lyric theatre is generously sized, so plenty of space to mill about before the show, rather than being crammed into a tiny bar. The toilets weren't in too bad a condition. Once again, no set dressing in the liminal spaces. Would it have been so hard to mock up some travel posters for the eponymous station? Or have something for people to take photos with?

The themed cocktail menu was inventive but shockingly expensive, even for London prices. The programme is only a fiver and, unlike other West End shows, is full of interesting information and not just an excuse to cram in adverts - excellent value for money.

After the curtain call, we get a few more minutes with the musicians, which was delightful. On the way out there was no leaflet offering a discount on return visits (unlike Avenue Q). There is, apparently, a "Hadestown Passport" which you can get stamped every visit - although I didn't see any evidence of that.

#musical #TheatreReview
shkspr.mobi

Better TTS on Linux – Terence Eden’s Blog

0
45
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
Stupidly Simple SVG Sparklines https://shkspr.mobi/blog/2026/05/stupidly-simple-svg-sparklines/

A sparkline is a little line-graph with no axes or other unnecessary details. They're useful for getting quick understanding of what the data is showing.

They're also really easy to create programmatically.

This uses the SVG "polyline" which takes a list of x,y co-ordinate pairs. But can you spot the small problem?


    

The SVG co-ordinate system has position 0,0 at the top left. Most graphics formats are like that. That's fine for our x value - but it means higher y values will appear lower on the graph.

Getting the x co-ordinate of each data point is easy. Take the width of the SVG image and divide it by the number of data-points.

The y co-ordinate is harder. The algorithm is:

  1. Find the height of the SVG.
  2. Find the maximum value in the data.
  3. Find the minimum value in the data.
  4. Divide the maximum value by the height of the graph.
  5. For each data point, either:
    • To have the lowest value at the bottom of the graph, subtract the minimum from the value, then multiply by the ratio in (4).
    • Or, to retain the gap between zero and the lowest value, multiply the value by the ratio in (4).
  6. The y co-ordinate is calculated by subtracting the value in (5) from the height in (1).

Here's some code showing how it works. I've added a little padding to the inside of the graph - you'll see why later:

//  Max and min of views.
$max_views = max( $svg_views_data );
$min_views = min( $svg_views_data );
$svg_data_length = sizeof( $svg_dates_data ) - 1;

//  SVG details for scaling.
$svg_padding = 12;
$svg_width_graph  = 1000;
$svg_width  = $svg_width_graph + ( $svg_padding * 2 );
$svg_height_graph = 100;
$svg_height = $svg_height_graph + ( $svg_padding * 2 );

//  Calculate where each point should be.
$x_per = $svg_width_graph / ( $svg_data_length );
$y_per = $svg_height_graph / $max_views;

//  Loop through the data.
foreach ( $svg_views_data as $index=>$views ) {
    //  X is from the left.
    $x_pos = intval( $x_per * $index ) + $svg_padding;
    //  Y is from the top.
    $y_pos = $svg_height - intval( $y_per * $views ) - $svg_padding;

    //  Add a point to the line.
    $polyline_points .= "{$x_pos},{$y_pos}\n";
}

echo <<< SVG

    

SVG;

Suppose someone suggests stupidly simple sparklines suffer seriously so someone should supplement statistics several circles?

Using the same co-ordinates, we can place an SVG circle on top of the point. Give it a "title" attribute and you have a little bit of interactivity.

4,707 Views

Here's how it looks (view source to understand how it is constructed).

4,707 2025-09-012,051 2025-09-022,444 2025-09-031,627 2025-09-042,450 2025-09-053,453 2025-09-062,491 2025-09-072,326 2025-09-081,754 2025-09-097,268 2025-09-104,113 2025-09-111,503 2025-09-121,394 2025-09-131,108 2025-09-14533 2025-09-15

Hover over any of those little circles and you'll see some pop-up text giving you information about that datapoint.

…that's it! If you have an array of data points, you can easily create a graph with no graphing library, no plugins, no 3rd party dependencies. Just super simple SVG.

#svg #tutorial
shkspr.mobi

There’s still no point in gigabit broadband – Terence Eden’s Blog

0
66
1
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 2mo ago
Are political journalists always wrong? https://shkspr.mobi/blog/2026/07/are-political-journalists-always-wrong/

I've mostly tuned out of reading the news. But, once in a while, a headline will be shared on social media and I'll momentarily stare into the abyss.

There has recently been a change in UK Prime Minister. I neither know nor care whether that's a good thing. What I do know is that Senior Political Correspondents collectively shat their pants with excitement at being able to breathlessly report any half-baked gossip which would drive clicks.

I saw "Rumours suggest so-and-so will be appointed…", and "Supporters say that A. N. Other will be fired from…", and "Insiders reveal urgent change of policy around…", and so on.

They were all bollocks.

I spent a dull afternoon going through a couple of dozen "sources say" headlines. About 85% were completely wrong. That person didn't become Minister for Administrative Affairs, that other one wasn't fired, the much ballyhooed policy announcement never came.

A few weeks ago, The Economist ran a searing exposé on the accuracy of… The Economist. In an article called "Is The Economist always wrong?" they used a Large Langue Model to test the accuracy of their forecasts. It made for fascinating reading:

We declared smartphones the ­future of computing in 2002, said that something like streaming would devour DVDs in 2008, and cautioned in 2011 that a flood of Chinese-made cars would wash over the West. Still, our techno-optimism occasionally got ahead of itself. Distributed electric grids (boosted by The Economist in 2000), cheap bioethanol (2003), open ­standards for social media (2008) and augmented ­reality (2016) have yet to bring about the breakthroughs we prophesied.

I'd like someone to run the same process on the political rumours reported by the mainstream press. Just how accurate are the tips journalists receive?

Now, obviously, perhaps the rumour was true at the time - but circumstances changed. Perhaps journalists are hanging around in bars and listening to SpAds boast about what the boss has just said. Perhaps they're just making shit up.

It would be fascinating to see if any political journalist has a better than 50% ratio of hits to misses. I strongly suspect that they have an incentive to post the most outrageous rumour rather than the most accurate one.

So, if you have access to a couple of years of newspaper archives, a local AI model which won't burn the planet, and want to cause chaos - please create a leaderboard of the most- and least-accurate political rumour-mongers in the UK.

#AI #journalism #LLM #newspapers #politics
0
1
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Reprojecting Dual Fisheye Videos to Equirectangular (LG 360) https://shkspr.mobi/blog/2026/04/reprojecting-dual-fisheye-videos-to-equirectangular-lg-360/

I still use my obsolete LG 360 Camera. When copying MP4 videos from its SD card, they come out in "Dual Fisheye" format - which looks like this:

Dual fisheye photo of us and some elephants.

VLC and YouTube will only play "Equirectangular" videos in spherical mode. So, how to convert a dual fisheye to equirectangualr?

The Simple Way
ffmpeg \
  -i original.mp4 \
  -vf "v360=input=dfisheye:output=equirect:ih_fov=189:iv_fov=189" \
  360.mp4

However, this has some "quirks".

The first part of the video filter is v360=input=dfisheye:output=equirect - that just says to use the 360 filter on an input which is dual fisheye and then output in equirectangular.

The next part is :ih_fov=189:iv_fov=189 which says that the input video has a horizontal and vertical field of view of 189°. That's a weird number, right?

You'd kind of expect each lens to be 180°, right? Here's what happens if :ih_fov=180:iv_fov=180 is used:

Flattened image, but there are overlaps at the seams.

The lenses overlaps a little bit. So using 180° means that certain portions are duplicated.

I think the lenses technically offer 200°, but the physical casing prevents all of that from being viewed. I got to the value of 189° by trial and error. Mostly error! Using :ih_fov=189:iv_fov=189 get this image which has less overlap:

A flattened image which has less overlap at the edges.

It isn't perfect - but it preserves most of the image coherence.

Cut Off Images

There's another thing worth noticing - the top, right, bottom, and left "corners" of the circle are cut off. If the image sensor captured everything, the resultant fisheye would look something like this:

Two circular images with gaps between them.

I tried repaging the video to include the gaps, but it didn't make any noticeable difference.

Making Equirectangular Videos Work With VLC

Sadly, ffmpeg will not write the metadata necessary to let playback devices know the video is spherical. Instead, according to Bino3D, you have to use exiftool like so:

exiftool \
        -XMP-GSpherical:Spherical="true" \
        -XMP-GSpherical:Stitched="true" \
        -XMP-GSpherical:ProjectionType="equirectangular" \
        video.mp4
Putting It All Together

The LG 360 records audio in 5.1 surround using AAC. That's already fairly well compressed, so there's no point squashing it down to Opus.

The default video codec is h264, but the picture is going to be reprojected, so quality is always going to take a bit of a hit. Pick whichever code you like to give the best balance of quality, file size, and encoding time.

Run:

ffmpeg \
  -i original.mp4 \
  -vf "v360=input=dfisheye:output=equirect:ih_fov=189:iv_fov=189" \
  -c:v libx265 -preset fast -crf 28 -c:a copy \
  out.mp4; exiftool \
        -XMP-GSpherical:Spherical="true" \
        -XMP-GSpherical:Stitched="true" \
        -XMP-GSpherical:ProjectionType="equirectangular" \
        out.mp4

That will produce a reasonable equirectangular file suitable for viewing in VLC or in VR.

If this has been useful to you, please stick a comment in the box!

#ffmpeg #HowTo #LG360 #linux #video
0
4
0
1
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 2mo ago
Scattered thoughts on social geolocation https://shkspr.mobi/blog/2026/07/scattered-thoughts-on-social-geolocation/

I want to be able to share my location with my friends on social media. Twitter (RIP) had a way to attach an optional location to a post. Facebook still lets me check in to venues. But neither ActivityPub (Mastodon) nor AT Protocol (BlueSky) allow me to do that.

I've been banging on about this for a while so was delighted to be invited to chat with the GeoSocial Task Force on their monthly call.

But, before I start, please remember that these proposals are not mandatory. If you don't want to share your location, then please don't share your location. This is an optional feature which shouldn't be used by people with a strong need for privacy.

We were primarily discussing the nascent Geographical Microsyntax proposals.

Firstly, I love the idea of being able to share my location. I want my friends to know I'm in town for a gig. I want people to think I'm cool because I'm seeing some experimental theatre. I want to virtue signal that I'm giving blood.

Similarly, I want to be able to find social media posts by location. What's happening right now in Paris? Did anyone else hear that sonic boom in London? Which cool people are also at this gig with me?

But, I do think these proposals have some issues which need to be addressed.

User Research

The primary thing missing from the proposal is any form of understanding what users want to do with a geotagged post.

You see a post like:

Hanging out with friends. I just checked in to Leicester Square.

What do you expect to happen when you click that link?

  • See who is at the location?
  • Read more information about the place being discussed?
  • Find all posts at that specific address?
  • Discover posts which are close to there?
  • Something else?

What other things do people want to do with geotagged posts?

  • Find all posts within 5Km of me?
  • Discover users who have posted near me?
  • Get emergency alerts for the city I'm in?
  • See what's trending in a specific country?

Without knowing what people might want to do with this information, it's rather hard to design a service which meets their needs.

To micro or not to micro?

Where I disagree with the proposals is the idea of using inline text as a form of microsyntax.

Proposals like "I am in /London/ eating ice-cream" or "Checked in to Leicester Square L:N123456" fail for a couple of reasons.

Things like #hashtags and @mentions developed organically on social networks before they were eventually adopted by the platforms themselves. It is rare that a top-down diktat can be used to tell people how they should be formatting their posts.

More importantly, people are crap at formatting things consistently! Every event I go to has people using #Event alongside #Event2026 or #Event26 or a hundred variations.

Even if users could format it consistently, names are ambiguous. Is 🌐:Paris the one in France or Texas?

I'm strongly of the opinion that text is for text, not syntax.

Openness 🆚 Centralisation

Saying that you're on a specific point on the globe doesn't always provide useful information. Even with altitude, it isn't always possible to work out if your in the Starbucks or the Costa next door. Do you want to say you're in a train station, or a distinct platform, or even a specific train journey?

There are various services which offer unique IDs per loosely-defined place.

Google Maps provides a Place ID for every thing that it knows about. There's a similar service from FourSquare. But both of those are closed and proprietary systems - they can only be updated by the company that creates them.

Wikipedia's Wikidata has IDs for lots of places, similarly OpenStreetMap has nodes with names which can be used to identify locations.

But all of these suffer from the same flaw; they are centralised.

If Google kills its service then all those Place IDs die.

This has happened before. Yahoo used to run the Where On Earth IDentifier service but discontinued it.

While OSM and Wikipedia are great projects, they're still centralised. If you're banned from OSM, you can't create a new node.

So, to my mind, the primary way of identifying a place has to use a fully open, globally agreed, and unrestricted standard.

Location Plus Plus

The obvious choice is latitude and longitude as defined by WGS 84. It allows for arbitrary precision anywhere on the planet.

No one can stop you issuing lat/long just because a country is under sanctions. The standards community can't revoke your access to it. The co-ordinates are well understood by almost all software.

There are some alternatives. Google's Plus.Codes build on top of lat/long to make something more human readable. But, crucially, human readability is not the issue here. This is metadata which should never be shown to a human. If a user interface wants to format a lat/long they can do so as a Plus.Code or any other format.

GeoJSON

There are dozens of competing ways to mark up a location.

It seems sensible to me that, given most major social media protocols use JSON, adding GeoJSON would be the simplest way to add geographic information to a post's metadata.

At its most basic, a single "Point" can be shared like so:

{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [-0.13005,51.5103]
    }
}

It can have as much or as little precision as needed.

If the place being checked into has a name, it can also be added - this could be used for display purposes within the message

{
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [-0.13005,51.5103]
    },
    "properties": {
        "name": "Leicester Square"
    }
}

The properties can be as complex as the sender wants. For example it could add Wikidata references, OpenStreetMap IDs, telephone numbers, or some cool new thing which hasn't been invented yet.

Here's a maximalist example of checking in to a park:

{
    "type": "Feature",
    "geometry": {
        "type": "Polygon",
        "coordinates": [
        [
                [-0.1303791,51.5099976],
                [-0.1295305,51.5100444],
                [-0.1297077,51.510947 ],
                [-0.1308786,51.5105859],
                [-0.1308893,51.5105793],
                [-0.1303791,51.5099976]
            ]
        ]
    },
    "properties": {
        "name": "Leicester Square",
        "WikiData": "Q848912",
        "OSM": "4082589",
        "GooglePlaceID": "ChIJPcTFENIEdkgR94E58rgB69o",
        "PlusCode": "9C3XGV69+4X",
        "Quinfrob": "🌐89451_𰻝",
        "address": {
            "road": "Leicester Square",
            "neighbourhood": "St. James's",
            "quarter": "East Marylebone",
            "suburb": "Covent Garden",
            "city": "City of Westminster",
            "ISO3166-2-lvl8": "GB-WSM",
            "state": "England",
            "ISO3166-2-lvl4": "GB-ENG",
            "postcode": "WC2H 7NA",
            "country": "United Kingdom",
            "country_code": "gb"
        }
    }
}
What's Next

My personal opinion is that the following needs to happen:

  • Talk to some users - find out what they might use this for.
  • Work with privacy advocates to reduce possible harms (for example, being able to redact a location from a previously shared post).
  • Discuss with developers about how they'd work with this metadata.
  • Clients should start adding GeoJSON metadata to their posts, even if it can't be displayed yet.

You can read the minutes of the meeting and I'd encourage you to join the next call.

#ActivityPub #BlueSky #fediverse #FourSquare #geolocation #json #openStandards #OpenStreetMap
0
5
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Why is it so hard to passively stalk my friends' locations? https://shkspr.mobi/blog/2026/04/why-is-it-so-hard-to-passively-stalk-my-friends-locations/

I feel terribly guilty when I visit a new city, post photos of my travels, only to have a friend say "Hey! Why didn't you let me know you were in my neck of the woods?"

Similarly, if I bump into an old acquaintance at a conference, we both tend to say "If only I'd known you were here, we could have had dinner together last night!"

I do enjoy the serendipity of events like FOSDEM - randomly seeing a mate and expressing the joy of spontaneity. But I also like arranging to meet up in advance.

At the moment, my strategy is sending a blast on social media saying "I'm visiting [this city] next week, anyone fancy a beer and a natter?" I've met friends all over Europe, Australia, and New Zealand that way. It mostly works. But I can't help feeling it is inefficient and prone to missing connections.

I even wrote my own code to auto-post FourSquare checkins to my other social media sites.

Here are my ideal scenarios. Imagine something built in to Signal / WhatsApp / Whatever app you already use.

Plan In Advance

I tell my app that I'm going to Barcelona from 14th - 19th February and am happy to meet any of my friends.

✨Background Magic✨

My friend Alice has also planned a trip to Barcelona around those dates. She gets a ping saying that one of her friends is going to be in the same city. Does she want to know more?

So far, so Dopplr.

My friend Bob lives just outside of Barcelona. He's set his "willing to travel" settings to be about 30 minutes, so also receives a ping.

I don't know that either of them have seen the notification until they decide they want to meet.

Spontaneous Fun

I step off the train in Manchester, England England. Perhaps the app notices I'm away from home, or maybe I press the "Anyone Around?" button.

On a map I can see friends who have shared their rough location. I decide to message Chuck to see if he's free for a chat.

Dave notices my location is now within his preferred travel distance. He gives me a ring.

A bit like how FourSquare used to be - but with less precision.

Downsides

The above is very much the "happy path". It doesn't look at any of the knotty problems or grapple with the UI that would be needed to make this work. But we know the technology for sharing location is viable - so what are the social issues that make this so difficult?

Social Awkwardness

"Oh, fuck, Edgar's location says he's in town. Can we pretend to be out of the country?"

Alternatively, "Huh, I know at least a dozen people who live in Skegness. Why aren't any of them responding to me?"

Social pressure and awkwardness are hard problems. No one wants to use the app that makes you feel like a friendless loser.

Privacy

Do you want your friends knowing your every movement? I'm sure some people do, but most probably don't. It's possible to sketch out some vague controls:

  • Only send a notification if I push this button.
  • Don't send alerts if I am within this radius of my home / work.
  • Fuzz my location to the city / state / country level.
Danger

Is it a risk to let people know vaguely where you are? Is meeting up with (semi-) strangers from the Internet a smart life choice? Is having an app stalk you across the globe giving too much data to advertisers?

Does that creep from work abuse the system to keep popping up whenever you're out with friends?

Technology

I said the technology exists for this, and that was sort of true. Every device has GPS & an Internet connection. Storing a log of friends and sending them a message is a solved problem.

But is it solved in a decentralised and privacy preserving way?

No one wants to give all this power to one company. Google will build it and kill it. Facebook will sell your secrets to dropshippers. A funky start-up will be acquhired by Apple & restricted to iOS devices.

My location is fuzzed to an acceptable degree of imprecision and then sent… where? To all my friends directly? To a central server? Can k-anonymity help?

Is this a separate app? Everyone seemed to leave FourSquare after they buggered around with it. Perhaps it is just a feature in existing apps?

What's Already There?

Messaging apps like Signal, Telegram, and WhatsApp allow you to share your location with one or more friends.

To me, it feels a bit weird to manually send a dropped pin to some / all of my contact. It also doesn't let you share "tomorrow I will be in…"

Using "Stories" is the common way to share an update with all contacts - but none of them let you automatically share your location in a story.

FourSquare's Swarm app allows you to check in to a "neighbourhood". But there's no obvious way of saying "London" or "Manchester" - and I'm not sure how close to an area you need to be to get an alert that your friend is there.

What's Next?

I don't want to build this. Trying to get everyone I know to adopt a new app isn't going to happen. With the fragmentation of messaging and the lack of interoperability, this is likely to remain an unsolved problem for some time.

So here's my strategy.

  • Get back in to using FourSquare. Most of my friends seemed to stop using it back in 2017 when it was split into Swarm. But a few are still on there.
  • Manually post a story on Mastodon, BlueSky, Facebook, WhatsApp, Signal, and Telegram saying "Visiting Hamburg next week. Anyone want a beer?"
  • Hope that something better comes along.
#FourSquare #geolocation #location
0
3
0
1
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
London Data Store Relaunch https://shkspr.mobi/blog/2026/06/london-data-store-relaunch/

It has been sixteen years since the launch of data.london.gov.uk. Back then, it was a trailblazer as one of the first major cities to release Open Data in this way. Now, over a decade later, it is more than a mere repository; it is a celebration of Open Data and the way it can improve Londoners' lives.

So, time for a refresh front and back. As well as a bunch of back-end updates, the front-end has been spruced up which should make it easier to find the data you're looking for. I particularly the way they're now highlighting the licence under which data are available.

Screenshots showing the difference between the old and new version.

You can check it out right now at https://dfl.london.gov.uk/

If you spot any bugs, send them to datastore@london.gov.uk

The most important thing you can do is use your library! Just like any other library, it lives or dies based on how much use it gets. Rummage around in those datasets, build interesting things, and convince your local area to send data to it.

This is a brilliant resource and I'm glad to see it get the love it deserves.

#OpenData
0
1
1
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
You can parse an .env file as an .ini with PHP - but there's a catch https://shkspr.mobi/blog/2026/04/you-can-parse-an-env-file-as-an-ini-with-php-but-theres-a-catch/

The humble .env file is a useful and low-tech way of storing persistent environment variables. Drop the file on your server and let your PHP scripts consume it with glee.

But consume it how? There are lots of excellent parsing libraries for PHP. But isn't there a simpler way? Yes! You can use PHP's parse_ini_file() function and it works.

But…

.env and .ini have subtly different behaviour which might cause you to swear at your computer.

Let's take this example:

# This is a comment
USERNAME="edent"

Run $env = parse_ini_file( ".env" ); and you'll get back an array setting the USERNAME to be "edent". Hurrah! Works perfectly. Ship it!

But consider this:

# This is a comment
USERNAME="edent" # Don't use an @ symbol here.

It will happily tell you that the username is "edent# Don"

WTAF?

Here's the thing. The comment character for .ini is not # - it's the semicolon ;

Let me give you some other examples of things which will fuck up your parsing:

# Documentation at https:/example.com/?doc=123
DOCUMENTATION=123
# Set the password
PASSWORD=qwerty;789

That gets us back this PHP array:

[
  '# Documentation at https:/example.com/?doc' => '123',
  'DOCUMENTATION' => '123',
  'PASSWORD' => 'qwerty',
];

When the .ini is parsed, it ignores every line which doesn't have an = sign. It also treats literal semicolons as the start of a new comment until they're wrapped in quotes.

My code highlighter should show you how it is parsed:

# Documentation at https:/example.com/?doc=123
DOCUMENTATION=123
# Set the password
PASSWORD=qwerty;789

It gets worse. Consider this:

# Set the "official" name
REALNAME="Arthur, King of the Britons"

That immediately fails with PHP Warning: syntax error, unexpected '"' in envtest on line 1

You can use single quotes in pseudo-comments just fine, but if the ini parser sees a double quote without an equals then it throws a wobbly.

I'm sure there are several other gotchas as well. For example, there are certain reserved words and symbols you can't used as a key.

This will fail:

# Can we fix it? Yes we can!
FIX=true

It chokes on the exclamation point.

How to solve it (the stupid way)

The comments on an .env file start with a hash.

The comments on an .ini file start with a semicolon.

So, it is perfectly valid for a hybrid file to have its comments start with #;

Look, if it's stupid but it works…

What Have We Learned Here Today?
  • There's a right way and a wrong way to do .env parsing.
  • The wrong way works, up until the point it doesn't.
  • You should probably use a proper parser rather than hoping your .env looks enough like an .ini to pass muster.

On next week's show - why you shouldn't store your passwords inside a JPEG!

#php
shkspr.mobi
0
7
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 10mo ago
Now witness the power of this fully operational Fediverse! https://shkspr.mobi/blog/2025/11/now-witness-the-power-of-this-fully-operational-fediverse/

How can you measure the popularity of a social network site? Perhaps by counting the number of active accounts, or the quality of the discourse, or even how many people reply to your witty memes.

Me? I prefer to look at how many people visit my blog from each site. It is an imperfect measure - and a vain one - but lets me know where I should be spending my time. No point posting on a network which is just bots talking to each other, right?

Earlier this year I built a stats-counter for my blog. Every time someone clicks from a website which links to my blog, it records that visit in a database. I get to see which blog posts are doing numbers, and where those numbers came from.

Until fairly recently, the Mastodon social network didn't send referer details. I thought that reduced the visibility of the network and lobbied for it to change. As various Mastodon servers upgrade, and admins opt-in, it is becoming more apparent just how much traffic originates from the Fediverse.

Over the last few weeks, here's how many people have clicked from BlueSky and Mastodon to one of my blog posts.

TotalSource1,607bsky.app752mastodon.social

At first glance, it doesn't look good for our elephantine friends, does it? The butterfly sends over twice the traffic. Game over!

But, of course, while Mastodon.social is the biggest instance - it is far from the only one. What happens if we slide down the long tail? Here's all the Mastodon-ish instances which sent me over 10 clicks.

TotalSource193phanpy.social120 android-app://org.joinmastodon.android/106infosec.exchange62mas.to59mstdn.social55social.vivaldi.net49wandering.shop48fosstodon.org33mathstodon.xyz27mastodon.online26mastodon.scot24app.wafrn.net19indieweb.social18social.lol17tech.lgbt17toot.wales16en.osm.town16feditrends.com14mstdn.ca14piefed.social12wetdry.world11c.im11mastodon.nl51 Sites sending < 10 clicks

Ah! Add them all up and you get a grand total of 1,773 visitors from Mastodon-powered sites. That's more than BlueSky.

Now, there are some obvious caveats to the data:

  • I have a smaller follower count on BlueSky than I do on Mastodon.
  • My posts may appeal more to one demographic than another.
  • People may have strict privacy controls which suppress the true volume of visitors.
  • There's no way to measure how long someone spends reading my posts.
  • RSS and newsletter visitors aren't counted.
  • Clicks from apps may not always show a referer.
  • Some people may be on multiple services.
  • Fediverse users can follow the post directly, so don't need to visit the site to read it.

And yet… no matter how you slice it, Fediverse servers are sending as much traffic as BlueSky!

I think this is brilliant. Web services should be able to scale from small to big - and each ActivityPub-powered site helps power the open Internet.

Just for completeness, this is how Reddit, Facebook, LinkedIn, Twitter, and Lemmy do over the same period:

TotalSource1,158reddit.com585 android-app://com.reddit.frontpage/76facebook.com76https://old.reddit.com/r/programming/56https://www.reddit.com/r/programming/52youtube.com41t.co38https://old.reddit.com/r/todayilearned/comments/1nsw7f4/til_in_mongolia_instead_of_a_street_address_a/31linkedin.com27 android-app://io.syncapps.lemmy_sync/27https://www.reddit.com/r/todayilearned/comments/1nsw7f4/til_in_mongolia_instead_of_a_street_address_a/22https://old.reddit.com/r/programming/comments/1n96ftn/40_years_later_are_bentleys_programming_pearls/22lemmy.ca17 android-app://com.linkedin.android/16lemmy.dbzer0.com14feddit.org11https://www.reddit.com/r/programming/comments/1n96ftn/40_years_later_are_bentleys_programming_pearls/10discuss.tchncs.de10l.instagram.com8lemmy.blahaj.zone6https://www.reddit.com/r/GrapheneOS/comments/1m2l84b/considering_making_the_switch_does_google_pay/6reddthat.com

If you add up all the Lemmy instances, they send about as much traffic as Facebook and LinkedIn combined. That's not a huge surprise - those platforms hate anyone clicking away to the wider web.

Twitter is basically the Dead Internet. I'm no longer on there, but I do occasionally search it to see who is sharing my posts. The popular posts I write get shared a lot - sometimes by accounts with huge followers - yet there are no comments or retweets and barely and clicks.

I don't do Instagram or Threads, and that might be reflected in their low numbers. But I'm not active on YouTube either - yet people there occasionally link back to me.

Final Thoughts

Firstly, my stats only represent my site. Your site might be very different.

Secondly, I've ignored search engine traffic, big blogs, newsletters, and other sources.

Thirdly, and most importantly, this isn't a competition! The desire for a "winner-takes-all" service is dangerous and disturbing. An ecosystem is at its most vibrant when there are multiple participants each thriving in their own niche.

I want a thousand sites, running a hundred different software stacks, some of which only serve a dozen people, or even a lone participant.

Diversity is strength.

#ActivityPub #BlueSky #fediverse #mastodon #statistics
reddit.com
0
1
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 6mo ago
Someone at BrowserStack is Leaking Users' Email Address https://shkspr.mobi/blog/2026/04/someone-at-browserstack-is-leaking-users-email-address/

Like all good nerds, I generate a unique email address for every service I sign up to. This has several advantages - it allows me to see if a message is legitimately from a service, if a service is hacked the hackers can't go credential stuffing, and I instantly know who leaked my address.

A few weeks ago I signed up for BrowserStack as I wanted to join their Open Source programme. I had a few emails back-and-forth with their support team and finally got set up.

A couple of days later I received an email to that email address from someone other than BrowserStack. After a brief discussion, the emailer told me they got my details from Apollo.io.

Naturally, I reached out to Apollo to ask them where they got my details from.

They replied:

Your email address was derived using our proprietary algorithm that leverages publicly accessible information combined with typical corporate email structures (e.g., firstname.lastname@companydomain.com).

Wow! A proprietary algorithm, eh? I wonder how much AI it takes to work out "firstname.lastname"????

Obviously, their response was inaccurate. There's no way their magical if-else statement could have derived the specific email I'd used with BrowserStack. I called them out on their bullshit and they replied with:

Your email address came from BrowserStack (browserstack.com) one of our customers who participates in our customer contributor network by sharing their business contacts with the Apollo platform.

The date of collection is 2026-02-25.

So I emailed BrowserStack a simple "Hey guys, what the fuck?"

Web contact form. It says

I love their cheery little "No spam, we promise!"

Despite multiple attempts to contact them, BrowserStack never replied.

Given that this email address was only used with one company, I think there are a few likely possibilities for how Apollo got it.

  • BrowserStack routinely sell or give away their users' data.
  • A third-party service used by BrowserStack siphons off information to send to others.
  • An employee or contractor at BrowserStack is exfiltrating user data and transferring it elsewhere.

There are other, more nefarious, explanations - but I consider that to be unlikely. I suspect it is just the normalisation of the shabby trade in personal information undertaken by entities with no respect for privacy.

But, it turns out, it gets worse. My next blog post reveals how Apollo got my phone number from from a very big company.

Be seeing you 👌

#gdpr #privacy
0
11
1
1
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 2mo ago
Book Review: A City on Mars - by Dr. Kelly Weinersmith and Zach Weinersmith https://shkspr.mobi/blog/2026/07/book-review-a-city-on-mars-by-dr-kelly-weinersmith-and-zach-weinersmith/ Book cover featuring a cartoon Martian city.

I'm pretty sure this book is a psyop designed to demoralise a generation of starry-eyed dreamers. It is obviously written by the same people who told us not to land on Europa. A malignant energy designed to limit the scope of human ambition and thwart our plans to colonise the universe.

The problem is, I can't find fault with any of their logic.

The Weinersmiths make a compelling case that space is much harder than any of the propagandists are willing to admit. Even if it were faster, safer, and cheaper - there's still very little point. Any of the technologies we could point at the skies would be infinitely more useful (and profitable) pointed back at our pale blue dot.

Along the way they take in biology (is it even possible to breed in space?), legality (OK, but what jurisdiction will it be under?), and moral philosophy (will we actually become more enlightened beings?)

And yet, space is cool. I know that "because it is there" isn't a logical argument; but it is a hell of an emotional pull. In amongst all their (justified) snarky cartoons are occasional pearls in the rubble:

As with the cathedrals of Earth, those of us who cast the first few bricks may not be around to see the spire placed on top, but we might nevertheless want to start building.

The excel at making the dull delightful. There are a lot of big and serious facts to get through, but they have a gift for communicating them simply and eloquently. I just wish they'd've come to a different conclusion.

#BookReview #science
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
PHP - simple way to send HTTP headers before a script ends https://shkspr.mobi/blog/2026/05/php-simple-way-to-send-http-headers-before-a-script-ends/

Suppose you want PHP to keep processing after it has sent back an HTTP response. Normally, this doesn't work:

<?php
   header( "Location: https://example.com/" );
   //   Long operation.
   sleep(10);
   die();

Try it yourself. You'll have to wait 10 seconds before you get back

< HTTP/2 302 
< location: https://example.com/

There are some complex ways to fix this - they usually involve spawning sub-processes or having a cron job run something. But there's a simpler way!

Most servers do some form of output buffering. They wait for the buffer to fill (or be explicitly terminated) before they send any content. My server was set to a buffer of 4,096 bytes. So I forced some dummy output to fill it up, then told PHP to flush the buffer:

<?php
   header( "Location: https://example.com/" );
   echo str_repeat("😆", 4097);
   flush();
   sleep(10);
   die();

Some clients, like Python's Requests, wait until they've explicitly seen the end of the response before processing it.

But, for something like curl, the above is sufficient.

#HowTo #php
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 60mo ago
EBCDIC is incompatible with GDPR https://shkspr.mobi/blog/2021/10/ebcdic-is-incompatible-with-gdpr/ Welcome to acronym city! The Court of Appeal of Brussels has made an interesting ruling. A customer complained that their bank was spelling the customer's name incorrectly. The bank didn't have support for diacritical marks. Things like á, è, ô, ü, ç etc. Those accents are common in many languages. So it was a little surprising that the bank didn't support them. The bank refused to spell their customer's name correctly, so the customer raised a GDPR complaint under Article 16. The data subject shall have the right to obtain from the controller without undue delay the rectification of inaccurate personal data concerning him or her. Cue much legal back and forth. The bank argued that they simply couldn't support diacritics due to their technology stack. Here's their argument (in Dutch - my translation follows) Bank X also explained that the current customer data management application was launched in 1995 and is still running on a US manufactured mainframe system. This system only supported EBCDIC ("extended binary-coded decimal interchange code"). This is an 8-bit standard for storing letters and punctuation marks, developed in 1963-1964 by IBM for their mainframes and AS/400 computers. The code comes from of the use of punch cards and only contains the following characters… (Emphasis added.) EBCDIC is an ancient (and much hated) "standard" which should have been fired into the sun a long time ago. It baffles me that it was still being used in 1995 - let alone today. Look, I'm not a lawyer (sorry mum!) so I've no idea whether this sort of ruling has any impact outside of this specific case. But, a decade after the seminal Falsehoods Programmers Believe About Names essay - we shouldn't tolerate these sorts of flaws. Unicode - encoded as UTF-8 - just works. Yes, I'm sure there are some edge-cases. But if you can't properly store human names in their native language, you're opening yourself up to a lawsuit. Source GDPRhub - 2019/AR/1006 DanceReactions Marie ʕʘᴥʘʔ Julien @mariejulienTrès intéressant ! Terence Eden is on Mastodon @edentThis is interesting. A bank claimed it couldn't use diacritics in a customer's name due to technical limitations. Customer sued… and won! Your name is personal data, and GDPR says it should be recorded accurately.❤️ 1,143💬 0🔁 49407:53 - Wed 20 October 2021❤️ 40💬 2🔁 011:54 - Wed 20 October 2021 Grumpy Nat 🇨🇭🇧🇷🇲🇫 @Nat_KeelyHâte de mettre en justice tous les sites et autres compagnies qui ont décidé que le fait que j'ai un accent dans mon nom de famille soit source de bug (avec évidemment un message d'erreur qui n'a rien à voir. Histoire de bien pas comprendre pourquoi ça marche pas) Terence Eden is on Mastodon @edentThis is interesting. A bank claimed it couldn't use diacritics in a customer's name due to technical limitations. Customer sued… and won! Your name is personal data, and GDPR says it should be recorded accurately.❤️ 1,143💬 0🔁 49407:53 - Wed 20 October 2021❤️ 3💬 0🔁 010:43 - Wed 20 October 2021 Lays Y. M. Farra @LYMFHSRLa France va sortir de l'UE juste pour que leur état-civil et autres administrations puissent continuer à ruiner la vie de quelqu'un parce qu'il a un tilde dans son nom Terence Eden is on Mastodon @edentThis is interesting. A bank claimed it couldn't use diacritics in a customer's name due to technical limitations. Customer sued… and won! Your name is personal data, and GDPR says it should be recorded accurately.❤️ 1,143💬 0🔁 49407:53 - Wed 20 October 2021❤️ 9💬 0🔁 013:38 - Wed 20 October 2021 KristoferA 🌏 @KristoferADoes this mean that Z̷̡̧̢̰͓̪͖̭͙̰̣̱̬̹̙̜̪̣̏̿̏̋͑́̒͑́̒̿̇̈̍̇̌͝͝a̵̡̧͍̘̮̤̙̹͙̦̙͙͖͓̥̟̦͔͒̇̊̊̔̓́͒́̌̈́̑͋̏̏̏̚͘͝͠͝l̶͉̯̱͇̭̭̉̉̈́̿͐̽̒̎̽͌̚͜ģ̸̧̛͙̩̹̰̤̱̖̘̻̪̻̮̫̟̙̲͍̰̻͕̗̫̿̆̃́͗̽̊̽̌̔̂͂̈͊̐̈́̈̈́̈̓̆͌̑́̕͜ǫ̶̢̹̥̮̟͍̔̑̔̽ can finally open a bank account? Terence Eden is on Mastodon @edentThis is interesting. A bank claimed it couldn't use diacritics in a customer's name due to technical limitations. Customer sued… and won! Your name is personal data, and GDPR says it should be recorded accurately.❤️ 1,143💬 0🔁 49407:53 - Wed 20 October 2021❤️ 16💬 0🔁 013:10 - Wed 20 October 2021 Bastien Nocera @hadessukNext up, I’m suing La Poste for still using ISO-8859-1 when printing labels. Poor “Frédéric” I recently sent a game to… Terence Eden is on Mastodon @edentThis is interesting. A bank claimed it couldn't use diacritics in a customer's name due to technical limitations. Customer sued… and won! Your name is personal data, and GDPR says it should be recorded accurately.❤️ 1,143💬 0🔁 49407:53 - Wed 20 October 2021❤️ 7💬 0🔁 016:08 - Wed 20 October 2021 Michael Büker 🇺🇦 @emtiuEine Erschütterung der Macht, als würden Millionen Banken-ITler in panischer Angst aufschreien und dann verstummen. Terence Eden is on Mastodon @edentThis is interesting. A bank claimed it couldn't use diacritics in a customer's name due to technical limitations. Customer sued… and won! Your name is personal data, and GDPR says it should be recorded accurately.❤️ 1,143💬 0🔁 49407:53 - Wed 20 October 2021❤️ 25💬 2🔁 006:13 - Thu 21 October 2021 #gdpr #name #unicode
0
2
1
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
GDS weighs in on the NHS's decision to retreat from Open Source https://shkspr.mobi/blog/2026/05/gds-weighs-in-on-the-nhss-decision-to-retreat-from-open-source/

Within the UK's Civil Service you occasionally hear the expression "being invited to a meeting without biscuits". It implies a rather frosty discussion without any of the polite niceties of a normal meeting0. In general though, even when people have severe disagreements, it is rare for tempers to fray. It is even rarer for those internal disagreements to spill over into public.

Which is what makes GDS's latest guidance so surprising. At the start of the month, NHS England made the bizarre and irresponsible decision to close all their Open Source repositories due to unfounded fears of AI hacking1. Lots of people within the NHS were outraged. As were many outside - with this petition against the move gathering over 2,000 signatures.

Within other parts of government there was also alarm. Although I no longer work for Government Digital Service, I was contacted by several concerned people there who remembered all my work on Open Source. The brilliant team in Whitechapel have now published their guidance "AI, open code and vulnerability risk in the public sector".

It is brutal.

They utterly repudiate the NHS's stance and forensically eviscerate it. I'll let you read the whole thing, but here are a few choice excerpts:

Recent public reporting about organisations restricting access to public repositories due to AI-enabled code analysis illustrates how quickly leaders may reach for blanket closure in response to uncertainty.

Basically, non-technical managers need to stop over-reacting.

Private repositories can create a false sense of security.

I think that's the crux of the argument. Closing code doesn't solve the underlying problems.

Making code private is not an appropriate mitigation for lack of ownership, patching capability, or operational assurance, so systems that cannot be safely maintained should be remediated or retired.

If you are so concerned about the poor security of your systems, you should shut them down completely to mitigate the threat.

Closure can become a one-way door.

As I said to the BMJ, "nothing lasts longer than a temporary fix".

Where code has been developed in the open, making a repository private later may not remove access for a capable adversary as popular repositories are often mirrored or forked

Indeed. A friend of mine has already archived all of the NHS's repositories. You can see the ones they've tried to hide.

But the killer blow, I think, is this:

Moving code from public to private as a substitute for investment in secure-by-design delivery, ownership and remediation is a warning sign because it reduces sharing and scrutiny, can slow coordinated improvement across government and suppliers, and does not remove the underlying weaknesses in a running service.

Exactly! Coding in the open has been shown time and again to produce high quality and secure work. The looming threat of AI vulnerability scanners doesn't change that - security is a shared responsibility. Technical teams need to be well enough resourced to create secure systems; hiding code is as reliable as papering over structural cracks.

GDS was created was to be a strong centre with vast technology expertise. This was to counter the frankly shoddy approach to tech in other departments. Back then, a Service Assessment was a way for a department to prove that they were actually capable of designing, launching, and managing a complex IT project.

Most departments have become significantly better at the development and running of these sorts of projects, so the raison d'etre of GDS has somewhat waned. Departments feel more confident in running off on their own. Usually I'd celebrate that - it's important that GDS doesn't become a bottleneck and that the talent is distributed throughout the whole Civil Service.

But NHS England has always been a bit of a weird one. One of the reasons NHSX was created2 was to ensure that the health service had strong expertise in technology and its deployment. As the Head of Open Technology there, I helped craft the policies which embedded Open Source and Open Standards within it3.

I don't know what discussions have taken place within NHS England - although I looking forward to receiving a response to my FOI request. It looks to me like a small group within NHS England have received a report showing some potential vulnerabilities discovered by Mythos. Rather than following their own internal guidance, they've over-reacted and slapped a blanket ban on coding in the open.

I fervently hope that this new guidance will encourage DHSC to bring NHS England into line with best practice. If not, perhaps GDS ought to reassert itself as the technical authority with power to veto a department's incomprehensible decisions?


  1. Of course, all the budget cuts mean that biscuits cannot be purchased for any meetings. Which may explain some of the morale issues within the Civil Service. Thanks Austerity. Thausterity. ↩︎

  2. As of today, they've shut down nearly 200 repositories. More may be coming. ↩︎

  3. I was there right before the start of NHSX and helped set it up. ↩︎

  4. Which, I suppose, is why I'm bitter and angry that all our hard work is being undone. ↩︎

#AI #gds #government #nhs #nhsx #OpenSource
0
58
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
Book Review: Terrible Worlds: Destinations by Adrian Tchaikovsky https://shkspr.mobi/blog/2026/05/book-review-terrible-worlds-destinations-by-adrian-tchaikovsky/ Book cover.

What's better than one Adrian Tchaikovsky novella? Three Adrian Tchaikovsky novellæ! Or is it "novellii"? Either way, a delightful triptych of stories on a common theme. On the surface, they're about travelling to a new destination (Space! The Future! For-Copyright-Reasons Not Narnia!)

Except, deep down, they're about loneliness. No matter how far or fast we run, no matter where or when we go, we can't outrun ourselves. When you enter the void, sometimes the void enters you.

There's also the constant theme about the hunter becoming the hunted. All three of the stories reminded me a bit of Piranesi by Susanna Clarke - in that I was never quite sure if the characters were simply delusional and waging war on an enemy of their own making.

It brims with a pathos which I find rare in modern science fiction. That's offset with the perfectly placed British humour within it. Yes, there's a touch of the Weir/Scalzi "Only I, a nerdy guy, can save the universe in a self-knowing way" - but those authors aren't brave enough to mention Reading town centre or have their hero hail from Stevenage. Whereas Tchaikovsky knows what's up with the Furries.

An excellent collection of tales.

Many thanks to NetGalley for the review copy. The book is available to buy now.

#BookReview #NetGalley #SciFi
shkspr.mobi

Why is it so hard to passively stalk my friends’ locations? – Terence Eden’s Blog

0
58
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 6mo ago
How Can Governments Pay Open Source Maintainers? https://shkspr.mobi/blog/2026/03/how-can-governments-pay-open-source-maintainers/

When I worked for the UK Government I was once asked if we could find a way to pay for all the Open Source Software we were using. It is a surprisingly hard problem and I want to talk about some of the issues we faced.

The UK Government publishes a lot of Open Source code - nearly everything developed in-house by the state is available under an OSI Approved licence. The UK is generally pretty relaxed about people, companies, and states re-using its code. There's no desire and little capability to monetise what has been developed with public money so it becomes public code.

What about the Open Source that UK Government uses?

The state uses big projects like WordPress, as well as moderately popular NPM packages, and small Python libraries and everything in between. But can it pay the maintainers of that software?

A version of this blog post was originally published on Hackernoon.

Fixing The Plumbing

Open Source is facing a crisis. The code that the world relies on is often developed by underpaid engineers on the brink of burn-out. While I don't think anyone wants Open Source to have a paywall, it seems obvious that large organisation should pay their way and not rely solely on volunteer labour.

Here are some of the problems I faced when trying to get the UK Government to pay for OSS and how you as a maintainer can help make it easier for large organisations to pay you.

Firstly, lots of OSS doesn't have a well defined owner; so who gets the money?

I'm not saying that every little library you create needs to be published by a registered company, nor am I suggesting that you should remove your anonymity. But Governments and other organisations need to know who they are funding and where the money is going. The danger of accidentally funnelling money to a sanctioned state or person is just too big a risk for most organisations.

If you want to receive funding - make it really clear who you are.

What Can You Offer?

Even when there is an owner, there often isn't an easy mechanism for paying people. Donation sites like GitHub Sponsors, Ko-Fi, and Patreon are great for individuals who want to throw a small amount of money to creators but they can be problematic for larger organisations. Many OSS projects get around this by offering support contracts. It makes it much easier for an organisation to justify their spend because they're no longer donating to something which can be obtained for free; they're paying for a service.

This doesn't have to be a contract offering a 24/7 response and guaranteed SLA. It can be as simple as offering best-effort email support.

The important thing is to offer an easy way for a larger organisation to buy your services. Many organisations have corporate credit cards for lower-cost discretionary spending which doesn't require a full business-case. How easily could a manager buy a £500 support contact from your site?

Maintainers don't only have to offer support contracts. Many choose to offer training packages which are a good way to raise money and get more people using your product. Some project maintainers will speak at your conference for a suitable fee.

Again, the aim here is for maintainers to offer a plausible reason for a payment to be made.

Playing Well With Others

Open Source has a brilliant culture of allowing multiple (often anonymous) contributors. That's fine when there's no money involved, but how does a moderately sized project decide who receives what share of the funding? Services like OpenCollective can make it easier to show where the money is going but it is better to discuss in advance with all contributors what they expect as a share.

If people think they're being taken advantage of, or that a project maintainer is unjustly enriching themselves, it can cause arguments. Be very clear to contributors what the funding is for and whether they're entitled to any of it.

Finally, we faced the issue that some OSS projects didn't want to take money from the "big bad state". They were worried that if people saw "Sponsored by the Government" they would assume that there were backdoors for spies, or that the developer might give in to pressure to add unwanted features. This (usually) isn't the case but it is easy to see why having a single large organisation as the main donor could give the impression of impropriety.

The best defence against this is to have lot of paying sponsors! Having the state as one of many partners makes it clear that a project isn't beholden to any one customer.

It isn't impossible to get Governments to spend on Open Source. But state spending is heavily scrutinised and, bluntly, they aren't set up to pay ad hoc amounts to non-suppliers, who aren't charging money. While large projects often have the resources to apply for Government grants and contracts, smaller projects rarely have the time or expertise. It is critical that maintainers remove the barriers which make it too hard for organisations to pay them.

In Summary
  • Make it easy for Governments and other large organisations to pay you.
  • Be as obvious as possible that you are able to accept payments from them.
  • Don't be afraid to put a large price on your talents.
  • Offer multiple paid-for options like speaker fees, support, and feature development funding.
  • Talk with your contributors to let them know how any funding will be shared.
#government #money #OpenSource
0
5
0
1
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Book Review: How To Kill A Witch - A Guide For The Patriarchy by Claire Mitchell and Zoe Venditozzi https://shkspr.mobi/blog/2026/04/book-review-how-to-kill-a-witch-a-guide-for-the-patriarchy-by-claire-mitchell-and-zoe-venditozzi/ Book cover featuring a noose and flames.

After reading The Wicked of the Earth, I wanted to understand some of the history behind the stories. Why were women0 accused of being witches? What really happened in those trials? What are the modern consequences of those events?

This is the story of the Scottish Witch Trials - with brief forays into England and abroad. It examines the central tension of whether witchcraft was real to the accusers, or just a convenient means to oppress troublesome women. The descriptions of the imprisonment, torture, and state-sanctioned murder is visceral and horrific.

It's also rather stark in its modern assessment of the historic context:

Nonetheless, it’s important to remember it was a proper legal trial, with evidence being put forward and the judge assessing it and carrying out legal tests. Some people think that witchcraft trials were carried out by angry peasants waving pitchforks. Perhaps this is a more acceptable way for a modern person to think about it. No one wants to think that a judicial system can get it so wrong. But it did, with catastrophic consequences for those accused.

The book is mostly good, it's a spin off from the Witches Of Scotland podcast and that's reflected in the writing. As with any parasocial1 entertainment, it attempts to centre the authors and bring the audience along for the ride - so there's lots of descriptions of the libraries the authors visit, how things make them feel, how enamoured they are with their podcast guests. I found it a little distracting, but it's obviously right for their main audience.

Similarly, there's an attempt to bring the past to life by imagining a little monologue from various historic figures. I found that a little unconvincing; I dislike putting words in peoples' mouths. But with sparse primary documentation, that may be the best way to bring these characters to life. It's also well illustrated. Too many books eschew pictures - but this has a nice collection of woodcuts and portraits to contextualise what we're reading about.

One little nitpick, the book makes the claims:

Life was hard and life expectancy was around 35

and

Lilias was an old woman, at least 60 years old and possibly as old as 80. At a time when life expectancy was much lower than it is now, even the lower estimate was still a considerable age.

That's not quite right. Although the average life expectancy was low, that's the average at birth - with a large number of infant mortalities dragging down the average. When you look at the full data, you'll see people used to live long lives even in the distant past.

In a way, it reminds me of Invisible Women. A national tragedy hidden from view.

It builds to a rousing end. There are parts of the world where witchcraft is still taken seriously - with devastating consequences. The febrile atmosphere which led to unfounded accusations against women is still prevalent even in modern societies.


  1. And a small number of men. But this is firmly focused on the overwhelming majority. ↩︎

  2. As opposed to paranormal. ↩︎

#BookReview #feminism
0
47
0
1
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 5mo ago
Book Review: The Names by Florence Knapp https://shkspr.mobi/blog/2026/05/book-review-the-names-by-florence-knapp/ Book cover featuring a man with three shadows.

This has an excellent narrative structure, some beautiful prose, and I just didn't enjoy it.

The story is Sliding Doors meets Same Time Next Year mixed with a distressing amount of domestic violence.

A mother faces a difficult choice. Should she name her child after her abusive and violent husband? In one strand she does, in another she doesn't, and in the third she makes a compromise. We rejoin the story every few years to see how our protagonists are progressing.

It mostly works and pushes us to consider how much the path of our life is influenced by factors outside of our control.

I have a real difficulty with books about violence. All of the characters are unsympathetic - trapped by tyrant but also trapped by their own inaction. I also struggled with how pedestrian and limited it was. In a world where you can read anything, why would you choose to spy on your horrible neighbours? Like a tawdry soap-opera it offered nothing more than misery and heartbreak. Fine if you need that sort of substitute empathy, but it left me feeling grubby and unsatisfied.

To be fair, the characters in the book address this:

‘Why read them if they make you feel bad?’

‘Because I’m hoping one of them might feel like me,’

It isn't a bad book - although it does veer into cliché a little too often - and the structure is interesting enough. But I found its subject matter too distressing to be enjoyable,

Book Club Discussion

This isn't the sort of book I'd normally pick up - but it was chosen by the book club I attend. The majority of readers rated it higher than I did. Here are some of the things we discussed.

The central message sees to be that, no matter how hard you try, the tragedy which infects your life can never be escaped. I found that depressing and disempowering. The domestic dreariness was stifling and just left me irritated with the passivity of the characters.

The evil father is an arsehole - but a one-dimensional arsehole. I get that there's a risk to humanising an antagonist, but other than a brief mention of his back-story there's nothing about him. I didn't want a justification for his actions, but he felt like a cartoon villain.

Even when one character gains a moment of happiness, it is offset by another's misery. No matter which path is chosen, someone always ends up broken.

Are we "destined" to meet the same people, no matter what path we take?

#BookClub #BookReview
shkspr.mobi

London Data Store Relaunch – Terence Eden’s Blog

0
60
1
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
Find blog posts with missing featured images - and missing alt text - without a plugin https://shkspr.mobi/blog/2026/05/find-blog-posts-with-missing-featured-images-and-missing-alt-text-without-a-plugin/

WordPress has the concept of "Featured Images". They are the images which show up when you share a blog post on social media or, on some themes, as the "hero" image.

How can you quickly and easily find any posts which don't have a featured image?

For this, I use WP CLI - it allows you to run complex WordPress actions and queries using the command line. After you have installed WP CLI you can get started.

Missing Images

On the command line, run:

wp eval 'foreach(get_posts(array("post_type"=>"post","post_status"=>array("publish"),"posts_per_page"=>-1,)) as $post){if(get_the_post_thumbnail($post)==""){$post_type_object=get_post_type_object($post->post_type);$link=admin_url(sprintf($post_type_object->_edit_link . "&action=edit", $post->ID));echo $post->post_date . " " . $link . " " . $post->post_title . "\n";}}'

Here's the code in a slightly more readable format:

foreach ( 
   get_posts( 
       array( "post_type"      => "post", 
              "post_status"    => array("publish"), 
              "posts_per_page" => -1,
       ) 
   ) as $post) { 
      if( get_the_post_thumbnail( $post)== "" ) { 
         $post_type_object = get_post_type_object( $post->post_type ); 
         $link = admin_url( sprintf( $post_type_object->_edit_link . "&action=edit", $post->ID ) ) ;
         echo $post->post_date . " " . $link . " " . $post->post_title . "\n";
      } 
}

That will print out:

2024-05-02 12:34:11 https://example.com/wp-admin/post.php?post=123&action=edit "A post about sausages" 
2023-09-13 20:55:52 https://example.com/wp-admin/post.php?post=456&action=edit "I like cheese"
2021-12-31 15:43:33 https://example.com/wp-admin/post.php?post=789&action=edit "Touching computers"

You can then go and edit each of those posts to add a featured image.

Missing Alt Text

Adding alt text means that people who can't see images will still be able to understand what the picture represents. Here's another one-lines to find all featured images with missing alt text:

wp eval 'foreach (get_posts(array("post_type"=>"post","post_status"=>array("publish"),"posts_per_page" => -1,)) as $post){if(simplexml_load_string(get_the_post_thumbnail($post))["alt"]==""){$post_type_object=get_post_type_object($post->post_type);$link=admin_url(sprintf($post_type_object->_edit_link . "&action=edit",$post->ID));echo $post->post_date . " " . $link . " " . $post->post_title . "\n";}}'

And, in slightly more readable form:

foreach (
   get_posts( 
      array( "post_type"      => "post", 
             "post_status"    => array("publish"), 
             "posts_per_page" => -1,
           ) 
   ) as $post) { 
      if( simplexml_load_string( get_the_post_thumbnail( $post ) )["alt"] == "") { 
         $post_type_object = get_post_type_object( $post->post_type ); 
         $link = admin_url( sprintf( $post_type_object->_edit_link . "&action=edit", $post->ID ) ) ;
         echo $post->post_date . " " . $link . " " . $post->post_title . "\n"; 
      } 
}

Again, that lists the datetime of the post, its edit link, and its title.

No, if you'll excuse me, I have about 873 posts which need updating 🤯

#accessibility #TILvember #WordPress
0
0
0
0
Open post
Terence Eden’s Blog @blog@shkspr.mobi
· 4mo ago
Whale Fall https://shkspr.mobi/blog/2026/05/whale-fall/

Somewhere, in the endless blue ocean, a gigantic mammal shudders as it takes its last breath. Thanks to science, we know that all dogs go to heaven, but all whales descend through the murky depths until their carcasses litter the seabed.

Imagine a giant dying. You can't. They are huge and endless. A towering presence which, so it seems, has always been part of our world. They dominate and are indomitable. It is simply unfathomable that they can ever end. Yet end they must.

As the whale dies, we do not know what passes through its cavernous brain. But we do know what the rest of the ocean thinks.

Lunch.

The death of a whale is a thing to be celebrated. The thump of their still-warm body onto the floor is the starting bell for a feast. Some larger predators sense an easy meal and tear off the choicest morsels. But what of the scavengers? What about the new life not yet established? What happens to the weird little creatures just waiting for an energy boost?

In many ways, it was fortuitous that Twitter pre-signalled its death with the Fail Whale.

The twitching corpse is gently floating down to its watery grave. Some of the older and more established social networks have bitten out chunks of the still-fresh body and have run away with their spoils. But the fascinating thing is watching all the new services benefit from the death of a giant. Mastodon, Discord, BlueSky, Qaplion, Nostr, and a bunch of others hollowing out the rotting husk and using it to power their own growth.

Will those .meow social networks ever become a gigaton behemoth capable of ruling the waves? Maybe not, but size is not the only metric of success. Finding and defending an ecological niche is its own reward. Evolution abhors a monoculture.

Several bloated bodies meander through the brine, each one confident that its ageless wisdom will outlast the others. Had they any self-awareness, the hubris would gnaw at their tattered souls until the crushing realisation of their impending doom drove them mad.

Perhaps it will happen to GitHub next. The endless downtime and forced injection of crappy AI will start a death spiral. Already established forges are waiting to pounce once they smell blood in the water. But what critters will emerge to suck the bones of the old giant and develop in unexpected ways? Some bizarre fungal growth will devour the stinking jelly unlocked from those shattered bones and a new ecosystem will emerge.

Will WordPress's increasingly erratic leadership and tangle of legal disputes cause it fatal damage? Once minnows darted away from its presence; now they cautiously nip at its greying skin. Its mighty bellow still echoes through the clammy waters, but there's a tinge of frailty in its song.

Everything dies eventually.

The internal flora and fauna - be they parasitic or symbiotic - eagerly await their host's downfall. A chance to break free and explore new strange new world. A chance to begin a new relationship and co-evolve in unexpected ways.

The biological pump is primed, the hungry jaws of an uncountable fleet of new ideas is just waiting to pounce, the giants swim on in blissful ignorance.

You can read more about Whale Fall on Wikipedia.

#technology
0
0
0
0
Back
313k7r1n3
Elektrine

Tor hidden service

elekhj7afj4qnrr4yd3bkzslsyo5jgfxw3orgjkhlcxifueodybyiiad.onion

I2P eepsite

j6b6cyk6gjmepjih7jjadxgxvvf3lzzujljuu2v4biemzpg3naya.b32.i2p

Platform

  • Email
  • Chat
  • Timeline
  • VPN
  • DNS

Company

  • About
  • Contact
  • FAQ
  • Lite (no JS)

Legal

  • Terms of Service
  • Privacy Policy
  • Transparency Report
  • Report Abuse
  • Warrant Canary
  • VPN Policy

Support

  • support@elektrine.com
  • Report Security Issue
Mail client setup IMAP mail.elektrine.com:993 POP3 mail.elektrine.com:995 SMTP mail.elektrine.com:465
© 2026 Elektrine. All rights reserved. Server: 21:34:15 UTC