Vanity Nameservers (White-Label DNS) in 2026

When you buy a domain name, your registrar will typically offer to provide you with a collection of DNS nameservers. For most people, most of the time, that’s plenty sufficient.

A trip back to 2006

Terminal in which 'dig danq.dev @`dig NS dev +short | head -n1`' has been run, outputting NS responses representing three Gandi nameservers.
My secondary domain danq.dev has three nameservers, operated by its registrar Gandi.

This wasn’t always the case. In the long-distant past, I’ve registered domains for which I’ve had to run my own nameservers. Or else, where I’ve chosen to run my own nameservers in order to gain more control, or power, or just to play about with the technology inevitably break things.

When I transitioned to using third-party DNS around 2006, I used to be a big fan of vanity nameservers. “Vanity nameservers” (or “white-label DNS”) is where your nameservers are hosted at subdomains of the domain for which they’re the nameserver.

So instead of the nameservers for danq.me being, say, looking like ns-48-a.gandi.net and ns-228-b.gandi.net, they might look like, say, ns1.danq.me and ns2.danq.me. They might still be provided by the same third-party (or might not!), but you don’t get to see that. DNS protocol doesn’t care about the hostname it’s connecting to, it just needs the right A/AAAA records and it’s good to go!

Well, once you solve the bootstrapping problem, anyway!

If the nameservers for a domain are at a subdomain of that domain, you’ve got a circular dependency. To solve that, you have the servers one level higher provide “glue records” in addition to the list of nameservers. The glue records, which are shown in the “additional section:” of dig‘s output, above, solve the circular dependency. Now, the nameservers can be found without first having to… find the nameservers!

Terminal in which 'dig danq.me @`dig NS me +short | head -n1`' has been run, outputting NS responses ns1.danq.me through ns4.danq.me, with additional section records for A and AAAA records for each.
Tada! For the first time in about 20 years I’ve configured “vanity DNS”: danq.me‘s nameservers are now called ns1.danq.me, ns2.danq.me, ns3.danq.me and ns4.danq.me.

Vanity nameservers in 2026

The essential steps for setting up vanity nameservers are fundamentally the same as they always were. Propagation times are much shorter now and I was able to have the whole thing done and dusted within a couple of hours. In case you’re looking to follow-along, here’s the broad steps (the specifics depends on your registrar, DNS provider, etc.):

  1. Set up A (and AAAA, it’s 2026 you know!) records pointing ns1.example.com (or whatever your domain is) to their IP addresses.1
  2. Change the NS records for your domain to point to your new vanity nameservers.
  3. Change the SOA record for your domain to point to the first vanity nameserver2. Bump your serial.
  4. Have your registrar create glue records mirroring those you created in step 1.
  5. Have your registrar change the authoritative nameservers for your domain to those you created in step 1.
  6. (Optional) 😰 Frantically and repeatedly poke the registry’s DNS servers with dig until you’re confident that you didn’t just make a hideous typo and broke your domain in a way that would have been a pain in the arse to unpick when you last did this, in 2006. Calm down when you remember that it’s 2026 and nowadays it’s gonna be easy to fix via some API or web portal of your registrar!

That’s all there is to it.

But… why would anybody do this?

For most folks, this is pointless. Larger companies, especially in tech fields, sometimes do it as a branding exercise, especially if they’re re-selling services atop somebody else’s infrastructure and don’t want to so-clearly lampshade that3. But I took a look and… I don’t think people bother any more.

Hit up a handful of corporate domains you know and, with the exception of the few that run their own DNS, you’ll see the same big providers keep cropping up: Cloudflare, Amazon, Google, Microsoft…  I experimentally probed a hundred or so domains that I thought might use “vanity DNS” in front of a third-party DNS service… and found… none4.

Nobody cares any more. You’re either running your own, or you tell the world who’s running it for you, with no in-between.

Bringing back an old tradition

Vanity DNS is a dying art.

Soo…  I’m now doing vanity DNS on danq.me; it’s the first time I’ve run vanity DNS on a personal domain since… I want to say 2010‽ The journey started when Jacob asked me about my DNS setup, and it made me nostalgic for a time when nerdy techies whose nameservers were provided by a third party would just “do” vanity DNS as a matter of course.

Vanity DNS felt nerdy and fun back in 2006. And I guess that nowadays… it still feels nerdy and fun. It’s still as pointless as it ever was, but I don’t care. I’m doing something that I thought was cool when I first learned about it in 2001, just for the fun of it.

Type dig NS danq.me in your terminal to see the result: four nameservers, all with a .danq.me suffix5. Cute!

Footnotes

1 There’s a convention of naming nameservers ns1, ns2, ns3 etc., but if you want “fun” names then that’s fine too. Cloudflare’s nameservers have cute names, if you haven’t seen already!

2 Check your dotted-notation hostmaster email while you’re there; everybody forgets to look at these and so they’re often outdated.

3 Using vanity nameservers to conceal an underlying DNS provider does not conceal the third-party’s identity because you can always use the IP address of those nameservers to work out who’s behind them. For example, if you’re interested in seeing who’s really providing the DNS for danq.me, you might run NS_NAME=`dig NS danq.me +short | head -n1` to get the name of a random one of my nameservers, then NS_IP=`dig ${NS_NAME} +short | head -n1` to get its IP address, and finally do an reverse DNS lookup on that with e.g. dig -x $NS_IP. Often, this canonical name will be a giveaway and you won’t even have to look at the lists of who owns which blocks of IP addresses. It’s not a secret. (Gotta admit, though I’m not entirely happy with my provider… maybe it’s time to switch… or even go back to selfhosting DNS once more!)

4 whatsapp.com appears to have its own nameservers a.ns.whatsapp.com through d.ns.whatsapp.com, but their A records point to IP addresses whose reverse DNS names are a.ns.facebook.com through d.ns.facebook.com. Not terribly exciting, nor surprising, that Meta are running their own DNS services for their various properties (the same thing happens with instagram.com). paypal.com seems to have both its own DNS servers and some replicas provided by Digicert UltraDNS, which for a moment excited me when I thought that they might be part-way through a white-labelling exercise, but no: they’re two different services. I thought I’d find something interesting via one of the big blog, eccomerce, or VPS providers that offer free subdomains: folks like Bearblog, Dreamwidth, Substack or Medium. But nope; some seem to run their own DNS, and others just sit on top of a big third-party. Sigh.

5 Want to see the glue records? Run dig NS me +short to get the names of the authoritative nameservers for the .me TLD, e.g. a0.nic.me, and then query it directly with e.g. dig NS danq.me @a0.nic.me: you’ll see not just that I have four nameservers under .danq.me but also their IP addresses (in the “additional section”) – that’s the glue doing its thing!

× ×

A Postcard from Tony (who the heck is Tony‽)

For almost a year now, I’ve been actively soliciting Internet strangers to send me a postcard (in addition to the usual ways of contacting me, via comments or email). I had no idea it would be so-successful: I’ve received a postcard almost every month! I’ve been keeping them in a mildly-interactive gallery if you’d like to see.

Today was novel, though. Today, for the first time, I received a postcard from somebody… whom I can’t identify.

Composite photograph showing the front and rear of a postcard written on the plain brown cardboard bulk packaging of a Canadian boil-in-the-bag food product.
The postcard is from “Tony”. I’ve transcribed the full text on the postcards page.

The postcard is from “Tony”. So I can identify them that far. But… who the heck is Tony‽

In the case of every previous postcard I’ve received, it’s been somebody I’ve been able to “trace”: either because they’ve previously left a comment on my blog, or emailed me, or we’ve moved in the same circles of a (relatively small community) website, or they’ve included a URL or some other way to “find” them.

This one though, is a mystery.

Let me tell you my favourite thing about this postcard, though: it taught me something cool. The postcard is made out of the (billingual) outer packaging of some kind of MRE/boil-in-the-bag ration pack, and Tony tells me that when they were in the Canadian armed forces, their unit would send postcards like this “back home”: written directly onto the packaging.

How neat! If I had a family member in the services, it’d be neat to get a postcard from wherever they were deployed that not only told me how they were doing… but as a side-effect what they’d been having for dinner. It’s cute.

If you’re out there Tony, feel free to say hi in the comments or email, too. And thanks for the card!

×

Boring Polyamory: Equality and Bedrooms

Among the correspondence I engaged in following my blog post about my (boring) polyamory were a few examples of people being concerned about the equality of our arrangement: how we keep things “fair”1. By way of example, let’s take a look at a specific example that’s come up. Here’s something that I was asked recently:

Why does [my partner] Ruth not have her own bedroom? Both of her partners [JTA and I] get one!

Where does my partner sleep?

Simplified calendar showing May 2026 with different-coloured dots on the days: 14 of one, 17 of the other.
It’s been joked that polyamory is just a fetish for calendar management. Our family calendars are moderately simple, I imagine, compared to those of people in larger polycules or with less routine.

Except when she’s travelling or otherwise elsewhere2, Ruth spends her nights in an approximately even split3 between JTA‘s bedroom and mine.

This leads some people to observe that:

  • JTA has a bedroom of his own,
  • I have a bedroom of my own, and
  • Ruth “shares” both of those,
  • and this is unfair because her partners both get something that she is denied.

Superficially, this sounds true. But it conflates “fairness” with “parity”.

Fairness versus parity

Parity is making sure that everybody gets the same thing. It’s a simple, but crude, measure of equality. That’s probably why it’s so-popular with children.

“My sister got a doughnut so I should get one too.”

“You had an iced finger instead. You said you prefer iced fingers to doughnuts. And your sister doesn’t like iced fingers. Both of you got what you wanted.”

“Yeah, but now I want a doughnut because she had one!”

– the kind of conversation that’s probably familiar to you if you have children

When you aim for parity, you’re trying to make sure that every person gets the same thing. But this isn’t ideal, because not every person wants or needs the same thing!

A child with a ring doughnut decorated to look like a monster imitates the face of that monster, towards another child who is pointedly not paying attention.
“I don’t even want this. I just don’t want to feel like you’re getting something I’m not!”

Fairness, is aiming to for everybody to be content.

Ideally, everybody would get everything they wanted, all the time! But where that’s impossible, we can aim to at-least ensure that everybody is content. That everything is “good enough” for everybody. Unlike a quest for parity, this respects the fact that people have different needs.

Me personally? I absolutely prefer to have a bedroom of “my own”! In fact, to go even further than that: if I were in Ruth’s position I probably would want a room of my own, if it were feasible. Also, in some kind of hypothetical universe in which neither of us had other partners… I’d still ideally want to sleep alone some of the time (maybe once every couple of weeks?), because I’m of an inclination to occasionally luxuriate in being able to totally starfish-out.

If it were me instead of Ruth at the fulcrum of our V-shaped polycule… I suspect I’d have different needs to Ruth. And that’s fine!4

I’m a big fan of people being able to have their own space if they want it.

When the three of us first started cohabiting I suggested that Ruth should have her own bedroom. In our first shared house, we ensured that she did! But in practice, it never got used. Over time we’ve dropped it in favour of having a spare bedroom: a versatile space that can be place for gaming, or television, or guests5.

It was valuable to start from a position of assuming that we would all get “our own” room: parity is a good starting point! But fairness – meeting everybody’s needs in the most-equitable manner – is a better finishing point.6

Communicating a way to fairness

The world sometimes sucks. Many of the social interactions humans engage in, on a day-to-day basis, are not rooted in fairness. Some human social interactions go to the opposite extreme: they even exploitative.

Have you ever been in a salary negotiation? You might have heard the idiom that the first person to say a number loses. Salary negotiations are an adversarial game. Both sides want to come out with the most money, and so neither side is incentivised to show their hand.

Everything I learned about salary negotiations… I learned from playing Theme Park. Just make sure you’ve got a deal before you run out of biscuits.

Relationships between people who care about each another don’t have to work by adversarial rules (and, in fact, probably shouldn’t!7). If you love and trust and want the best for one another, then – hopefully – you can be honest about what you want, and can be okay with being hearing whether or not it’s something that your partner(s) can provide. Or else work together to find compromise position that best facilitates everybody’s needs!

So: if Ruth decides that she wants to have a bedroom of her own again, we can try to make that happen. If I start an additional serious/committed relationship and decide that I’m not getting enough “alone time”, we can work out how to achieve that. If JTA’s work starts requiring a long and tiring commute and he needs fewer childcare responsibilities, we’d solve for that. We tackle these problems as a family who love and care for one another, with the goal of getting an outcome that’s fair to everybody!

Those outcomes don’t have to mean that we each get “the same”. Just that we each, as far as possible, get what we most want.

Footnotes

1 Sometimes somebody – almost always a man – will claim that our arrangement is unfair to both JTA and I who have to “share” one woman, as if her role were to be “owned” by one of us. Sometimes somebody – almost always a woman – will claim that our arrangement is unfair to Ruth because she has to split her time and attention between two men. I find it hilarious that these two arguments, diametrically opposed, are most-often made on gender lines.

2 The other month, for example, Ruth stayed over at her aunt and uncle’s house after celebrating her uncle’s birthday. JTA and I hung out and watched some RobWords until I, tired after an afternoon of beginners’ tango, took an early night!

3 In actuality, Ruth spends slightly more nights sleeping in JTA’s room than in mine. This, too, is one of those things where people will sometimes instinctively assume represents some kind of injustice to me and that I’m somehow being hard done by or deprived of some kind of relationship “rights”. This is, clearly, nonsense.

4 Also: I couldn’t think of a better way to graphically represent us swapping around into some differently-pivoted V-shaped relationship than by using the deck of playing cards that was on my desk anyway. I was feeling unimaginative, apparently. Can you tell?

5 Or – indeed – a spare room can be a space for for one of us to use, if we’re ill or leaving early in the morning or something and don’t want to disturb a bedpartner.

6 If you’re looking for another example of the difference between parity and fairness, consider taxation! A flat tax like a poll tax exhibits strong parity, because everybody pays the same, but it doesn’t exhibit much fairness because the value of that tax burden is less for somebody who is wealthy than for somebody who is poor. We call taxes that favour parity over fairness regressive taxes. I guess that we could call sharing of family resources in a way that favours parity over fairness regressive sharing?

7 If you’re in a relationship that’s routinely adversarial, then… and I don’t mean to be judgemental… that doesn’t sound like a very healthy relationship to me. Perhaps step back and re-assess whether it serves you both?

× ×

Three(ish) Weeks In Spain

Ruth, JTA, the kids and I are all back in the UK1 after a three week period during which some or all of us were consistently in Spain. The whole adventure was the kind of masterpiece of epic planning that only Ruth could have pulled off, and it worked spectacularly2.

A fawn-coloured French Bulldog lies comfortably on a blanket on a sofa, with her tongue sticking out in a large sideways blep.
I wasn’t around for the first week of the trip, but continued working from home (with the dog, pictured) as per the usual.

San Sebastián

Through clever permutations of remote-working from overseas (mostly by Ruth) and overlapping/intersecting stretches of annual leave (mostly by JTA and I), we were able to avoid having to send the dog to the dogsitter for a block of more than a single week3, didn’t need to break the bank on our collective leave budgets, and managed to give the kids the longest possible block of continuous immersion in the language and culture of Spain.

A group of children in wetsuits surf on low waves.
The one time I tried surfing, I wasn’t good at it, but I was reassured that was normal for a first day. The kids disproved that theory, becoming pretty reasonable boarders very quickly.

In the first week (when I wasn’t there), the kids got to take a mixture of surfing classes and Spanish language lessons in San Sebastián, among other activities. The Bordeaux wildfires caused some travel chaos for the others getting there, but they made it work in the end.

Tarragona

Later, I flew out to meet up with them and we switched to the opposite coast of Spain, staying in a delightful little villa North of Tarragona. The summer heatwaves that are affecting the continent made the middle of the day especially oppressive, so we did as the locals do and sensibly sheltered indoors during the hottest part of the day… but the kids in particular were glad to be able to take a dip in the pool to cool off.

Under nearly-cloudless skies and surrounded by trees and olive and grape-laden slopes, a stone villa and its outbuildings sit prominently under the bright sun.
The villa was a lovely building in a fabulous spot, nestled among hillside olive groves and vineyards, but the lack of wired Internet access/WiFi plus the signal-blocking stone walls made it more “disconnected” than we’d anticipated4!

As has become my tradition when travelling and on family holidays – because I’m an earlier riser than most, but also because I wanted to make the most of the coolest part of the day – I got out early most days for a whole bunch of geocaching expeditions5. But once others were awake we found plenty of other opportunities to explore the area.

Wide/panoramic view from a pagoda-like tower, where a woman and two children lean over a railing to look at a network of bridge-linked islands in a lake below, dotted with palm and other trees.
Parc Samà‘s breezy towers and water features took some of the heat out of the day, when we visited its attractive botanic gardens.

