Immensely enjoyed the ATP member special where John goes through his window management. Very illuminating. I do recommend watching it on YouTube rather than listening to it as a podcast.

Happy Grand Prix week for anyone who celebrates (I absolutely do not celebrate! πŸ‘Ž)

Bunting strung up in the street with a Grand Prix theme, including checkered flags.

From Merlin’s wisdom project:

Related: most kids can be surprisingly entertained by your making them just a little bit terrified.

Not sure I was ever entertained by being a bit terrified as a kid. I think I left feeling more angry.

You know how iA Writer shades anything coming from an LLM to indicate that an AI generated it? I wish Goland did the same thing for copy-and-pasted code. That’ll save me from missing changes of a pasted code fragment that’ll inevitably show up as duplicates in the review.

Spun out the sidebar I added to my site into a standalone Micro.blog Plugin, called Sidebar For Tiny Theme. This can be used to add a sidebar with your blog-roll recommendations to any blog that’s using Tiny Theme. Click through to see usage and examples, and let me know what you think.

I feel envious of those that are happy to work on one thing β€” project, job, cause β€” for a lifetime. I’ve never felt that myself: after a while, I need to move onto something else. I wonder if it’s the same feeling one gets when they fall in love. Can’t say myself (I’ve never fallen in love either).

πŸ”— Doing Weeknotes

This is probably worth trying. I know for myself that I get lost in the day-to-day activities of work that I loose a sense on what we’ve accomplished during the week. Besides, Confluence has got this blogging feature which never seems to get used.

Dreamt that I was writing a blog post about software design and how it relates to eating vegetables. Not sure the analogy works so I won’t be writing it here. The setting was nice though: I was drafting it on a Swiss train pulling into Geneva where I was to meet up with family at the station.

I’ll bring the lighter fluid. #burn-all-computers-to-the-ground

DALL-E image of a pile of 90's desktop computer in a field set on fire.

(sorry, it’s been one of those days 😼).

This year’s Ides of March started with some stormy internet weather this morning. May have been behind a few production issues we had. Always a fun way to start a Friday. πŸ˜’

Internet weather’s fining up though.

Matt Bircher made an excellent comment about UI design sensibilities:

I get the feeling a non-insignificant contingent of commentators have taken this to the point where they think people who aren’t them are just dumb idiots who can barely figure out how a fork works, let alone how to use a piece of software that does more than one simple thing.

I get this sense as well. Of couse there will be those that arn’t interested in going beyond the basics. But what about those that are? Those that are willing to invest time and effort in your software? Surely they’re worth serving, no?

Oof, not feeling great today. Tired and spaced out. Hope I’m not coming down with something. 😩

Adding A Sidebar To A Tiny Theme Micro.blog

I’d though I’d write a little about how I added a sidebar with recommendations to my Tiny Theme’ed Micro.blog, for anyone else interested in doing likewise. For an example on how this looks, please see this post, or just go to the home page of this site.

I should say that I wrote this in the form of a Micro.blog plugin, just so that I can use a proper text editor. It’s not published at the time of this post, but you can find all the code on Github, and although the steps here are slightly different, they should still work using Micro.blog’s template designer.

I started by defining a new Hugo partial for the sidebar. This means that I can choose which page I want it to appear on without any copy-and-paste. You can do so by adding a new template with the name layouts/partials/sidebar.html, and pasting the following template:

<div class="sidebar">
    <div class="sidebar-cell">
        <header>
            <h1>Recommendations</h1>
        </header>
        <ul class="blogroll">
            {{ range .Site.Data.blogrolls.recommendations }}
                <li><a href="{{ .url }}">{{ .name }}: <span>{{ (urls.Parse .url).Hostname }}</span></a></li>
            {{ else }}
                <p>No recommendations yet.</p>
            {{ end }}
        </ul>
    </div>
</div>

This creates a sidebar with a single cell containing your Micro.blog recommendations. Down the line I’m hoping to add additional cells with things like shoutouts, etc. The styling is not defined for this yet though.

The sidebar is added to the page using Tiny Theme’s microhooks customisation feature. I set the microhook-after-post-list.html hook to the following HTML to include the sidebar on the post list:

{{ partial "sidebar.html" . }}

In theory it should be possible to add it to the other pages just by adding the same HTML snippet to the other microhooks (go for the “after” ones). I haven’t tried it myself though so I’m not sure how this will look.

Finally, there’s the styling. I added the following CSS which will make the page slightly wider and place the sidebar to the right side of the page:

@media (min-width: 776px) {
    body:has(div.sidebar) {
        max-width: 50em;
    }

    div.wrapper:has(div.sidebar) {
        display: grid;
        grid-template-columns: minmax(20em,35em) 15em;
        column-gap: 60px;
    }
}

div.sidebar {
    font-size: 0.9em;
    line-height: 1.8;
}

@media (max-width: 775px) {
    div.sidebar {
        display: none;
    }
}

div.sidebar header {
    margin-bottom: 0;
}

div.sidebar header h1 {
    font-size: 1.0em;
    color: var(--accent1);
}

ul.blogroll {
  padding-inline: 0;
}

ul.blogroll li {  
  list-style-type: none !important;
}

ul.blogroll li a {
  text-decoration: none;
  color: var(--text);
}

ul.blogroll li a span {
  color: var(--accent2);
}

This CSS uses the style variables defined by Tiny Theme so they should match the colour scheme of your blog. A page with a sidebar is also wider than one without it. It doesn’t change with width of pages that don’t have the sidebar (if this isn’t your cup of tea, you can remove the :has(div.sidebar) selector off the body tag) and the sidebar will not appear on small screens, like a phone in portrait orientation. I’m not entirely sure if I like this, and I may eventually make changes. But it’s fine for now.

So that’s how the sidebar was added. More to come as I tinker with this down the line.

Update: This is now a standalone Micro.blog Plugin called Sidebar For Tiny Theme.

Blogroll ported to Micro.blog and placed in a sidebar on the post list screen using Tiny Theme Microhooks. I’ve yet to port the Blogroll page, and may trim some of the recommendations appearing in the sidebar, but not bad for a first pass.

Screenshot of lmika.org with the blogroll recommendations displayed as a sidebar

Spent the last two hours combing through logs trying to find the root cause of a problem, only to solve it by just restarting a random Kubernetes pod out of desperation. If this is not the modern day, software equivalent to bashing the side of your TV to get a picture, I don’t know what is.

🎡 Stationary Loops, by Lee Rosevere

Album cover of Stationary Loops

Bought when I needed a few screenshots of Alto but growing to like it. Quite nice ambient chill out music. Got hints of Tangerine Dream and Jene-Michel Jarre.

Hmm, this is a new one. Apparently Telstra is blocking the site to Whisky app for some reason. Going to the website gave me this:

Screenshot of a browser showing a certificate error for the site getwhisky.app

Suspecting that the Whiskey devs just got their certificate missconfigured, I tried viewing the source using curl --insecure. Here’s what I found:

Screenshot of Terminal showing the output of curl insecure, which includes the quote below

We blocked this website because it may contain malicious content and could be harmful to your devices.
You haven’t done anything wrong. We automatically block potentially dangerous websites. We recommend you leave this website.
[…]
Copyright Β© 2023 Telstra

I’ve submitted a request to unblock it just now. I’m suspect this to just be a mistake but I am curious to know how it got blocked in the first place.

I did manage to get Whisky via a VPN.

Photo Bucket Update: Exporting To Zip

Worked a little more on Photo Bucket this week. Added the ability to export the contents of an instance to a Zip file. This consist of both images and metadata.

Screenshot of a finder window showing the contents of the exported Zip file

I’ve went with lines of JSON file for the image metadata. I considered a CSV file briefly, but for optional fields like captions and custom properties, I didn’t like the idea of a lot of empty columns. Better to go with a format that’s a little more flexible, even if it does mean more text per line.

As for the images, I’m hoping the export to consist of the “best quality” version. What that means will depend on the instance. The idea is to have three tiers of image quality managed by the store: “original”, “web”, and “thumbnail”. The “original” version is the untouched version uploaded to the store. The “web” version is re-encoded from the “original” and will be slightly compressed with image metadata tags stripped out. The “thumbnail” version will be a small, highly compressed version suitable for the thumbnail. There is to be a decision algorithm in place to get an image given the desired quality level. For example, if something needed the “best quality” version of an image, and the “original” image is not available, the service will default to the “web” version (the idea is that some of these tiers will be optional depending on the need of the instances).

This is all partially working at the moment, and I’m hoping to rework all this when I replace how stores and images relate to each other (This is what I’m starting on now, and why I built export now since this will be backwards incompatible). So for the moment the export simply consists of the “web” version.

I’ve got unit tests working for this as well. I’m trying a new approach for unit testing in this project. Instead of using mocks, the tests are actually running against a fully instantiated versions of the services. There exists a servicestest package which does all the setup (using temporary directories, etc) and tear down of these services. Each individual unit test gets the services from this package and will run tests against a particular one.

This does mean all the services are available and exercised within the tests, making them less like unit tests and more like integrations tests. But I think I prefer this approach. The fact that the dependent services are covered gives me greater confidence that they’re working. It also means I can move things around without changing mocks or touching the tests.

That’s not to say that I’m not trying to keep each service their own component as much as I can. I’m still trying to follow best practice of component design: passing dependencies in explicitly when the services are created, for example. But setting them all up as a whole in the tests means I can exercise them while they serve the component being tested. And the dependencies are explicit anyway (i.e. no interfaces) so it makes sense keeping it that way for the tests as well. And it’s just easier anyway. 🀷

Anyway, starting rework on images and stores now. Will talk more about this once it’s done.

I’ve being reading several posts from Aaron Francis recently around doing work and talking about it in public. All really good posts on the topic, particularly this one I’ve read a while ago which still resonates with me today.

Anything worth doing is worth doing badly.

G.K. Chesterton

Best quote from this video by Aaron Francis.