Scheduling synchronization of Anki databases on OS X

While working on a project to automatically collect statistics on my Anki databases (stay tuned…) I worked out a system for scheduling synchronization from my desktop OS X machine.

Prerequisites

  • LaunchControl is a GUI application that lets you create and manage user services on OS X
  • Anki is a spaced repetition memorization software system

The solution relies on Automator. Normally, I don’t care much for Automator. It has too many limits on what tasks I can accomplish and workflows created with it are often fragile. However, in this case, we take advantage of its workflow recording feature. We’re going to record the process of opening Anki, selecting the profile to sync, then quitting Anki. This sequence of events ensures that the database on the local system is synchronized with the remote version.

Creating a new workflow

  • Start Automator and create a new workflow document.
  • Make sure that Anki resides in the OS X Dock because our workflow is going to look for it there.
  • Click “Record” to begin recording the workflow.
  • Click “Anki” in the Dock.
  • After Anki launches, select the profile that you want to load. (I’m note sure whether you see this dialog when you have only a single profile. I have three so I see a dialog box asking which one to load. If you don’t see this window, just skip this step.)
  • Anki will synchronize. When it is done, select “Quit” from the menu bar. Anki will sync again. Since we didn’t change any content this is an unnecessary step, but Anki does it automatically.
  • After Anki has finished synchronizing, click the “Stop” button on the recording window.

Watch Me Do Actions

Saving the workflow

You should now have an unsaved sequence of actions in the Watch Me Do group as above.

  1. Save the workflow as a workflow first. This will allow you to edit the workflow in some way in the future if you need to.
  2. Convert the workflow to an application. This will allow you to run it from the command line later on.
  3. Save the converted workflow to an application file type. Name it anything you like. I called it ankisync.
  4. Quit Automator

Allowing the workflow to control the computer

The privacy and security features on OS X may not allow you to run the Automator workflow from the command line without adding it to the list of trusted application.

Add ankisync

  1. Open the Security and Privacy section of the System Preferences
  2. Click on the Privacy tab
  3. Click on Accessibility in the source list
  4. Drag the newly created workflow application into the list and grant it permission to control the computer.

This should be enough to allow the workflow to do its job.

Test that you can launch the workflow from the command line

  1. Open the Terminal or iTerm depending on your preference. I prefer iTerm but Terminal is pre-installed on OS X.
  2. Launch the workflow as follows:
$ open /path_to_your_workflow_app/ankisync.app

If this doesn’t properly launch your workflow, check that the everything is authorized properly in System Preferences.

Schedule the workflow to run using LaunchControl

Add ankisync to LaunchControl

  • Add a new User Agent in LaunchControl by selecting User Agents from the job types list and clicking the + button at the bottom of the source list.
  • Use the reverse DNS standard for naming your job.
  • Drag a “Start calendar interval” item on the job.
  • Configure the calendar interval according to the time you would like the job to run.
  • In the text box “Program to run” add open and the path of the workflow application.
  • Save your job and that should be it!

You should be aware that this relies on a somewhat fragile set of UI actions; but when it works, you’ll have a automated method for keeping your Anki collection in sync.

Resizing of images for Anki with Hazel and ImageMagick

I use Anki to study foreign language vocabulary. It’s the de facto spaced repetition software for memorization.^[Yes, I’m aware that others exist. I’ve tried many but always have come back to Anki.] When making flashcards for language learnings, I try to use imagery as much as possible. So a card may have a Russian word on one side and just an image on the opposite side. (Since I already know the English word that the image represents, why not try to engage a different part of the brain to help with memorization?)

If you use Anki on multiple devices, then synchronization is a key step. However, image size becomes a limiting factor for sync speed. Since only a small image is often necessary to convey the intended meaning, we can improve the sync efficiency by using them while not sacrificing any meaning. Bulk, efficient resizing of images for Anki cards is an important part of the process for me.

Here I’ll describe a process of automatically processing images for use on Anki cards using Hazel and ImageMagick. Sorry, PC and Linux users, this is OS X only.

Hazel

Hazel is an indispensable tool for OS X automation. It’s a little hard to describe all of the things that it can do, but suffice it to say that it is a background application that watches folders and then performs rules on the contents of those folders. You will need to buy it for this process to work.

ImageMagick

ImageMagick is a well-known Swiss army knife of image process. You will need to install it which you can do using Homebrew or this installer

The process

Image handling directories

I created two directories on the Desktop: ankibound and ankidone. Incoming images go into ankibound. The rule we create in Hazel will watch ankibound, convert the image to a smaller size, adjust the quality slightly, strip the unused metadata and move the processed file to ankidone.

Hazel rule to process incoming images