Having come from, remarkably, a similar level of temperature and humidity in the UK, I was interested to see how much greener everything was here on the Mediterranean coast. The plants here, better-adapted to hot and dry summers than those that we plant on our little island, were clearly more-suited to these kinds of conditions. Is it perhaps time that Britain started ditching her lawns and other year-round thirsty vegetation… instead planting more tropical-adjacent plants to provide shade (and carbon capture!) as the climate continues to shift?

A freshwater turtle pokes its head out of blue-green water near a rocky shore, with small black fish visible swimming in the depths.
This little fella had the right idea about keeping cool.

I enjoyed that we were able to split out time between a diversity of activities. A week-long jaunt can be dominated by a single activity – a skiing holiday, for example – but by the time you’re spending most of a month exploring a country, you want to be able to mix things up a bit, right?

A Roman aquaduct spans a forested valley.
Per local legend (and in common with many similar spans around the world6, which usually share a myth about the devil aiding in its otherwise-impossible construction in exchange for the first soul to cross it and then being tricked when an animal is sent across first), the Ferreres Aquaduct  is also known as Devil’s Bridge, which lead me to observe that of all the architecture I’ve seen with which Hell’s ruler is credited, this might be the best (nice work, Satan!).

Sometimes we kept it slow-paced and relaxing, like reading by the pool while the children invent splashing-based games or playing board games in the shade. Other times we explored history and culture, like our visit to the Ferreres Aqueduct, the Catedral de Tarragona, or the old Roman amphitheatre.

Two children wearing VR headsets and holding parasols, in the ruins of a restored Roman amphitheatre.
An augmented reality tour of the amphitheatre was both engaging and educational for the kids, bringing to life its long and complex history: did you know it started as an amphitheatre, but later was the ground of a church (commemorating Saint Fructuosus, who was executed there), then became a prison, and now… it’s an amphitheatre again: in addition to being a historical monument it’s used to stage concerts and things!

And other times still we even did the typical “British tourist in Spain” things, like a trip to the beach or an expedition out on a catamaran to swim in the sea while the sun set.

Dan, a white man, drips from a swim in the sea as he stands, holding a plastic cup of white wine, on the deck of a catamaran.
I expected the catamaran trip to be a bit tacky, but it was actually lush. (I may have availed myself of the open bar, a bit!)

Obviously the biggest reason for our trip was to catch sight of the total solar eclipse as it passed over the region, and our villa’s garden/vineyard was without a doubt a superlative spot for this. We’d initially been concerned that visibility of the low-in-the-sky/close to sunset eclipse might be obstructed by the hills and that, therefore, we’d need to find another spot from which to spectate, but an early-in-the-week experiment of watching the sunset (with an eye on the clock) reassured us that this wasn’t the case. So – as long as we were lucky with the cloud cover – we should be set.

Dan sits on a sun lounger on a driveway, alongside a covered brick barbeque building. He's alongside two children doing the same, and all are wearing disposable eclipse glasses.
A particular highlight of the entire trip was hanging out as a family in our private vineyard, watching the solar eclipse.

I’ve been fortunate enough to have had great visibility of a total solar eclipse once before, in 1999, but honestly: this one beat it. The perfect location, the reds of the setting sun, the “moon illusion” exaggerating the perceived size of the moon as it approached the sun, the joy of vicariously sharing in the childrens’ wonder… all of these made the whole experience pretty mind-blowing.

The sun completely occluded by the moon.
You’ve seen pictures of eclipses before, but this one is mine. I maintain that even the good/professional photographs are poor substitutes for the real experience, though!

We watched, we awed, and then we saw the still half-obscured sun gradually disappear over the horizon. And then, a round of hugs and cheers and conversation later, we sat up late to enjoy the Perseids begin their nocturnal display.

Over the silhouette of hills, a total solar eclipse is just coming to an end, with a 'diamond ring' effect resulting from the sun's reappearance visible.
Mostly I was looking at the sky (through the safety of my eclipse glasses, of course). But I managed to snap a handful of photographs that, despite the limitations of my phone’s camera, came out pretty well.

PortAventura

After our week in the villa we delivered JTA to the airport to return home. Then Ruth, the kids and I drove on to PortAventura, perhaps our favourite theme park anywhere in the world. Since our last visit, the younger kid has reached a milestone of height that permits him to ride all of the largest rides, and he was excited to take advantage of this newfound privilege.

A man (Dan), a woman (Ruth), and two children sit in a circular boat on a 'river rapids' style ride.
A particularly useful thing about PortAventura compared to some other theme parks is that it’s designed with heatwaves in mind: it’s got lots of natural shade, cooling-off areas, and the right ratio of water rides for when you positively, absolutely need a good soaking.

Both the elder child and I were particularly excited to share with him my favourite non-looping rollercoaster, Shambhala. Shambhala is simply excellent: it’s a highly-vertical smooth ride with a free and open-feeling restraint that, collectively, give amazing “air” and a sensation of “flying” that’s hard to compare to almost any other coaster ride I’ve been on. I could sing its praises aplenty.

A man with a screwdriver repairs the restraint system on a rollercoaster car.
The second we reached the front of the line for our first ride on Dragon Khan it broke down. But we got to watch it being repaired right in front of us, so that’s cute!

Going to Disneyland Paris and PortAventura in the same summer gives me the confidence to say: PortAventura is the better theme park. The rides, the theming, the food, the queue management, the accommodation, the value-for-money… it’s all better. So if  you’re considering a European theme park trip and you don’t care about getting your photo taken with Goofy or whatever… PortAventura would be my suggestion.

PortAventura’s water park is good too, although it was pretty busy on the day we went. Their 30-metre tall near-vertical waterslide King Khajuna is a little intimidating7, but nothing our thrillseeking little man wasn’t up for.

Barcelona

Finally, we made our way to Barcelona for a “wind-down” couple of days at a hotel we’ve always enjoyed there. Aside for being mistaken for staff while I was using my laptop by the rooftop pool, there’s little of note to say about it: we took it easy, did as little as we could get away with, and generally “unplugged” before our journey back to the UK and a return to normal life (boo!).

Altogether a fabulous trip… and a really interesting experiment in a model that we could replicate if we ever opted for a three week (but drop-in/drop-out/telework) holiday in future. Though… I’d again want (our scheduling queen) Ruth to wrangle the logistics, because it gets complicated when there are so many moving parts!

Footnotes

1 Although not in our house, of course, which is still being repaired following the flood in February; it’s now F-Day plus 191 days… more on that in a future blog post, I’ve no doubt.

2 For a while, she was talking about trying to engineer it into a five-week expedition spanning both this and our trip to France earlier in the summer (to which JTA, the kids and I drove/LeShuttle’d, and to which Ruth flew following a work-related event in Austria: my, what a cosmopolitan life we’re leading this year!). But that’d have been an enormously more-complicated affair and I’m glad we settled on this “simpler” trip in the end!

3 Not that she cares: the dog loves hanging out with her little doggy friends, and is always excited to be taken to our dogsitter‘s, where she also “commutes” for a workday or two most weeks.

4 During out post-holiday ‘retro’ (because of course that’s what we do), the lack of connectivity appeared as both a negative and a positive on some of our lists! Obviously we’re all aware that a little digital disconnection is healthy and valuable, but sometimes it takes being in the middle of nowhere to impose the requisite self-discipline to keep off your devices!

5 Geocaching logs: 1, 2, 3, 4, 5, 6, 7, 8, 9 (my 1000th successful find)not that Geocaching.com can count that correctly!10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37.

6 Obviously, the Devil’s Bridge nearest where I used to live and at which Ruth and I spent our first anniversary – back when we had no idea that we’d be able to make our relationship last… what…? 19 years this month!) – will always have a special place in my heart.

7 Reaching the top of King Khajuna’s tower, you can feel it swap in the breeze, and when you get to the slide itself its ‘horizon’ disappears precipitously until you shuffle completely up to it, at which point there’s little choice about your destination! While we queued for our first goes, we witnessed several people reach the top, change their minds, and turn back!

× × × × × × × × × × × × ×

Geocaching.com Can’t Count? (my 1000+ geocache finds!)

This week I’m in Spain to see a spectacular eclipse, among other things. I’ve also done a reasonable amount of geocaching, including on Tuesday finding my 1000th geocache.

Dan - a white man wearing a rainbow-striped bandana - stands with his arms raised in celebration, alongside the superimposed words '1000th find'.

Which led me today to ask: how many caches does Geocaching.com think I’ve found? It’s the biggest, but not the only, site I use, and so I didn’t expect it to show the same total as me. A difference is expected.

Well… it turns out how you ask it. In the top-right corner of the page, when I log in, it says that I have… 1,035 finds:

