<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
  <channel>
    <title>davep</title>
    <link>https://blog.davep.org</link>
    <description>Posts in category "Tech" from davep</description>
    <atom:link href="https://blog.davep.org/feeds/tech.rss.xml" rel="self"/>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>python-feedgen</generator>
    <language>en</language>
    <lastBuildDate>Mon, 05 Oct 2026 09:46:53 +0000</lastBuildDate>
    <item>
      <title>Siri is broken</title>
      <link>https://blog.davep.org/2026/09/24/siri-is-broken.html</link>
      <description>&lt;p&gt;I think, in part, I regret upgrading any of my &lt;a href="https://blog.davep.org/tag/apple/"&gt;Apple&lt;/a&gt; devices
to the 27 line of operating systems. While my experience as a whole has been
pretty favourable, the one thing I was looking forward to is not just
disappointing, but is a huge step backwards.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Waiting for Siri to do anything" height="914" loading="lazy" src="https://blog.davep.org/attachments/2026/09/24/siri-waiting.webp#centre" width="1206" /&gt;&lt;/p&gt;
&lt;p&gt;I don't use &lt;a href="https://blog.davep.org/tag/siri/"&gt;Siri&lt;/a&gt; for many things, but I do use it a lot for a
small number of core things. On any given day I'll lift my watch up and
speak to it to set a timer or a reminder. Occasionally I'll ask other
things, but they're the main uses. Thanks to the fairly recent addition of
on-device voice handling, these requests have been near-instant.&lt;/p&gt;
&lt;p&gt;With the new Siri that comes with iOS 27, etc., if I'm really lucky the
reply will be super slow (getting on for 20 seconds or so to do the job),
but more often than not it just doesn't work at all. Either it tells me that
my main device isn't available right now&lt;sup id="fnref:427-1"&gt;&lt;a class="footnote-ref" href="#fn:427-1"&gt;1&lt;/a&gt;&lt;/sup&gt; (which I take to mean my
&lt;a href="https://blog.davep.org/tag/iphone/"&gt;iPhone&lt;/a&gt;, which is wild given it's always in my pocket at the
time), or it just busy spins for ages and then simply times out and does
nothing.&lt;/p&gt;
&lt;p&gt;If I try to use Siri on the iPhone itself, it either just busy waits for
ages without getting anything done, or it finally tells me it isn't working.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Siri failing" height="960" loading="lazy" src="https://blog.davep.org/attachments/2026/09/24/siri-failed.webp#centre" width="1206" /&gt;&lt;/p&gt;
&lt;p&gt;I was one of the people who upgraded to the 16 Pro because of the promise of
&lt;em&gt;"Apple Intelligence"&lt;/em&gt;. I was, unsurprisingly, kind of annoyed that they
didn't deliver. But it was fine, the phone is a good one and it's still
serving me well. Also, if I'm honest, I was comfortable with the idea that
they chose to not really implement anything&lt;sup id="fnref:427-2"&gt;&lt;a class="footnote-ref" href="#fn:427-2"&gt;2&lt;/a&gt;&lt;/sup&gt; rather than implement
something bad.&lt;/p&gt;
&lt;p&gt;Sadly though, based on my experience so far, they've implemented something
bad. Since upgrading, on the Watch and iPhone, I've found that it's either
horrifically slow or it just doesn't work. On top of that, I've lost all the
benefit of the on-device voice handling of my watches.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:427-1"&gt;
&lt;p&gt;Or words to that effect; I can't remember the exact wording.&amp;#160;&lt;a class="footnote-backref" href="#fnref:427-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:427-2"&gt;
&lt;p&gt;I mean, of course, they did do the image playground and writing tools,
but they're hardly the leap forward in assistant intelligence that was
originally being hinted at.&amp;#160;&lt;a class="footnote-backref" href="#fnref:427-2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/09/24/siri-is-broken.html</guid>
      <category>Tech</category>
      <category>AI</category>
      <category>Apple</category>
      <category>Mac</category>
      <category>Siri</category>
      <category>iPhone</category>
      <category>macOS</category>
      <pubDate>Thu, 24 Sep 2026 08:12:05 +0100</pubDate>
    </item>
    <item>
      <title>GitHub PR reviews broken</title>
      <link>https://blog.davep.org/2026/09/13/github-pr-reviews-broken.html</link>
      <description>&lt;p&gt;Late on last week I was doing a PR review at work and noticed that, for some
odd reason, the author of the PR seemed to have absolutely nuked all of the
indentation in the code. While not a problem given the nature of the files I
was reviewing, I wasn't happy with their apparent disregard for style and
good practice, and was about to leave a remark and a request for changes.
But something seemed off. So I did a refresh of the page and... everything
fell into place.&lt;/p&gt;
&lt;p&gt;Weird.&lt;/p&gt;
&lt;p&gt;Since then I've seen the issue on multiple machines. To be fair, each time
it's been in Safari, and each time I've been busy with something else so
haven't had the chance to really dive into it. But given it's suddenly
cropped up, at the same time, on multiple machines, with nothing else
changing, it feels like something on the GitHub side of things.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Broken code review" height="2056" loading="lazy" src="https://blog.davep.org/attachments/2026/09/13/borked-code-review.webp#centre" width="2600" /&gt;&lt;/p&gt;
&lt;p&gt;Perhaps I'm letting a bit of bias creep in here, but I feel like this sort
of thing is happening more and more on GitHub. It's not that long back since
&lt;a href="https://blog.davep.org/2026/08/21/github-social-preview-is-broken.html"&gt;social previews suddenly
broke&lt;/a&gt;, for example. It's
hard to shake the idea that changes are being made without regard to
comprehensive testing, and likely without regard to how things connect.&lt;/p&gt;
&lt;p&gt;Now, at this point, it would be easy to reach for the &lt;em&gt;"well they're
obviously using agents to do most of the work"&lt;/em&gt; argument -- and I'm sure
plenty of people would -- but that doesn't quite fit with my experience.
Having experimented with such tools for a good chunk of this year now, both
for personal and, more recently, professional projects, I've generally found
that such tooling easily helps with catching such issues.&lt;/p&gt;
&lt;p&gt;Plenty of times now, when using something like
&lt;a href="https://blog.davep.org/tag/antigravity/"&gt;Antigravity&lt;/a&gt; or Claude Code to work on some code, I've
found that with reasonable care (you know: the sort of care you'd put into
your work anyway) you can quickly and easily uncover connections and
knock-on effects you might not have immediately noticed. Moreover, if LLMs
are useful for anything when it comes to coding, it's for writing tests&lt;sup id="fnref:419-1"&gt;&lt;a class="footnote-ref" href="#fn:419-1"&gt;1&lt;/a&gt;&lt;/sup&gt;.
With that in mind you should be able to reasonably expect the number of
silly bugs to go down.&lt;/p&gt;
&lt;p&gt;Unless, of course, there's no human in the loop anywhere, or the human in
the loop lacks adequate training and experience, or, I guess, they simply
lack the ability to give a shit.&lt;/p&gt;
&lt;p&gt;I wonder when this particular issue will get fixed? I should probably go and
see if it's reported in the GitHub forums anywhere. I know for sure that
there's little point in actually reporting it as a bug; my experiences with
that in the past haven't been great, and the GitHub subreddit has seen
enough stories of people getting nowhere.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:419-1"&gt;
&lt;p&gt;Arguably they're a little too good at it to the point of coming round
the other side and doing badly again, if you don't keep an eye on things.&amp;#160;&lt;a class="footnote-backref" href="#fnref:419-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/09/13/github-pr-reviews-broken.html</guid>
      <category>Tech</category>
      <category>GitHub</category>
      <category>web</category>
      <pubDate>Sun, 13 Sep 2026 15:19:16 +0100</pubDate>
    </item>
    <item>
      <title>GitHub social preview is fixed</title>
      <link>https://blog.davep.org/2026/08/26/github-social-preview-is-fixed.html</link>
      <description>&lt;p&gt;Five days &lt;a href="https://blog.davep.org/2026/08/21/github-social-preview-is-broken.html"&gt;after I first noticed
it&lt;/a&gt;, the ability to upload
a social preview for a repository has been fixed.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Rogallo with an updated social preview" height="476" loading="lazy" src="https://blog.davep.org/attachments/2026/08/26/fixed-social-preview.webp#centre" width="663" /&gt;&lt;/p&gt;
&lt;p&gt;So now I can finally update the preview for
&lt;a href="https://rogallo.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;Rogallo&lt;/a&gt; again.&lt;/p&gt;
&lt;p&gt;From what I can see it took a couple or so threads in the community forums
to get this issue noticed, and at least one person in those threads said how
they'd initially raised a ticket to report it as a bug and had been brushed
off and told to go to the community, as if it was something they were doing
wrong rather than reporting a genuine issue.&lt;/p&gt;
&lt;p&gt;This has been my experience in the past at least once. I forget the actual
issue now, but I remember stumbling into a problem, being a good user and
reporting the bug, along with details on how to reproduce, etc., and having
the ticket closed and being brushed off with some vague and unhelpful reply.
My recollection is that I then found a thread or two where others were
talking about the problem. Eventually it was acknowledged and fixed.&lt;/p&gt;
&lt;p&gt;It's hard not to feel like such an approach is a deliberate policy. It feels
like their front-line support is now a shield that deflects problems to a
place where community triage takes place.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/08/26/github-social-preview-is-fixed.html</guid>
      <category>Tech</category>
      <category>GitHub</category>
      <category>web</category>
      <pubDate>Wed, 26 Aug 2026 08:43:51 +0100</pubDate>
    </item>
    <item>
      <title>GitHub social preview is broken</title>
      <link>https://blog.davep.org/2026/08/21/github-social-preview-is-broken.html</link>
      <description>&lt;p&gt;Earlier today, now that &lt;a href="https://rogallo.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;Rogallo&lt;/a&gt; has matured a
