Posts tagged with "Coding"

Rogallo v3.3.0

1 min read; 10 GFI

Rogallo v3.3.0 has been released. This update adds the ability to ignore some types of errors you may encounter when navigating Geminispace.

The update was prompted by the fact that, yesterday, the certificate for AstroBotany expired. Rogallo, quite rightly, alerted me to this and didn't carry on with loading the content. But it got me realising that it's easy enough to inspect the situation, realise that it's just a blip that will be fixed pretty quickly, and meanwhile you just want to get on with watering your plant, etc. At that point, Rogallo didn't allow you to do this.

So v3.3.0 adds the ability to ignore some errors that might crop up when visiting a capsule.

The ignore button

When an error is ignored, it is only valid for that host, that port, and that particular error for the duration of your Rogallo session. If you close Rogallo and start it again, you'll be shown the same dialog when visiting that host/port.

As a reminder, if an error is being ignored for the document you're viewing, the verification icon in the document title will indicate an error with its background colour:

Showing a capsule error

If you click on the icon (if using a mouse), or use the AboutThisPage command (bound to F7 by default), any ignored errors will be shown along with the other document information.

Errors in the about dialog

With all this in place, all being well, if AstroBotany has a wee certificate update lag again in the future, I should still be able to visit the Koi pond without a problem.

Well, okay, with an ignored problem.

Wasat v1.11.0

1 min read; 8 GFI

Another little update to Wasat, this time bumping the version to v1.11.0.

After this morning's change, I made a start on the work I wanted to do on Rogallo and quickly realised that most of what I had planned was better done in Wasat itself. The short version is: rather than maintaining a just-this-session ignore list in the application, it made more sense to handle this in Wasat.

So this release adds an ignore_security_error method to the client that lets you -- for the current session -- ignore a particular type of error for a given host/port pair. This makes for a lot less work needing to be done by the application making use of Wasat. Now it's just a case of1:

from wasat import Client, IgnorableSecurityError

client = Client()
uri = "gemini://expired.example.com/"

try:
    response = await client.request(uri)
except IgnorableSecurityError as error:
    client.ignore_security_error(uri, error)
    response = await client.request(uri)

Obviously, the code in Rogallo is a bit more involved than the above, but that's the gist of it: try the request, if it fails with an error that can be ignored, ignore it and try again.


  1. Yes, I know the await isn't going to work in this example; consider it pseudo-code. ↩

Wasat v1.10.0

1 min read; 11 GFI

Since getting into Gemini, one of my daily rituals has been to tend to my plant in AstroBotany. This morning, when trying to visit there with Rogallo, I was greeted with this:

Expired certificate

In other words: the certificate has expired1. At this point, the error dialog isn't that useful. It's pretty much designed for dealing with capsules that are using self-signed certificates -- where TOFU is being used and so it would normally make sense to just forget and re-establish trust. With an expired CA certificate, the act of forgetting does nothing, it'll just fail again.

While it's technically fine to simply refuse to progress, in this case, it's not exactly friendly to the user. What would be sensible would be to allow an "Ignore" option. This would, I imagine, ignore the problem for the current Rogallo session -- ideally with some sort of indication that the capsule is suspicious at the moment. Also, the dialog that gives you this option should show all the certificate details so the user can make an informed decision.

The issue here is that, until now, Wasat has dealt with security-type problems by raising a single SecurityError exception. Aside from dumpster-diving the description in the exception, there's no way of knowing the nature of the security issue. v1.10.0 addresses this by adding and raising many different exceptions:

  • CertificateExpiredError
  • CertificateNotYetValidError
  • CertificateRejectedError
  • CertificateRevokedError
  • CertificateUntrustedError
  • FingerprintMismatchError
  • HostnameMismatchError

All of these inherit from SecurityError to maintain backward-compatibility.

While this change doesn't alter the way that Rogallo handles this situation right now, it does at least set me up for tackling the work I have planned.


  1. By the looks of things it expired at 2026-10-26T01:52:07+00:00 ↩

blogmore.el v5.4.0

1 min read; 9 GFI

I've just made a very small update to blogmore.el to fix a small bug, and also to update some deprecated code.

The blogmore-new command inserts the result of expanding a template into the buffer when making a new post, and I've not touched that template since I started writing blogmore.el. This includes not updating it when I switched much of the frontmatter-handling code over to proper YAML parsing. The problem here was that the title didn't get quotes around it, which became an issue if there was something like a : in the title; any subsequent attempt to modify frontmatter properties would throw an error.

So this release ensures that the title and the date get quoted right away. I guess, at some point, I should rework this code so that it uses the frontmatter-handling code to set up those properties and, instead, just uses the template for the main body.

I've also changed all uses of things like when-let and if-let to use when-let* and if-let*. It seems that, as of Emacs 31.1, the former are deprecated.

Rogallo v3.2.0

1 min read; 7 GFI

I've just bumped Rogallo to v3.2.0. This release has one small new feature and one wee bug fix.

The new feature is something I found myself wanting a short while ago. I was copying some URIs and then turning them back into Gemtext links in another document; after doing that a few times, I realised that it might be handy to extend the "copy URI" facility in the viewer so that there's a "copy URI as Gemtext" version. To this end, I've added gemtext_link.copy_link_as_gemtext as a viewer widget binding, bound to Shift+c by default.

The fix is a small one to how MIME type checks are done. In one particular case, Rogallo wasn't stripping off any parameters where it should have. This is now fixed.

Recently I found - 9

1 min read; 8 GFI

Introduction

An occasional collection of things I've recently found on the Internet and added to my bookmarks.

DHH Is Way Worse Than I Thought

While a year old at the point of saving this, it's still a pretty good collection of details of problematic things related to DHH. It's only got worse since.

Awesome Steam Frame

An "awesome" list of all sorts of things related to the Steam Frame.

Mach Run

Fun arcade-style flying game that runs well in the browser. A great way to kill 10 minutes.

Hole Punch

A web-based gravity puzzle game.

Gravity Assist

Another web-based gravity puzzle game.

Getting Started With XR in Godot 4.3 Tutorial!

A video tutorial that goes into the basics of getting some VR code going in Godot.

R U STILL THERE?

How well are Reform folk doing after they got jobs they didn't know they had to work at?

You are a tornado

There's plenty of tornado-chasing games out there. Quite a lot of them. Games where you are the tornado... not so many. Here's one.

If you accept something is unethical, its usefulness is irrelevant, isn't it?

A good toot-sized argument against the "both sides balanced" take on the current state of AI use. Or, rather, it's a good argument in favour of the "it's unethical so I won't use it" approach not being stupidly stubborn.

Why is Hacker News like that?

Good essay that goes over the general political feel of Hacker News, and goes into the background of why it is that way.

Free Promotions on Steam

A list of stuff that is currently free on Steam.

Rogallo v3.1.0

2 min read; 10 GFI

Rogallo v3.1.0 is now available. This release is in response to a recent user request.

Right from the start of the development of Rogallo, I ensured that any MIME types that the application couldn't handle were correctly handed off to the operating system, to allow it to work out what to do. While it is possible for me to do some work to allow images inline -- something I might explore at some point in the future -- Rogallo doesn't currently support this and, accordingly, when faced with image/jpeg or image/png, etc, it delegates to the wider environment.

The problem, of course, is that the user might not have a tool in their environment that's capable of taking over the duties of downloading an image from a gemini URI and displaying it. So the next best thing is that Rogallo itself offers to download the file for you. With v3.1.0 this is now an option.

If you encounter a MIME type that hasn't already been marked for always opening in an external tool, there's a new Download button.

Download as an option

If selected, you'll be asked for a location to save the file.

The download dialog