User information area from the top of a website, showing Dan Q with no incoming messages and, crucially," 1,035 finds".

That turns out to be significantly higher than I’d anticipated, which initially made me wonder: did I fail to count some in my tally?

My tally comes from those which have been imported right here onto my blog. I use a computer-assisted but still-manual approach1 to PESOS my geocaching logs from various sites – Geocaching.com, OpenCache.uk2, TerraCaching, etc.3 – onto my blog, and then I count them here. Could my data be wrong?

So I went about checking it. Which turned out to be challenging, because the “foreign key” I use to associate the caching logs on my website is the log ID that appears in the links on Geocaching.com… and those changed format somewhere along the way.4 So first I had to fix all of my metadata spanning about 750 rows. Then I was able to check.

But while I did that, I noticed something strange. When I click on that link that says I have “1,035 finds”, the resulting page has a link to see what they are. And it claims there are… 1,005 finds:

List of geocaching logs, filtered to "Found it", showing 1,005 rows.

Stranger still, a different link from the same page on Geocaching.com told me that I had 1,006 finds!

Screenshot showing that Dan Q has 1,035 finds, of which all 1,006 are shown in a table. Wait, what?
This screenshot’s my favourite, because it shows two different totals at the same time!

Even before I’d corrected all of my metadata and rechecked my totals, I was becoming increasingly convinced that I couldn’t trust any of Geocaching.com’s totals. How many finds is it, exactly: is it 1,035? Or 1,006? Or 1,005?

It doesn’t really matter, of course. I keep my own count, and I’m now even-more confident than ever that it’s accurate. The correct answer to to the question “how many geocaches have I found?” is 1,019.

And for some reason, Geocaching.com can’t count even the ones that are logged on their site three times and get the same number twice. 🤣

Footnotes

1 This helps me sidestep Geocaching.com’s draconian rules on scraping and API access.

2 I got in trouble once with a Geocaching.com reviewer for hinting at the existence of other geocaching listing sites, once. I don’t understand why: they’re unlikely to be a commercial threat to Geocaching.com’s business, and those other sites typically allow you to talk about Geocaching.com! I guess that they’re mostly afraid that it weakens their trademark on the word “geocaching”, which I’ve never been convinced is legitimate anyway because it was being widely used online to describe the activity it represents before they tried to start centralising and hoovering-up all of the cache listings. It’s just sneaky monopolistic silo behaviour on the part of Geocaching.com, really. I’m not a fan. I can list plenty of examples of this kind of dipshittery on the part of Geocaching.com, but I’ll spare you for now.

3 I do a similar thing with my geohashing logs, although without the same anti-anti-scraping mitigations because geohashing.site’s site owner is a much more-chill dude.

4 Many of my old logs used a GUID, but newer ones use a GL-ID. It’s a whole thing.

× × × ×

Casa Ventola

This week, I’m living in a villa on a vineyard about 9km North of Tarragona, on the East coast of Spain.

Under nearly-cloudless skies and surrounded by trees and olive and grape-laden slopes, a stone villa and its outbuildings sit prominently under the bright sun.
Gotta say, it’s a pretty place to walk the grounds of.

A large part of our choice of location for this trip was, of course, the total solar eclipse that’s expected this evening, whose path of totality just barely passes over this spot before disappearing somewhere over the Mediterranean.

A red and orange sunset with beams reaching up over the hilly horizon of climatically- Mediterranean farmlands.
We tested by watching a couple of sunsets that, at the time of day the eclipse will occur, the sun will still be visible over the horizon.1

26 years ago, almost to the day, I blogged about witnessing the 1999 solar eclipse from Paris, where we were fortunate enough that Europe’s cloudy conditions on that day broke just in time for a midday totality and a proper “diamond ring” occlusion. I’m not confident I’ll ever see an eclipse quite so spectacular again in my lifetime, but I’m hopeful!

Obviously the eclipse is a primary deciding factor in our location this summer, but this family holiday’s about more than just seeing the sun vanish and hoping that it comes back out again.

A freshwater turtle swims close to the rocky shore of a blue-green lake, peeping its head above the water.
For example, we’ve also braved the August heat for a variety of outings around the area, such as to the beautiful botanic gardens of Parc Samà where we met this curious little turtle.

I’ve been out geocaching a lot on the mornings, for example, as is my way when visiting any foreign country! I’ve enjoyed taking advantage of being a naturally earlier-riser than most of my family, coupled with the cooler morning temperatures, to explore the hills and forests of this region. And look: I found my thousandth ever geocache!2

The one downside3 of our accommodation is the lack of connectivity. There’s no wired Internet here, and the hilly location and stone walls make acquiring a reasonable cellular signal… challenging.

Dan, a white man with a short 'goatee' beard and a blue ponytail, sits in the drivers' seat of a left-hand drive car with a laptop perched between his belly and the steering wheel, giving a sarcastic grin to the camera.
To look into a Three Rings issue this morning, I first needed to drive down the hill and around the valley a short way to get line-of-sight to a cellular tower, in order to get more than one bar of 5G signal and tether myself a reasonable Internet connection!

Anyway: it’s beautiful and bright (and scorchingly hot!) out here, and I’ve got my fingers crossed for clear skies in eight hours’ time. Here’s hoping!

Footnotes

1 Without clouds in the way, the prettiest pictures of sunsets occurs just after this point, of course. I’ve spared you seeing a photo of an unoccluded sun, which – depending on the brightness fidelity of your screen – you’d possibly need to wear special shades to look at anyway?

2 I know, I know: I’ve been geocaching for sixteen years – I “should” have found more than that by now. Well, I’m pretty laid-back about the sport, and often only target caches with a reasonable number of positive reviews or that are otherwise interesting to me. I’m not so-interested in making the “number go up” as I am in exploring interesting places and seeing cool things.

3 Or is it an upside? It’s certainly keeping my focus on the world around me and away from screens!

× × × ×

BeepAlive – keeping my soundbar from going to sleep

My living room TV is attached to an ageing Windows box that we use as a media centre and middleweight gaming1 PC. To better fill the room with sound (I hate those tinny flat speakers they like to put into TVs these days!), the TV is also attached to a soundbar.

Line-art illustration showing a computer attached to a 4K TV, in turn attached to a speaker.

The problem is that the soundbar keeps shutting itself down. If it doesn’t receive any signals for ~20 minutes, it enters sleep mode2. It automatically turns itself on when the TV turns on, but it turns itself off all by itself.

This is annoying, because if we pause what we’re watching for a conversation or something, the soundbar switches itself off, even though the computer and television are still switched-on. It’s doubly-annoying because we then have to get up and walk over to it to switch it back on again, because the dog ate the remote3.

But what if I could solve this… with software?4

Top surface of a TV soundbar showing plus, minus, and power buttons, and a red LED.
LED’s gone red again?5 Sigh. Whose turn is it to get up and press the button?

My solution is BeepAlive, a little Go program that runs in a Windows system tray and makes a very quiet noise once every 9 minutes. I’ve tuned the noise so that it’s quiet enough that I can’t hear it unless I’m specifically listening for it… but loud enough that it the soundbar sees that there are still audio signals coming in, so it doesn’t go to sleep.

Now, so long as the media centre computer and TV remain powered-on, the soundbar stays awake. And that’s how a hacky engineer like me can solve a hardware problem with a software tool.

Footnotes

1 Mostly the gaming’s done by the kids, and they’re likely-as-not to use the Switch or Steam Deck instead… or, when we’re not at the Chicory House, Bee, the Bazzite-powered gaming rig I set up in the playroom… but in principle it’s equipped for gaming. I guess we sometimes fire a Jackbox Party Pack on it when we have guests?

2 It doesn’t even seem to save any power to be in sleep mode: my power checker tool says it draws basically the same amount whichever mode it’s in!

3 It’s triply-annoying because our soundbar is the only infrared-controlled device in our house that doesn’t follow the IrDA standard, which makes it incredibly difficult for me to automate switching it on from the TV remote, our Flic hub, any “universal remote” etc. I managed to pull off a replay using my Flipper Zero, but that’s not a solution I want to put into the hands of the kids (or anywhere that the dog might eat it). I suppose I could buy a replacement remote, but I don’t feel like giving any more money to a company that turned their nose up at IrDA.

4 Okay, so technically I solved this with software a few years ago, but I misplaced the software and it, frankly, wasn’t very good. My thinking is that by doing it better, and open-sourcing it, I’ll be able to find it when I need it next. And as a bonus, it might just maybe help somebody else, someday.

5 At our regular house, rather than the Chicory House, the soundbar lives above the TV, close to the ceiling, and it’s hard to even see the annoying LED. So I mounted a tiny mirror, about a quarter of the size of a fingernail, to the ceiling above it to improve its visibility from the sofa. Now that’s a hardware solution!

×

(Feeling Fucking) Fabulous in Blackpool

Like many others1, MEEK’s Fabulous has been stuck on-loop in my head for most of this year. What a fucking banger of a track, amirite?

And yet… somehow, today was the first time I figured I’d watch the music video. If you’ve not seen it (or perhaps not even heard the song), go do that now; I’ll wait.

The outdoor shots start about 20 seconds in, and… they’re instantly-recognisable by what they aren’t.

They aren’t London, where singer-songwriter Georgia Meek hails from, that’s for sure.

A partially-boarded up and heavily-graffitied residential street with unmaintained peeling paint, in front of which a woman in an enormous red dress walks.
You don’t get this level of deprivation in the South. Also, I’m pretty sure the director must’ve deliberately flung the tail-end scratchings from a crisp packet into the road to get those seagulls to play ball.

You probably know from the title of this blog post, but the filming location MEEK and her team chose is… Blackpool!

That first outdoor shot is opposite Pier Street Car Park.2

Now dressed in a leopardprint pantsuit and red furry hat, the singer walks down a narrow street, paved over cobblestones, while an organist plays on one side and a man walks his dog on the other.
The music video winds its way around a few streets in the town centre: this one’s distinctively-badly paved-over cobblestones makes it clear it’s the East end of Pier Street. Oh; and I gather that the guy with the dog was just a random passer-by who Meek collared and got to sign a release and just recruited for the video, then and there. Badass.

The music video goes indoors, continuing – nay, increasing – how fabulously queer-and-glam it is, through a theatre and arcade/bingo hall3. Eventually, it hits and a series of fast food establishments cumulating in Feast About.

At nighttime, a woman in a wispy and feathery white dress stands outside Feast About Fast Food on a street corner, with illuminated Blackpool Tower just visible over the rooftops.
It’s easy enough to line up the tower with The Strand to find this location, even if the named shops didn’t give it away. We’re on the opposite corner of the block from Ma Kelly’s now, and just around the corner from Garlands (if you’re looking for a cheap drink and a drag show) and The Flying Handbag (where my 18th birthday party‘s pub crawl began).

Then there’s some faster and blurrier videography, but it’s clearly the Golden Mile, where she’s heading South and… hey, wait… is this music video actually shot in a geographically-sound order? So far, she seems to have moderately-consistently been moving South through the roads about one or two streets back from the Promenade, from a little North of the North Pier down towards the Central Pier…

Model camels race across a desert at a sideshow stall, while a woman wearing a red strapped dress over a tracksuit sings energetically.
Half-way down the Golden Mile, this carnival game looks distinctly like the Camel Derby at Coral Island: you can see it photographed from a definitive angle in this review post!

Anyway; after her party night out, she finds her way to a late-night chippy, as you do.

She’s still heading South… which makes me think that the ruined steps she’s seen sitting on for literally three seconds might be somewhere between Coral Island and the Crispy Cod. Anybody know?

In a red poofy dress, a woman sits alone in a blue-lit fish and chip shop, as seen through the window, at night.
You don’t need my help with this one, but here it is anyway.

Anyway, the bottom line is that this music video was – surprisingly but delightfully – set in the area of… what might be the gayest pub crawl in the UK. Which, on top of this already awesome song, leaves me… feeling fucking fabulous.

Footnotes

1 Especially those in queer or adjacent spaces, obvs.

2 Pier Street and York Street Car Park’s are a comfortable walk from Ma Kelly’s Cabaret Bar, which – and I’m less-certain about this one – might be the host of some of the interior shots from the music video. Anyway, if you go around the corner in Google Street View you’ll find Higgitts Arcade and Burger Bar, which – just trust me and go look at it – is the most-Blackpool thing imaginable.

3 I’m almost-certain the arcade is the Higgitts, which I mentioned previously because of its proximity to an earlier shot!

× × × × ×

Contactless Transport in London vs Paris

Paris’s public transport tickets suck… for now!

In his blog post yesterday, Terence Eden observed that of all the cities he’s travelled to over the last year, Paris had the most-ridiculously-unhelpful public transport ticketing system:

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.

This absolutely parallels my experience of hopping around the Paris’s metro area, last time I was there.

Dan, a white man with a ponytail and a goatee, site in a Parisian cafe sipping a glass of white wine.
If I’ve got to navigate my way through Paris’s public transport network… I’m going to need a drink first.

I was interested to hear, though, that by 2030 virtually all of Paris’s public transport will accept contactless payment, bringing its convenience level to a similar level to that of London. Cool.1

From the sounds of things, this is clearly designed as a convenience for visitors to the city, not regulars and locals:

Dès le 30 juin 2026, les touristes et les voyageurs hyperoccasionnels pourront opter pour valider leur titre en sortie de l’aéroport d’Orly sur la ligne 14 avec la carte bancaire.2

Paris’s relationship with tourists is different from London’s

But the bit that surprised me is Paris’s pricing for the parts they’ve deployed so far:

Les prix des titres de transport via les bornes d’achat sont les suivants :

  • Bus/tram/funiculaire : 2,55 € (soit + 0,50 € sur le prix classique) ;
  • Métro/train/RER : 3,35 € (soit + 0,80 € sur le prix classique) ;
  • Aéroports : 14,80 € (soit + 0,80 € sur le prix classique).

Buying transport tickets in Paris using a contactless card… costs 0.50 € to 0.80 € more. Paris will charge you for the convenience of tapping in and out with your carte bancaire.

A row of ticket gates in a London Underground station.
Tap in, tap out. Unless you’re eligible for discounted travel, you probably might as well use your debit card to get around London. Photo by Luca Sammarco.

Contactless is clearly more-convenient for city visitors, but I think the difference between London and Paris’s attitude to it says something about the relationship both cities have with their tourists. In London, most travellers can use whatever bank card and mobile wallet they’ve already got… and they’ll get as good a deal as possible. But in Paris, doing the same will invariably cost more than a conventional ticket would. You pay a convenience-tax.

Both cities get tens of millions of annual visitors and extract billions of euros worth of financial benefit from their tourist economies. Paris doing slightly better overall, but they’re closely-comparable enough that differences like this probably mean something.

Crowds file down the escalator into Charles de Gaulle-Étoile station.
Tap in, pay a premium for the privilege. Thanks, Paris! Photo by Candelario Benítez.

I’m not saying that London loves tourists and Paris hates them! It’s not so simple as that. But I think perhaps the cites try to present themselves in a different way.

London’s public transport says: we’ll work around you. You can learn the rules as you go; you don’t have to “learn London” to get around. Just use your usual contactless card wherever you go; we’ll work out the details, and your daily cost will get capped just the same as if you chose to pick up an Oyster card. Visiting the city as a tourist is an ordinary use-case for the transport network.

Paris’s public transport says: you should learn the rules. You’re welcome to visit, but you either need to do the work to be a “temporary Parisian”… or you can just use your usual contactless card but we’ll charge you a premium for the convenience. Visiting the city as a tourist is a special case that the transport network sees differently from being a local.

Neither approach is “wrong”… but I think it’s interesting. And now I’m wondering what the approach is like across other European cities.

Footnotes

1 I’ll almost-certainly have to tackle the current-generation of Paris’s public transport at some point before then, but I’ll look forward to the improved version once it rolls-out.

2 “From 30 June 2026, tourists and hyper-ocassional travellers will be able to pay by bank card on Line 14 out of Orly Airport.” Emphasis mine.

× × ×

“You saved my life!” (or: how my kids briefly thought I was a superhero)

This weekend, my friend Liz arranged for some other Abnibbers and I to gather, with our families, for a camping/glamping weekend East of Oxford.

Here’s a story of something that transpired there, presented in three parts:

  1. The fire
  2. The battery pack
  3. “You saved my life!”
Adults and children mill around a firepit, some of them holding marshmallows on skewers.
The campsite provided our large group with an entire field to ourselves, including spaces for socialising, a fire pit (at which the kids enjoyed toasting marshmallows), and a wood-fired hot tub.

The entire weekend would have surely been a memorable experience already, but one particular event will probably stick in the minds of everybody in attendance: the fire.

The fire

The UK’s in its unprecedented third heatwave of the year: the grass is all dying and everything is tinder dry. And so it was that, on Friday night as the kids and I slept in our glamping “dome”, I was woken by the distant beep-beep-beep of a domestic smoke alarm. A few seconds later, I heard a second such alarm with a different tone, and it became clear that this wasn’t just somebody’s toast on fire.