fair bit, I thought I'd update the banner image and, in doing so, refresh
the "social preview" for &lt;a href="https://github.com/davep/rogallo" rel="noopener noreferrer" target="_blank"&gt;the repository&lt;/a&gt;.
This is easy enough, and something I've done plenty of times with plenty of
projects. You just go into the general settings and upload a new image.&lt;/p&gt;
&lt;p&gt;So, I faffed in Pixelmator Pro for a short while, got the new banner going,
and then uploaded it. Weirdly, it didn't preview. I was just left with a
blank rectangle.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Borked social preview on GitHub" height="473" loading="lazy" src="https://blog.davep.org/attachments/2026/08/21/borked-social-preview.webp#centre" width="663" /&gt;&lt;/p&gt;
&lt;p&gt;I tried a couple more times... nothing. I then tested the repository itself
with an online "social card" checking tool and, unsurprisingly, an image was
set but it was a broken image.&lt;/p&gt;
&lt;p&gt;Initially, I was entertaining the idea that I'd somehow done something
silly, but really it's something hard to get wrong. A little bit of
searching shows that it's not just me, with &lt;a href="https://github.com/orgs/community/discussions/205451" rel="noopener noreferrer" target="_blank"&gt;not
one&lt;/a&gt; but
&lt;a href="https://github.com/orgs/community/discussions/205449" rel="noopener noreferrer" target="_blank"&gt;two&lt;/a&gt; reports showing
up.&lt;/p&gt;
&lt;p&gt;It's things like this that bother me most when using GitHub (or any other
large service). Sure, &lt;a href="https://github.blog/news-insights/company-news/the-august-17-outage-and-the-work-ahead/" rel="noopener noreferrer" target="_blank"&gt;the big outages are
bad&lt;/a&gt;,
but with them you know they're being actively worked on, they're something
that's going to be getting constant attention until they're resolved.
Moreover, those sorts of issues generally suggest a scale problem&lt;sup id="fnref:450-1"&gt;&lt;a class="footnote-ref" href="#fn:450-1"&gt;1&lt;/a&gt;&lt;/sup&gt;. These
little bugs, though, suggest a lack of attention to detail, a lack of proper
testing, a lack of care about the product as a whole.&lt;/p&gt;
&lt;p&gt;It's not even the first time in the last couple of weeks that I've run into
something like this. The other day I wanted to convert an issue into a
discussion -- a feature I've used so many times before. This time... nope.
Just didn't work. I forget exactly at what point it failed; I think the
dialog popped up and then disappeared. Whatever the now-forgotten detail of
the failure, the issue was that a long-standing, reliable feature just
stopped working.&lt;/p&gt;
&lt;p&gt;Again: big outages can be annoying, but in those cases I tend to just go off
and do something else, either at my keyboard or, shockingly, away from it.
By the time I get back into the office it'll be sorted. These little
things... who knows when they'll be fixed?&lt;/p&gt;
&lt;p&gt;Perhaps this bit-rot is a result of the panicked fixes to those big-bang
problems?&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:450-1"&gt;
&lt;p&gt;Yes, of their own design. But still...&amp;#160;&lt;a class="footnote-backref" href="#fnref:450-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/08/21/github-social-preview-is-broken.html</guid>
      <category>Tech</category>
      <category>GitHub</category>
      <category>web</category>
      <pubDate>Fri, 21 Aug 2026 13:53:39 +0100</pubDate>
    </item>
    <item>
      <title>Some documentation in Geminispace</title>
      <link>https://blog.davep.org/2026/07/19/some-documentation-in-geminispace.html</link>
      <description>&lt;p&gt;Given that &lt;a href="https://blog.davep.org/tag/rogallo/"&gt;Rogallo&lt;/a&gt; is coming on pretty well, I feel it's
about time to get some sort of documentation for it going &lt;em&gt;in&lt;/em&gt; Geminispace.
With this in mind, I've created an account over on
&lt;a href="https://tilde.team/" rel="noopener noreferrer" target="_blank"&gt;tilde.team&lt;/a&gt; so I can make use of &lt;a href="https://tilde.team/wiki/gemini" rel="noopener noreferrer" target="_blank"&gt;their support for
the Gemini protocol&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While I don't imagine I'll be writing documentation as comprehensive as &lt;a href="https://rogallo.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;the
main site for Rogallo&lt;/a&gt;, I do aim to provide
&lt;a href="gemini://tilde.team/~davep/rogallo/" rel="noopener noreferrer" target="_blank"&gt;some basic information&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The other thing I'm going to maintain there is &lt;a href="gemini://tilde.team/~davep/rogallo/changelog.gmi" rel="noopener noreferrer" target="_blank"&gt;a version of the change
log&lt;/a&gt;. Rather than edit it
by hand each time, I've &lt;a href="https://github.com/davep/rogallo/blob/main/docs/bin/log2gemini" rel="noopener noreferrer" target="_blank"&gt;added a tool to the Rogallo
repository&lt;/a&gt;
that converts the Markdown version of the ChangeLog into Gemtext.&lt;/p&gt;
&lt;p&gt;It looks pretty good in Rogallo.&lt;/p&gt;
&lt;p&gt;&lt;img alt="The Rogallo ChangeLog in Rogallo" height="1952" loading="lazy" src="https://blog.davep.org/attachments/2026/07/19/rogallo-changelog.webp#centre" width="1606" /&gt;&lt;/p&gt;
&lt;p&gt;Initially, I set all of this up so that I was editing the files via
&lt;a href="https://www.gnu.org/software/tramp/" rel="noopener noreferrer" target="_blank"&gt;Tramp&lt;/a&gt;. This worked fine and got me
going, but pretty quickly I decided that it would make more sense to &lt;a href="https://github.com/davep/tilde-team-capsule" rel="noopener noreferrer" target="_blank"&gt;create
a repository&lt;/a&gt;, edit stuff
locally, and then just &lt;code&gt;rsync&lt;/code&gt; it when I'm good to go.&lt;/p&gt;
&lt;p&gt;Not editing in production... I know... How boring.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/07/19/some-documentation-in-geminispace.html</guid>
      <category>Tech</category>
      <category>Blogging</category>
      <category>Coding</category>
      <category>Gemini Protocol</category>
      <category>Markdown</category>
      <category>gemtext</category>
      <category>smolweb</category>
      <pubDate>Sun, 19 Jul 2026 20:50:55 +0100</pubDate>
    </item>
    <item>
      <title>Terminal bean soup</title>
      <link>https://blog.davep.org/2026/07/17/terminal-bean-soup.html</link>
      <description>&lt;p&gt;I'm sure most people reading this will be familiar with the concept of "bean
