Dropbox Ignore Rules - At last!

Dropbox has finally introduced the equivalent of .gitignore . Go to your Dropbox Preferences settings and find the "Sync" section: in here you may (depending on your version of Dropbox) find a "Set ignore rules" command.
This command will create a file called rules.dropboxignore in your root Dropbox folder (unlike .gitignore, this file only works at the root of your Dropbox folders).
The syntax for rules in this file is explained in comments in the file itself - although I have found that it is possible to use wild cards in slightly more sophisticated ways than are explained in the file.
One problem this solves for me with Dropbox is that it was difficult to prevent Dropbox from synchronising incidental files generated by software compilation processes, such as the files under tmp/cache/* in a Rails project, or those under target/* in a Rust project. The following snippet successfully prevents these from being needlessly shared with Dropbox, at any level of your file-system:

*/target/debug/
*/target/release/
*/target/bench/
*/tmp/cache/

Figshare's OAI-PMH Interface is Broken

Figshare, a repository hosting service, implements OAI-PMH... kinda.

Repositories hosted on Figshare are forced to use the same OAI-PMH Base URL. As far as I can tell, Figshare uses OAI-PMH sets to differentiate between metadata records belonging to particular repositories. So, to use an example documented on the Figshare site, this is how you might harvest some OAI_DC formatted records from a particular repository:

https://api.figshare.com/v2/oai?verb=ListRecords&metadataPrefix=oai_dc&set=portal_63

It seems logical to guess that "portal_63" represents a repository hosted on Figshare. However, I have no idea how you would determine the correct set to use for a given repository, or vice versa, how you would determine the repository for a given set. I could find nothing in the documentation about this.

This means that OAI-PMH's Identify verb is now useless in terms of being able to convey any information about a particular repository hosted on Figshare. Identify on the Figshare BaseURL does work properly:

https://api.figshare.com/v2/oai?verb=Identify

However, passing a set parameter is illegal in the OAI-PMH specification when combined with the Identify verb:

https://api.figshare.com/v2/oai?verb=Identify&set=portal_63

And, indeed, this gives an error on Figshare.

The Identify verb is an important part of the specification. It is commonly used not only to gather some basic information about a repository - such as its name & contact details, but also simply to check that the repository's OAI-PMH interface is functioning. For example, the International Repositories Directory (IRD) automatically checks that repositories have a working OAI-PMH interface by sending a verb=Identify request. This will currently fail for all Figshare hosted repositories.

This could have been avoided by making the "portal_63" component part of the OAI-PMH Base URL path for each repository, instead of over-loading the OAI-PMH sets feature, something like:

https://api.figshare.com/v2/oai/portal_63?verb=Identify

Generation Augmented Retrieval

It just occurred to me how even the term "RAG (Retrieval Augmented Generation)" is a product of the AI-bullshit-marketing hype machine.

It ought to be "GAR (Generation Augmented Retrieval) since the indispensable part of the operation is the "retrieval", not the "generation"....

But no - accurate search which works properly is somehow "augmenting" the natural language processor part...

Throwing Muses, Electric Ballroom, Camden


I went to see Throwing Muses play the Electric Ballroom in Camden last night.

This is the third time I have seen them play (I have also seen Kristin Hersh play solo gigs a couple of times). So I guess you could say I'm a fan.

I first saw Throwing Muses at the Portsmouth Polytechnic in 1989. I'm startled to realise this is thirty six years ago. Fast forward to last night, I assumed the crowd would be ageing indie-kids of my generation, and I was mostly right. But standing next to me, as we waited for the band to come on, were a couple of much younger lads. I told them I had been roughly their age when I first saw the band. It turned out 1989 was a dozen years before they were even born! They had been introduced to Throwing Muses by an uncle, so I guess the band is still finding new audiences after all this time.

It was great to see the band again, even if three-quarters of its members have changed (the lineup has always been quite fluid). The heart of Throwing Muses is, and has always been, Kristin Hersh. She is a mesmerising performer - perhaps because she doesn't overtly perform so much as just share her weird, intricate, fascinating songs with us. She is also a great and original guitarist. Her son, Dylan, played bass (he's really good!) and I guess he too wasn't even born in 1989....

