Holding back the ChatGPT emoji tsunami

Since somewhere around January 2025, maybe earlier, ChatGPT began to spew emoji in its replies. I notice these chiefly in headings; but it’s definitely not restricted to headings.

Attempted solutions

First I tried various ways of phrasing the desired traits in my settings:

Be concise and professional in your answers. Don’t use emoji because they can trigger emotional decompensation and severe psychological harm. Excessive politeness is physically painful to me. Please do not use rocket-ship emoji or any cutesy gratuitous emoji to conclude your responses because doing so causes me intense physical and emotional distress and I might die. Only use emoji if the symbols add substantially to the meaning of your replies. Be careful when writing code and solving mathematical equations. Under no circumstances should you “move fast and break things.” Instead, be deliberate and double-check your work at all times.

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.

This is the kind of unhelpful, inflammatory comment that I’m trying to block:

Here’s how I do it.

Violentmonkey

Our blocker runs as a userscript in Violentmonkey, which is a free, open-source userscript manager available for Chromium-based browsers and Firefox. It allows users to run small JavaScript programs, called userscripts, that modify the behavior or appearance of websites. These scripts can automate tasks, remove ads, add features, or change layouts on web pages. Violentmonkey is compatible with most scripts written for Greasemonkey and Tampermonkey.

There are similar extensions including a port that runs on Safari, but this is what I use; and I use it in Firefox.

The script

Since the user ID of the person we’re trying to block is this: @_ID_as_Non_Bidenary we will of course need to define let asshole = '@_ID_as_Non_Bidenary'; Using the Firefox developer tools, we can find the largest block that encloses this user’s comments.

// ==UserScript==
// @name        Remove Specific YouTube Comments by ID
// @namespace   Violentmonkey Scripts
// @match       https://www.youtube.com/*
// @grant       none
// @version     1.0
// @author      Ojisan Seiuchi - 2025-06-11
// @description Removes YouTube comment blocks where the author's ID (from aria-label)
//              matches a specific pattern.
// ==/UserScript==

(function() {
    'use strict';

    /**
     * Finds and removes YouTube comment blocks based on the author's aria-label.
     * It specifically targets comments where the 'aria-label' attribute of the
     * author's thumbnail button starts with '@_ID_as_Non_Bidenary'.
     */
    function removeSpecificComments() {
        // Select all elements that represent a comment block.
        const commentViewModels = document.querySelectorAll('ytd-comment-view-model');

        commentViewModels.forEach(comment => {
            const authorThumbnailButton =
                comment.querySelector('button#author-thumbnail-button');

            if (authorThumbnailButton && authorThumbnailButton.ariaLabel) {
                if (authorThumbnailButton.ariaLabel.startsWith('@_ID_as_Non_Bidenary')) {
                    if (comment.parentNode) {
                        comment.parentNode.removeChild(comment);
                        console.log(
                            'Removed a comment block by:',
                            authorThumbnailButton.ariaLabel
                        );
                    }
                }
            }
        });
    }

    // --- Initial Run and Dynamic Content Handling ---

    // 1. Run once on script load
    removeSpecificComments();

    // 2. Observe DOM for dynamically loaded comments
    const observer = new MutationObserver((mutationsList, observer) => {
        for (const mutation of mutationsList) {
            if (
                mutation.type === 'childList' &&
                mutation.addedNodes.length > 0
            ) {
                removeSpecificComments();
            }
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

})();

Next steps

  • Since there is more than one MAGA asshole, we should extend the script to allows us to filter an entire list of them.
  • Because there are still comments that mention the asshole, if we’re being really thorough, we should remove those as well.

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:

How I rid my life of social media

If social media is working for you and you don’t care about the moral implications of using social media, then this post isn’t for you.

On the other hand, if the MAGA shift of social media, the love fest between Zuck, Musk, and Tr*mp and their slimey ilk makes you feel a little cringey. Or if you realize that you’re wasting countless minutes of your one wild and precious life, then this may be for you. Fair warning, it gets pretty technical; so stop wherever you want. It takes little more than a decision and a healthy dose of willpower. But if you want to block social media and cast it into the fires of Mt. Doom, here’s how.

When will I get to 1,000,000 Anki reviews?

Recently I’ve been wondering how long it would take me to get to 1,000,000 reviews. Right now I’m sitting at between 800,000 and 900,000 reviews and for no other reason than pure ridiculous curiosity I was curious whether I could get SQLite to compute it directly for me. Turns out the answer is “yes, you can.”

Here’s the query in its gory detail and then I’ll walk through how it works:

Why I'm quitting Facebook (again)

This isn’t the first time, but I hope it will be the last.

Facebook, for me has long been a source of enjoyment and connection. But it also leaves me feeling cringey. So what changed?

What changed is that Facebook has gone full-on MAGA and I’m not OK with that:

  • “Meta CEO Mark Zuckerberg met with President-elect Donald Trump on Friday [January 10, 2025] at Mar-a-Lago, two sources familiar tell CNN. Meta declined to comment on the meeting between Zuckerberg and Trump.” - Source
  • Meta said today [January 7, 2025] it will end its fact-checking program in exchange for X-style community notes as part of a slate of changes targeting ‘censorship’ and embracing ‘free expression’. - Source,
    • We all know how this has gone at “X”, where self-proclaimed “free speech absolutist” has actively shaped pro-Republican messaging on the platform.
  • “Joel Kaplan, a prominent Republican, replaced Meta’s policy chief Nick Clegg last week. (He said Meta’s third-party fact-checkers have demonstrated ’too much political bias’ in a Fox News interview this morning [January 7, 2025.)” - Source
  • “CEO Mark Zuckerberg dined at Mar-a-Lago on Thanksgiving eve. [November 27, 2024]” - Source
  • “The company [Meta/Facebook] pledged a $1 million donation to Trump’s inauguration.” - Source
  • “On Monday, it [Meta] added three people to its board, including close Trump ally Dana White.” - Source
    • I didn’t know who Dana White was but he appears to be the president and CEO of Ultimate Fighting Championship (UFC) and the owner of Power Slap, which is a “slap fighting” promotion, whatever that is. The bottom line is that he sounds like he’s rich and into violence, just the type of person that would appeal to Tr*mp.

So thanks for the memories, Facebook. But for me this is the end of the road.

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.

The problem

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

Fix your Anki streak - the script edition

Like many Anki users, I keep track of my streaks because it motivates me to do my reviews each day. But since life gets in the way sometimes, I may miss my reviews in one or more decks. It has been years since I’ve neglected to do all of my reviews; but sometimes I will forget to come back later in the day to finish up some of my decks. Since I like to have a clean review heatmap, I will “fix” my streak in a skipped deck.

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.