soup theory". In case anyone isn't, &lt;a href="https://en.wikipedia.org/wiki/Glossary_of_2020s_slang#B" rel="noopener noreferrer" target="_blank"&gt;here's how Wikipedia describes
it&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A specific phenomenon described as a 'What about me' effect. An individual
watches a video that doesn't pertain to them, but finds a way to make it
about them anyway. Stems from a 2023 TikTok recipe for bean soup, with
commenters saying "What if I don't like beans?"&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I feel there's a very specific set of folk who love to "bean soup" anything
relating to terminals, and it's common to have them turn up in your mentions
if you happen to do &lt;em&gt;anything&lt;/em&gt; in the terminal, or for the terminal, that
isn't about their purist opinions and how everything &lt;em&gt;must&lt;/em&gt; be a Vim clone,
or worse.&lt;/p&gt;
&lt;p&gt;I first encountered this when &lt;a href="https://blog.davep.org/2022/10/05/on-to-something-new-redux.html"&gt;I started working at
Textualize&lt;/a&gt;. Unsurprisingly,
given the point, purpose and focus of &lt;a href="https://blog.davep.org/tag/textual/"&gt;Textual&lt;/a&gt;, some folk
would turn up in the Discord server, in the issues, in the discussions, in
the mentions of posts in various places, and post their &lt;em&gt;very important
opinions&lt;/em&gt; about how TUI software &lt;em&gt;must&lt;/em&gt; work. Not... discuss their
preferences, or offer suggestions (there were plenty of people who were
pleasant like that, they were lovely to converse with), no: their engagement
was written as if every word that was mashed into their keyboard was a
well-crafted, handed-from-on-high RFC-like holy document that &lt;strong&gt;MUST&lt;/strong&gt; and
&lt;strong&gt;SHOULD&lt;/strong&gt; be followed&lt;sup id="fnref:415-1"&gt;&lt;a class="footnote-ref" href="#fn:415-1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;If I was being very charitable I could cut them some slack. If you're
building a framework for building applications for the terminal, there's a
good reason to make it at least possible for the application authors to
follow recognised best practice and to stick with hard-won conventions.
Indeed, Textual has some design choices that I think are deeply questionable
and misguided and I objected to them on more than one occasion. So, yeah, if
I was being charitable, I could cut them some slack.&lt;/p&gt;
&lt;p&gt;I could... if they weren't such arseholes about it.&lt;/p&gt;
&lt;p&gt;This gets worse though if you're building an application for the terminal,
especially if it's built as Free Software and the motivation is &lt;em&gt;to build
something for yourself and be kind enough to share&lt;/em&gt;. It irks the hell out of
me when I build some application for myself, as a TUI, and then someone
turns up and starts complaining about &lt;em&gt;my&lt;/em&gt; choice of default key bindings,
that work in &lt;em&gt;my&lt;/em&gt; choice of terminal emulator and &lt;em&gt;my&lt;/em&gt; configuration for
that emulator.&lt;/p&gt;
&lt;p&gt;It's even worse when they do it in a way where they have to show their &lt;em&gt;very
deep knowledge&lt;/em&gt; of terminals, and how they're very proud of just how lacking
in features and progress their own choice of terminal emulator is.&lt;/p&gt;
&lt;p&gt;Dude...&lt;sup id="fnref:415-2"&gt;&lt;a class="footnote-ref" href="#fn:415-2"&gt;2&lt;/a&gt;&lt;/sup&gt; I know. I've used physical terminals. I've written COBOL on a
minicomputer using a line editor on some honking great dumb all-green
all-in-one box. I've even written code on a terminal using fan-fold paper.
I've used all sorts of terminal emulators. I spent well over a decade doing
shit inside &lt;code&gt;rxvt&lt;/code&gt; which was running on my GNU/Linux server while displaying
on my Windows desktop machine.&lt;/p&gt;
&lt;p&gt;I've &lt;a href="https://github.com/Textualize/textual-key-recorder" rel="noopener noreferrer" target="_blank"&gt;installed and tested plenty of terminal
emulators&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I'm well aware of the conventions and expectations. If
&lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;C&lt;/kbd&gt; doesn't quit... that is &lt;strong&gt;my choice&lt;/strong&gt;. It's not
ignorance, it's not a lack of history with this stuff, it's a choice. For my
software.&lt;/p&gt;
&lt;p&gt;So when you turn up and feel the need to tell me that some function keys
might not work in some terminal on some GNU/Linux box... I get it, you don't
like beans. If that's the case, how about you either don't make my hobby all
about &lt;em&gt;your&lt;/em&gt; tastes and how I should build my application to suit you, or
how about you RTFM and configure my application so it works in your choice
of terminal?&lt;/p&gt;
&lt;p&gt;I mean... we know you won't. We know you don't even care about the
application I'm having tons of fun building, that I'm spending time in a
joyous flow-state creating and tinkering with. You just care about making
the post all about you and your purity. We know you just care about showing
how smart you are.&lt;/p&gt;
&lt;p&gt;We know you just can't resist the urge to reply-guy&lt;sup id="fnref:415-3"&gt;&lt;a class="footnote-ref" href="#fn:415-3"&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;We get it: you don't like bean soup. Nobody cares. Nobody asked.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:415-1"&gt;
&lt;p&gt;That reminds me: one day I should write a rant about the folk who obsess about the &lt;em&gt;"Zen of Python"&lt;/em&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:415-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:415-2"&gt;
&lt;p&gt;Let's be honest: it's &lt;em&gt;always&lt;/em&gt; a dude.&amp;#160;&lt;a class="footnote-backref" href="#fnref:415-2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:415-3"&gt;
&lt;p&gt;Let's be honest: it's &lt;em&gt;always&lt;/em&gt; a guy.&amp;#160;&lt;a class="footnote-backref" href="#fnref:415-3" title="Jump back to footnote 3 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/07/17/terminal-bean-soup.html</guid>
      <category>Tech</category>
      <category>Coding</category>
      <category>FOSS</category>
      <category>Free Software</category>
      <category>terminal</category>
      <category>textual</category>
      <pubDate>Fri, 17 Jul 2026 20:54:32 +0100</pubDate>
    </item>
    <item>
      <title>Recreating my blog stats</title>
      <link>https://blog.davep.org/2026/06/02/recreating-my-blog-stats.html</link>
      <description>&lt;h2 id="introduction"&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Having &lt;a href="https://blog.davep.org/2026/05/29/blogmore-v2-33-0.html"&gt;recently added the &lt;code&gt;dump&lt;/code&gt; command to
BlogMore&lt;/a&gt; I've been thinking I should try
and learn a little more about &lt;a href="https://jqlang.org/" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;jq&lt;/code&gt;&lt;/a&gt;. It's one of those
tools that's been on my radar for ages, which I've used on very rare
occasions to get something done quickly, but which I've never really used in
anger.&lt;/p&gt;
&lt;p&gt;So I thought it might be fun to see about recreating some of the stats from
the &lt;a href="https://blog.davep.org/stats/"&gt;stats page&lt;/a&gt; using &lt;code&gt;jq&lt;/code&gt; alone. Well, I say "alone", I mean
&lt;em&gt;"from the JSON data that is produced by &lt;a href="https://blogmore.davep.dev/command_line/#dump-command" rel="noopener noreferrer" target="_blank"&gt;the BlogMore &lt;code&gt;dump&lt;/code&gt;
command&lt;/a&gt;"&lt;/em&gt;, and of
course that makes it easier given it dumps some of the key calculated
values. In other words I won't be using &lt;code&gt;jq&lt;/code&gt; to calculate the word count, or
reading time, or GFI, etc.&lt;/p&gt;
&lt;h2 id="post-count"&gt;Post count&lt;/h2&gt;
&lt;p&gt;To start with, working out the number of posts in my blog is simple enough:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'. | length'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mi"&gt;371&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="category-count"&gt;Category count&lt;/h2&gt;
&lt;p&gt;Getting the list of categories would be:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .safe_category] | unique'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"ai"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"coding"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"creative"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"emacs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"gaming"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"life"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"music"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"tech"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s2"&gt;"til"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;and so getting the count of them is simple enough:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .safe_category] | unique | length'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mi"&gt;11&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="tags-count"&gt;Tags count&lt;/h2&gt;
&lt;p&gt;Getting the count of tags takes a little more work, as &lt;a href="https://blogmore.davep.dev/command_line/#output-properties" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;safe_tags&lt;/code&gt; is a
list too&lt;/a&gt;, so I
start out with a list of lists, which I need to flatten first.&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .safe_tags] | flatten | unique | length'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mi"&gt;224&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This, right away, is an interesting finding. In my &lt;a href="https://blog.davep.org/stats/"&gt;stats page&lt;/a&gt;, as
of the time of writing, the number of tags is reported as 243, but here I'm
getting 224. Given I'm using the &lt;code&gt;safe_tags&lt;/code&gt; property, which ensures all
similar tags end up with the same value (so &lt;code&gt;Hello World&lt;/code&gt;, &lt;code&gt;hello world&lt;/code&gt;,
and all variations, become &lt;code&gt;hello-world&lt;/code&gt;), that would suggest the stats page
&lt;em&gt;isn't&lt;/em&gt; taking that into account. That's &lt;a href="https://github.com/davep/blogmore/issues/580" rel="noopener noreferrer" target="_blank"&gt;an issue to
address&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="a-datetime-interlude"&gt;A date/time interlude&lt;/h2&gt;
&lt;p&gt;Here's where things get a little interesting for a moment. In the output of
the &lt;code&gt;dump&lt;/code&gt; command from &lt;a href="https://blogmore.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;BlogMore&lt;/a&gt;, the dates
of the posts are given in &lt;a href="https://en.wikipedia.org/wiki/ISO_8601" rel="noopener noreferrer" target="_blank"&gt;ISO 8601
format&lt;/a&gt;; specifically the date and
time with offset format. From what I can tell, while &lt;code&gt;jq&lt;/code&gt; does have some
date/time parsing support, it can't handle that format specifically.&lt;/p&gt;
&lt;p&gt;This means that if I try:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.[0] .date | fromdate'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I just get:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq: error (at &amp;lt;stdin&amp;gt;:27293): date "2015-06-18T14:53:00+01:00" does not match format "%Y-%m-%dT%H:%M:%SZ"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After some searching around it seems the only approach I can really take is
to drop the timezone offset and pretend every time is a &lt;code&gt;Z&lt;/code&gt; time:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.[0] .date[:19] + "Z" | fromdate'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mi"&gt;1434639180&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From here I can then get a fully-parsed list of date/time values using &lt;code&gt;gmtime&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'.[0] .date[:19] + "Z" | fromdate | gmtime'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;2015&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mi"&gt;168&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This isn't ideal for what I'd like to do, it's going to skew some of the
values related to time, but it's close enough for experimenting.&lt;/p&gt;
&lt;h2 id="posts-per-year"&gt;Posts per year&lt;/h2&gt;
&lt;p&gt;Now that I have a way of breaking the posting time into a workable array of
values, getting the number of posts per year becomes:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .date[:19] + "Z" | fromdate | gmtime[0]] | group_by(.) | .[] | "\(.[0]): \(length)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;2015: 32
2016: 26
2017: 7
2018: 1
2019: 15
2020: 23
2022: 11
2023: 49
2024: 19
2025: 11
2026: 177
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Although, to be fair to &lt;code&gt;jq&lt;/code&gt;, that's kind of long-winded when I could just
pull the year itself out of the posting time:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .date[:4]] | group_by(.) | .[] | "\(.[0]): \(length)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="posts-by-month"&gt;Posts by month&lt;/h2&gt;
&lt;p&gt;At this point getting the posts by month of year seems obvious too:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .date[5:7]] | group_by(.) | .[] | "\(.[0]): \(length)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;01: 14
02: 12
03: 53
04: 57
05: 76
06: 33
07: 25
08: 25
09: 13
10: 29
11: 19
12: 15
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="posts-by-weekday"&gt;Posts by weekday&lt;/h2&gt;
&lt;p&gt;For this, I need to go back to the more involved version of the posting date
handling query, where I use &lt;a href="https://jqlang.org/manual/#dates" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;gmtime&lt;/code&gt;&lt;/a&gt; to
break down the time. It turns out that the penultimate value is the day of
the week as a number. So, while it's not quite as readable in that I don't
have day names, I can get the values:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .date[:19] + "Z" | fromdate | gmtime[-2]] | group_by(.) | .[] | "\(.[0]): \(length)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;0: 48
1: 54
2: 51
3: 48
4: 56
5: 56
6: 58
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case Sunday is the first day (the &lt;code&gt;0&lt;/code&gt; day here).&lt;/p&gt;
&lt;h2 id="posts-by-hour"&gt;Posts by hour&lt;/h2&gt;
&lt;p&gt;Getting the posts by the hour is really just a variation on the
date-chopping query used for the posts by year and the posts by month; it's
all there in the string version of the date.&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .date[11:13]] | group_by(.) | .[] | "\(.[0]): \(length)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;00: 1
06: 1
07: 6
08: 51
09: 35
10: 32
11: 25
12: 14
13: 22
14: 24
15: 25
16: 24
17: 18
18: 9
19: 23
20: 33
21: 21
22: 6
23: 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="first-and-last-posting-dates"&gt;First and last posting dates&lt;/h2&gt;
&lt;p&gt;Getting the date of the first and latest post seems nice and easy:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .date[0:10]] | {first: min, last: max}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"first"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2015-06-18"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"last"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-01"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Although, from what I can tell, &lt;code&gt;jq&lt;/code&gt; doesn't have anything that makes date
arithmetic easy so working out the elapsed time between the two isn't so
straightforward. It can be done, but it's not as easy as it might be with a
bit of Python code, for example. The best I could come up with was:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[ .[] | .date[:19] + "Z" | fromdate ] | ((max - min) / (365.25 * 24 * 60 * 60))'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mf"&gt;10.95438841990519&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For an approximate value of "year", &lt;a href="https://en.wikipedia.org/wiki/Leap_year" rel="noopener noreferrer" target="_blank"&gt;of
course&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="word-counts"&gt;Word counts&lt;/h2&gt;
&lt;p&gt;From here on in many of the stats that can be pulled out from the JSON, with
&lt;code&gt;jq&lt;/code&gt;, become easier to handle. Each post has a &lt;code&gt;word_count&lt;/code&gt; property, so I
only need to do this:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .word_count] | {least: min, most: max, average: (add / length)}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"least"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"most"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2792&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"average"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;475.0700808625337&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="reading-times"&gt;Reading times&lt;/h2&gt;
&lt;p&gt;A post's reading time can be accessed by &lt;code&gt;reading_time&lt;/code&gt;, so it's as easy to
handle as the word counts:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .reading_time] | {least: min, most: max, average: (add / length)}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"least"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"most"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"average"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.8921832884097034&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id="gunning-fog-index"&gt;Gunning fog index&lt;/h2&gt;
&lt;p&gt;The Gunning fog index is available as the &lt;code&gt;gfi&lt;/code&gt; property so there's no work
to do to figure it out. It is, however, a floating point value and I want
counts in each integer "bucket". That can be done with
&lt;a href="https://jqlang.org/manual/#math" rel="noopener noreferrer" target="_blank"&gt;&lt;code&gt;round&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;-r&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'[.[] .gfi | round] | group_by(.) | .[] | "\(.[0]): \(length)"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;3: 1
4: 2
5: 3
6: 7
7: 30
8: 46
9: 67
10: 70
11: 75
12: 35
13: 18
14: 11
15: 1
16: 3
17: 2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As for working out the mean, median and mode... while I worked out the above
queries by reading the docs, experimenting, and using Gemini on occasion to
either help me understand an error message or to explain why an approach
works the way it did, I'm going to have to leave this one 100% to Gemini.
Here's its approach to using &lt;code&gt;jq&lt;/code&gt; to work out those averages:&lt;/p&gt;
&lt;div class="highlight" data-lang="sh"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;jq&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
&lt;span class="s1"&gt;  [ .[] | .gfi | select(. != null) ] as $raw_gfi&lt;/span&gt;
&lt;span class="s1"&gt;  | [ $raw_gfi[] | round ] as $rounded_gfi&lt;/span&gt;
&lt;span class="s1"&gt;  | ($raw_gfi | length) as $count&lt;/span&gt;

