Programming

Removing inflammatory YouTube comments programmatically

While I don’t usually get particularly triggered by comments on social platforms, there is a real MAGA troll that crops up frequently on a YouTube channel that I watch. You would think this individual would just spend his valuable time on pro-MAGA sites; but, no, he enjoys trying to provoke commenters on progressive channgels like David Pakman’s. Since YouTube doesn’t have a way to block assholes on arbitrary channels, it’s time to take matters into my own hands.

Wednesday, June 4, 2025

When you run a script as a systemd service, you have to define its environment variables in the service filem, e.g.

# Set your environment variables here
Environment="OJISAN_INCREMENTAL_UPLOAD_API_KEY=YOUR_ACTUAL_API_KEY_VALUE"
Environment="OJISAN_INCREMENTAL_UPLOAD_DB_USER=your_db_user"
Environment="OJISAN_INCREMENTAL_UPLOAD_DB_PW=your_db_password"
Environment="OJISAN_INCREMENTAL_UPLOAD_DB_NAME=your_db_name"
Environment="DB_HOST=your_db_host"

Tuesday, June 3, 2025

Show systemd running services as a list

systemctl list-units --type=service --state=running --no-pager

Thursday, April 17, 2025

vim: Jump to specific character on a line

In Vim, to jump to a specific character on a line, you can use the following commands:

  • f{char} - Jump to the next occurrence of {char} on the current line
  • F{char} - Jump to the previous occurrence of {char} on the current line
  • t{char} - Jump until (one position before) the next occurrence of {char}
  • T{char} - Jump until (one position after) the previous occurrence of {char}

For your specific example of “go to first #”:

Creating Obsidian tables of content

When viewing longer Markdown notes in Obsidian, tables of content (TOC) help a lot with navigation. There is a handful of community plugins to help with TOC generation, but I have two issues with them:

  1. It creates a dependency on code whose developer may lose interest and eventually abandon the project. At least one dynamic TOC plugin has suffered this fate.
  2. All of the TOC plugins have the same visual result. When you navigate to a note, Obsidian places the focus at the top of the note, beneath the frontmatter. That’s fine unless the content starts with a TOC markup block, in which case it’s not the TOC itself that is displayed, but the markup for the TOC plugin itself as depicted in the image below.

For me the solution was to write a script that scans the vault looking for this pair of markers:

Registering a custom collation to query Anki database

While working on a project that requires querying the Anki database directly outside of the Anki desktop application, I encountered an interesting issue with sqlite3 collations. This is is just a short post about how I went about registering a collation in order to execute SQL queries against the Anki db.

        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
        
    </div>
    <div class="callout-title-inner">CAUTION</div>
</div>
<div class="callout-content" >
    Before you run anything that accesses the Anki database, you absolutely should backup your database first.
</div>

The problem

Let’s try a simple query. Open the Anki database:

An API (sort of) for adding links to ArchiveBox

I use ArchiveBox extensively to save web content that might change or disappear. While a REST API is apparently coming eventually, it doesn’t appear to have been merged into the main fork. So I cobbled together a little application to archive links via a POST request. It takes advantage of the archivebox command line interface. If you are impatient, you can skip to the full source code. Otherwise I’ll describe my setup to provide some context.

A Keyboard Maestro action to save bookmarks to Espial

So this is a little esoteric, but it meets a need I encountered; and it may meet yours if you use Espial, Keyboard Maestro and are on macOS.

For several years I’ve been using Espial a bookmark manager that looks and feels like Pinboard, but is both self-hosted and drama-free1. Espial is easy to setup, stores its data in a comprehensible sqlite database and has an API, which comes in handy when it came to solving the problem I encountered.

FreeRTOS stack size on ESP32 - words or bytes?

Although FreeRTOS1 is an indispensible tool for working on anything more than the simplest application on ESP32, there are some difficulties to master, such as multitasking. Multitasking using FreeRTOS is accomplished by creating tasks with xTaskCreate() or xTaskCreatePinnedToCore(). In both of these calls, one of the parameters is uxStackDepth which is the allocated stack size for the task. The FreeRTOS documentation on the subject is clear about the units for uxStackDepth:

Telling Hazel not to match locked files

Hazel is a centrepiece of my automation suite on macOS. I rely on it to watch directories and take complex actions on files contained within them. Recently I discovered an issue with files that are locked in the Finder. If files that otherwise match all the rules are locked, then Hazel will attempt to execute the rules. But the locked status may preclude execution. For example, I began seeing frequent Hazel notifications popups such as: