<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feeds.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://chameth.com/">
    <title>Chameth.com - posts like escaping-spotify-the-hard-way but not g15-ram-upgrade, reverse-engineering-arctis-pro-wireless-headset, why-you-should-be-using-https</title>
    <subtitle>Personal homepage of Chris Smith</subtitle>
    <link href="https://chameth.com/feeds/posts/like/escaping-spotify-the-hard-way/unlike/g15-ram-upgrade,reverse-engineering-arctis-pro-wireless-headset,why-you-should-be-using-https/" rel="self"/>
    <link href="https://chameth.com/"/>
    <icon>https://chameth.com/favicon.png</icon>
    <updated>2026-09-01T00:00:00Z</updated>
    <id>https://chameth.com/</id>
    <author>
        <name>Chris Smith</name>
    </author>
    <entry>
        <title>Monthly Meanderings: August 2026</title>
        <link href="https://chameth.com/monthly-meanderings-2026-08/"/>
        <updated>2026-09-01T00:00:00Z</updated>
        <id>https://chameth.com/monthly-meanderings-2026-08/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Another month, another edition of “What’s Chris been up to?”. Fun fact: I very nearly published this post with a “[intro]” placeholder here instead of this
paragraph, despite proofreading it multiple times. “Yep, that’s where the intro will go, all good”. Now instead we have this weirdly meta introduction.&lt;/p&gt;
&lt;h3 id=&#34;website-updates-and-other-projects&#34;&gt;Website updates and other projects&lt;/h3&gt;
&lt;p&gt;A few website updates this month, and one of them neatly addresses the “other projects” bit too. First, I’ve added a new &lt;a href=&#34;https://chameth.com/fitness/&#34;&gt;fitness page&lt;/a&gt; which has some stats
and information about my cycling and running. I’ve also added some fitness-related widgets to support that page and these monthly summaries, and a new music one you can
see a bit further down.&lt;/p&gt;
&lt;p&gt;I’ve also added what I think is quite a fun new feature: a &lt;a href=&#34;https://chameth.com/feeds/posts/build/&#34;&gt;post feed builder&lt;/a&gt; that lets you build RSS feeds containing
only posts that are semantically similar (or dissimilar) to other posts. So if you want to only hear about my fitness journey you can pin a few of those
posts, or if you want to exclude posts that talk about LLMs you can exclude a few of those. It’s basically super-charged fuzzy tags, but it means I don’t
have to actually tag things.&lt;/p&gt;
&lt;p&gt;I blogged about &lt;a href=&#34;https://chameth.com/building-a-family-of-single-user-services/&#34;&gt;building a family of single-user services&lt;/a&gt; which is where most of my coding
energy went this month. Those projects were almost entirely authored by LLMs, and I’m not hating the process. The models have got a lot better at coding,
and I enjoyed getting to focus on the bigger picture aspects rather than getting bogged down in details.
Rest assured, all the writing on my website is still 100% me. I am the load-bearing seam, here.&lt;/p&gt;
&lt;h3 id=&#34;entertainment&#34;&gt;Entertainment&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://chameth.com/monthly-meanderings-2026-03/&#34;&gt;Back in March&lt;/a&gt; I said ‘I can’t do “what I listened to last month” stats until next month’, and then for the next four months completely forgot about it.
Well, not any more! Now I come equipped with some stats about my monthly music habits:&lt;/p&gt;
&lt;div class=&#34;played-albums raised-box&#34; data-title=&#34;Top albums · 1 Aug – 31 Aug 2026&#34;&gt;
    &lt;table class=&#34;plain-table&#34;&gt;
        &lt;thead&gt;
        &lt;tr&gt;
            &lt;th scope=&#34;col&#34;&gt;&lt;/th&gt;
            &lt;th scope=&#34;col&#34;&gt;&lt;/th&gt;
            &lt;th scope=&#34;col&#34;&gt;&lt;/th&gt;
            &lt;th scope=&#34;col&#34;&gt;Album&lt;/th&gt;
            &lt;th scope=&#34;col&#34;&gt;Artist&lt;/th&gt;
            &lt;th scope=&#34;col&#34; class=&#34;numeric&#34;&gt;Unique tracks played&lt;/th&gt;
            &lt;th scope=&#34;col&#34; class=&#34;numeric&#34;&gt;Total tracks played&lt;/th&gt;
        &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;1&lt;/td&gt;
            &lt;td class=&#34;movement movement-up&#34; title=&#34;Up from #4&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-up&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 11l-6 -6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 11l6 -6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/190/cover.jpg&#34; alt=&#34;Cover art for Fallen&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;Fallen&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;Evanescence&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;8&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;40&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;2&lt;/td&gt;
            &lt;td class=&#34;movement movement-up&#34; title=&#34;Up from #5&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-up&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 11l-6 -6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 11l6 -6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/341/cover.jpg&#34; alt=&#34;Cover art for Love, Drugs &amp;amp; Misery&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;Love, Drugs &amp;amp; Misery&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;Eva Under Fire&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;12&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;32&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;3&lt;/td&gt;
            &lt;td class=&#34;movement movement-up&#34; title=&#34;Up from #10&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-up&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 11l-6 -6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 11l6 -6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/378/cover.jpg&#34; alt=&#34;Cover art for NEON VOID&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;NEON VOID&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;Sumo Cyco&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;6&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;23&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;4&lt;/td&gt;
            &lt;td class=&#34;movement movement-down&#34; title=&#34;Down from #1&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-down&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 13l-6 6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 13l6 6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/522/cover.jpg&#34; alt=&#34;Cover art for The Strange Case of…&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;The Strange Case of…&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;Halestorm&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;11&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;21&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;5&lt;/td&gt;
            &lt;td class=&#34;movement movement-up&#34; title=&#34;Up from #7&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-up&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 11l-6 -6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 11l6 -6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/120/cover.jpg&#34; alt=&#34;Cover art for Coming in Hot&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;Coming in Hot&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;DIAMANTE&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;9&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;20&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;6&lt;/td&gt;
            &lt;td class=&#34;movement movement-up&#34; title=&#34;Up from #8&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-up&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 11l-6 -6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 11l6 -6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/180/cover.jpg&#34; alt=&#34;Cover art for Everest&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;Everest&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;Halestorm&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;7&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;20&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;7&lt;/td&gt;
            &lt;td class=&#34;movement movement-up&#34; title=&#34;Up from #126&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-up&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 11l-6 -6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 11l6 -6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/227/cover.jpg&#34; alt=&#34;Cover art for Glory Days&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;Glory Days&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;Little Mix&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;5&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;20&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;8&lt;/td&gt;
            &lt;td class=&#34;movement movement-down&#34; title=&#34;Down from #3&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-down&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 13l-6 6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 13l6 6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/212/cover.jpg&#34; alt=&#34;Cover art for From Zero&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;From Zero&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;Linkin Park&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;9&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;19&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;9&lt;/td&gt;
            &lt;td class=&#34;movement movement-up&#34; title=&#34;Up from #78&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-up&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 11l-6 -6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 11l6 -6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/310/cover.jpg&#34; alt=&#34;Cover art for KPop Demon Hunters (Soundtrack from the Netflix Film)&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;KPop Demon Hunters (Soundtrack from the Netflix Film)&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;KPop Demon Hunters Cast&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;7&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;19&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td class=&#34;position&#34;&gt;10&lt;/td&gt;
            &lt;td class=&#34;movement movement-up&#34; title=&#34;Up from #430&#34;&gt;
                &lt;svg xmlns=&#34;http://www.w3.org/2000/svg&#34; width=&#34;16&#34; height=&#34;16&#34; viewBox=&#34;0 0 24 24&#34; fill=&#34;none&#34; stroke=&#34;currentColor&#34; stroke-width=&#34;2&#34; stroke-linecap=&#34;round&#34; stroke-linejoin=&#34;round&#34; class=&#34;icon icon-tabler icons-tabler-outline icon-tabler-arrow-up&#34; aria-hidden=&#34;true&#34;&gt;&lt;path stroke=&#34;none&#34; d=&#34;M0 0h24v24H0z&#34; fill=&#34;none&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M12 5l0 14&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M18 11l-6 -6&#34;&gt;&lt;/path&gt;&lt;path d=&#34;M6 11l6 -6&#34;&gt;&lt;/path&gt;&lt;/svg&gt;
            &lt;/td&gt;
            &lt;td class=&#34;art&#34;&gt;
                &lt;img src=&#34;https://chameth.com/music/albums/387/cover.jpg&#34; alt=&#34;Cover art for No Need to Argue&#34; loading=&#34;lazy&#34;/&gt;
            &lt;/td&gt;
            &lt;td&gt;No Need to Argue&lt;/td&gt;
            &lt;td class=&#34;artist&#34;&gt;The Cranberries&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;6&lt;/td&gt;
            &lt;td class=&#34;numeric&#34;&gt;19&lt;/td&gt;
        &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;I suspect I won’t show this every month, as it’s probably going to be quite same-y. I, shockingly, tend to play music that I like more than that which I don’t.
I’ll usually either put on my “favourites” playlist, or my “daily mix” playlist which biases higher-rated tracks over lower ones. So effectively this just
becomes a noisy view over how highly I’ve rated the tracks in an album. Maybe I can control for that, but then I’m not sure what it’d actually be showing…
“Here are all the albums I played this month that I don’t usually play because I don’t like them as much as the other albums I’m not showing any more”?
It’s a bit wordy. Back to the drawing board with that idea, I think.&lt;/p&gt;
&lt;p&gt;I was away for a few weeks this month, including a few days at a small LAN event. Being at a computer gaming event meant that we, naturally, played some board games.
Apparently I hit an h-index of 23 from these plays. That’s 23 games I’ve played at least 23 times each. I’ve been at 22 since December last year: obviously
the higher the number goes, the harder it is to reach. I also go on and off games (and the whole hobby at times), which doesn’t help on that front. Anyway, here’s
&lt;del&gt;Wonderwall&lt;/del&gt; the plays for this month:&lt;/p&gt;
&lt;ul class=&#34;played-boardgames&#34;&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Codenames (2015)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/178900/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/178900/image.jpg&#34; alt=&#34;Box art of Codenames&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;6 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Just One (2018)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/254640/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/254640/image.jpg&#34; alt=&#34;Box art of Just One&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;3 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Martian Fluxx (2009)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/35369/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/35369/image.jpg&#34; alt=&#34;Box art of Martian Fluxx&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;3 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Arkham Horror: Lovecraft Letter (2025)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/424784/image.png&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/424784/image.png&#34; alt=&#34;Box art of Arkham Horror: Lovecraft Letter&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;1 play&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Take 5 (1994)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/432/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/432/image.jpg&#34; alt=&#34;Box art of Take 5&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;1 play&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No films this month, but my &lt;a href=&#34;https://chameth.com/wow/&#34;&gt;World of Warcraft&lt;/a&gt; habit has picked back up with the launch of the new season. They’ve made Mistweaver Monk, my previous specialisation, a
lot less fun to play, so I’m focusing on one of my many alts: a Restoration Shaman:&lt;/p&gt;
&lt;div class=&#34;wow-char-grid&#34;&gt;
&lt;div class=&#34;wow-char raised-box&#34; data-title=&#34;World of Warcraft Character Data&#34;&gt;
&lt;div class=&#34;overview&#34;&gt;
&lt;img src=&#34;https://chameth.com/wow/characters/Hirameth.png&#34; alt=&#34;Hirameth&#34; loading=&#34;lazy&#34;/&gt;
&lt;p class=&#34;detail&#34;&gt;Level 90&lt;/p&gt;
&lt;p class=&#34;detail&#34;&gt;Female Dwarf&lt;/p&gt;
&lt;p class=&#34;detail&#34;&gt;&lt;span class=&#34;wow-class-shaman&#34;&gt;Restoration Shaman&lt;/span&gt;&lt;/p&gt;
&lt;p class=&#34;detail&#34;&gt;309 average item level&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;info&#34;&gt;
&lt;h3 class=&#34;plain-header&#34;&gt;Hirameth&lt;span class=&#34;realm&#34;&gt;-Terenas&lt;/span&gt;&lt;/h3&gt;
&lt;h4 class=&#34;plain-header&#34;&gt;Professions&lt;/h4&gt;
&lt;table class=&#34;plain-table professions&#34;&gt;
&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Midnight Blacksmithing&lt;/td&gt;&lt;td&gt;&lt;progress class=&#34;tier-progress&#34; value=&#34;41&#34; max=&#34;100&#34;&gt;&lt;/progress&gt;&lt;/td&gt;&lt;td class=&#34;tier-count&#34;&gt;41/100&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Midnight Inscription&lt;/td&gt;&lt;td&gt;&lt;progress class=&#34;tier-progress&#34; value=&#34;72&#34; max=&#34;100&#34;&gt;&lt;/progress&gt;&lt;/td&gt;&lt;td class=&#34;tier-count&#34;&gt;72/100&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Midnight Fishing&lt;/td&gt;&lt;td&gt;&lt;progress class=&#34;tier-progress&#34; value=&#34;35&#34; max=&#34;300&#34;&gt;&lt;/progress&gt;&lt;/td&gt;&lt;td class=&#34;tier-count&#34;&gt;35/300&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h4 class=&#34;plain-header&#34;&gt;Mythic+&lt;/h4&gt;
&lt;table class=&#34;plain-table mythic-plus&#34;&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Altar of Fangs&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;23:10&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;329&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Den of Nalorakk&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;27:36&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;325&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Kings&amp;#39; Rest&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+12&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;28:57&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;370&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Murder Row&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+12&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;28:37&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;371&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Ruby Life Pools&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+11&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;24:28&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;340&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Temple of Sethraliss&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;30:57&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;321&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;The Blinding Vale&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;24:38&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;327&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Voidscar Arena&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;22:37&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;329&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&#34;total&#34;&gt;
&lt;th colspan=&#34;3&#34; class=&#34;plain-header&#34;&gt;Total M+ rating&lt;/th&gt;
&lt;td class=&#34;rating&#34;&gt;2711&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div class=&#34;links&#34;&gt;
&lt;a href=&#34;https://worldofwarcraft.blizzard.com/en-gb/character/eu/terenas/hirameth&#34;&gt;View on blizzard.com&lt;/a&gt;
&lt;a href=&#34;https://raider.io/characters/eu/terenas/Hirameth&#34;&gt;View on raider.io&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I don’t quite like it as much as Mistweaver in season 1, but it’s a lot nicer than Mistweaver in season 2. You can actually make health bars move when you press your healing buttons, rather than
ignoring half of them because they’re not worth using.&lt;/p&gt;
&lt;h3 id=&#34;fitness&#34;&gt;Fitness&lt;/h3&gt;
&lt;p&gt;My running kick is still going. I’ve “officially” finished the couch-to-5k programme I was doing, and I actually hit 5k on the last day of the programme. I didn’t actually mean to do that:
I was saving the 5k run for this week, but by the time I noticed I’d run “too far” it was close enough that I just kept going. I have an actual 5k race coming up
this month, which is exciting. Once that’s over I’m planning to work my way up to 10k. I’ve added a few widgets to keep track of some stats:&lt;/p&gt;
&lt;div class=&#34;workout-summary-sections&#34;&gt;
&lt;div class=&#34;workout-summary-section raised-box&#34; data-title=&#34;Cycling · 1 Aug – 31 Aug 2026&#34;&gt;
&lt;div class=&#34;stat-row&#34;&gt;
&lt;div class=&#34;stat&#34;&gt;
&lt;p class=&#34;stat-value&#34;&gt;3&lt;/p&gt;
&lt;p class=&#34;stat-label&#34;&gt;activities&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;stat&#34;&gt;
&lt;p class=&#34;stat-value&#34;&gt;6h 5m&lt;/p&gt;
&lt;p class=&#34;stat-label&#34;&gt;total time&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;stat&#34;&gt;
&lt;p class=&#34;stat-value&#34;&gt;103.6km&lt;/p&gt;
&lt;p class=&#34;stat-label&#34;&gt;total distance&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;stat&#34;&gt;
&lt;p class=&#34;stat-value&#34;&gt;42.3km&lt;/p&gt;
&lt;p class=&#34;stat-label&#34;&gt;longest distance&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul class=&#34;workout-summary-pbs&#34;&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;1km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;2:17&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;1:52&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;2km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;5:34&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;4:13&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;5km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;14:51&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;12:32&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;10km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;36:00&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;27:21&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;20km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;1:43:33&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;1:13:24&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;30km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;no previous&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;1:54:25&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;40km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;no previous&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;2:55:52&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;workout-summary-section raised-box&#34; data-title=&#34;Running · 1 Aug – 31 Aug 2026&#34;&gt;
&lt;div class=&#34;stat-row&#34;&gt;
&lt;div class=&#34;stat&#34;&gt;
&lt;p class=&#34;stat-value&#34;&gt;12&lt;/p&gt;
&lt;p class=&#34;stat-label&#34;&gt;activities&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;stat&#34;&gt;
&lt;p class=&#34;stat-value&#34;&gt;6h 16m&lt;/p&gt;
&lt;p class=&#34;stat-label&#34;&gt;total time&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;stat&#34;&gt;
&lt;p class=&#34;stat-value&#34;&gt;43.1km&lt;/p&gt;
&lt;p class=&#34;stat-label&#34;&gt;total distance&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;stat&#34;&gt;
&lt;p class=&#34;stat-value&#34;&gt;5km&lt;/p&gt;
&lt;p class=&#34;stat-label&#34;&gt;longest distance&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul class=&#34;workout-summary-pbs&#34;&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;800m&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;5:56&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;6:02&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;1km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;7:35&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;7:36&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;1 mile&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;12:28&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;12:16&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;2km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;15:35&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;15:16&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;3km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;24:32&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;23:05&lt;/span&gt;
&lt;/li&gt;
&lt;li class=&#34;workout-summary-pb&#34;&gt;
&lt;span class=&#34;pb-trophy&#34;&gt;🏆️&lt;/span&gt;
&lt;span class=&#34;pb-label&#34;&gt;New PB&lt;/span&gt;
&lt;span class=&#34;pb-distance&#34;&gt;5km&lt;/span&gt;
&lt;span class=&#34;pb-previous&#34;&gt;no previous&lt;/span&gt;
&lt;span class=&#34;pb-time&#34;&gt;38:40&lt;/span&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As well as the running, I did a couple of long (for me) cycle rides, clocking in at around 40 km. It’s a fun loop, but both times I did it I started flagging towards the end. The second time
I made sure to eat and drink plenty along the way, and my legs still raised objections about halfway round. My next goal is 50 km which would let me get to the next town over and back but
the route has a lot more elevation to go with its increased length, so it’s probably going to be quite a bit more taxing. I’m not sure when I’ll attempt that, as the weather is starting to
turn. I was previously bemused when people mentioned “cycling seasons” and switching to indoor trainers. Then I wanted to go out when it was raining, and suddenly I understood. Running in
the rain: surprisingly pleasant; cycling in the rain: no thank you.&lt;/p&gt;
&lt;h3 id=&#34;around-the-web&#34;&gt;Around the web&lt;/h3&gt;
&lt;h4 id=&#34;hacker-news-in-uncompromised-detailhttpsvalerockspostshacker-news&#34;&gt;&lt;a href=&#34;https://vale.rocks/posts/hacker-news&#34;&gt;Hacker News In Uncompromised Detail&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;When I first read the title my gut reaction was “I know everything I need to know about Hacker News, right?”.
The title is accurate though. There’s so much interesting stuff, presented really cleanly. It’s a good read.&lt;/p&gt;
&lt;h4 id=&#34;a-proposal-for-new-netflix-content-rating-iconshttpsericwbaileywebsitepublisheda-proposal-for-new-netflix-content-rating-icons&#34;&gt;&lt;a href=&#34;https://ericwbailey.website/published/a-proposal-for-new-netflix-content-rating-icons/&#34;&gt;A proposal for new Netflix content rating icons&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Another dry sounding title, another fun article. It starts with a treatise on rating systems and
ends with a lovely satirical list of rating ideas.&lt;/p&gt;
&lt;h4 id=&#34;find-git-commits-by-commit-message-texthttpshamvockecombloggit-revisions-by-text&#34;&gt;&lt;a href=&#34;https://hamvocke.com/blog/git-revisions-by-text/&#34;&gt;Find Git commits by commit message text&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;I like to think I’m relatively well versed in how to use Git. I can do an interactive rebase
and everything! This tip from Ham was new to me, though, and is incredibly useful.&lt;/p&gt;
&lt;h4 id=&#34;novice-marathon-training-planhttpswwwhalhigdoncomtraining-programsmarathon-trainingnovice-1-marathon&#34;&gt;&lt;a href=&#34;https://www.halhigdon.com/training-programs/marathon-training/novice-1-marathon/&#34;&gt;Novice Marathon Training Plan&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Hal Higdon has a whole bunch of training plans. He literally wrote the book on marathon training.
I’ll hopefully be following this plan next year, assuming I manage the 5k, 10k and half-marathon training!
This would be the perfect plan for someone who’s run a half marathon a while ago, and is tempted
to join me in my “marathon before I’m 40” goal…&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>Monthly Meanderings: March 2026</title>
        <link href="https://chameth.com/monthly-meanderings-2026-03/"/>
        <updated>2026-04-01T00:00:00Z</updated>
        <id>https://chameth.com/monthly-meanderings-2026-03/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Since &lt;a href=&#34;https://chameth.com/monthly-meanderings-2026-02/&#34;&gt;last month’s update&lt;/a&gt; I’ve been unpleasantly reminded that I’m middle aged, through the medium of a dodgy knee. There’s nothing quite like not being able to stand up without groaning to underscore that you’re not young any more. The ongoing game of “will this seemingly mundane activity make my knee go funny again?” is a &lt;em&gt;delight&lt;/em&gt; to play, too. I’m great at it.&lt;/p&gt;
&lt;h3 id=&#34;website-updates&#34;&gt;Website updates&lt;/h3&gt;
&lt;p&gt;Two new blog posts this month: &lt;a href=&#34;https://chameth.com/the-longest-way-to-represent-a-date/&#34;&gt;the longest way to represent a date&lt;/a&gt; is a short thought experiment on absurd date formats, and &lt;a href=&#34;https://chameth.com/modern-css-is-fun/&#34;&gt;modern CSS is fun&lt;/a&gt; goes through some neat new CSS features I’ve used recently for this site.&lt;/p&gt;
&lt;p&gt;I did some design tweaks this month: headers now have a blue background behind them&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and a lot of components have been redesigned to have a consistent style. You can see that component in action in the new “now playing” widget I’ve added:&lt;/p&gt;
&lt;div class=&#34;now-playing raised-box&#34; data-title=&#34;Now playing&#34;&gt;
    &lt;img src=&#34;https://chameth.com/music/albums/341/cover.jpg&#34; alt=&#34;Love, Drugs &amp;amp; Misery&#34; loading=&#34;lazy&#34;/&gt;
    &lt;div class=&#34;now-playing-info&#34;&gt;
        &lt;span class=&#34;artist-track&#34;&gt;Eva Under Fire — Unstoppable&lt;/span&gt;
        &lt;span class=&#34;album-name&#34;&gt;Love, Drugs &amp;amp; Misery&lt;/span&gt;
        &lt;span class=&#34;play-status&#34;&gt;Scrobbled 0m ago&lt;/span&gt;
    &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Instead of each component defining its own styles (which were &lt;em&gt;mostly&lt;/em&gt; copied and pasted), there’s now a single class that handles the drop shadow, border, background colour, and the optional title. It also applies a consistent format to elements that are clickable: they use the blue accent colour for their borders, and have a glow effect shown on hover.&lt;/p&gt;
&lt;p&gt;The now playing widget is part of a larger bit of work I did on importing some music stats. I’m pulling in the data from my &lt;a href=&#34;https://www.navidrome.org/&#34;&gt;Navidrome&lt;/a&gt; instance. A new &lt;a href=&#34;https://chameth.com/music/&#34;&gt;music page&lt;/a&gt; shows my most listened albums and artists. Navidrome doesn’t store a complete play history, just the last play and the count, so I can’t do “what I listened to last month” stats until next month.&lt;/p&gt;
&lt;h3 id=&#34;other-projects&#34;&gt;Other projects&lt;/h3&gt;
&lt;p&gt;Other than a minor bug-fix update to &lt;a href=&#34;https://github.com/csmith/contempt&#34;&gt;contempt&lt;/a&gt;, my Dockerfile templating/updating tool, I’ve not done much on my other open source projects. I’ve got a bit more work to do finish migrating all my repositories from GitHub to my private &lt;a href=&#34;https://forgejo.org/&#34;&gt;Forgejo&lt;/a&gt; instance. I’ve also been thinking about mirroring my public repositories to &lt;a href=&#34;https://codeberg.org/&#34;&gt;Codeberg&lt;/a&gt; so there’s a non-GitHub way to access them.&lt;/p&gt;
&lt;h3 id=&#34;entertainment&#34;&gt;Entertainment&lt;/h3&gt;
&lt;p&gt;I apparently only watched a single film in March:&lt;/p&gt;
&lt;div class=&#34;film-review-parent&#34;&gt;
  &lt;section class=&#34;film-review raised-box&#34;&gt;
    &lt;img src=&#34;https://chameth.com/films/253/poster.jpg&#34; alt=&#34;Poster for The Substance&#34; loading=&#34;lazy&#34;/&gt;
    &lt;header&gt;
      &lt;h3 class=&#34;plain-header&#34;&gt;&lt;a href=&#34;https://chameth.com/films/the-substance-2024/&#34;&gt;The Substance&lt;/a&gt;&lt;/h3&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div title=&#34;5/10&#34;&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-half.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Half star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
      &lt;time&gt;2026-03-18&lt;/time&gt;
    &lt;/header&gt;
    &lt;div&gt;&lt;p&gt;I really didn’t get on with this. It’s too long for what it is, and over-the-top in a way that just didn’t work for me.&lt;/p&gt;
&lt;p&gt;Demi Moore and Margaret Qualley were great, but nothing else really was. The cinematography and sound design were too affected, the plot was pretty shallow and obvious, most of the body horror fell into the uncanny CGI valley for me.&lt;/p&gt;
&lt;p&gt;It’s not completely without merit: there were around 40 minutes in the middle where I was really into it, but that’s not really enough given it’s closing in on a 2.5 hour runtime.&lt;/p&gt;
&lt;p&gt;There’s something to be said for the message it’s presenting about women in Hollywood, too, but it was very heavy handed. Dennis Quaid’s character is even called Harvey; it’s not so much a subtle nod as a sledgehammer to the face.&lt;/p&gt;
&lt;/div&gt;
  &lt;/section&gt;
&lt;/div&gt;
&lt;p&gt;Instead of films, I’ve been watching a bunch of TV. After devouring &lt;a href=&#34;https://www.themoviedb.org/tv/250307-the-pitt&#34;&gt;The Pitt&lt;/a&gt; last month, I struggled to find something to fill the hole it left. I settled on catching up on &lt;a href=&#34;https://www.themoviedb.org/tv/44006-chicago-fire&#34;&gt;Chicago Fire&lt;/a&gt; and &lt;a href=&#34;https://www.themoviedb.org/tv/58841-chicago-p-d&#34;&gt;Chicago P.D.&lt;/a&gt;. They’re both mostly about getting things done without personal drama becoming the primary focus. They’re not quite as grounded as The Pitt, but at least they’ve not completely gone off the deep end like &lt;a href=&#34;https://www.themoviedb.org/tv/75219-9-1-1&#34;&gt;9-1-1&lt;/a&gt; where the first responders end up in space somehow?&lt;/p&gt;
&lt;p&gt;I’ve also watched the first two episodes of &lt;a href=&#34;https://www.themoviedb.org/tv/288670-saturday-night-live-uk&#34;&gt;SNL UK&lt;/a&gt;. I didn’t have very high expectations, and it gave me a pleasant surprise. Both episodes so far have some hilarious sketches, and are obviously written by British comics with the typical darker, more sardonic humour that separates us from the USA.&lt;/p&gt;
&lt;p&gt;Last but not least, board games! I spent a weekend at a tabletop/LAN event with friends, so got to physically play some games for a change. I also kept up with some turn-based games on &lt;a href=&#34;https://boardgamearena.com/&#34;&gt;Board Game Arena&lt;/a&gt;, as usual.&lt;/p&gt;
&lt;ul class=&#34;played-boardgames&#34;&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Just One (2018)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/254640/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/254640/image.jpg&#34; alt=&#34;Box art of Just One&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;6 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;7 Wonders Dice (2025)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/446231/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/446231/image.jpg&#34; alt=&#34;Box art of 7 Wonders Dice&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;4 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Can&amp;#39;t Stop (1980)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/41/image.png&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/41/image.png&#34; alt=&#34;Box art of Can&amp;#39;t Stop&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;4 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Martian Dice (2011)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/99875/image.png&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/99875/image.png&#34; alt=&#34;Box art of Martian Dice&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;4 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Cartographers (2019)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/263918/image.png&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/263918/image.png&#34; alt=&#34;Box art of Cartographers&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;3 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Coffee Rush (2023)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/377061/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/377061/image.jpg&#34; alt=&#34;Box art of Coffee Rush&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;3 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Super Mega Lucky Box (2021)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/341530/image.png&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/341530/image.png&#34; alt=&#34;Box art of Super Mega Lucky Box&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;3 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Cthulhu Fluxx (2012)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/122159/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/122159/image.jpg&#34; alt=&#34;Box art of Cthulhu Fluxx&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;2 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Obsession (2018)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/231733/image.png&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/231733/image.png&#34; alt=&#34;Box art of Obsession&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;2 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Plant-Based Riot (2022)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/342940/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/342940/image.jpg&#34; alt=&#34;Box art of Plant-Based Riot&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;2 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Space Base (2018)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/242302/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/242302/image.jpg&#34; alt=&#34;Box art of Space Base&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;2 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Terraforming Mars (2016)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/167791/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/167791/image.jpg&#34; alt=&#34;Box art of Terraforming Mars&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;2 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Next Station: Tokyo (2023)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/380165/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/380165/image.jpg&#34; alt=&#34;Box art of Next Station: Tokyo&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;1 play&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;around-the-web&#34;&gt;Around the web&lt;/h3&gt;
&lt;h4 id=&#34;warranty-void-if-regeneratedhttpsnearzerosoftwarepwarranty-void-if-regenerated&#34;&gt;&lt;a href=&#34;https://nearzero.software/p/warranty-void-if-regenerated&#34;&gt;Warranty Void if Regenerated&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Some really cool speculative fiction about a future where all software is written by LLMs, and the social effects that may have. Unfortunately the story itself is written with an LLM, and that becomes painfully obvious about a third of the way in. By that point I was already hooked, though.&lt;/p&gt;
&lt;h4 id=&#34;my-2-step-process-for-ai-free-blogginghttpsmanuelmorealecomthoughtsmy-2-step-process-for-ai-free-blogging&#34;&gt;&lt;a href=&#34;https://manuelmoreale.com/thoughts/my-2-step-process-for-ai-free-blogging&#34;&gt;My 2-step process for AI-free blogging&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Speaking of LLM-generated text, this short piece by Manuel Moreale made me laugh. I’m by no means anti-LLM, but I really hate people publishing the output like it’s their own work. It breaks the social assumption that the writer put more effort in than the reader, and makes me wonder how much is hallucinated.&lt;/p&gt;
&lt;h4 id=&#34;25-years-of-eggshttpswwwjohn-rushcompostseggs-25-years-20260219html&#34;&gt;&lt;a href=&#34;https://www.john-rush.com/posts/eggs-25-years-20260219.html&#34;&gt;25 Years of Eggs&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;An interesting applied use of coding agents. I’m a sucker for personal statistics. I have no explicit desire to keep my receipts, or generate graphs of my egg consumption, but seeing the graphs makes me question that. The journey to get there is a great read, too.&lt;/p&gt;
&lt;h4 id=&#34;i-made-a-one-page-notebookhttpsjoelchronoxyzblogi-made-a-one-page-notebook&#34;&gt;&lt;a href=&#34;https://joelchrono.xyz/blog/i-made-a-one-page-notebook/&#34;&gt;I made a one-page notebook&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The clever paper folding is interesting, but I really like some of the small touches on the page. There’s a nice little “in reply to” callout providing context at the top of the page, you can click to rotate the image further down, and there’s a details element containing a textual version of it. It has that great ‘small web’ vibe of someone who really cares about what they’re doing.&lt;/p&gt;
&lt;h4 id=&#34;workers-who-love-synergizing-paradigms-might-be-bad-at-their-jobshttpsnewscornelledustories202603workers-who-love-synergizing-paradigms-might-be-bad-their-jobs&#34;&gt;&lt;a href=&#34;https://news.cornell.edu/stories/2026/03/workers-who-love-synergizing-paradigms-might-be-bad-their-jobs&#34;&gt;Workers who love ‘synergizing paradigms’ might be bad at their jobs&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;I haven’t read the full paper, but the summary given by the article is equal parts interesting and amusing. They developed a “Corporate Bullshit Receptivity Scale”, what more is there to say?&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;It’s meant to resemble painter’s tape, but I’m not sure quite how well it works. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
    <entry>
        <title>Further Adventures in Music Organisation</title>
        <link href="https://chameth.com/further-adventures-in-music-organisation/"/>
        <updated>2025-09-21T00:00:00Z</updated>
        <id>https://chameth.com/further-adventures-in-music-organisation/</id>
        <content xml:lang="en" type="html">&lt;p&gt;I wrote before about how I’d &lt;a href=&#34;https://chameth.com/escaping-spotify-the-hard-way/&#34;&gt;dropped Spotify in favour of locally stored music&lt;/a&gt;,
but things have advanced a bit since. I had a few issues: Tauon would
occasionally manage to lose its database and along with it all my carefully
constructed playlists and song ratings&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and the experience on my phone was
not very fun.&lt;/p&gt;
&lt;p&gt;I had to manually sync the music by plugging my phone in to the
computer, and sometimes it just refused to mount the right partition. I don’t
think there’s really a good way to debug an Apple phone not behaving properly
when connected to a Linux desktop. Then I started wanting more than one playlist
synced&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:2&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, and trying to find a way to make that work just broke me.&lt;/p&gt;
&lt;p&gt;I spent a while looking at different ways of hosting the music centrally.
&lt;a href=&#34;https://www.plex.tv/en-gb/plexamp/&#34;&gt;Plexamp&lt;/a&gt; gets lots of good reviews, and
I’ve used Plex a fair bit. I set about spinning up a Plex server, and just
could not get it working. The server ran fine, served the web interface, but
would neither associate with my account nor run standalone. The docs were
contradictory and there was very little useful logging. After a lot of
frustration, I stumbled across mentions that
&lt;a href=&#34;https://lowendbox.com/blog/plex-blocks-hetzner-in-move-against-piracy/&#34;&gt;Plex block running on Hetzner&lt;/a&gt;.
I assume that’s the cause of my issues, although I have no way to know for sure.
I use Hetzner for all my servers and other hosted services, but Plex have
decided I can’t run the self-hosted software that I have a lifetime subscription
for there. What the actual fuck?&lt;/p&gt;
&lt;p&gt;I could have probably worked around the arbitrary restriction, but I didn’t
want to throw more time down the drain. Instead, I set up
&lt;a href=&#34;https://www.navidrome.org/&#34;&gt;Navidrome&lt;/a&gt;, an open source music server. It
supports the Subsonic protocol, which means you can use a whole slew of
different clients with it (or even write your own). It also means there’s a
nice way to get data in and out of it programmatically, which I recall being
a bit of a fight with Plex.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3 id=&#34;syncing-and-organising&#34;&gt;Syncing and organising&lt;/h3&gt;
&lt;p&gt;All my music lived on my desktop, but now I wanted it on my server. At first
I just used &lt;code&gt;rsync&lt;/code&gt; to copy everything up. I’d maintain a local “master” copy,
and periodically shove the changes to the server&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:3&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. That quickly got old,
so I set up &lt;a href=&#34;https://syncthing.net/&#34;&gt;Syncthing&lt;/a&gt; to keep the two folders in
sync. That worked… for a while.&lt;/p&gt;
&lt;p&gt;Concurrently, I was looking at improving the organisation of my music. It
was mostly organised by some Go programs I’d thrown together to automate the
importing, with no real validation of metadata or anything else. Some albums
got split up into multiple folders because the tracks had different artists
(and didn’t have an album artist set); some artists ended up with multiple
folders with slight spelling or case variations. It was upsetting.&lt;/p&gt;
&lt;p&gt;I’d used &lt;a href=&#34;https://picard.musicbrainz.org/&#34;&gt;MusicBrainz Picard&lt;/a&gt; before to fix
some issues, but I didn’t really like the UI, especially when trying to do
bulk actions. The main alternative is &lt;a href=&#34;https://beets.io/&#34;&gt;beets&lt;/a&gt;, which
describes itself as “the music geek’s media organiser”, and is entirely
command line. I was intrigued.&lt;/p&gt;
&lt;p&gt;I started playing around with beets, and quickly noticed a problem. Every time
I changed a metadata tag in a music file, Syncthing had to upload the entire
file. I was frequently changing tags across the whole library as I got beets
set up how I wanted, and Syncthing was handling it by uploading gigabytes of
files for every minor change. I was already a bit unhappy with having the
content duplicated in two places, so now I was using a command line organiser
I figured I could just get rid of my local copy and move everything to the
server.&lt;/p&gt;
&lt;p&gt;I set up a Docker container for beets, and then wrote some incredibly hacky
shell scripts so I could run &lt;code&gt;beet&lt;/code&gt; locally on my desktop and it would SSH
to the server over Tailscale and exec into the container, passing the arguments
along. Then I did one final sync of the music library, got rid of Syncthing,
double checked I had a backup and deleted all of my local music.&lt;/p&gt;
&lt;h3 id=&#34;bears-beets-battlestar-galactica&#34;&gt;Bears, Beets, Battlestar Galactica&lt;/h3&gt;
&lt;p&gt;Beets is amazing. It has a vast array of plugins that can do almost anything
you could want with a music library, and the command line workflow works really
well for me. It’s very well documented, and all the individual parts are
pleasingly simple and easy to understand.&lt;/p&gt;
&lt;p&gt;Here’s what it looks like when importing some new music:&lt;/p&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/further-adventures-in-music-organisation/beets-importing.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/further-adventures-in-music-organisation/beets-importing.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/further-adventures-in-music-organisation/beets-importing.png&#34; alt=&#34;Screenshot of beets output when importing an album. It shows the source folder in blue, the matched metadata information in white with green highlights, the MusicBrainz URL, then a listing of all tracks&#34; loading=&#34;lazy&#34; width=&#34;782&#34; height=&#34;377&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Beets importing an album&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;If it doesn’t get a perfect match then it shows the closest matches, and
summarises what’s different about them (missing tracks, different names,
etc), and lets you decide what to do. Aside from the metadata matching, it’s
doing a lot of things under the hood that aren’t necessarily apparent. It:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Looks up the genre from Last.fm&lt;/li&gt;
&lt;li&gt;Analyses all the tracks and writes ReplayGain metadata to them&lt;/li&gt;
&lt;li&gt;Fetches album art&lt;/li&gt;
&lt;li&gt;Checks all the files to make sure they’re actually playable&lt;/li&gt;
&lt;li&gt;Scrubs any existing metadata tags&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It also maintains its own database, and you can query against it. The query
language is both simple and quite powerful, like the rest of beets. As an
example:&lt;/p&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;$ beet ls artist:&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;Linkin Park&amp;#34;&lt;/span&gt; year:2025 length:2:00..2:30 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;Linkin Park - From Zero - Casualty
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Almost all the other commands also let you use the query syntax, which makes
the whole tool really powerful. Want to delete all country tracks that you
added last month? No problem. Redownload all the album art for a certain
band? Easy. You can even do smart playlists using the filters.&lt;/p&gt;
&lt;h3 id=&#34;actually-playing-music&#34;&gt;Actually playing music&lt;/h3&gt;
&lt;p&gt;With all this organisation, I’ve not actually mentioned one tiny detail: how
I actually play music now. Navidrome has a web UI, which is perfectly usable,
but I don’t really want my web browser involved as it makes balancing sound
levels tricky, and getting media keys working is a pain. Thankfully there
are loads of Subsonic clients. I’ve tried several, but eventually settled on
&lt;a href=&#34;https://github.com/jeffvli/feishin&#34;&gt;Feishin&lt;/a&gt; on the desktop. It’s very pretty:&lt;/p&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/further-adventures-in-music-organisation/feishin.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/further-adventures-in-music-organisation/feishin.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/further-adventures-in-music-organisation/feishin.jpg&#34; alt=&#34;A screenshot of Feishin. On the left side of the screen is the album art (Love, Drugs &amp;amp; Misery by Eva Under Fire), with the track, album, artist, year and file format below it. On the right hand side is a tabbed panel, currently showing &amp;#39;Up Next&amp;#39; which shows a queue of music. At the bottom is a standard player interface with play/pause/skip/etc buttons.&#34; loading=&#34;lazy&#34; width=&#34;1723&#34; height=&#34;985&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Feishin’s ’now playing’ screen&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;What attracted me to it, though, was its built-in support for Navidrome’s smart
playlists. These aren’t even properly exposed in Navidrome’s web UI yet, but
Feishin has a visual editor that lets you create and edit them. I ended up with
an identical system to the playlists I had in Tauon: a “blacklist” playlist
which are tracks I never want to play, a “favourites” playlist, and then an
“everything” playlist which is the entire catalogue minus the blacklist.&lt;/p&gt;
&lt;p&gt;On iOS I’ve settled on &lt;a href=&#34;https://www.reddit.com/r/arpeggiApp/&#34;&gt;Arpeggi&lt;/a&gt;. It’s
not actually on the App Store yet, but available via TestFlight. It’s one of
those really nicely polished apps that are obviously a labour of love, not just
out to do the minimum possible to get your money. It can cache songs offline,
and automatically download entire playlists, and supports all of the standard
Subsonic features like rating, reporting plays back to the server, and so on.&lt;/p&gt;
&lt;p&gt;One unexpected benefit of using a central server is that it handles reporting
plays to &lt;a href=&#34;https://last.fm/&#34;&gt;Last.fm&lt;/a&gt; and &lt;a href=&#34;https://listenbrainz.org/&#34;&gt;ListenBrainz&lt;/a&gt;
instead of the clients. I don’t think I’ve ever bothered to configure my mobile
clients to do that before, and now it just works automagically. I’m relying on
those services more for recommendations and discovery, as that’s something you
lose out on when self-hosting.&lt;/p&gt;
&lt;h3 id=&#34;making-bad-decisions-about-bitrates&#34;&gt;Making bad decisions about bitrates&lt;/h3&gt;
&lt;p&gt;With all the moving, copying, and organising, I started thinking about how
large the collection was. The songs were all in different formats, depending
on when and where I’d picked them up, and I couldn’t tell the difference
between them. I did a test and transcoded an MP3 file down to 128kbps, and
still couldn’t tell the difference. So armed with that sample size of 1, I
transcoded the entire library and saved &lt;em&gt;so much&lt;/em&gt; space.&lt;/p&gt;
&lt;p&gt;I don’t remember which track I did that first test with, but it must have
been a very unlucky pick. I quickly started to notice the distortions caused
by the low bitrate. It was particularly bad in any song with a lot of treble,
and started to really annoy me. I started a painful process of reimporting
things in their original format. Beets came in clutch again, both with the
import process (if you import a duplicate album, it asks if you want to
replace the original, and shows the format and bitrate of them for comparison),
and keeping track of what was left to fix (&lt;code&gt;beet ls bitrate:..128000&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Having started paying more attention to the sound quality, I think I’ve been
nibbled on by the audiophile bug. I’ve been trying to get new music in FLAC
format where possible. I’m pretty sure I &lt;em&gt;can’t&lt;/em&gt; tell the difference between
a decent bitrate MP3 and a FLAC, but maybe if I got a better DAC and some nice
headphones…? Someone please hide my credit card!&lt;/p&gt;
&lt;p&gt;As for the library taking up a lot of space, I now realise it’s a price worth
paying. I might need to swap out the server to one with more storage at some
point in the future, but it’s generally worth upgrading every few years with
rented dedicated servers anyway, as you often get more for the same amount of
money. Next upgrade I’ll just make sure there’s an appropriately-sized disk
instead of focusing entirely on RAM and CPU.&lt;/p&gt;
&lt;h3 id=&#34;writing-more-code&#34;&gt;Writing more code&lt;/h3&gt;
&lt;p&gt;Naturally, this whole process spawned several side projects. When browsing
albums in Navidrome, I was a bit upset that the album art wasn’t all a
consistent size. I thought about scripting something to crop them consistently,
but then I had a better idea, and &lt;a href=&#34;https://github.com/csmith/jewelcase&#34;&gt;jewelcase&lt;/a&gt;
was born. It takes the album art, crops it down to a consistent size, and then
renders it inside a jewel case. It applies some slight effects, like adjusting
the colours, rounding the corners, and tweaking the edges so it looks a bit more
real. I don’t know why&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:4&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;, but every time I see the effect it gives me a little
spark of joy.&lt;/p&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/further-adventures-in-music-organisation/jewelcase.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/further-adventures-in-music-organisation/jewelcase.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/further-adventures-in-music-organisation/jewelcase.jpg&#34; alt=&#34;A comparison screenshot. On the left are four albums, with their unaltered artwork. Some are different aspect ratios. On the right are the same four albums, but the art work is now consistently rendered as though its in a jewel case.&#34; loading=&#34;lazy&#34; width=&#34;1737&#34; height=&#34;702&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Album art, before and after jewelcase is applied&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The other project is &lt;a href=&#34;https://github.com/csmith/bass&#34;&gt;BASS&lt;/a&gt;, a tool that uses
the Subsonic API to grab information about my music catalogue, and then
generates a “Daily Mix” playlist. It uses a system of weights to select tracks
semi-randomly, biasing towards favourite tracks, those that haven’t been played
much, and a few other criteria. This gives me a nice balance between having my
favourites on repeat, and exploring the full library at random.&lt;/p&gt;
&lt;p&gt;All the weights in BASS are customisable, so I can tweak it to my heart’s
desire, and anyone else can also run it and configure it entirely differently
to me if they want to. I can’t imagine I would’ve been able to do that if I were
using Plex!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I was running a version from git as the stable release had fun dependency
issues on Arch, so it’s possible this wouldn’t be an issue in normal use. I also
started backing up the database, but it’s still annoying to have to restore it. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;A “favourites” playlist for me, and a more “family friendly” playlist
for when I’m playing music out loud that has a bit less screaming/swearing/etc. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:2&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;One of the reasons for starting this was being annoyed by the periodic
sync to my phone, obviously it makes perfect sense to introduce a new, different
periodic sync. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:3&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Nostalgia? A little bit of OCD? Both? &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:4&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
    <entry>
        <title>Escaping Spotify the hard way</title>
        <link href="https://chameth.com/escaping-spotify-the-hard-way/"/>
        <updated>2025-07-25T00:00:00Z</updated>
        <id>https://chameth.com/escaping-spotify-the-hard-way/</id>
        <content xml:lang="en" type="html">&lt;figure class=&#34;image right&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/escaping-spotify-the-hard-way/wall-e.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/escaping-spotify-the-hard-way/wall-e.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/escaping-spotify-the-hard-way/wall-e.jpg&#34; alt=&#34;Still from WALL-E, showing two overweight people on floating beds, mindlessly consuming media&#34; loading=&#34;lazy&#34; width=&#34;500&#34; height=&#34;360&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;I realised my media consumption was too close to this for comfort.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;For the longest time I used Spotify for all my music needs. And I listen to
a lot of music: sometimes actively, but mostly passively as background noise.
I cancelled my premium subscription last December, and stopped using the
service entirely. Why? There’s a bunch of reasons.&lt;/p&gt;
&lt;p&gt;Let’s talk about the money first. Spotify launched at £9.99/month, and stayed
that way for over a decade. Then in 2023 it went up to £10.99/month. That’s
probably fair: the economy was in the toilet, and they haven’t changed their
price in so long. Then in 2024 they upped it again to £11.99/month. Hmm.
The service they were providing me didn’t improve in that time. I didn’t want
audiobooks in my music player, I didn’t want an AI DJ that spouted inane
comments at me. Paying them more money to do things I didn’t want seemed silly,
and the money that actually goes to the artists is both so small and gets split
in such a convoluted way that it’s not worth even thinking about.&lt;/p&gt;
&lt;p&gt;My bigger concern was how uninvolved I became in choosing what to listen
to. I leaned hard on their algorithmic playlists like “Discover Weekly” instead
of manually curating playlists. But they ended up developing this weird
feedback loop where it kept playing a country band&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; that I didn’t
particularly like, but also didn’t dislike enough to skip. That acted as
positive reinforcement, and they kept coming up everywhere. There were
definitely ways to solve that by changing how I used Spotify, but the
realisation that I was basically just consuming whatever was fed to me made
me want to try something completely different. So I decided to go back to
buying music instead. Which is where things got… complicated.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3 id=&#34;getting-some-mp3s-will-be-easy-right&#34;&gt;Getting some MP3s will be easy, right?&lt;/h3&gt;
&lt;p&gt;I figured with the money I was no longer giving to Spotify, I could just buy an
album or two a month and slowly build up a nice music collection. I already
had some music kicking around from before the streaming era, so there would at
least be some variety in my listening while I got started. Where to buy music
from, though?&lt;/p&gt;
&lt;p&gt;Amazon used to do DRM-free music, but as far as I can tell it all got folded up
into their own streaming service. Some smaller bands are on
&lt;a href=&#34;https://bandcamp.com/&#34;&gt;Bandcamp&lt;/a&gt;, but you won’t be able to grab Taylor
Swift’s latest album from there. &lt;a href=&#34;https://www.qobuz.com/gb-en/shop&#34;&gt;Qobuz&lt;/a&gt;
have a good catalogue, but some of the stuff is &lt;em&gt;pricey&lt;/em&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:2&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. It’d be cheaper
to buy CDs and rip them like it was 1998 again.&lt;/p&gt;
&lt;p&gt;I finally stumbled across an unlikely answer: the iTunes store&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:3&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. This is
still somehow separate from the behemoth of Apple Music, and if you fire up
the iTunes software you can indeed buy reasonably priced, DRM free music.
For comparison, 1989 (Taylor’s Version)&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:4&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; is £12.89 (plus delivery) on CD
from Taylor’s official website, £16.79 in CD quality from Qobuz, and
£12.99 from iTunes.&lt;/p&gt;
&lt;p&gt;Now, I use Linux, so using iTunes isn’t exactly easy. I ended up running a
virtual machine with Windows on it. Every time I wanted to buy an album, I’d
boot the VM, open iTunes, search for the album, press the buy button, enter
my password, wait for it to download, copy all the files to a shared drive,
and then back on Linux copy those files into my music directory. Smooth,
right? But it worked. Earlier in the year I switched computers, though, and
didn’t want to bother with the VM rigamarole. Spoiler alert: I didn’t make
things any simpler.&lt;/p&gt;
&lt;h3 id=&#34;do-you-guys-not-have-phones&#34;&gt;Do you guys not have phones?&lt;/h3&gt;
&lt;p&gt;I tried a lot of things to avoid setting up a Windows VM again. I’m pretty
sure I went through most of the 7 stages of grief in the process. I tried to
get Apple Music to work, because that was obviously where all their development
was focused, but you can’t actually buy music there (at least not on any version
I could run on Linux). I tried running iTunes under Wine, but it just wouldn’t
work. I looked into third-party clients, but unsurprisingly they didn’t go
anywhere near payment flows.&lt;/p&gt;
&lt;p&gt;I eventually realised that I have an Apple device in my pocket. After a bit of
searching, it turns out there is actually still an iTunes app for iOS&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:5&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;. I
bought an album&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:6&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; to see if I could exfiltrate it. I connected my phone to
the computer, paired it with &lt;code&gt;idevicepair&lt;/code&gt; and then mounted the storage using
&lt;code&gt;ifuse&lt;/code&gt;&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:7&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;. Looking around, I could see a bunch of m4a files, and I could play
them. Success!&lt;/p&gt;
&lt;p&gt;Except… the file names were random hex strings, and they had no metadata.
Yuck. I grabbed a copy of &lt;a href=&#34;https://picard.musicbrainz.org/&#34;&gt;MusicBrainz Picard&lt;/a&gt;
and had it sort out the mess. I stuck with this process for a while, but
matching albums in Picard was sometimes a pain. MusicBrainz does a great
job of figuring out what the tracks are, but it struggles to tie those back
to a single edition of an album. I wasn’t aware how many subtly different
versions of albums there were until I had to manually find the one iTunes had
given me. Not fun. Eventually I got so fed up with this that I did something
about it.&lt;/p&gt;
&lt;h3 id=&#34;plists-all-the-way-down&#34;&gt;Plists all the way down&lt;/h3&gt;
&lt;p&gt;Armed with an instance of Claude Code, I set out to see if I could write some Go
code to import the files properly. There were &lt;code&gt;plists&lt;/code&gt; in the directory with
the m4a files, and I know enough to know that they’re where all the juicy
metadata lives on iOS. Maybe we can parse them and do something useful?&lt;/p&gt;
&lt;p&gt;There’s a nice &lt;a href=&#34;https://github.com/DHowett/go-plist&#34;&gt;plist parser&lt;/a&gt; written
in Go already, so I got Claude to write a program to dump the contents of
one of the many &lt;code&gt;plist&lt;/code&gt; files in the directory. Inside was all the metadata
for one of the tracks. Yay! Just one small problem: there’s no way to link
the &lt;code&gt;plist&lt;/code&gt; file to the audio file. There’s one &lt;code&gt;plist&lt;/code&gt; file that has a real
name, though: &lt;code&gt;StorePurchasesInfo.plist&lt;/code&gt;. I had Claude translate it to JSON
and found that it contained a &lt;code&gt;data&lt;/code&gt; field with a bunch of binary data. Huh.&lt;/p&gt;
&lt;p&gt;I thought this was probably a dead end, but stuck the base64’d data into
&lt;a href=&#34;https://gchq.github.io/CyberChef/&#34;&gt;CyberChef&lt;/a&gt; and fiddled around a bit
to get a hexdump of the binary. Six characters jumped out at me: &lt;code&gt;bplist&lt;/code&gt;.
I went back to Claude and suggested this might be a plist-in-a-plist scenario.
Claude then got very confused because it couldn’t understand where the base64
was coming from&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:8&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;. After some LLM-induced suffering, I eventually got the
contents of the inner-plist, and for each track it had a list of the audio
file, the metadata, and the album art. Yay!&lt;/p&gt;
&lt;p&gt;With the data figured out, it was fairly simple to get Claude to write code to
parse everything and link them together, and after that move the files into
their correct place in my library. I also had it take the metadata from the
track’s &lt;code&gt;plist&lt;/code&gt; file and write it into tags on the m4a so my media player
didn’t have to understand Apple nonsense. I looked around for a Go library to
do this, but couldn’t find one supporting m4a files, so ended up just shelling
out to &lt;code&gt;exiftool&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As a bonus, I made the tool automatically make a temporary directory and use
&lt;code&gt;ifuse&lt;/code&gt; to mount the phone, then unmount it when it’s finished. So now all I
have to do is plug my phone in, and run &lt;code&gt;import-music&lt;/code&gt; on the command line&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:9&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;.
It’s a very nice quality-of-life upgrade that I probably wouldn’t have bothered
with if I didn’t have Claude Code to speed the process up&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:10&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id=&#34;sometimes-i-actually-play-music-too&#34;&gt;Sometimes I actually play music too&lt;/h3&gt;
&lt;p&gt;With all this talk about buying and sorting music, I almost forgot about the
most important bit: listening! I use &lt;a href=&#34;https://tauonmusicbox.rocks/&#34;&gt;Tauon&lt;/a&gt;,
and it looks like this:&lt;/p&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/escaping-spotify-the-hard-way/tauon.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/escaping-spotify-the-hard-way/tauon.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/escaping-spotify-the-hard-way/tauon.png&#34; alt=&#34;Screenshot of Tauon music player. There are playlist tabs on top, and album art for 1989 (Taylor&amp;#39;s Version) on the right. Most of the screen is a track listing, and all the tracks are by Taylor Swift.&#34; loading=&#34;lazy&#34; width=&#34;1547&#34; height=&#34;886&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Tauon, showing off a wide range of different music in my library.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I tried a bunch of different music players, but Tauon hits the sweet spot of
being simple enough to use but capable enough in the right places. I
particularly like the playlist generators. My “Music” playlist just auto-imports
all music in my “Music” folder, then I have a “Classical” playlist with a
generator of &lt;code&gt;s&amp;#34;Music&amp;#34; g&amp;#34;classical&amp;#34; auto&lt;/code&gt;. That makes it use the “Music”
playlist as a source, filter on tracks that have “classical” in their genre,
and automatically update when the base playlist changes&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:11&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;. The “Disliked”
playlist does the same but filters on rating: &lt;code&gt;s&amp;#34;Music&amp;#34; a rat=0.5 auto&lt;/code&gt;. That
takes all tracks (&lt;code&gt;a&lt;/code&gt;) from the Music playlist, then filters it down to only
those that have a rating of 0.5 out of 5&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:12&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;. Finally, the “Normal” playlist imports
everything from “Music” that’s not in one of the others. It sounds a bit clunky,
but it works well in practice and I like the way it works.&lt;/p&gt;
&lt;p&gt;Tauon in general just seems to work the way I’d expect it to, which is
refreshing. You can just start typing anywhere to search for a track, hit
enter, and it starts playing. It has keyboard shortcuts for other operations,
and standard features like reporting to last.fm and other sites.&lt;/p&gt;
&lt;p&gt;Tauon also supports transcoding and copying tracks to a music player or a phone.
I use this to sync my main playlist to my phone. I’ll give you a minute to just
bask in the glory of the rube goldberg machine I’ve created to move music from
my phone, to my computer, and ultimately back to my phone. This does actually
serve a purpose, though: it lets me control which tracks are on my phone. I
don’t have to deal with excluding genres or tracks I dislike on the phone
in addition to the computer. In the future I might opt to just sync a subset
of my tracks to keep the storage size down. I’m telling you it makes sense!
Stop looking at me like that!&lt;/p&gt;
&lt;h3 id=&#34;paying-attention-pays-off&#34;&gt;Paying Attention Pays Off&lt;/h3&gt;
&lt;p&gt;I mentioned one of my aims for getting away from Spotify was to feel less
like I was just consuming whatever’s in front of me. The corollary to that
is how do you discover new music without an algorithm to feed it to you?
I’ve ended up subscribing to a few blogs, paying more attention to music-related
news, and being more aware of songs on the radio and from other sources.&lt;/p&gt;
&lt;p&gt;When I find a song I like these days, I tend to listen to a few other tracks
on the album (via YouTube, normally, as it’s the least friction) and decide
if I want to buy it. When I do, I sit down and listen to the whole thing in
order. It’s a radically different experience to just hearing a song now and
then. There are themes and connections between tracks that you just miss
if you listen to songs at random. Of course, you could do that on Spotify, but
I don’t think it really lent itself to it.&lt;/p&gt;
&lt;p&gt;My favourite example of this is my rediscovery of Linkin Park&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:13&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;. I’m of the
age where they were around as I was growing up. I knew a couple of their big
hits but younger-me wasn’t that into rock&lt;sup id=&#34;fnref:14&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:14&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt;, so I didn’t pay them much
attention. Then I caught Up From the Bottom on the radio, and from there
ended up buying and listening to all of From Zero. It’s an amazing album.
The Emptiness Machine has become my favourite song: not only is it a great tune,
performed well, it’s also a fantastic introduction to a new era for the band
and to Emily Armstrong as the new vocalist. The rest of the album then builds
on it to show off what they can do.&lt;/p&gt;
&lt;p&gt;I’ve since gone back and reconnected with a lot of Linkin Park’s older albums,
too. And from there discovered a lot of other rock bands I really like.
Could this have happened with Spotify? Maybe, but it seems unlikely. It had me
in a country-band-I-can’t-remember filter bubble, it seems pretty unlikely it’d
drop some Linkin Park on me out of nowhere. And the passivity that came along
with it would have meant that I probably wouldn’t have paid enough attention
when I heard it from elsewhere.&lt;/p&gt;
&lt;p&gt;Would I recommend that everyone runs out and cancels their Spotify
subscriptions? Eh, probably not. If it works for you, that’s fine. Discovering
recursive plists is fun for me, but I appreciate it’s not everyone’s cup of tea.
What I would recommend is being a bit more deliberate in your choice of music.
Don’t just tune in to a random playlist, or let the ‘DJ’ decide what to play.
Find something, and actually &lt;em&gt;listen&lt;/em&gt; to it. Then recommend it to me. I want
more music!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I can’t even remember the name of the band, that’s how much I was into
them. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;And they’re annoyingly deceptive about it. All the prices are “From £x”,
where x is the discounted price you’d get if you paid them £15/month. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:2&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;I’d link to it, but… there isn’t a website. That’s not how things were
done in the 1990s, silly. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:3&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;I don’t know why I’m so hung up on Taylor Swift in this post. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:4&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Again, unrelated to the Apple Music app. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:5&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;It &lt;em&gt;probably&lt;/em&gt; wasn’t a Taylor Swift album. Maybe. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:6&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;The Arch wiki has &lt;a href=&#34;https://wiki.archlinux.org/title/IOS&#34;&gt;a useful page&lt;/a&gt;
on this (of course). &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:7&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;We were translating the plists to JSON, and if you serialise a byte array
to JSON in Go it ends up as a base64-encoded string. Claude was then &lt;em&gt;adamant&lt;/em&gt;
it needed to base64 decode the binary plist. It did not. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:8&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;I just had the sudden realisation that I can probably automate running
the &lt;code&gt;import-music&lt;/code&gt; tool whenever I plug my phone in using systemd… &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:9&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;I feel like I say that a lot lately. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:10&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;I like classical music, but it’s a mood, and I’m often not in that
mood. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:11&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;I basically use this to filter out those introduction/bridge tracks
on albums that are just talking and not singing. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:12&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;Surprise! My library isn’t &lt;em&gt;actually&lt;/em&gt; just Taylor Swift songs. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:13&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;Younger-me was a dumbass, in some ways. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:14&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
    <entry>
        <title>How I Get Things Done</title>
        <link href="https://chameth.com/how-i-get-things-done/"/>
        <updated>2024-09-01T00:00:00Z</updated>
        <id>https://chameth.com/how-i-get-things-done/</id>
        <content xml:lang="en" type="html">&lt;p&gt;I always quite like reading about how other people &lt;em&gt;do things&lt;/em&gt;. What software
or hardware they use, or how they manage reminders, todo lists, and so on.
I’ve never actually written about how I do any of that, though. So here it is!&lt;/p&gt;
&lt;h3 id=&#34;productivity&#34;&gt;Productivity&lt;/h3&gt;
&lt;p&gt;In the past I’ve fallen victim to the idea of there being One True Productivity
System that would solve all my problems and make me amazing at getting things
done. The title of this post is a nod to Getting Things Done, which I’ve read
and tried to religiously follow in the past, but it’s just not for me. One thing
that did actually stick from it, though, was the idea of “open loops”:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Anything that does not belong where it is, the way it is, is an “open loop,”
which will be pulling on your attention if it’s not appropriately managed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If I want to do something and it’s not recorded in a way I trust, it
weighs on me a little. Those little weights all add up, and just make life
uncomfortable. I deal with those in a few ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inbox Zero-ish: if an e-mail needs me to do something, it sits in my inbox
until it’s done. When it’s done, it gets archived.&lt;/li&gt;
&lt;li&gt;Notes: random things I try to remember I put into my notes, so I can search
for them later.&lt;/li&gt;
&lt;li&gt;Budget: anything monetary I just adjust in my budget or create a category for.&lt;/li&gt;
&lt;li&gt;Todo list: any other kind of task I want/need to do either now or at some
point in the future goes into Todoist.&lt;/li&gt;
&lt;/ul&gt;
&lt;!--more--&gt;
&lt;h4 id=&#34;todoist&#34;&gt;Todoist&lt;/h4&gt;
&lt;p&gt;In the past I’ve gone through a lot of different todo systems, once again
hunting for one that will fix all my problems etc&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. In the end I always ended
up coming back to &lt;a href=&#34;https://todoist.com/&#34;&gt;Todoist&lt;/a&gt;, and have stuck with it for a
decent period now.&lt;/p&gt;
&lt;p&gt;In Todoist, I have everything split up into projects. Work projects are one
colour and personal projects are another. Anything that needs more than a
handful of individual tasks gets a project, which is archived when it’s done.
Any one-off things that don’t neatly fall into projects go into “Random junk”
project.&lt;/p&gt;
&lt;p&gt;As I’m writing this, I have 116 items in 22 projects. A good deal of those are
things that I might want to do at some point, not things that I actively need
to worry about. If I want to get one of them done, I schedule it so it shows
up in the “today” view. I have the Todoist desktop app open automatically when
I login to my computer, and it gets positioned on the right hand side of my
ultra-wide monitor, so I can see the “today” view and add/remove things
immediately at any point.&lt;/p&gt;
&lt;p&gt;I’m not precious about tasks becoming overdue, or unscheduling things I’d
previously scheduled. Priorities change, ideas that sounded good a week ago
might no longer sound good, and so on.&lt;/p&gt;
&lt;p&gt;I do a few things to help me manage tasks and keep track of things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I have a monthly recurring task to look through everything that’s not
scheduled, just so I keep a rough idea of what’s there, and can update or
get rid of it as needed.&lt;/li&gt;
&lt;li&gt;I wrote &lt;a href=&#34;https://github.com/csmith/todoistager&#34;&gt;todoistager&lt;/a&gt; and have it
running on a server to automatically apply tags to tasks based on their rough
age: &lt;code&gt;weeks&lt;/code&gt;, &lt;code&gt;months&lt;/code&gt; or &lt;code&gt;years&lt;/code&gt;. This lets me identify things that are
lingering and reconsider them&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:2&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;I automate adding tasks for things that demand my attention, like incoming
GitHub pull requests. The Todoist API is nice and straight forward, and
hooking it up to things is trivial.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;other-desktop-software&#34;&gt;Other desktop software&lt;/h3&gt;
&lt;p&gt;For notes I use &lt;a href=&#34;https://logseq.com/&#34;&gt;Logseq&lt;/a&gt;, and I just put whatever I need
to write under today’s note and rely on search or tags to find it again when
I need to. I note basically anything that I might like to use again in the
future. One of my most common tags is &lt;code&gt;#blub&lt;/code&gt;, a term I came across in
the excellent article “&lt;a href=&#34;https://www.benkuhn.net/blub/&#34;&gt;In defense of blub studies&lt;/a&gt;”.
Blub is random ultra-specific knowledge; it might not be eminently useful
to know on its own, but over time it can pay dividends.&lt;/p&gt;
&lt;p&gt;I’ve previously tried a bunch of note taking apps, and methodologies, but like
with todo lists I end up just wanting something that &lt;em&gt;just works&lt;/em&gt; and stays out
of the way. Logseq stores notes in Markdown, and I have a cronjob to commit and
push my changes to a private git repository.&lt;/p&gt;
&lt;p&gt;Like Todoist, Logseq launches when I log into my computer, and sits in the same
500px-or-so region on the right of my monitor. This allows me to switch from
Todoist to take or refer to notes when needed. To do this positioning, I use
&lt;a href=&#34;https://www.nongnu.org/devilspie2/&#34;&gt;devilspie2&lt;/a&gt;. I also use this to position
Discord and my IRC client side-by-side on a small portable monitor that sits
underneath my ultrawide.&lt;/p&gt;
&lt;p&gt;More mundane software: I use &lt;a href=&#34;https://www.jetbrains.com/idea/&#34;&gt;IntejjiJ IDEA&lt;/a&gt;
for almost all development and complex text editing&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:3&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. The only exception is
Android development where &lt;a href=&#34;https://developer.android.com/studio&#34;&gt;Android Studio&lt;/a&gt;
rules the roost. For lighter text editing, &lt;a href=&#34;https://www.sublimetext.com/&#34;&gt;Sublime Text&lt;/a&gt;
is my choice.&lt;/p&gt;
&lt;p&gt;I spend a fair bit of the time at the command line. I use &lt;a href=&#34;https://sw.kovidgoyal.net/kitty/&#34;&gt;kitty&lt;/a&gt;
as a terminal emulator, with the &lt;a href=&#34;https://www.zsh.org/&#34;&gt;zsh&lt;/a&gt; shell and
&lt;a href=&#34;https://ohmyz.sh/&#34;&gt;Oh My Zsh&lt;/a&gt; for some nice plugins and enhancements. One thing
I couldn’t live without is &lt;a href=&#34;https://github.com/wting/autojump&#34;&gt;autojump&lt;/a&gt;, which
allows quickly jumping to any directory you’ve previously visited using a
substring of the name.&lt;/p&gt;
&lt;p&gt;Web browsing is all &lt;a href=&#34;https://www.mozilla.org/en-GB/firefox/new/&#34;&gt;Firefox&lt;/a&gt;,
with &lt;a href=&#34;https://bitwarden.com/&#34;&gt;Bitwarden&lt;/a&gt; for password management and two pinned
&lt;a href=&#34;https://www.fastmail.com/&#34;&gt;Fastmail&lt;/a&gt; tabs, one for personal e-mail and one for
work. I don’t think there’s much else to note there.&lt;/p&gt;
&lt;p&gt;Oh, I use &lt;a href=&#34;https://archlinux.org/&#34;&gt;Arch&lt;/a&gt;, by the way.&lt;/p&gt;
&lt;h3 id=&#34;infrastructure&#34;&gt;Infrastructure&lt;/h3&gt;
&lt;p&gt;This is the hodge-podge of things that support my computer usage but sit outside
the actual computer. In no particular order…&lt;/p&gt;
&lt;p&gt;All my DNS queries go through &lt;a href=&#34;https://nextdns.io/&#34;&gt;NextDNS&lt;/a&gt; using
DNS-over-HTTPS. NextDNS lets you add custom responses, block certain things
from resolving, and subscribe to pre-made anti-tracking or anti-advertising
lists. It gives you far more control over everything than most other services
I’ve looked at.&lt;/p&gt;
&lt;p&gt;Every device I control runs &lt;a href=&#34;https://tailscale.com/&#34;&gt;Tailscale&lt;/a&gt; to enable remote
access. I also use Tailscale’s SSH authentication feature for my servers,
allowing quick and easy access from my phone where I don’t have or want normal
SSH keys.&lt;/p&gt;
&lt;p&gt;One exciting service that combines these two is &lt;a href=&#34;https://github.com/tailscale/golink&#34;&gt;golink&lt;/a&gt;.
It was created by Tailscale, presumably based on the &lt;code&gt;go&lt;/code&gt; service used extensively
inside Google. I run a version on my tailnet, and have NextDNS configured to
resolve &lt;code&gt;go&lt;/code&gt; to the tailscale IP of the service. That lets me type “go/whatever”
on any machine I set up with NextDNS and Tailscale, including mobile devices.
I use go links for all sorts of things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shortcuts to tools I use commonly: &lt;code&gt;go/board&lt;/code&gt; gets updated to my current
client’s kanban board or similar tracker, whether it’s in Jira, GitHub, Asana
or whatever; &lt;code&gt;go/meet&lt;/code&gt; goes to Google Meet with the user parameter set
so I’m logged in with my work account not my personal account.&lt;/li&gt;
&lt;li&gt;In place of bookmarks: &lt;code&gt;go/flex&lt;/code&gt; goes to the
&lt;a href=&#34;https://css-tricks.com/snippets/css/a-guide-to-flexbox/&#34;&gt;CSS-Tricks flexbox guide&lt;/a&gt;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:4&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;,
&lt;code&gt;go/cad&lt;/code&gt; goes to the &lt;a href=&#34;https://www.onshape.com/en/&#34;&gt;OnShape&lt;/a&gt; login page,
&lt;code&gt;go/hmrc&lt;/code&gt; goes to the &lt;a href=&#34;https://www.gov.uk/log-in-register-hmrc-online-services&#34;&gt;HMRC online services&lt;/a&gt;
page, and so on&lt;/li&gt;
&lt;li&gt;A few dynamic things: &lt;code&gt;go/github/chameth.com&lt;/code&gt; will go to the &lt;code&gt;csmith/chameth.com&lt;/code&gt;
project on GitHub; &lt;code&gt;go/ref/pipico&lt;/code&gt; will go to the &lt;a href=&#34;https://ref.c5h.io/view/pipico&#34;&gt;Pi Pico page&lt;/a&gt;
on my electronics reference wiki.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For my servers I have a minimal &lt;a href=&#34;https://www.ansible.com/&#34;&gt;Ansible&lt;/a&gt; setup that
does some basic configuration and deploys SSH keys to the right places. Almost
everything runs inside Docker, and I use my own software for HTTP proxying:
&lt;a href=&#34;https://github.com/csmith/dotege&#34;&gt;Dotege&lt;/a&gt; uses tags I apply to containers to
build a config for &lt;a href=&#34;https://github.com/csmith/centauri&#34;&gt;Centauri&lt;/a&gt; which handles
reverse proxying, using &lt;a href=&#34;https://letsencrypt.org/&#34;&gt;Let’s Encrypt&lt;/a&gt; for TLS certs.
At the minute I have two servers: a dedicated server that runs basically all my
services (including this website), and a little VPS for monitoring and backups.
Both are from &lt;a href=&#34;https://www.hetzner.com/&#34;&gt;Hetzner&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I wrote my own basic monitoring software called &lt;a href=&#34;https://github.com/csmith/goplum&#34;&gt;Goplum&lt;/a&gt;
to make sure things that should be running on my servers actually are. If it
fails checks it sends a notification to my phone using &lt;a href=&#34;https://pushover.net/&#34;&gt;Pushover&lt;/a&gt;,
and a message to a channel on my private IRC server (running &lt;a href=&#34;https://github.com/ergochat/ergo/&#34;&gt;Ergo&lt;/a&gt;).&lt;/p&gt;
&lt;h3 id=&#34;hardware&#34;&gt;Hardware&lt;/h3&gt;
&lt;p&gt;For the last two years I’ve used a laptop as my main computer&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:5&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;. It’s a Dell G15
Special Edition. After some upgrades its specs are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Intel i7-12700H processor&lt;/li&gt;
&lt;li&gt;NVIDIA GeForce RTX 3060 graphics card&lt;/li&gt;
&lt;li&gt;2x32GB DDR5 RAM&lt;/li&gt;
&lt;li&gt;2TB Gen4 SSD&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At home it sits behind my &lt;a href=&#34;https://www.dell.com/en-uk/shop/alienware-34-curved-qd-oled-gaming-monitor-aw3423dwf/apd/210-bfrq/monitors-monitor-accessories&#34;&gt;Alienware AW3423DWF&lt;/a&gt;
monitor. This is a Quantum Dot OLED monitor, and I bought it almost immediately
upon seeing someone else use it at a LAN event. As did three other people that
were sat near us. It just looks &lt;strong&gt;so&lt;/strong&gt; good. I wasn’t sure I’d get on with
a widescreen monitor, and made sure it supported picture-by-picture before
buying it, but have never actually used that. I generally run whatever I’m
working on at nearly-fullscreen, then have Todoist or Logseq on the far right.
Games go fullscreen over everything, of course.&lt;/p&gt;
&lt;p&gt;Above the widescreen I have a &lt;a href=&#34;https://www.amazon.co.uk/gp/product/B09FHMPFW1/&#34;&gt;curved lightbar&lt;/a&gt;
that I find helps reduce eyestrain and makes it easier to focus on the monitor.
And on top of &lt;em&gt;that&lt;/em&gt; I have a &lt;a href=&#34;https://www.logitech.com/en-gb/products/webcams/brio-4k-hdr-webcam.960-001106.html&#34;&gt;Logitech Brio webcam&lt;/a&gt;
which gives a great picture with lots of control over pan/zoom/etc for meetings.
I have a little set of systemd scripts that detect when the external webcam is
connected and disable the laptop’s built-in webcam, and vice-versa when it’s
disconnected; that means whenever I jump into a video call in any app there’s
only one input and it’s always the right one, which is nice.&lt;/p&gt;
&lt;p&gt;Below the main monitor and its friends, I have a generic 1080p portable monitor
connected to the laptop via USB-C. This comes with me when I travel, and serves
as a Discord/IRC monitor when at home. It’s handy for throwing other things on
as well, like if I need to reference a design while writing code, and don’t
want to keep alt+tabbing.&lt;/p&gt;
&lt;p&gt;I have two &lt;a href=&#34;https://www.durgod.com/product/k320-space-gray/&#34;&gt;Durgod K320&lt;/a&gt;
keyboards: one with Cherry MX Silent Red switches for when I’m at home and don’t
want to annoy people with the sounds, and one with Cherry MX Blues for when I’m
travelling and can make a bit more noise in exchange for a much nicer typing
experience. They’re both tenkeyless so they can handily fit in a backpack.&lt;/p&gt;
&lt;p&gt;I use a &lt;a href=&#34;https://zowie.benq.eu/en-uk/mouse/ec1-c.html&#34;&gt;Zowie EC1-C&lt;/a&gt; wired mouse,
which does the job well. I got fed up with mice from more mainstream manufacturers
failing: my previous mouse was a Razer Viper that lasted 7 months before it
started losing clicks. All my audio goes through a
&lt;a href=&#34;https://uk.hyperx.com/products/hyperx-cloud-alpha-wireless&#34;&gt;HyperX Cloud Alpha Wireless&lt;/a&gt;,
which has the most insanely good battery life of any wireless headset I’ve ever
owned or seen. Their claim of 300 hours is not just marketing!&lt;/p&gt;
&lt;p&gt;In non-computer hardware, I have a &lt;a href=&#34;https://uk.store.bambulab.com/products/p1s&#34;&gt;Bambu P1S&lt;/a&gt; 3D printer
that I’ve mentioned in my blog before. For printing in fewer dimensions I have an
&lt;a href=&#34;https://www.epson.co.uk/en_GB/products/printers/inkjet/consumer/p/30174&#34;&gt;Epson EcoTank ET-1810&lt;/a&gt;,
which is surprisingly reasonable for an inkjet printer, and the ink costs aren’t as astronomical
as normal cartridges. Plus, you can’t decide to DRM ink when it’s loaded raw into the
printer…&lt;/p&gt;
&lt;p&gt;I have a small Zigbee network set up mainly to control the lights and the old
3D printer I no longer use (the P1S has a sensible standby mode so you don’t
have to yank its power away to make the fans stop spinning!). That’s run through
a Raspberry Pi running &lt;a href=&#34;https://www.zigbee2mqtt.io/&#34;&gt;Zigbee2Mqtt&lt;/a&gt; and a custom
app I wrote to monitor events on MQTT and generate the appropriate responses
(or just log the data).&lt;/p&gt;
&lt;p&gt;My daily-driver phone is an &lt;a href=&#34;https://www.apple.com/uk/iphone-15-pro/&#34;&gt;iPhone 15 Pro&lt;/a&gt;,
but I have a bunch of Android devices kicking around for work purposes. I read
nearly every day on a &lt;a href=&#34;https://www.amazon.co.uk/gp/product/B08N2QK2TG/&#34;&gt;Kindle Paperwhite Signature Edition&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;money-and-work&#34;&gt;Money and work&lt;/h3&gt;
&lt;p&gt;I use &lt;a href=&#34;https://www.ynab.com/&#34;&gt;You Need A Budget&lt;/a&gt; for figuring out how much money
I can spend on what, and making sure I have enough put aside for bills and taxes
and so on. I use it for both business and personal accounts together, but I mark
all the business categories and accounts with a 💼 emoji, and have some scripts
that use the API to make sure the money split makes sense&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:6&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Every recurring monthly and annual payment has a category, as do all upcoming
events I plan to attend, and all the wonderful taxes I have to pay. I also have
categories for hobbies and other expenditure. I think all of that is pretty
typical for a normal YNAB setup.&lt;/p&gt;
&lt;p&gt;I also use YNAB for tracking anything I might like to buy at some point: it
gets a category in a “Wishlist” group, and I’ll occasionally budget to buy
things from there. I try (and often fail) to use that as a way to put off
impulse purchasing. As my income is often very inconsistent, I try to set
aside money so that I can “spend” a bit every week on things in the wishlist
group. That feels a lot nicer to me than just budgeting everything in one go
as soon as I get paid, and gives me more time to consider whether I &lt;em&gt;really&lt;/em&gt;
want those things&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:7&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;For work, I do all the more technical accountancy and tax filing and so on
through &lt;a href=&#34;https://www.freeagent.com/&#34;&gt;FreeAgent&lt;/a&gt;. For my fairly straight-forward tax
situation, I can basically manage everything myself using FreeAgent without
paying for an accountant. That does mean occasionally spending a bunch of time
reading tax manuals, but I’d rather fully understand the rules than just follow
advice anyway.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;The problem with implementing productivity systems or switching todo apps
or anything of that ilk is that it can &lt;em&gt;feel&lt;/em&gt; like you’re being productive by
doing so. It takes a while to realise that you’re not, and actually getting on
with things is better. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Or just accept that I’ll maybe do them at some point. I kept the labels
vague to try and not make it feel judgmental. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:2&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Including writing this blog post right now. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:3&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;One day I will get all the &lt;code&gt;justify-&lt;/code&gt; and &lt;code&gt;align-&lt;/code&gt; options right without
looking them up, but until then… &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:4&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;This is very normal for developers, but much less common for computer
gamers. I’ll probably go back to a desktop next time I upgrade, as I’m
travelling a lot less. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:5&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;I can’t just arbitrarily move money from the business to myself, it has
to be given as salary or a divided etc, which has tax implications. If I budget
“business money” for personal things, then it actually has to be properly
transferred and accounted for before being spent (as I’m in effect budgeting
a future paycheck). It would be cleaner to keep the accounts completely
separate, but I find this way works well for me as I can be a bit more flexible. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:6&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;It feels a little like I’m giving myself pocket money, which is a bit
weird, but it’s a lot better than having no “income” for several months when
client invoices fall weirdly or I’m between contracts. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:7&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
</feed>
