#!/usr/bin/env python # coding: utf-8 # I'm a big fan of Anki, which is a flashcard software written in Python. # # Sometimes, it's interesting to know how the software you like works. In this case, there are already existing guides, for instance this one: https://www.juliensobczak.com/write/2016/12/26/anki-scripting.html. # # In this exploration, I'm building upon this guide to explore my collection and list particular Japanese cards for further editing. # # Opening the database # I'm working on a Mac. Where is the Anki data located in this case? Searching around in the GUI, I've found the following locations: # In[1]: import os path_to_anki = os.path.expanduser('~/Library/Application Support/Anki2/User 1') path_to_collection = os.path.join(path_to_anki, 'collection.anki2') # To make use of the Anki API, we need to append the path to the Anki library to our Python path. As suggested in the above blog, I've cloned the Anki repo for the purpose of this blog post. # # ```shell # git clone https://github.com/dae/anki.git # ``` # In[2]: import sys sys.path.append(os.path.expanduser('~/workspace/anki')) # We can now access the API used by the Desktop Anki App itself and open my existing database to display some of the Japanese kanji I've used in my decks. # In[3]: from anki.storage import Collection col = Collection(path_to_collection, log=True) for cid in col.findNotes("tag:RTK"): note = col.getNote(cid) front = note.fields[0] print(front, end='') col.close() # # A more complicated query # Where this gets interesting is that we can quite easily extract some more information about the characters, for instance to sort them. Here, my kanji cards can be ordered by "Heisig number" which should make more sense than the above raw listing. # In[4]: col = Collection(path_to_collection, log=True) fields = [col.getNote(cid).fields for cid in col.findNotes("tag:RTK")] fields = sorted(fields, key=lambda items: int(items[4])) print("".join([field[0] for field in fields])) col.close() # # Exporting to HTML with related vocabulary # The last thing I would like to show here is how to use this data to create a mapping of kanji to words containing these kanji. What I mean by this, is that I also have a list of Japanse words that are made of kanji. I would like to produce a table that shows, for each kanji, the associated vocabulary I already have in my deck. Let's try this with the kanji 出. I can list the vocabulary cards that have this character in them: # In[5]: col = Collection(path_to_collection, log=True) try: notes = col.findNotes('出 deck:Japanese "note:Japanese (expression, meaning, reading)"') for cid in notes: note = col.getNote(cid) expression = note.fields[1] if '出' in expression: print(expression) finally: col.close() # There we are: I can list all expressions associated with a given kanji. Let's now write an HTML file that lists the Kanji and associated vocabulary, in Heisig order. # In[6]: kanjis = [field[0] for field in fields] mapping = {} col = Collection(path_to_collection, log=True) try: for kanji in kanjis: query = '{} deck:Japanese "note:Japanese (expression, meaning, reading)"'.format(kanji) notes = col.findNotes(query) vocab = [] for cid in notes: note = col.getNote(cid) expression = note.fields[1] if kanji in expression: vocab.append("{} ({}): {}".format(expression, note.fields[2], note.fields[0])) mapping[kanji] = vocab finally: col.close() # In[7]: path_to_html = os.path.join(os.path.expanduser('~/workspace/anki'), 'kanji_vocab.html') with open(path_to_html, 'w') as f: f.writelines('') f.writelines('') f.writelines('') for kanji, field in zip(kanjis, fields): rendered_kanji = '{} - {} {}'.format(field[4], kanji, field[1]) rendered_vocab = '' for word in mapping[kanji]: rendered_vocab += "
  • {}
  • ".format(word.strip().replace('
    ', ' ').replace(kanji, '{}'.format(kanji))) line = """
    {}
    """.format(rendered_kanji, rendered_vocab) f.writelines(line) f.writelines('') # Using the above, I've ended up with a nice HTML file that looks like this. # # Embedded Image # # # # # # That's it! I hope you've enjoyed this post about using the Anki API for advanced access of your Anki database. # *This post was entirely written using the IPython notebook. Its content is BSD-licensed. You can see a static view or download this notebook with the help of nbviewer at [20190323_AnkiKanji.ipynb](http://nbviewer.ipython.org/urls/raw.github.com/flothesof/posts/master/20190323_AnkiKanji.ipynb).*