&lt;span class="s1"&gt;  # 1. Mean Calculation&lt;/span&gt;
&lt;span class="s1"&gt;  | (($raw_gfi | add) / $count) as $mean&lt;/span&gt;

&lt;span class="s1"&gt;  # 2. Median Calculation&lt;/span&gt;
&lt;span class="s1"&gt;  | ($raw_gfi | sort) as $sorted_gfi&lt;/span&gt;
&lt;span class="s1"&gt;  | (if $count % 2 == 1 then&lt;/span&gt;
&lt;span class="s1"&gt;       $sorted_gfi[($count - 1) / 2]&lt;/span&gt;
&lt;span class="s1"&gt;     else&lt;/span&gt;
&lt;span class="s1"&gt;       ($sorted_gfi[($count / 2) - 1] + $sorted_gfi[$count / 2]) / 2&lt;/span&gt;
&lt;span class="s1"&gt;     end) as $median&lt;/span&gt;

&lt;span class="s1"&gt;  # 3. Mode Calculation (using the rounded values)&lt;/span&gt;
&lt;span class="s1"&gt;  | [ $rounded_gfi&lt;/span&gt;
&lt;span class="s1"&gt;      | group_by(.)&lt;/span&gt;
&lt;span class="s1"&gt;      | map({gfi: .[0], frequency: length})&lt;/span&gt;
&lt;span class="s1"&gt;      | sort_by(.frequency)&lt;/span&gt;
&lt;span class="s1"&gt;      | reverse&lt;/span&gt;
&lt;span class="s1"&gt;      | .[]&lt;/span&gt;
&lt;span class="s1"&gt;    ] as $frequencies&lt;/span&gt;
&lt;span class="s1"&gt;  | [ $frequencies[] | select(.frequency == $frequencies[0].frequency) | .gfi ] as $modes&lt;/span&gt;

&lt;span class="s1"&gt;  # Final Object Assembly&lt;/span&gt;
&lt;span class="s1"&gt;  | {&lt;/span&gt;
&lt;span class="s1"&gt;      count: $count,&lt;/span&gt;
&lt;span class="s1"&gt;      mean: $mean,&lt;/span&gt;
&lt;span class="s1"&gt;      median: $median,&lt;/span&gt;
&lt;span class="s1"&gt;      mode: $modes&lt;/span&gt;
&lt;span class="s1"&gt;    }&lt;/span&gt;
&lt;span class="s1"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;div class="highlight" data-lang="json"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;371&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"mean"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.908842231503396&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"median"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;9.979198312236287&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;"mode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As of the time of writing: that's bang on what I get in the stats. Honestly
though, by this point, I think I'd be reaching for Python or something
similar to do this sort of work. For sure, I can't say if this is a good
&lt;code&gt;jq&lt;/code&gt; query, if it's in any way idiomatic, or even if it's error-free. The
numbers match what BlogMore says though.&lt;/p&gt;
&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This has been a useful exercise in getting to know a little more about &lt;code&gt;jq&lt;/code&gt;,
and I can see myself reaching for it to do quick little jobs now that I've
finally taken some time to dive into it. As it turns out, it's also been a
useful little audit of the content of the stats page because I've even found
a bug that needs addressing; so that's a bonus.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/06/02/recreating-my-blog-stats.html</guid>
      <category>Tech</category>
      <category>BlogMore</category>
      <category>Blogging</category>
      <category>jq</category>
      <category>JSON</category>
      <pubDate>Tue, 02 Jun 2026 17:01:42 +0100</pubDate>
    </item>
    <item>
      <title>Wipr</title>
      <link>https://blog.davep.org/2026/05/23/wipr.html</link>
      <description>&lt;p&gt;While I know the subject really fires some people, ad blockers are something