Hazel rule list

If you are not familiar with creating Hazel rules, you first add the folder to be watched (ankibound) and add a new rules which we’ve cleverly named “Resize images for Anki.” Then we just need to add the criteria and the steps for the rule.

Hazel criteria and actions

We’ve specified the type of file to be processed inside of ankibound and added two actions:

  • resize incoming images using ImageMagick on the command line, and
  • move the processed images to ankidone.

The code for image scaling is simple, it’s just:

/usr/local/bin/convert "$1" -adaptive-resize 150x150 -quality 80\
 -density 72 -strip "$1"

Now, any image that you save to ankibound will get resized to 150px in its largest dimension and moved to ankidone, ready to import into your Anki cards. Of course, you could also use the ImageResizer add-on for Anki but I like being in control of my own process and being able to deal with images without having to get them onto the clipboard. Either way works.

References

Writing Hexo filters

Hexo, the static blogging system that I use is very extensible and provides numerous hooks into generation pipeline.

While working on a Russian language blog that’s coming online soon, I had the opportunity to write a filter to render Cyrillic text in a different font than the rest of the body text.

Markup filter use case

I wanted to set the Cyrillic text apart both in color, typeface, and font weight. Although I could have extended Hexo using a new tag, I decided to use a filter so that after rendering HTML anywhere on the blog, items demarcated by double pipes || would be replaced by a new <span>.

Fine-tuning caching for S3-hosted static blogs using AWS CLI

Because the blogging system that I use doesn’t apply finely grained object-level caching rules, I end up with objects such as images that cache appropriately but an index.html page that does not. I don’t want client browsers to hang on to the main index.html page for more than an hour or so because it should update much more frequently than that as its content changes.

It’s possible that I could dig around under the hood of hexo and create a version that applies customized caching rules. Instead, I make a second pass over the content, adjusting the Cache-Control and other metadata according to my needs. For this task I use the Amazon Web Services command line interface AWS-CLI.

Modern textbook design: an architecture for distraction

The design of textbooks in common use at all levels from elementary school through high school are appallingly bad. I’ve come to this conclusion after several years of carefully looking at my sons’ books as they went through public middle and high school. What follows is a critique of very common design “features” in these books in reference to visual information design principles. Since I’m not a subject expert in the content of the disciplines presented, I’ll just refer to the visual design, typography and information design principles in general.

Trump, the conspiracy theorist

One of the most striking features of the GOP front-runner is his special fondness for conspiracy theories. From the (non-existent) connection between vaccines and autism to the “real culprits” behind 9/11, he shows the typical clustered endorsement of multiple conspiracy theories.

The question about whether this a form of pandering or a genuinely held set of perspectives is interesting, though barely relevant. In the former case, the abandonment of reason to achieve a political goal is an egregious fault. In the latter case, it sheds considerable light on crucial decision-making capacities. Endorsement of conspiracy theories requires a set of cognitive biases that fundamentally hobble evidence-based decision making.

The spread of anger in social networks and its implications for political violence

An ingenious study using the massive Weibo network revealed insights into the spread of certain emotions through social networks. Weibo is a social network platform not unlike Twitter. It is also hugely popular in China with millions of users making it an ideal platform for understanding how emotional states between socially-connected users correlate with each other.

But the highest correlation by far was among angry users. Rui and co say anger strongly influences the neighbourhood in which it appears, spreading on average by about 3 hops or degrees. “Anger has a surprisingly higher correlation than other emotions,” they say.

anki_tool: low level manipulation of Anki databases

Speaking of Anki, here’s a Swiss Army knife of database utilities that provides searching, moving and renaming functions from the command line.

On GitHub.

You can do things like this to rename and collect tags:

$ anki_tool mv_tags '(dinosaur|mammal)' animal

Looks cool.

JavaScript in Anki cards

[N.B. 2016-03-26 Nathan Ifill pointed out that it is possible to use Anki’s built-in conditional replacement feature to do what I’m illustrating. I’ll have to work on another example!]

Anki is a widely-used flashcard application. If you’re learning a foreign language and you’re not using Anki, you should be.

If you are using Anki and are picky about the appearance of the cards, you should know that JavaScript can be used in the card template. This opens up a number of possibilities for dynamic cards. I’m just touching on the technique here.

Organizing knowledge for memorization

Memorization has a bad reputation in education today, but it underpins the abilities of all sorts of high-performing people. I often refer to this article from 1999 about how to better organize information for memorization.

My favorite pieces of advice:

  • Do not learn (memorize) if you do not understand.
  • Stick to the minimum information principle.
  • Use imagery
  • Avoid sets and enumerations
  • Use mnemonic techniques.