Not recorded: the sound of the occupant of this static caravan/cabin – having jumped through the window to safety as the front door was blocked by flames – on the phone to the fire brigade.

I went back into the dome to check on the children, which is when Penny knocked on my door to ensure I was aware of what was going on. The kids were sound asleep, so I ran out to the car park to move the car (which was parked in such a position that embers were raining down on it!) and to check on the situation.

A static caravan is engulfed in flames behind a dome tent, at night.
The fire intensity of the fire grew particularly intense as the sound of fire engine sirens began to be heard from the valley below. Photo copyright Rory Prior.

I returned to the dome and got the children dressed. We evacuated to a safer distance and watched as the firefighters arrived and began to tackle the blaze. Short of water, they had one pump dousing the flaming building while two others relayed water from the nearest fire hydrant, way down the hill.

Firefighters pull hoses from a fire engine towards the inferno of a flaming cabin.
There was a brief faux pas when one of the Abnib kids exclaimed “this is so cool“… without realising that he was standing right next to the people whose home was being destroyed in front of us.

Eventually the situation came under control and we were all able to return to bed.

The battery pack

I spoke to Mike, whose holiday home was the building that was destroyed. He’d managed to escape with some shorts and his mobile phone, but little else: in particular, his car keys remained inside and were probably destroyed, which rendered him unable to drive back to his regular home.

A group of adults and older children stand out in a field at night, while in the distance thick smoke is illuminated by flashing blue lights.
The firefighters worked quickly, but it still took over three hours before they were able to finish spreading out and drenching everything that had caught light. We watched from a distance, and sheltered all the children (including those of a non-Abnib family on-site) in one of our tents.

Mike had been turning his phone on only in bursts in order to conserve battery for all of the essential calls he’d have to make (e.g. his bank, to extract some money without his cards, and a locksmith, to get him back into his car). His phone charger – an awkward USB-B-Micro one – hadn’t survived the fire.

But conveniently… I happened to have such a cable in my bag. Plus a fully-charged battery pack. So I lent both to Mike, in the hope that it’d make it easier for him to do all of the necessary administration1.

A handful of metal frame struts stick out from an ash pile that was clearly once a static caravan.
It’s got to be a pretty-devastating thing to happen to your holiday home and everything in it. Mike was surprisingly chill about it when I spoke to him, taking soft-of an attitude of “well, there’s no point fretting about it after the fact!”

“You saved my life!”

Anyway: on Saturday night, shortly after the kids and I had turned-in, there was a knock on the door. It was Mike, come to return the battery pack I’d lent him.

The kids didn’t know who he was, so I explained: “This is Mike; he’s the fella who lived in the home that burned down last night.”

Mike handed over the battery pack and charging cable and, grateful for them, used a metaphor that. “Thanks,” he said, passing the hardware to me, “You saved my life!”

Several beds laid-out in a darkened glamping pod.
I hadn’t told Mike which glamping pod was ours, and just figured I’d see him around. Or else if I didn’t get my battery pack back, that’d be fine: it’ll have been more-useful to him than to me in the days to come! But there we were, in our pyjamas, when he appeared at our door.

He turned and left, and both kids sprung out of bed and exclaimed “You saved the life of the guy whose house burned down‽”

I’m sure they had in their minds the idea that, during the period between the fire starting and me waking and evacuating them, I’d singlehandedly dragged this dude out of a burning building. Y’know, instead of just lending him a phone charger after-the-fact.

I only let them hold the misapprehension for a few minutes, but for a moment it lightened the mood.

Footnotes

1 I was already using my phone to call our insurance company before our flood, earlier this year, had finished. I can only imagine how inconvenient it is to suffer a disaster and lose your communications lifeline at the same time!

× × × ×

Hashcard #2

Six years and four months ago to the day, I received my first hashcard – an achievement-earning postcard sent while out on a geohashing expedition, to another geohasher. This experience went some way to my acquisition last year of a PO Box through which anybody on the Internet is invited to send me a postcard! (I’ve collected a few!)

Photo postcard showing a valley flanked by deciduous woodlands.

Well: today I received my second hashcard (and tenth “postcard from the Internet”)! This one came from GeorgDerReisende, whose 800+ expeditions are more than a little intimidating! He’d spent his 13th hashiversary on an expedition to a location outside Frankfurt earlier this month, where he narrowly failed to reach the hashpoint because it was just slightly too far into somebody’s private property.

Postcard reading: Hi Dan Q! / Today is my 13th hashiversary. This was a good moment & an expedition. It let me go to Kronberg am Taunus, but I couldn't go near enough. Is a reading of 5m for a second without proof good enough? I think no. / Greetings from 2026-07-06 50 8 / GeorgDerReisende

But at least he was able to claim the hashcard achievement (although not for the first time)! Well done, GeorgDerReisende!

× ×

The secret API I used to tell LeShuttle about different outbound and return passengers

I’ve got an upcoming trip to France: I’ll be driving there through the Channel Tunnel, via LeShuttle. But owing to a quirk in our family travel arrangements, we’ve have a slightly different set of passengers in the car for the outbound leg than for the return journey.

LeShuttle’s broken website

This is something that LeShuttle’s Advance Passenger Information registration form ought to be able to handle… but it very-much can’t.

Screenshot showing a web form with Dan Q and three other passengers on the outbound leg of a journey. Personal details appear to be blurred, but are actually spoofed AND blurred, per Dan's tradition. A 'Return passenger information is the same' checkbox is checked.
You’d think that to specify different passengers for the return leg, all I’d have to do is uncheck that checkbox, right? Wrong!

I was able to provide all of the personal and passport details of everybody on the outbound leg, but un-checking the “Return passenger information is the same” checkbox did… nothing. In fact, when saving the form and logging in again, the checkbox would be automatically re-checked.1

This is the point at which a normal person would either:

  1. Add the details of all passengers, both outbound and returning, to the form, and just hope they can sort out the confusion at the terminal, or,
  2. Try to get hold of a human Help Centre/Contact Us system (good luck!) who can sort it out.

Fortunately, I am not a normal person. I… am a software security engineer.

API reverse-engineering

My browser debug tools quickly indicated how this entire process works, and gave a clue as to what was broken in LeShuttle’s systems.

  1. When you log in, it makes a POST request to https://nextus-api-prod.leshuttle.com/b2c-api/GuestApi/Read?bookRef=...&surname=..., including your booking reference and surname (which acts as your password) in the relevant parameters.
  2. This returns all of your details in a JSON document. Prettified, and with all of the actual data replaced with explanatory comments, it looks something like this:
{
  "loginDetails": {
    /* credentials you used and other metadata */
  },
  "bookingDetails": {
    "outboundTravelDetails": {
      /* details about your outbound train and vehicle */
    },
    "returnTravelDetails": {
      /* details about your return train and vehicle */
    },
    "leadName": {
      /* details of the person who booked the trip */
    },
    "outboundPaxDetails": {
      /* For the outbound journey: */
      "paxLine": [
        /* First passenger: */
        {
          "paxDets": {
            /* - name, nationality, gender, DOB */
          },
          "docDets": {
            /* - passort number, expiry, issuing country */
          }
        },
        /* Second passenger: */
        {
          /* ... and so on .... */
        },
      ],
      /* Total number of passengers: */
      "noOfPax": "4"
    },
    "returnPaxDetails": {
      /* For the return journey: */
      "paxLine": [
        /* ... each passenger: same format as outbound... */
      ],
      /* Total number of passengers: */
      "noOfPax": "5"
    },
    "storedPaxDetails": {
      /* Pre-saved details? All blank for me */
    },
    /* More metadata */
  },
  "status": {
    /* Yet more metadata */
  },
  /* Even more metadata */
}
  1. Once you’ve made some changes, you press “Save”. This triggers a POST request to https://nextus-api-prod.leshuttle.com/b2c-api/GuestApi/Save with Content-Type: application/json and the entire JSON document from before, with your modifications, passed back.2

If you’re a programmer, you’re probably already making a guess as to what the underlying problem is. And you’re probably right:

  • The “Return passenger information is the same” checkbox value is not stored in the data that gets passed back and forth.
  • Instead, it’s derived by looking at the outbound and return passenger information. If it matches, it gets checked.
  • If it’s initially checked… the form doesn’t bother loading the UI that allows return passenger details to be modified.
  • But… this means that it never loads that UI:
    • the first time you visit the page the passenger list is empty both ways, which matches: anything you enter will necessarily be recorded into both the outbound and return fields, so
    • the next time you visit, it also matches… so it still doesn’t load the fields,
    • and so on.3