I've never really paid too much attention to. Back in the early days of the
web, the &lt;em&gt;really&lt;/em&gt; early days, I used to run with full-on JavaScript
blocking&lt;sup id="fnref:350-1"&gt;&lt;a class="footnote-ref" href="#fn:350-1"&gt;1&lt;/a&gt;&lt;/sup&gt;. The web changed and I accepted it.&lt;/p&gt;
&lt;p&gt;More recently, as I've become a full-time Safari user in the last couple of
years, I've been running with &lt;a href="http://kablock.com/" rel="noopener noreferrer" target="_blank"&gt;Ka-Block!&lt;/a&gt; installed.
It's been fine. I've never really noticed it. I &lt;em&gt;think&lt;/em&gt; it blocked some
stuff, but not other stuff. I've never really noticed if it was getting
updated or not; I just wasn't paying attention.&lt;/p&gt;
&lt;p&gt;Then, this morning, &lt;a href="https://mastodon.social/@miskolin/116622382892637246" rel="noopener noreferrer" target="_blank"&gt;I saw this post in the
Fediverse&lt;/a&gt; and for
some reason it caught my eye. I followed the link, did a bit of searching,
asked Misko about his experiences with the app, and saved a bookmark.&lt;/p&gt;
&lt;p&gt;Now, this evening, I've thrown down my fiver and I'm running with &lt;a href="https://kaylees.site/wipr2.html" rel="noopener noreferrer" target="_blank"&gt;Wipr
2&lt;/a&gt; installed, both on my
&lt;a href="https://blog.davep.org/2026/03/28/hello-macbook-air-again.html"&gt;Air&lt;/a&gt; and my iPhone. When I'm next
on either of my Minis, or on my iPad, I'll throw it on there too.&lt;/p&gt;
&lt;p&gt;The installation process was straightforward, albeit one where you need to
enable four extensions rather than just the one.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Wipr installed" height="424" loading="lazy" src="https://blog.davep.org/attachments/2026/05/23/wipr.webp#centre" width="440" /&gt;&lt;/p&gt;
&lt;p&gt;As well as that, you then need to enable it in the app itself and you're
good to go. I've since tried visiting a couple of locations that I know
still showed adverts or consent pop-ups and... clean. So clean!&lt;/p&gt;
&lt;p&gt;My expectation for tools like this is that they end up breaking some site in
a way you least expect, so I'll be very aware of that for a while. That
said, if I do run into a problem, not only is it easy enough to turn
blocking off just for that one site, there's a very clear route to reporting
problems too.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Encouragement to report a problem" height="1364" loading="lazy" src="https://blog.davep.org/attachments/2026/05/23/wipr-problem.webp#centre" width="1302" /&gt;&lt;/p&gt;
&lt;p&gt;Mostly, though, I hope I can go back to paying this app no attention
whatsoever. If I can, I imagine that's high praise and a job well done for
this sort of tool.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:350-1"&gt;
&lt;p&gt;I just know someone is reading that and thinking &lt;em&gt;"pfft, JavaScript
came along late into the web you noob"&lt;/em&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:350-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/05/23/wipr.html</guid>
      <category>Tech</category>
      <category>Ad Blocker</category>
      <category>Mac</category>
      <category>Safari</category>
      <category>iOS</category>
      <category>iPhone</category>
      <category>macOS</category>
      <category>software</category>
      <pubDate>Sat, 23 May 2026 20:29:17 +0100</pubDate>
    </item>
    <item>
      <title>Ghosted by Ghostty</title>
      <link>https://blog.davep.org/2026/04/13/ghosted-by-ghostty.html</link>
      <description>&lt;p&gt;I just grabbed and opened up the &lt;a href="https://blog.davep.org/2026/03/28/hello-macbook-air-again.html"&gt;MacBook
Air&lt;/a&gt; and met this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Ghosted!" height="1560" loading="lazy" src="https://blog.davep.org/attachments/2026/04/13/ghosted.webp#centre" width="1794" /&gt;&lt;/p&gt;
&lt;p&gt;First time I've ever seen this and I've been using Ghostty for quite a while
now.&lt;/p&gt;
&lt;p&gt;To be fair, the MacBook did update to 26.4.1 overnight and has tried to get
back to the state it was in before the restart, so I imagine that's the
cause. But I've never seen this before.&lt;/p&gt;
&lt;p&gt;I'm all good now; I &lt;kbd&gt;⌘&lt;/kbd&gt;-&lt;kbd&gt;q&lt;/kbd&gt; the app and started it again
and there's no sign of a problem.&lt;/p&gt;
&lt;p&gt;Goodness knows how I get to see that log...&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/13/ghosted-by-ghostty.html</guid>
      <category>Tech</category>
      <category>MacBook</category>
      <category>MacBook Air</category>
      <category>Ghostty</category>
      <category>macOS</category>
      <category>terminal</category>
      <pubDate>Mon, 13 Apr 2026 19:19:31 +0100</pubDate>
    </item>
    <item>
      <title>Discovering powRSS</title>
      <link>https://blog.davep.org/2026/04/11/discovering-powrss.html</link>
      <description>&lt;p&gt;This was a nice find yesterday: I think I came across it when someone I
follow on Mastodon boosted a post from &lt;a href="https://mastodon.social/@powRSS" rel="noopener noreferrer" target="_blank"&gt;the account related to the
site&lt;/a&gt;; it's a site called
&lt;a href="https://powrss.com/" rel="noopener noreferrer" target="_blank"&gt;powRSS&lt;/a&gt;. The concept is pretty simple: collect links
to all sorts of small blogs on all sorts of topics, and then provide a
honking great discovery feed/pool. You can read more about the idea &lt;a href="https://powrss.com/about" rel="noopener noreferrer" target="_blank"&gt;on
their about page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For sure, this sort of thing isn't exactly novel: those of us of a certain
age will fondly remember the fun of
&lt;a href="https://en.wikipedia.org/wiki/Webring" rel="noopener noreferrer" target="_blank"&gt;webrings&lt;/a&gt; and other similar
initiatives, not to mention feed aggregation sites where you could discover
trending blogs or see what your friends were reading, and all that. But, to
some degree, that fell out of favour and/or the limelight when social media
got really popular.&lt;/p&gt;
&lt;p&gt;So with this in mind it's good to see people still providing such sites.
I've added this blog to it and I'll be diving in there now and again to &lt;a href="https://powrss.com/blogs" rel="noopener noreferrer" target="_blank"&gt;see
if there's anything new I should be following&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It'll be fun to populate &lt;a href="https://oldnews.davep.dev/" rel="noopener noreferrer" target="_blank"&gt;OldNews&lt;/a&gt; with more
things to read.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/04/11/discovering-powrss.html</guid>
      <category>Tech</category>
      <category>Blogging</category>
      <category>RSS</category>
      <category>atom</category>
      <category>writing</category>
      <pubDate>Sat, 11 Apr 2026 09:50:34 +0100</pubDate>
    </item>
    <item>
      <title>Hello MacBook Air (again)</title>
      <link>https://blog.davep.org/2026/03/28/hello-macbook-air-again.html</link>
      <description>&lt;p&gt;As I &lt;a href="https://blog.davep.org/2026/03/27/macbook-air-m5.html"&gt;mentioned yesterday&lt;/a&gt; I decided it was
time to update my portable/sofa hacking setup and treat myself to a nice new
MacBook Air. It's here (well, I picked it up yesterday evening after
dinner).&lt;/p&gt;
&lt;p&gt;&lt;img alt="MacBook Air M5" height="430" loading="lazy" src="https://blog.davep.org/attachments/2026/03/28/macbook-air.webp#centre" width="512" /&gt;&lt;/p&gt;
&lt;p&gt;So far I'm &lt;em&gt;very&lt;/em&gt; pleased with the choice. It's light but feels sturdy. The
screen is very pleasing to read. The keyboard is really nice to type on
(albeit I do prefer the old MacBook Pro, but on the other hand this is a bit
more quiet, which matters if you're sharing a living room with someone
else). It's fast. So fast! It's also so quiet! So very quiet! And cool too.
The Intel-based MacBook Pro would get very warm as I worked; this just stays
cold.&lt;/p&gt;
&lt;p&gt;The really great part though is the battery life. Depending on what I was
doing, with the Intel Pro, I'd get a couple of hours off the cable. On the
other hand, last night, I spent a few hours setting things up on the Air and
I barely noticed the battery drop at all. This, more than anything, is what
I wanted.&lt;/p&gt;
&lt;p&gt;Well, okay, I wanted the speed, the quiet, the lack of heat, and the long
battery life.&lt;/p&gt;
&lt;p&gt;Oh, and the rather lovely "Midnight" colour. It's not black, but it's close
enough.&lt;/p&gt;
&lt;p&gt;The setup itself went pretty well, although for some odd reason I ran into
problems when setting up Emacs. These days I always use &lt;a href="https://github.com/d12frosted/homebrew-emacs-plus" rel="noopener noreferrer" target="_blank"&gt;Emacs Plus via
Homebrew&lt;/a&gt; and have never
had issues. Weirdly though, this time, if I did the installation method that
builds locally all sorts of things went wrong. I don't know if I missed a
step or something but I did what I normally do when dropping Emacs on a Mac.
So I started again with the pre-built approach and that worked better.&lt;/p&gt;
&lt;p&gt;Even then though, I ran into problems with &lt;a href="https://github.com/davep/.emacs.d" rel="noopener noreferrer" target="_blank"&gt;my setup downloading
everything&lt;/a&gt;. Things &lt;em&gt;mostly&lt;/em&gt; worked but I
kept seeing all sorts of issues relating to &lt;code&gt;git-gutter&lt;/code&gt; and
&lt;code&gt;git-gutter-fringe&lt;/code&gt; not being able to load (despite the fact they'd
downloaded fine, from what I could see).&lt;/p&gt;
&lt;p&gt;In the end I gave up trying to get it to all work from scratch and
hand-removed and then hand-installed via &lt;code&gt;package-list-packages&lt;/code&gt; instead.
Not the most scientific of approaches, and one I'm sure I'll regret at some
point in the future, but at least I got to a point where I could get other
stuff done on the machine.&lt;/p&gt;
&lt;p&gt;All of which is to say: if you're reading this blog post I got my Emacs and
git environment to the point I can write things and push them out to the
world. At which point that's the really important stuff up and going and I
can call this "set up".&lt;/p&gt;
&lt;p&gt;Once I'm happy that's working, I think it's time to revisit my Emacs setup.
While I don't think it needs another &lt;a href="https://blog.davep.org/2016/05/26/starting_fresh_with_gnu_emacs.html"&gt;complete
restart&lt;/a&gt;, I think it might
be time to at least look through what I have loading in and perhaps remove
some things I don't use any more (for example, I always carry around &lt;code&gt;vterm&lt;/code&gt;
from the days when I was testing every possible terminal I could get my
hands on -- &lt;a href="https://blog.davep.org/2024/03/28/goodbye-textualize.html"&gt;that's less important to me these
days&lt;/a&gt;.)&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/28/hello-macbook-air-again.html</guid>
      <category>Tech</category>
      <category>Apple</category>
      <category>Mac</category>
      <category>MacBook</category>
      <category>MacBook Air</category>
      <category>hardware</category>
      <category>macOS</category>
      <pubDate>Sat, 28 Mar 2026 10:30:09 +0000</pubDate>
    </item>
    <item>
      <title>MacBook Air M5</title>
      <link>https://blog.davep.org/2026/03/27/macbook-air-m5.html</link>
      <description>&lt;p&gt;It's just over a month shy of being 10 years since &lt;a href="https://blog.davep.org/2016/04/28/i-now-own-a-macbook.html"&gt;I bought my first