I didn't plan to go into this gig thinking about the passing of time, but those were the thoughts that somehow crept up on me. The songs of Throwing Muses and Kristin Hersh have been a constant for me since my mid-teens. It was weird to hear Soap and Water - introduced by Kristin last night as "an old song, and kind of a stupid one!". I can vividly remember hearing that for the first time, in the bedroom of a friend, who had just bought an early EP called The Fat Skier. That EP grabbed my attention like few records have ever done - I think I knew straightaway that I had discovered something special.

Anyway - a great gig, covering decades of songs from a prolific songwriter. Many just sounded great on the night, especially the higher energy songs - Sunray Venus near the start, Slippershell, and Bright Yellow Gun as the perfect final encore. Other songs had a more personal impact - I actually had a little shiver when I recognised the opening of Colder, a song I used to play over and over the summer I bought the vinyl of House Tornado. And similarly - hearing Bea played live and remembering that one from the 1989 gig.

It makes me happy to realise that there are some young folk discovering this music for the first time and, like me nearly forty years ago, realising that its something special.

Here's the crowd-sourced set-list in case you're interested.

Using CloudFlare Turnstile to protect certain pages on a Rails app

https://bibwild.wordpress.com/2025/01/16/using-cloudflare-turnstile-to-protect-certain-pages-on-a-rails-app/

There is a growing problem of so-called "bots" harvesting content from repositories in an aggressive manner. They are often poorly designed and have no care for the bandwidth or processing capacity they demand from the repository as they attempt to "hoover" up all available content (increasingly to use for AI training purposes). The result of this is to impact - sometimes severely - on the performance of the repository.

This piece by Jonathan Rochkind describes approaches to mitigating this problem. In particular, it describes an interesting approach to blocking only certain resources - e.g the search function - from machine processes, while leaving content resources freely available for machine processes to access.

Adding Icons To Obsidian's File Explorer

There are plugins available for adding icons to the Obsidian file-explorer, but I decided not to use them for two reasons:

  1. I'm trying to maintain a "plugin diet", on the grounds that the more plugins I add to Obsidian, the more likely I will hit problems related to incompatibility and performance
  2. The plugins I tried, although mostly functional, were nonetheless buggy.

Instead, it is possible to decorate the file-explorer with plugins using nothing other than CSS, via the Obsidian CSS "snippets" feature, and the standard set of Unicode emoji characters. This appeals to me because it avoids the need for a plugin just for what is largely a cosmetic concern.

There are two ways to add emoji to files:

Rendering Images with Hugo

This website is served as static HTML, compiles by a really capable "static-site-generator" called Hugo. I had a problem to solve with rendering images here: sometimes I wanted an image which is local to a particular blog post to also show up in the homepage, which serves the most recent posts. The problem is that the relative URL for the image is different when that content is served on the homepage. I don't want to hard-code absolute URLs, but I do want to use the sources of the webpage in different parts of the website. Therefore, I needed Hugo to somehow intelligently re-write those URLs when compiling the website.

This is where Hugo's relatively new Markdown render hooks come in. I've added the following code to a partial under layouts/_default/_markup/render-image.html

{{ $url := urls.Parse .Destination }}
{{ if or (eq $url.IsAbs true) (hasPrefix .Destination "/") }}
    <img src="{{ .Destination }}" title="{{ .Title }}" alt="{{ .Title }}"/>
{{ else }}
    <img src="{{ .Page.Permalink }}/{{ .Destination }}" title="{{ .Title }}" alt="{{ .Title }}"/>
{{ end }}

This has the effect of prepending the page's absolute URL to the image path at compile time. It is invoked every time a Markdown image element is encountered in the sources. If the image is not local to the page, then the image HTML tag is rendered with the URL unchanged (e.g for external images, or for images served from a folder relative to the webroot, rather than the current page's folder.)

Hugo's render hooks are an interesting and useful addition. As well as images, you can specify render hooks for:

  • image
  • link
  • heading
  • codeblock