“Fixing” the problem

Knowing how the API worked, I was able to simply take the JSON document from the /Read endpoint, modify it so that the outboundPaxDetails and returnPaxDetails each contained the correct details for that leg of the journey (being sure also to update the total number of passengers noOfPax, which is for some reason a stored value rather than a derived one), and then submit it back via the /Save endpoint.

Having done this, I hit the /Read endpoint again to confirm that the data had, indeed, retained the data I submitted. When logging in again to the Web interface, I noticed that the checkbox now doesn’t automatically check itself. The correct data gets passed back and forth4.

Obviously LeShuttle need to fix their damn site. But at least – thanks to a little API reverse-engineering – I was able to submit the details they wanted from us.

Footnotes

1 Before anybody asks: yes, I tried all of the obvious things like using different browsers, clearing caches, disabling plugins, etc. I even had another passenger, using a different computer and operating system, give it a go. This one’s definitely a bug in LeShuttle’s systems.

2 I choose to assume that they’re doing some kind of server-side validation to ensure that a customer can’t, for example, modify details they’re not permitted to without a charge, such as which train they’re booked onto or the registration plate of the vehicle they’re bringing. But obviously I haven’t tested this, because it’s not among the information that I’m authorised to modify. Ethical hackers get permission before they poke at things they’re not sure whether they’re supposed to… especially if it’s a travel-related system and they’re somebody who has an unusual name that routinely gets them stopped and questioned at the UK border in general. 🤭

3 It occurs to me that possibly LeShuttle provide access to the relevant form only after the outbound journey has been made? Which would be a terrible design for the system and would represent terrible UI (why provide the checkbox if it doesn’t do anything?). I decided not to chance that this could be the expected approach, though, and just “fixed” the data up-front.

4 I haven’t tried modifying any of the outbound details to see if this re-breaks the return details. I suspect it would be fine, based on my analysis that the bug exists only in the front-end. But I can’t be sure without testing, and proper testing is something that LeShuttle’s own techies are getting paid to do. I don’t care enough about their website to do it for free!

×

How I (Don’t) Collect Blog Statistics

Inspired by Becky‘s post How I Collect Blog Statistics, Respectfully,1 I thought I’d share what I do.2

tl;dr: I collect virtually nothing and I use even less.

Let me take you on a journey through the different kinds of analytics tools I’ve used:

1996 —1999: Hit counters!

My original websites used a hit counter that I wrote in Perl based on a sample from Matt’s Script Archive. Because I was edgy and dark, I made it look like this:

"Flaming" black-on-black digits 0-9.
I made the flaming digits using a stock effect in Corel Photo-Paint; this is an attempt to replicate the “feel” of them.

Hit counters are pretty dumb for a variety of reasons. Counting “hits” was never a terribly-representative reflection of the popularity of your pages. But also: because they’re a public representation of your popularity, there was every incentive to “game” them… even just by hitting refresh a couple of times. Making them untrustworthy and pointless.

1998 — 2006: Webalizer

Screenshot from The Webalizer, showing a bar chart of web stats covering September 2005.
Who can forget The Webalizer? Those Microsoft Excel ’97-grade barcharts!

Back in the day, “proper” web stats was something you did on your log files. Take log files, pump them through a program, get amalgamated output. And the king of these tools was The Webalizer.3

On a few of my websites – and some that I helped host for my friends – I’d have The Webalizer run daily, collating an archive of monthly stats plus “month-so-far” for the current month.

The Webalizer attempted to differentiate “hits” from “visitors”. And it tried to distinguish between browsers, and isolated bots, and tracked pulled referrer-data, and could even try to geolocate IP addresses. It was pretty magical for its time.

2006 2016 Google Analytics

I was an early adopter of Google Analytics: my site ID (“UA code”) was only five digits long!

Screenshot from an early version of Google Analytics, featuring a line graph covering visitors between April and May 2009, showing a 1,064.1% higher visitor counter than 'sites of a similar size' on one date.
Those graphs were slick for the Web technology of the day. A product of that period in the mid-naughties when Google made products that actually impressed users and didn’t just make them roll their eyes?

Google Analytics works via a JavaScript snippet which collects a variety of information about the visitor and sends it to Google’s mothership.

A third-party cookie that connected all Google Analytics-powered sites, plus everybody’s activity on other Google products, provided a wealth of data that you couldn’t get any other way. Want a gender breakdown of your visitors or their interests? Google can “help” you with that… and all the while, “helping” themselves to copies of all the data too.

If your website runs Google Analytics, it’s part of Google’s massive data-harvesting machine, monitoring people as they move around the Web. Webmasters trading away their visitors’ identities for some pretty charts seems pretty disgusting to me; it saddens me that I was ever “part of the problem”.

2015 2023 Piwik

Since around 2010, I’d been actively blocking Google Analytics, which made me feel a bit like a hypocrite to be inflicting it upon others. I looked for an alternative and found it in Piwik (now Matomo), an open-source and self-hosted analytics tool.

Screenshot from Piwik, showing a world map, graphs, and search keywords.
A self-hosted Piwik/Matomo installation provides almost the same level of useful depth as Google Analytics, but you get to keep your soul.

I ran Google Analytics and Piwik side-by-side to validate the latter, and found it to be excellent. Not only was it collecting data in a much more-ethical and respectful way, but it was also producing more-accurate results for my readership who, leaning somewhat “techie”, would sometimes block Google Analytics outright for all of the same reasons I did.

It was pretty good, but…

2023 — … (Almost) nothing?

…I don’t like the kind of blogger I am when I’m collecting stats!

It’s like… being a teenager again and having that hit counter, and getting excited when it goes up.  So what if a number went up? What does “popularity” mean? Isn’t the impact more important than the number of eyeballs?4

So in 2023, after winding my analytics down by instalments for many years, I just… stopped.5 I realised that so long as I was able to easily “watch the stats”, I’d be temped to write for the stats. To treat it as a score. To make the hit counter go up.6

That, in essence, is why I don’t really “do” any webstats any more. Analytics don’t serve me and the blogger I want to be, and they didn’t represent anything that I would consider a useful metric of success.

If somebody’s moved by what I do, that’s great: but a hit counter going up by one doesn’t tell me that; and it never did. Now if they leave a comment or drop me an email or even send me a postcardthat’s how I know that I made a difference!

Exception to the rule: GoAccess!

While I don’t actively watch the stats any more, I suppose I can still generate them, from my webserver logs, Webalizer-style. Except nowadays I’d probably use GoAccess:

GoAccess dashboard for the last week, showing 1.9M requests by 350K visitors, pulling 160GB of data, with a big of a jump in traffic on 14 July.
There’s a bit of a “hump” where last week’s blog post about apps started trending on Bubbles, HackerNews, Lobste.rs and the like. But I knew that already because people sent me lots of comments!

There’s a script that I’m able to run, if I feel like it, to parse the most-recent of my Caddy logfiles. It takes about one minute to run per day of logs to process, and outputs a perfectly attractive self-contained HTML file.

Here’s that script:

#!/bin/bash
readonly LOG_DIR="/var/log/www/danq.me/"
readonly DAYS=7
readonly OUTPUT_HTML="/var/log/goaccess/danq.me.html"

sudo bash -c "{ find '$LOG_DIR' -maxdepth 1 -name 'access*.gz' -mtime -$DAYS -print0 | sort -z | xargs -0 zcat; cat '$LOG_DIR/access.log'; } | goaccess --log-format CADDY --output '$OUTPUT_HTML' -"

It’s not clever. It’s not sophisticated. It doesn’t use cookies or JavaScript or, indeed, anything other than what my webserver gives me for free.

I barely use it: maybe once every 18 months or so (today was the first time in well over a year). It’s there if I need it. And it’s inconvenient-enough to use that I’m not tempted to.

Footnotes

1 And perhaps also inspired to a lesser extent by Terence Eden‘s Reasonably accurate, privacy conscious, cookieless, visitor tracking for WordPress, which I’ve been thinking about on-and-off ever since I read it last year.

2 By “blog stats”, here, I mean statistics about visitors to my blog, not stats about my blogging (which I track and share in excruciating detail).

3 Did you know that the last point release of The Webalizer was in 2013 and the last feature release was in 2010: much later than I thought was the case!

4 Also, how do we even count “eyeballs”. Right now, about a fifth to a quarter of my visitors are bots. Amazonbot alone accounts for over 2% of my traffic. (I should probably tighten my robots.txt.)