MacBook&lt;/a&gt;. As I mentioned at the time:
I'd bought my first Mac about 10 months earlier than that, had got used to
it, had grown to like the OS, and had need of a small and light hacking
machine to use while doing a lot of train travel (and I &lt;em&gt;really&lt;/em&gt; did do &lt;a href="https://blog.davep.org/tag/virgin/"&gt;a
lot of train travel after that&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Fast forward a touch over 3 years and, by accident of a windfall due to work
things, I ended up treating myself to a MacBook Pro. This was one of the
last Intel models. It worked well and served as my main hack-at-home machine
for quite a long time. I used it to code and edit videos and a bunch of
other things. It sat there, on my desk, plugged into a couple of screens,
and never really served as a portable machine.&lt;/p&gt;
&lt;p&gt;Fast forward around 4 years and, having been using a MacBook Pro M1 for a
while through where I worked then, I had a desire to get a M-chip Mac for
personal use and settled on an M2 Pro Mac Mini. That thing was, and remains,
a beast of a machine. It's set up here in my office right now and I'm sure
will last me for some time to come.&lt;/p&gt;
&lt;p&gt;The thing is, in the last 6 months, my home life has changed. I moved. I now
share a place again. It's nice to sofa hack and hang out and all that "share
a space with other people" stuff. To that end I've been using the Intel
MacBook Pro again but I'm noticing that it's getting old now. It's not that
it isn't coping with what I need it for -- far from it -- but having the
fans kick in lots, and just the heat, and also the fact that the OS is stuck
in the past because it's now a "legacy" machine... I sensed it was time for
an upgrade.&lt;/p&gt;
&lt;p&gt;A new MacBook Pro was an option, of course, but that feels like overkill for
some sofa hacking. If I want to do any heavy video editing or any heavy
coding the M2 Pro Mini is still the machine for the job. The new Neo looked
really good too, but the entry-level storage seemed a bit stingy these days
and once you bump up to the next level, while still stuck with the same
memory, well the price starts to get dangerously close to...&lt;/p&gt;
&lt;p&gt;&lt;img alt="The MacBook Air M5" height="300" loading="lazy" src="https://blog.davep.org/attachments/2026/03/27/macbook-air.webp#centre" width="512" /&gt;&lt;/p&gt;
&lt;p&gt;So, yeah, as of today, I've kind of come full circle; a decade on from that
MacBook Air purchase I have a new sofa hacking machine coming in the shape
of the new M5 MacBook Air&lt;sup id="fnref:243-1"&gt;&lt;a class="footnote-ref" href="#fn:243-1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;So this weekend will involve me digging out my "new macOS environment"
checklist and working through it, getting a hacking environment up and going
again. One thing I do want to do is follow that list but also write out a
fresh copy, because this time around I want to see if I can get a good
Python environment up and going minus &lt;a href="https://blog.davep.org/2022/11/05/python-and-macos.html"&gt;the use of
pyenv&lt;/a&gt;. Not that
&lt;a href="https://github.com/pyenv/pyenv" rel="noopener noreferrer" target="_blank"&gt;pyenv&lt;/a&gt; is a problem, at all, but I feel
like I should be able to achieve everything I need using just
&lt;a href="https://docs.astral.sh/uv/" rel="noopener noreferrer" target="_blank"&gt;uv&lt;/a&gt;.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:243-1"&gt;
&lt;p&gt;I'm not a hardware nerd, so don't dive deep into this stuff. Despite
what I said about the M2 Pro Mini still being there for heavy coding and
video editing, it wouldn't surprise me to find out the Air is more than
capable too.&amp;#160;&lt;a class="footnote-backref" href="#fnref:243-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/27/macbook-air-m5.html</guid>
      <category>Tech</category>
      <category>Apple</category>
      <category>Mac</category>
      <category>MacBook</category>
      <category>MacBook Air</category>
      <category>hardware</category>
      <category>macOS</category>
      <pubDate>Fri, 27 Mar 2026 14:12:21 +0000</pubDate>
    </item>
    <item>
      <title>Astral and OpenAI</title>
      <link>https://blog.davep.org/2026/03/21/astral-and-openai.html</link>
      <description>&lt;p&gt;It's a couple of days now since &lt;a href="https://openai.com/index/openai-to-acquire-astral/" rel="noopener noreferrer" target="_blank"&gt;the news hit that OpenAI are in the process
of purchasing Astral&lt;/a&gt;.
When I first saw this my initial reaction was pretty much "woah", followed
by getting on with what I was doing.&lt;/p&gt;
&lt;p&gt;Until, that is, I opened up the socials. On Mastodon, Reddit, Bluesky,
Threads, etc... anywhere I followed any Python-based content, I was seeing
very firm opinions posted. Plenty of folk either talking like it was the end
of their tooling as they know it, or proudly boasting that they'd avoided
&lt;code&gt;uv&lt;/code&gt; and &lt;code&gt;ruff&lt;/code&gt; (and lately &lt;code&gt;ty&lt;/code&gt; too I guess -- not that I've really tried
that yet myself) because they'd predicted this evil outcome from the start
and they were untainted by this but look at all you idiots who fell for this
long play!&lt;/p&gt;
&lt;p&gt;Okay, I exaggerate slightly, but there were some pretty strong opinions
kicking around, especially in the (often fairly smug) &lt;em&gt;"I stayed pure and
never used &lt;code&gt;uv&lt;/code&gt;"&lt;/em&gt; camp.&lt;/p&gt;
&lt;p&gt;Personally, I don't get it. The last I looked the tools I use that Astral
are behind are FOSS. Also, the last I looked, plenty of FOSS tooling is
written by folk who are either paid to do so (&lt;a href="https://blog.davep.org/2024/03/28/goodbye-textualize.html"&gt;I had my
moment&lt;/a&gt;), given some time in the day
job to work on those tools, or just plain have a day job and &lt;em&gt;also&lt;/em&gt; work on
those tools. If, as plenty are speculating, the Astral purchase is an
acqui-hire, the likely result is going to be one of those three scenarios.&lt;/p&gt;
&lt;p&gt;If it isn't one of those scenarios, if work on &lt;code&gt;uv&lt;/code&gt; and friends just ceases,
well, at best some smart folk can fork the tools that are useful and keep
them going (this is a major benefit of FOSS after all) and, at worst,
well... we can fork them and agent the shit out of them. Right?&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2026/03/21/astral-and-openai.html</guid>
      <category>Tech</category>
      <category>Python</category>
      <category>uv</category>
      <category>Astral</category>
      <category>FOSS</category>
      <pubDate>Sat, 21 Mar 2026 08:11:53 +0000</pubDate>
    </item>
    <item>
      <title>macOS desktop widget switching</title>
      <link>https://blog.davep.org/2024/04/17/macos-desktop-widget-switching.html</link>
      <description>&lt;p&gt;When &lt;a href="https://support.apple.com/en-gb/108996" rel="noopener noreferrer" target="_blank"&gt;desktop widgets&lt;/a&gt; first turned
up in macOS I was pretty quick to embrace them. On my personal Mac Mini I
use a pair of screens, the right one mostly given over to Emacs, and there
was generally room to space there. These days that screen generally looks
something like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="The usual layout of my right screen" height="1440" loading="lazy" src="https://blog.davep.org/attachments/2024/04/17/right-screen.webp#centre" width="2561" /&gt;&lt;/p&gt;
&lt;p&gt;Recently I've got into &lt;a href="https://www.youtube.com/@davep-codes/streams" rel="noopener noreferrer" target="_blank"&gt;streaming while I do some
coding&lt;/a&gt; and it's the
right-hand screen that I work on and capture using OBS. When I was setting
this up I realised that the widgets being there could be a problem; not
because they could distract or anything, more that they could, at times,
contain sensitive information (there's my reminder list and my calendar
there after all).&lt;/p&gt;
&lt;p&gt;What I needed was a quick method of hiding all the widgets, and showing them
again later, without it being a lot of faff.&lt;/p&gt;
&lt;p&gt;With a little bit of digging around on the net I finally came up with a pair
of &lt;code&gt;fish&lt;/code&gt; abbreviations that do just the job!&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;abbr -g widoff "defaults write com.apple.WindowManager StandardHideWidgets -int 1"
abbr -g widon "defaults write com.apple.WindowManager StandardHideWidgets -int 0"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, when I'm going to stream, part of my "getting stuff ready to go live"
checklist is to run &lt;code&gt;widoff&lt;/code&gt; in the terminal; once I'm finished I can then
just run &lt;code&gt;widon&lt;/code&gt; again to have them come back.&lt;/p&gt;
&lt;p&gt;Fast, clean, handy.&lt;/p&gt;
&lt;p&gt;I've also got a pair for when I'm using &lt;a href="https://support.apple.com/en-gb/guide/mac-help/mchl534ba392/mac" rel="noopener noreferrer" target="_blank"&gt;Stage
Manager&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight" data-lang="text"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;abbr -g smwidoff "defaults write com.apple.WindowManager StageManagerHideWidgets -int 1"
abbr -g smwidon "defaults write com.apple.WindowManager StageManagerHideWidgets -int 0"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Although, really, I can't remember the last time I used Stage Manager. I
dabbled with it for a wee while, found it vaguely handy in a couple of
situations, but it doesn't seem to have stuck as part of my workflow or work
environment.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2024/04/17/macos-desktop-widget-switching.html</guid>
      <category>Tech</category>
      <category>macOS</category>
      <category>fish</category>
      <category>shell</category>
      <category>streaming</category>
      <pubDate>Wed, 17 Apr 2024 09:26:00 +0100</pubDate>
    </item>
    <item>
      <title>When it doesn't just work</title>
      <link>https://blog.davep.org/2023/12/08/when-it-does-not-just-work.html</link>
      <description>&lt;p&gt;My journey into the &lt;a href="https://blog.davep.org/tag/apple/"&gt;Apple&lt;/a&gt; ecosystem has been gradual but
all-consuming. I've gone from, &lt;a href="https://blog.davep.org/2015/06/27/my-first-couple-of-weeks-with-an-imac.html"&gt;around 8 years
ago&lt;/a&gt;, being
unconvinced about how good the whole Apple world is, to pretty much having
all the hardware they make available, in some form, that I have an actual
use for&lt;sup id="fnref:78-1"&gt;&lt;a class="footnote-ref" href="#fn:78-1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;One of the devices I was late to, but won over by, after moving away from
&lt;a href="https://blog.davep.org/tag/android/"&gt;Android&lt;/a&gt; to &lt;a href="https://blog.davep.org/tag/iphone/"&gt;iPhone&lt;/a&gt;, was the &lt;a href="https://blog.davep.org/tag/watch/"&gt;Apple
Watch&lt;/a&gt;. These days I have two: the original SE, and also a
Series 8. Generally I've marvelled at just how seamless the experience is. I
swap watches: the connection to my phone "just works" and it figures all
that out. Stuff syncs. Stuff stays in sync.&lt;/p&gt;
&lt;p&gt;I lean heavily on the watch. The Series 8 is my daily driver, and the SE
acts as my nighttime tracking device while the 8 charges and I sleep.&lt;/p&gt;
&lt;p&gt;I record walks. I record runs. I record lots of heart rate data. I pay for
things, pretty much everything, with it. I... take it for granted really.&lt;/p&gt;
&lt;p&gt;&lt;img alt="My main watch face" height="484" loading="lazy" src="https://blog.davep.org/attachments/2023/12/08/watch-face.webp#centre" width="396" /&gt;&lt;/p&gt;
&lt;p&gt;Yesterday though, something odd started to happen. I noticed that some
things didn't seem to be syncing from my watch to the phone. Health-related
things weren't turning up. A recorded workout didn't show. The control of
all things audio seemed to decouple and the watch kept taking over use of my
AirPods from the phone in an annoying way I'd never experienced before.
Things like that.&lt;/p&gt;
&lt;p&gt;I tried a reboot of the watch. Stuff turned up.&lt;/p&gt;
&lt;p&gt;It happened again. I tried a reboot of the phone. Stuff turned up.&lt;/p&gt;
&lt;p&gt;It happened again.&lt;/p&gt;
&lt;p&gt;I then rebooted watch and phone, stuff seemed fine, and I didn't think much
more about it.&lt;/p&gt;
&lt;p&gt;Then this morning I swapped from the SE back to the Series 8 as I sat down
for breakfast, my usual routine, and the syncing was failing &lt;em&gt;again&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;This, for me, this is when Apple stuff gets really frustrating. There's no
easy or obvious way to diagnose what's going on. Like: I could not sync some
health data from the watch to the phone, but I &lt;em&gt;could&lt;/em&gt; use "Find My" to ping
the watch (presumably a difference in communication route, BT vs Wi-Fi
perhaps). There's no obvious error dialog. There's no obvious log to look
at. There's no "your BT is borked" alert or something.&lt;/p&gt;
&lt;p&gt;Searching online the advice seemed to be the nuclear option: unpair the
watch, reset it, start again. So I've done that this morning and it's been
quite the pain. Getting it set up again was straightforward enough, but
having to go through the whole thing of dismissing all the &lt;em&gt;"here's some
tips on how to use this watch you've had for a year and used every day"&lt;/em&gt;
cards was annoying, also having to set up my payment cards again was
annoying. Also, and this is on me for not backing them up recently, trying
to recreate my watch faces from memory and remembering which ones they were
based on was also annoying.&lt;/p&gt;
&lt;p&gt;Apple are actually so good at a lot of this seamless shit; but damn do I
wish they'd also be good at making a tool that lets you easily and smoothly
diagnose some issues. I would imagine sync issues between watch and phone
are common enough that a wee tool where you run through diagnostics, and
where there's a Q&amp;amp;A to help narrow down the issue, would be a great
experience.&lt;/p&gt;
&lt;p&gt;Anyway... it seems to be up and running again, so hopefully that's that
issue solved. I tried a couple of things that would need to sync from the
watch to the phone and they showed up instantly; actually faster than I've
been used to for quite a while.&lt;/p&gt;
&lt;p&gt;Fingers crossed...&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:78-1"&gt;
&lt;p&gt;During a conversation about this at work the other week, I think I
figured out that the only Apple product category in which I don't own an
example of the hardware is displays&lt;sup id="fnref:78-2"&gt;&lt;a class="footnote-ref" href="#fn:78-2"&gt;2&lt;/a&gt;&lt;/sup&gt;. :-/&amp;#160;&lt;a class="footnote-backref" href="#fnref:78-1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:78-2"&gt;
&lt;p&gt;When the VisionPro comes out I'll be able to say there's two.&amp;#160;&lt;a class="footnote-backref" href="#fnref:78-2" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2023/12/08/when-it-does-not-just-work.html</guid>
      <category>Tech</category>
      <category>Apple</category>
      <category>watch</category>
      <pubDate>Fri, 08 Dec 2023 10:32:00 +0100</pubDate>
    </item>
    <item>
      <title>Constant Siri voice loss</title>
      <link>https://blog.davep.org/2023/10/20/constant-siri-voice-loss.html</link>
      <description>&lt;p&gt;This seems to have started with iOS 17, and I can't narrow down the how and
the when of it happening, but over the last week or so I've found that every
couple of days Siri seems to lose their voice. By this I mean the high
quality voice that's used when they speak seems to disappear. I notice this
when I ask my phone or headphones a question or to do something, and I get a
really low-quality voice that speaks back to me.&lt;/p&gt;
&lt;p&gt;The voice itself seems to be a version of the voice I normally use, but like
it's using an on-device much-cut-down version. If I go into the settings to
check what voice is selected, it's the one I normally use, but it wants to
download it again.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Downloading the voice all over again" height="1110" loading="lazy" src="https://blog.davep.org/attachments/2023/10/20/siri-voice-loss.webp#centre" width="512" /&gt;&lt;/p&gt;
&lt;p&gt;Sure enough, once the download is complete all is good again. I've not kept
track of when it happens -- and I think I should from now on -- but it feels
like it happens every couple of days; I almost always notice it first thing
in the morning, the first time I ask the phone or the headphones something.&lt;/p&gt;
&lt;p&gt;I hope it is some sort of iOS 17 weirdness and is gone when 17.1 turns up.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2023/10/20/constant-siri-voice-loss.html</guid>
      <category>Tech</category>
      <category>Apple</category>
      <category>iPhone</category>
      <category>Siri</category>
      <pubDate>Fri, 20 Oct 2023 13:04:00 +0100</pubDate>
    </item>
    <item>
      <title>LinkedIn is useless</title>
      <link>https://blog.davep.org/2023/10/16/linkedin-is-useless.html</link>
      <description>&lt;p&gt;I have a LinkedIn profile more by accident than on purpose. For most of that
site's early days I just ignored it, even needing to go to the trouble of
aggressively marking emails from it as spam as it seemed to want to turn
itself into some sort of online networking cult, encouraging folk to send
invites to their contacts, &lt;a href="https://en.wikipedia.org/wiki/LinkedIn#Use_of_e-mail_accounts_of_members_for_spam_sending" rel="noopener noreferrer" target="_blank"&gt;or
worse&lt;/a&gt;.
But after job-seeking in late 2017 the recruiter who found me the position I
took up asked if I might join up and endorse him or some such nonsense and,
at the time, I thought what the hell.&lt;/p&gt;
&lt;p&gt;Since then though I've mostly found it useless, and at times straight up
horrific. Don't even get me started on how a previous employer's push to
make everyone use their profiles as more company branding created a perfect
pool for people to go phishing in, while at the same time IT were on a
phishing-awareness push; a perfect illustration of how some people lose
their minds when it comes to that site.&lt;/p&gt;
&lt;p&gt;The last year though, while working in a more FOSSy world, I've started to
dip my toe back in when it comes to linking to what we're building with
Textual. As such, I drop into the app once or twice a week and look to see
what other folk might be talking about too.&lt;/p&gt;
&lt;p&gt;During a recent dip in I saw this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="A suggestion from LinkedIn" height="439" loading="lazy" src="https://blog.davep.org/attachments/2023/10/16/linkedin-suggestion.webp#centre" width="991" /&gt;&lt;/p&gt;
&lt;p&gt;Huh! Okay! That... that's actually kind of sensible! While I'm nowhere near
looking for anything else to do, showing off the public projects you care
about seems like a good idea. GitHub repos can be a good CV, I believe.&lt;/p&gt;
&lt;p&gt;So I click through...&lt;/p&gt;
&lt;p&gt;&lt;img alt="The project add form" height="2072" loading="lazy" src="https://blog.davep.org/attachments/2023/10/16/linkedin-add.webp#centre" width="1466" /&gt;&lt;/p&gt;
&lt;p&gt;And that's where it all falls apart. Pretty typical for LinkedIn I'd say.
Name, description, obsession with skills, obsession with building up a
social graph. But...&lt;/p&gt;
&lt;p&gt;No link to the repo.&lt;/p&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;Link.&lt;/p&gt;
&lt;p&gt;To.&lt;/p&gt;
&lt;p&gt;The.&lt;/p&gt;
&lt;p&gt;Repo. O_o&lt;/p&gt;
&lt;p&gt;o_O&lt;/p&gt;
&lt;p&gt;I can't even.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2023/10/16/linkedin-is-useless.html</guid>
      <category>Tech</category>
      <category>LinkedIn</category>
      <pubDate>Mon, 16 Oct 2023 14:16:00 +0100</pubDate>
    </item>
    <item>
      <title>Going full Apple search</title>
      <link>https://blog.davep.org/2023/10/14/going-full-apple-search.html</link>
      <description>&lt;p&gt;For as long as I've had a smartphone -- so ever since the &lt;a href="https://en.wikipedia.org/wiki/HTC_Magic" rel="noopener noreferrer" target="_blank"&gt;HTC
Magic&lt;/a&gt; was released -- I've used
whatever search tool Google have had available as my way of searching for
stuff from my phone. Even when I made the switch to the iPhone, back when
the iPhone 11 was around, I still installed and used the Google Search app.&lt;/p&gt;
&lt;p&gt;Since jumping ship from Android to iPhone, I've followed the usual track
that some do of "embracing the ecosystem", and it generally has paid off.
The more I lean into "the Apple way", the more stuff actually does work
together and work together well (I won't say "it just works", because that
can sometimes so &lt;em&gt;very&lt;/em&gt; not be true, but really I do find that Apple's
ecosystem is more coherent and more stable than the one Google provided).
But searching for stuff... that stuck with the Google search app.&lt;/p&gt;
&lt;p&gt;So, more as an experiment than anything else, starting this morning I've
removed the Google search app from the home screens of my iPhone and my iPad
and I'm going to force myself to use Spotlight to do all my searching, and
see how I get on with it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Searching with Apple" height="512" loading="lazy" src="https://blog.davep.org/attachments/2023/10/14/apple-search.webp#centre" width="236" /&gt;&lt;/p&gt;
&lt;p&gt;Of course, when it comes to searching for stuff on the web, it's not going
to make a whole heap of difference; it's still going to end up searching
with Google, but I do like the idea of search leaning into what Spotlight
knows about my stuff too.&lt;/p&gt;
&lt;p&gt;Also, on my phone at least, it has the added benefit of freeing up a slot in
the dock at the bottom of the home screen.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2023/10/14/going-full-apple-search.html</guid>
      <category>Tech</category>
      <category>Apple</category>
      <pubDate>Sat, 14 Oct 2023 08:39:00 +0100</pubDate>
    </item>
    <item>
      <title>Apple Design</title>
      <link>https://blog.davep.org/2023/09/23/apple-design.html</link>
      <description>&lt;p&gt;As someone who started out in the Android ecosystem when it came to smart
phones -- starting out with a &lt;a href="https://en.wikipedia.org/wiki/HTC_Magic" rel="noopener noreferrer" target="_blank"&gt;HTC
Magic&lt;/a&gt; and going through a few
different phones before settling on Pixels (until I finally jumped ship to
iOS in 2020) -- I have to admit that there's always been something nice
about the design of iPhones. iOS, less so... My first exposure to iOS was
&lt;a href="https://blog.davep.org/2015/06/23/and-now-for-some-ios.html"&gt;back in 2015 when I got an iPod&lt;/a&gt;,
and I wasn't terribly impressed. It looked okay, but it felt so far behind
Android in terms of functionality.&lt;/p&gt;
&lt;p&gt;Much has changed and improved since then. These days, 3 years into being
totally consumed by the Apple ecosystem (one day I should write a post about
how comprehensively I've moved over), I'm won over and I like how iOS works
now.&lt;/p&gt;
&lt;p&gt;Except this...&lt;/p&gt;
&lt;p&gt;&lt;img alt="Bad design" height="78" loading="lazy" src="https://blog.davep.org/attachments/2023/09/23/top-bad.webp#centre" width="512" /&gt;&lt;/p&gt;
&lt;p&gt;That thing where, when you're in one app, it will show the most useless link
"back" to another app, and in doing so bump the time up and out of the way a
little. Like, seriously, compare it to when the app link thing isn't there:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Good design" height="78" loading="lazy" src="https://blog.davep.org/attachments/2023/09/23/top-good.webp#centre" width="512" /&gt;&lt;/p&gt;
&lt;p&gt;Once you see it, you can't unsee it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Toggle of the two images" loading="lazy" src="https://blog.davep.org/attachments/2023/09/23/bad-good-toggle.gif#centre" /&gt;&lt;/p&gt;
&lt;p&gt;After all this time you'd think they would have found a less janky way of
doing this; perhaps even simply removed it (I can't remember the last time I
needed or wanted the ability to go "back" an app like this, especially not
with the bottom-of-screen swipe gesture being a thing). If nothing else
you'd think that, by now, they'd have found a way of doing it that doesn't
look so terrible.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;"eh, let's just shove it here"&lt;/em&gt; approach that seems to be on display
here almost reminds me of &lt;a href="https://blog.davep.org/2015/10/07/imac-time-wiggle.html"&gt;the "time wiggle" that used to mildly annoy me
back on my iMac&lt;/a&gt;.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2023/09/23/apple-design.html</guid>
      <category>Tech</category>
      <category>Apple</category>
      <category>iOS</category>
      <category>iPhone</category>
      <category>design</category>
      <pubDate>Sat, 23 Sep 2023 08:10:00 +0100</pubDate>
    </item>
    <item>
      <title>The HomePod fixed itself</title>
      <link>https://blog.davep.org/2023/08/12/the-homepod-fixed-itself.html</link>
      <description>&lt;p&gt;&lt;a href="https://blog.davep.org/2023/07/29/home-pod-stuck-installing.html#home-pod-stuck-installing"&gt;A couple of weeks
back&lt;/a&gt;
I mentioned home my main HomePod had got stuck installing 16.6 of the
software that runs it. This situation persisted for days after writing that
post and I kept promising myself that I was going to see if I could unstick
it by removing it from the Home, doing a factory reset and adding it back
again.&lt;/p&gt;
&lt;p&gt;Of course, during the week that followed, I never got round to that. You can
imagine what it's like: no time in the morning, and by the time I get home
in the evening I want to watch TV and use the HomePod as the speaker for the
Apple TV, I don't want to be doing tech support shit.&lt;/p&gt;
&lt;p&gt;The following weekend... yeah, I kinda forgot.&lt;/p&gt;
&lt;p&gt;So, here I am, a couple of Saturdays on, it's early morning, I've had
breakfast and I'm having coffee and I think it's the perfect time to do
this. I hope the Home app my on iPad and... it's sorted!&lt;/p&gt;
&lt;p&gt;&lt;img alt="HomePod all good again" height="733" loading="lazy" src="https://blog.davep.org/attachments/2023/08/12/fixed-homepod.webp#centre" width="512" /&gt;&lt;/p&gt;
&lt;p&gt;So, yeah, it looks like it somehow managed to unstick itself in the end. A
quick test of some of the issues I was seeing suggested there was still an
issue, for example asking for the temperature in the bedroom would still
result in a &lt;em&gt;"working on it"&lt;/em&gt; reply followed by it telling me it wasn't
responding. A quick reset seems to have fixed that.&lt;/p&gt;
&lt;p&gt;I guess it's good to know: if it happens again, it'll keep on working as the
speaker for my Apple TV, and it'll eventually sort itself out even if I
don't muck about with a hard reset.&lt;/p&gt;</description>
      <guid isPermaLink="false">https://blog.davep.org/2023/08/12/the-homepod-fixed-itself.html</guid>
      <category>Tech</category>
      <category>Apple</category>
      <pubDate>Sat, 12 Aug 2023 07:46:00 +0100</pubDate>
    </item>
  </channel>
</rss>
