Dynamic DNS - auto-updating from macOS

To run a little project (that I’ll describe at some point in the future) I have to run a small web server from my home computer, one that happens to run macOS. More than anything else, this is just a reply of what I did to get it running in case: a) I have to do it again, or b) Someone else can find it useful.

Sign up for dynamic DNS service

I signed up for service with dynv6 because I saw it recommended elsewhere and it didn’t look creepy like some of the other options. I just signed up with email - through an email proxy anonymizer, because I’m paranoid. After verifying my email, I was able to create a new “zone”, basically a record of my public IP address linked to custom DNS.

Updating the IP address.

Most of us don’t have static public IP addresses, so some mechanism is required to keep the custom DNS and your public IP address linked.

I used the ddclient tool Github to keep my dynamic DNS up-to-date. The Homebrew install works well:

brew install ddclient

Now we need to configure the ddclient tool with a ddclient.conf file. This is a little struggle because the syntax offered when you create a zone on dynv6 is not correct. Here is the syntax that works:

# ddclient configuration for dyndns
#
# /usr/local/etc/ddclient/ddclient.conf
syslog=yes
ssl=yes
use=web, web=checkip.dyndns.com/, web-skip='Current IP Address'
server=dynv6.com
protocol=dyndns2
login=none
password='YOUR PASSWORD'
YOUR_ZONE

YOUR_PASSWORD is the password key that you obtain from dynv6. YOUR_ZONE is the full zone name.

To check that the updater is working:

sudo /usr/local/opt/ddclient/sbin/ddclient -verbose -noquiet

If that succeeds, then you can set it up on a schedule:

sudo cp -fv /usr/local/opt/ddclient/*.plist /Library/LaunchDaemons
sudo chown root /Library/LaunchDaemons/homebrew.mxcl.ddclient.plist

sudo launchctl load /Library/LaunchDaemons/homebrew.mxcl.ddclient.plist

No sir, I do not want Big Sur

Maybe I’m just getting cranky after over a year of on-again-off-again pandemic lockdowns, but I’ve had it with Apple’s heavy-handed attempts to get me to upgrade to Big Sur. Mind you, I have nothing against it. It’s just an operating system. I don’t particularly like it’s translucent bubbly iOS look. But I could live with.

But I don’t want it. I depend on a very unorthodox setup. I have a lot of infrastructure tools that depend on certain versions of Python to be in just the right place. Every single macOS major upgrade breaks all of this and I spend days picking up the pieces. I’m tired of Apple messing with it. So when my system launched into what seems like an unbidden upgrade process today, I lost it.

I’m not exactly sure how the upgrade got triggered today. In my frustration I may have hit the wrong button or was otherwise too hasty. But what follows is the documentation of my quest to never face this again.

First, in System Preferences → Software Update, uncheck “Automatically keep my Mac up to date”. I already had this checked; so digging deeper there is an “Advanced…” button to deal with. Uncheck everything in the Advanced pane.

Next up, Terminal. In Terminal (or my preference, iTerm)

softwareupdate --ignore "macOS Big Sur"

which should report:

Ignored updates:
(
)

Software Update can only ignore updates that are eligible for installation.
If the label provided to ignore is not in the above list, it is not eligible
to be ignored.

Ignoring software updates is deprecated.
The ability to ignore individual updates will be removed in a future release of macOS.

There is a nuclear option known as bigsurblocker that apparently does what it says on the tin. I’m holding that one in reserve but it can be downloaded from Github if needed.

Dynamically loading Javascript in Anki card templates

The ability to execute Javascript in Anki card templates offers users flexibility in displaying data. In Anki 2.1, though, the asynchronous execution of Javascript means that user script functionality is not entirely predictable. This post on r/Anki discusses an approach for dynamically loading Javascript resources and ensuring that they are available when the card is displayed. Since I modularize my Javascript code so that it can be flexibly deployed to different card types, I extended this method to allow the template developer to load multiple scripts in one <script> block.

Fixing CodeRunner jQuery injection

CodeRunner is one of my favourite development environments on macOS. I use it for small one-off projects or for testing concepts for integration into larger projects. But in version 4.0.3, jQuery injection in a custom HTML page is broken, giving the error: It’s probably due to some unescaped bit of code in their minified jQuery, but I didn’t have time to work that hard. Instead I reported the error to the developer an fixed it myself.

Extending the Anki Cloze Anything script for language learners

It’s possible to use cloze deletion cards within standard Anki note types using the Anki Cloze Anything setup. But additional scripts are required to allow it to function seamlessly in a typical language-learning environment. I’ll show you how to flexibly display a sentence with or without Anki Cloze Anything markup and also not break AwesomeTTS. Anki’s built-in cloze deletion system The built-in cloze deletion feature in Anki is an excellent way for language learners to actively test their recall.

Complete fix for broken Knowclip .apkg files

I think this is the last word on fixing Knowclip .apkg files. I’ve developed this in bits and pieces; but hopefully this is the last word on the subject. See my previous articles, here and here, for the details. This issue, again, is that Knowclip gives these notes and cards sequential id values starting at 1. But Anki uses the note.id and the card.id as the creation date. I logged it as an issue on Github, but as of 2021-04-15 no action has been taken.

Fixing Knowclip .apkg files: one more thing

(N.B. A much-improved version of this script is published in a later post) Fixing the Knowclip note files as I described previously, it turns out, is only half of the fix with the broken .apkg files. You also need to fix the cards table. Why? Same reason. The rows are number sequentially from 1. But since Anki uses the card id field as the date added, the added field is always wrong.

Fixing Knowclip Anki apkg creation dates

(N.B. A much-improved version of this script is published in a later post) Language learners who want to develop their listening comprehension skills often turn to YouTube for videos that feature native language content. Often these videos have subtitles in the original language. A handful of applications allow users to take these videos along with their subtitles and chop them up into sentence-length bites that are suitable for Anki cards. Once such application is Knowclip.

Generating HTML from Markdown in Anki fields

I write in Markdown because it’s much easier to keep the flow of writing going without taking my hands off the keyboard. I also like to write content in Anki cards in Markdown. Over the years there have been various ways in of supporting this through add-ons: The venerable Power Format Pack was great but no longer supports Anki 2.1, so it became useless. Auto Markdown worked for a while but as of Anki version 2.

Pre-processing Russian text for the AwesomeTTS add-on in Anki

The Anki add-on AwesomeTTS has been a vital tool for language learners using the Anki application on the desktop. It allows you to have elements of the card read aloud using text-to-speech capabilities. The new developer of the add-on has added a number of voice options, including the Microsoft Azure voices. The neural voices for Russian are quite good. But they have one major issue, syllabic stress marks that are sometimes seen in text intended for language learners cause the Microsoft Azure voices to grossly mispronounce the word.