To augment this, I've also added downloading support for links in the viewer. It might be, for example, that you've already marked image/jpeg and image/png as MIME types that should always be handed off to the operating system (perhaps you have a GUI-based client such as Lagrange or Major Tom installed and it's configured to pick up the URI and handle it). In that case, you'd never be shown the dialog that would allow for downloading. So now, on the occasion that you do want to download within Rogallo, you can navigate to the link and press d. The download dialog will then appear, and you can save the content of the link that way.

ℹ️ Note

If you want to change the binding for the link-based download, you can use the recently added UI element binding facility to bind gemtext_link.download_link to something else.

For now, at least, the download process is pretty simple. It follows the same approach as acquiring the content of a URI for display purposes, but instead writes it to the file you picked. There's no "download manager" or similar and no sticky "download directory". These are things I might consider adding in the future.

Rogallo v3.0.0

3 min read; 10 GFI

It's been a while since I last published an update to Rogallo. In part this is because I've had other distractions, but also in part because I've not had a huge need to add any new features of late. For the most part I feel Rogallo is "done"1.

I haven't, however, been doing nothing with the code. On and off, over the last handful of weeks, I've been addressing something that I've wanted to tidy up since the early days of development: application configuration. The majority of my Textual-based applications use a simple JSON configuration file, and that's generally good enough. When I started Rogallo I used the same approach. Rogallo has since grown quite a lot and there's much that can be configured and so the "honking great pile-o-JSON" approach was starting to feel quite untidy.

So Rogallo v3.0.0 addresses this. The headline change is that the single JSON file has been replaced with a number of focused YAML files, and some items that were in the original configuration file have been moved out to either the data directory or the state directory, depending on their purpose.

Now for some details on the changes.

❗ Important

There are a lot of changes to how Rogallo is configured. As is mentioned at the end of this post, Rogallo will make a best effort to migrate your old configuration to the new format. However, as a precaution, you might want to think about making a backup copy of your configuration.json file before upgrading Rogallo.

Focused configuration files

As mentioned above, whereas before Rogallo kept all of its configuration in a single file, it now looks to a number of different YAML files that focus on a different aspect of configuration. These include:

General configuration

For the configuration items that remain, that aren't exactly focused on a particular Rogallo feature, the settings have moved to general.yaml.

Removal of some application commands

Rogallo's design is based around the idea of some "actions" being application-wide commands, and some actions being UI-control-specific. As I worked through the configuration changes I decided that it was time to "demote" some application-wide commands to either being UI-control-specific bindings or just simple configuration properties. With this in mind I've removed the following commands:

  • ChangeCommandLineLocation
  • StripeLinks
  • ToggleANSIEscapeSequenceHandling
  • ToggleCosyLinkNumbers
  • ToggleEmojiRemoval
  • ToggleLinkNumbers

All but ChangeCommandLineLocation are now keyboard shortcuts specific to the viewer widget itself (press F1 when the viewer has focus to get more details). ChangeCommandLineLocation is now a simple configuration property in general.yaml.

UI element action keyboard bindings

From the very start, Rogallo has supported some degree of control over keyboard bindings. As mentioned above, there's a split between "application-wide commands" and "UI-element-specific" actions. Until now it's always been possible to configure the bindings for the former, but never the latter.

In other words: you could always configure the binding for the HandOffToOperatingSystem application command (hands the URI of the currently-viewed document to your OS), but you couldn't change the in-viewer binding for the o key, which opens the URI of the focused link in the OS.

Rogallo v3.0.0 adds support for changing the bindings of the latter. So if you wanted to change o to b for opening a URI externally:

gemtext_link.open_link_externally: b

You can find the bindable IDs for each of the UI controls at the bottom of each page for each of the controls.

New Gophermap badges

Not directly a configuration setup change, but something I noticed while doing the work, was the fact that Rogallo (and the underlying Gophermap library) didn't handle PNG and RTF item types. They're now directly supported.

Conclusion

I believe all of the above changes make it easier to configure Rogallo, and more importantly easier to backup and share the configuration. Technically all of this is one huge breaking change -- everything that was in configuration.json now lives elsewhere. However, I've added some code to Rogallo that detects when you still have a pre-v3.0.0 configuration active, loads up the values, creates the new files, and then renames the old file to configuration.migrated.json. As mentioned near the start of this post, you might want to think about making a backup copy of configuration.json before upgrading.


  1. One last big thing I do want to add is support for tabs. Still to come. ↩

GopherMap v1.1.0

1 min read; 8 GFI

I've just made a small update to GopherMap. While doing some work on Rogallo I noticed that, somehow, I wasn't showing a type "badge" for PNG files (p). I spent a moment or two trying to figure out what was wrong with the code in Rogallo, and then realised that I'd managed to miss out both PNG and RTF files in GopherMap itself.

So this release adds those types.

At this point I believe that GopherMap now knows about all the canonical and most useful non-canonical types.

At some point I should probably look at Gopher+, which I suspect will also mean some changes to Port70.

Rogallo v2.4.0

1 min read; 10 GFI

I've released Rogallo v2.4.0, which contains two new features.

The first is the addition of a feature related to the Gemini Protocol, and it's something I've been meaning to add for a wee while: a trusted host browser/manager. It's a simple enough idea: you might want to have a look at all the host/port pairs that exist in your trusted hosts list and, perhaps, revoke the trust for one or more.

The trusted host browser

From the dialog you can either visit the host/port combination (perhaps you got curious about what you've trusted in the past and want to see what was there), or you can forget the trust. This also somewhat follows on from work done in Rogallo v2.1.0, except rather than having to make the decision when you visit a capsule, you can review all the capsules you currently trust.

If this seems useful, it's called up with the new BrowseTrustedHosts command, bound to Ctrl+Shift+t by default.

The second new feature is something that's been on my TODO list for quite a while, and has mainly been sat there because I wanted the viewer widget in the application to settle down a bit before I tackled this. I'm talking here about in-viewer search. It's a simple enough requirement, but one that's not that straightforward when you're dealing with views of different kinds of text files, views of the source of such documents, and also having to handle things like embedded ANSI escape sequences.

The work is now done, so if the viewer itself is focused, you can press Ctrl+f, enter some text to search for, and then press Ctrl+n to keep moving through all the hits. Once you hit the last match, you'll be told there are no more matches, but then the search will start again from the top.

Performing a text search

You can also cancel an ongoing search with Ctrl+Shift+f.

I'm glad to finally get this added to Rogallo as it's a feature I've been finding myself needing on a good few occasions.