5 Nowadays, there’s no tracking scripts whatsoever on my site. I don’t set a cookie unless you ask me to (and then it’s “transparent”: you can see exactly what it contains and what it’s for), I don’t try to fingerprint you in any way, I don’t even keep server logs longer than 60 days! Back when I used Jetpack I actively nerfed its stats-collection “features”. I don’t want your personal data!

6 Last week, I wrote a blog post about breaking into somebody’s “app” to make a web page that does the same things, but better. It attracted lots of comments, emails, and other feedback, so I can see it had impact. I have no idea how many eyeballs (or bots) saw it. That’s not the important bit.

× ×

Recreating a 1990 Book Cover (in HTML + CSS)

At the weekend, I became briefly obsessed with the cover of the manual for GoScript Plus, a 1990 software tool for converting PostScript output into a format that’s compatible with a wider array of IBM-compatible printers.

I’ve never used this piece of software. I can’t even remember how I found my way to archive.org’s copy of its documentation. Just one of those mysteries.

Anyway: here’s what it looks like:

Computer manual cover printed in blue, black, and white. The title 'GoScript Plus' is askew at one angle, and everything else is askew at a right angle to that.
I can see why, if you were making software like this, you’d want to show off the number of typefaces your tool could support. And look: we can print text at wonky angles! Buy this and you can too!

The design is very much a product of its era. That two-colour print, the strange angles, those smallcaps, the excessive use of title case, and the use of “ink jet” as two words rather than one.

Anyway: I decided I’d attempt to re-create the cover in pure HTML + CSS. No SVGs; no images. Here’s what I came up with:

Somehow mine looks slightly less-dated? But still very “90s”.

I’m not entirely happy with the fonts: in the short while I was working on this, I couldn’t find anything that was quite “right” for the main title, with its stencil-style Rs and Ps, super-rounded Os and Cs, and narrow Ss. In the end I just used Ubuntu Sans almost everywhere.

The white “stripe” with font samples is all just system fonts from your computer! So that’s not accurate either. But my aim was to capture the feel of the manual rather than necessarily make a 100% faithful recreation of it, so I guess it’s okay.

I was quite pleased with the LaserGo logo in the top left. The main “striped circle with one corner a different color” was implemented like this:

/* The <address> element contains the text "LaserGo, Inc" */
address {
  /* Before AND after it are two virtual elements: */
  &:before,
  &:after {
    content: '';
    display: block;
    position: absolute;
    /* Both are offset to where I want the "circle" to be. */
    /* (note use of container query units for responsive sizing!) */
    top: -8cqw;
    left: 3cqw;
    width: 8cqw;
    height: 8cqw;
    /* Make it circular: */
    border-radius: 50%;
    /* The background is striped, with a color specified in --logo-color: */
    background: repeating-linear-gradient(var(--logo-color) 0cqw, transparent 0.2cqw, transparent 0.3cqw);
    /* Then that gets masked; two variables control which part is shown: */
    mask-image: conic-gradient(var(--logo-corner-mask) 0deg, var(--logo-corner-mask) 90deg, var(--logo-remainder-mask) 90deg, var(--logo-remainder-mask) 360deg);
  }

  &:before {
    /* The "before" circle uses white stripes: */
    --logo-color: var(--white);
    /* And masks so that three-quarters of the circle is shown: */
    --logo-corner-mask: transparent;
    --logo-remainder-mask: black;
  }

  &:after {
    /* The "after" circle uses black stripes: */
    --logo-color: var(--black);
    /* And masks so that one-quarter of the circle is shown: */
    --logo-corner-mask: black;
    --logo-remainder-mask: transparent;
  }
}
I was pleased to be able to share 90% of the CSS code between the white-striped three-quarters-circle and the black-striped one-quarter-circle. All that remained after this was to “bite” a corner out of it with a background-coloured overlay.

Anyway; there’s probably nothing more to say about this, apart from a reminder than HTML + CSS is absolutely a an art medium. Take a look at the source code of my fake book cover, if you like (or inspect its DOM, if you prefer): it’s all self-contained and should be reasonably readable.

×

My piano came home from the hospital

When my house flooded 149 days ago, a lot of things were damaged. The oak floors, for one, were completely wrecked, as the ground floor electrical ring, the skirting boards, one internal wall, a few hundred books and small items, and a load of furniture. Since then we’ve lived in a few places – but mostly at the “Chicory House” – while the insurance company has been working on repairing and replacing everything that we’ve lost.

This week, we got back the piano.

Two men move an upright piano across a driveway and through a door, with the help of a small trolley and some boards.
Professional piano movers make this job look easy. But having tried to move a piano before, it’s definitely not.

Our insurance policy is “new for old”, but we own a handful of pieces of furniture whether it’s impractical or impossible to replace them like-for-like and we’ve instead petitioned for restoration. For example: our dining table is a bit of a family heirloom, a mahogany reading room desk formerly from the libraries of the University of Cambridge, adapted by Ruth‘s (carpenter) father into a dining table1.

Another example turns out to be our upright piano, which turns out to be a bit of a musical oddity: it’s got features, like it’s peculiar gravity-controlled overdampers that, among other characteristics, are pretty distinct to the Edwardian or perhaps inter-war construction techniques that were in vogue at the time2.

Post-flood photo of the body of an upright piano alongside a cabinet with a clear tide mark up to about a foot from the ground.
Follow the line of the tide mark fromt he glasses cabinet to the piano and it’s clear that the body of the instrument sat full of water for some time. 😢

In any case: after a piano specialist wrote us a statement explaining that it simply wasn’t possible to “new-for-old” this because they don’t make them like this any more, the insurance company signed-off on us sending it away to what I lovingly called a “piano hospital”, where she’s enjoyed a complete overhaul.

And now, at last, it’s back with us: we could have kept it in storage until we’re ready to move back “home” (there’s still a lot of repair work to be done!), but having it moved twice is cheaper… plus it means we get it back sooner.

The pristine inside of an upright piano.
There was clearly a lot of TLC available at the “piano hospital”: it’s got a whole new set of strings, new felt, and even her internal metalwork has been polished to a shine.

Personally, I’ve found it an enormous psychological relief to have the piano back, because I’ve missed it!

I started teaching myself to play the piano during the second Covid lockdown, looking for something to distract me from my inability to go outdoors and do things, and wanting to try to engage a different part of my brain. I was quickly hooked: I’d never learned any musical instrument before3, and I enjoyed having something I was (and still am!) pretty bad at which I could make slow incremental progress.

And so for several years, most days, I’d play about 10 minutes of piano. Not much: just a little each day usually while my lunch warmed up. But slowly but surely I reached the point that I could tolerate – or even enjoy! – hearing myself play4.

And then after the flood… I couldn’t. I’d get up from work to stretch my legs and my fingers would twitch in anticipation of fulfilling a routine that… I just didn’t get to, any more. I tried playing the electric piano at the local library but its headphones were damaged and the action didn’t feel right and… it just wasn’t the same. I wanted our piano back!

Dan, a white man with a beard and a blue-dyed ponytail, sits in a plain hallway at a polished upright piano, looking happy.
It feels a bit weird playing the piano between the bottom of the stairs and the front door, but space is short in the Chicory House so we make do with where we can put things.

And now I’ve got it. And it feels fantastic. It’s a little different – the sustain pedal’s response is a lot better, but more nuanced, and I’m not used to it yet, for example. But it’s still a wonderful thing: like a family member coming home after a long period away.

Also: it feels like a small victory to have something back, following the flood, because the entire insurance/assessment/repair process continues to be so slow.

Our house may still be stuck with no floors and missing walls… but, five months later, the first things to be repaired are coming back to us. Maybe soon we’ll have, I don’t know, a working kitchen or the plumbing re-connected. Here’s hoping!

Footnotes

1 The transformation of the reading room desk – which once sported integrated reading lights – into a general-purpose table has been done so-effectively that you wouldn’t know to look at it that our largest piece of furniture had ever had another life… unless you lift the secret panel in its centre foot, at which point you’d discover a BS 546 plug still wired-in to it!

2 Don’t ask me to enumerate the particular features or how we know: JTA, plus our piano tuner, did the research that ultimately underpinned the argument that you couldn’t possibly acquire a like-for-like replacement for it. I just know how it feels and sounds.

3 I didn’t even play a recorder at school!

4 I fully appreciate that I will never be as good a pianist as, say, the average 8-year old who plays for their YouTube channel. I am fine with this. Like my blogging, my piano-playing is, first and foremost, for me and not for anybody else.

× × × ×