--- a/py/gadict_srs_anki.py Sat Nov 12 12:39:02 2016 +0200
+++ b/py/gadict_srs_anki.py Sat Nov 12 13:55:08 2016 +0200
@@ -125,20 +125,7 @@
from anki.exporting import AnkiPackageExporter
-class AnkiDbBuilder:
-
- def __init__(self, tmpdir, name):
- self.tmpdir = tmpdir
- self.name = name
-
- self.collection = collection = anki.Collection(os.path.join(self.tmpdir, 'collection.anki2'))
-
- deck_id = collection.decks.id(self.name + "_deck")
- deck = collection.decks.get(deck_id)
-
- model = collection.models.new(self.name + "_model")
- model['did'] = deck_id
- model['css'] = """
+MODEL_CSS = """
.card {
font-family: arial;
font-size: 20px;
@@ -205,41 +192,172 @@
}
"""
- collection.models.addField(model, collection.models.newField('From'))
- collection.models.addField(model, collection.models.newField('To'))
+def note_add_tags(note, tags):
+ if isinstance(tags, str): note.tags = [tags]
+ elif isinstance(tags, list): note.tags = tags
+ elif tags is None: pass
+ else: raise Exception('Expecting string or list of tags...')
+
+
+class AnkiDbBuilder:
+
+ def __init__(self, tmpdir, name):
+ self.tmpdir = tmpdir
+ self.name = name
+
+ self.collection = collection = anki.Collection(os.path.join(self.tmpdir, 'collection.anki2'))
+
+ deck_id = collection.decks.id(self.name)
+ deck = collection.decks.get(deck_id)
+
+ # It is essential to keep model['id'] unchanged between upgrades!!
+ MODEL_ID = int(hashlib.sha1(self.name).hexdigest(), 16) % (2**63)
+
+ ################################################################
+ # Regular card model. SafeBack doesn't include examples to not spoil
+ # word spelling.
+ model = collection.models.new(self.name + "_frontback")
+ model['did'] = deck_id
+ model['css'] = MODEL_CSS
+
+ collection.models.addField(model, collection.models.newField('Front'))
+ collection.models.addField(model, collection.models.newField('Back'))
+ collection.models.addField(model, collection.models.newField('SafeBack'))
+
+ tmpl = collection.models.newTemplate('Front -> Back')
+ tmpl['qfmt'] = '<div class="front">{{Front}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="back">{{Back}}</div>'
+ collection.models.addTemplate(model, tmpl)
- tmpl = collection.models.newTemplate('From -> To')
- tmpl['qfmt'] = '<div class="from">{{From}}</div>'
- tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="to">{{To}}</div>'
+ tmpl = collection.models.newTemplate('SafeBack -> Front')
+ tmpl['qfmt'] = '<div class="safe-back">{{SafeBack}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="front">{{Front}}</div>'
+ collection.models.addTemplate(model, tmpl)
+
+ # Equivalent of ``collection.models.add(model)`` without setting
+ # auto-generated ID.
+ # Increment +1 is for keeping model['id'] unique from previous v0.9 release.
+ model['id'] = MODEL_ID + 1
+ collection.models.update(model)
+ collection.models.save(model)
+ self.model = model
+ # collection.models.setCurrent(model)
+
+ if not RICH_MODE:
+ return
+
+ ################################################################
+ # Model for irregular verbs.
+ model = collection.models.new(self.name + "_irrverb")
+ model['did'] = deck_id
+ model['css'] = MODEL_CSS
+
+ collection.models.addField(model, collection.models.newField('V1'))
+ collection.models.addField(model, collection.models.newField('V2'))
+ collection.models.addField(model, collection.models.newField('V3'))
+ collection.models.addField(model, collection.models.newField('V2alt'))
+ collection.models.addField(model, collection.models.newField('V3alt'))
+ collection.models.addField(model, collection.models.newField('Front'))
+ collection.models.addField(model, collection.models.newField('Back'))
+
+ question = u"<div class='ask'>Find irregular verb:</div>"
+
+ tmpl = collection.models.newTemplate('V1 -> Back')
+ tmpl['qfmt'] = question + '<div class="front">{{V1}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="back">{{Front}}</div><div class="back">{{Back}}</div>'
+ collection.models.addTemplate(model, tmpl)
+
+ tmpl = collection.models.newTemplate('V2 -> Back')
+ tmpl['qfmt'] = question + '<div class="front">{{V2}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="back">{{Front}}</div><div class="back">{{Back}}</div>'
collection.models.addTemplate(model, tmpl)
- # Equivalent of:
- # collection.models.add(model)
- # without setting auto-generated ID. It is essential to keep model['id']
- # unchanged between upgrades or notes will be skipped!!
- model['id'] = int(hashlib.sha1(self.name).hexdigest(), 16) % (2**63)
+ tmpl = collection.models.newTemplate('V3 -> Back')
+ tmpl['qfmt'] = question + '<div class="front">{{V3}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="back">{{Front}}</div><div class="back">{{Back}}</div>'
+ collection.models.addTemplate(model, tmpl)
+
+ tmpl = collection.models.newTemplate('V2alt -> Back')
+ tmpl['qfmt'] = question + '<div class="front">{{V2alt}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="back">{{Front}}</div><div class="back">{{Back}}</div>'
+ collection.models.addTemplate(model, tmpl)
+
+ tmpl = collection.models.newTemplate('V3alt -> Back')
+ tmpl['qfmt'] = question + '<div class="front">{{V3alt}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="back">{{Front}}</div><div class="back">{{Back}}</div>'
+ collection.models.addTemplate(model, tmpl)
+
+ model['id'] = MODEL_ID + 2 # Keep model['id'] unique.
collection.models.update(model)
- collection.models.setCurrent(model)
collection.models.save(model)
+ self.model_irr = model
+
+ ################################################################
+ # Model for irregular plurals.
+ model = collection.models.new(self.name + "_plural")
+ model['did'] = deck_id
+ model['css'] = MODEL_CSS
+
+ collection.models.addField(model, collection.models.newField('Singular'))
+ collection.models.addField(model, collection.models.newField('Plural'))
+ collection.models.addField(model, collection.models.newField('Front'))
+ collection.models.addField(model, collection.models.newField('Back'))
+
+ question = u"<div class='ask'>Find singular/plural form:</div>"
- def guid(self, type_, headword):
+ tmpl = collection.models.newTemplate('Singular -> Back')
+ tmpl['qfmt'] = question + '<div class="front">{{Singular}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="back">{{Front}}</div><div class="back">{{Back}}</div>'
+ collection.models.addTemplate(model, tmpl)
+
+ tmpl = collection.models.newTemplate('Plural -> Back')
+ tmpl['qfmt'] = question + '<div class="front">{{Plural}}</div>'
+ tmpl['afmt'] = '{{FrontSide}}<hr id=answer><div class="back">{{Front}}</div><div class="back">{{Back}}</div>'
+ collection.models.addTemplate(model, tmpl)
+
+ model['id'] = MODEL_ID + 3 # Keep model['id'] unique.
+ collection.models.update(model)
+ collection.models.save(model)
+ self.model_pl = model
+
+
+ def guid(self, nodetype, headword):
"""
- :type_ used to generate different notes from same headword
+ :nodetype used to generate different notes from same headword
"""
- h = hashlib.md5(":".join((self.name, type_, headword)))
+ h = hashlib.md5(":".join((self.name, nodetype, headword)))
return h.hexdigest()
- def add_note(self, type_, id_, from_, to_, tags_ = None):
- note = self.collection.newNote()
- note['From'] = from_
- # print(from_)
- note['To'] = to_
- # print(to_)
- if isinstance(tags_, str): note.tags = [tags_]
- elif isinstance(tags_, list): note.tags = tags_
- elif tags_ is None: pass
- else: raise Exception('Expect string or list of tags...')
- note.guid = self.guid(type_, id_)
+ def add_note(self, headword, front, back, safeback, tags = None):
+ note = anki.notes.Note(self.collection, self.model)
+ note['Front'] = front
+ note['Back'] = back
+ note['SafeBack'] = safeback
+ note_add_tags(note, tags)
+ note.guid = self.guid("front/back", headword)
+ self.collection.addNote(note)
+
+ def add_note_irr(self, headword, v1, v2, v2alt, v3, v3alt, front, back, tags = None):
+ note = anki.notes.Note(self.collection, self.model_irr)
+ note['V1'] = v1
+ note['V2'] = v2
+ note['V3'] = v3
+ note['V2alt'] = v2alt
+ note['V3alt'] = v3alt
+ note['Front'] = front
+ note['Back'] = back
+ note_add_tags(note, tags)
+ note.guid = self.guid("irregular verb", headword)
+ self.collection.addNote(note)
+
+ def add_note_pl(self, headword, singular, plural, front, back, tags = None):
+ note = anki.notes.Note(self.collection, self.model_pl)
+ note['Singular'] = singular
+ note['Plural'] = plural
+ note['Front'] = front
+ note['Back'] = back
+ note_add_tags(note, tags)
+ note.guid = self.guid("singular/plural noun", headword)
self.collection.addNote(note)
def export(self, fname):
@@ -317,13 +435,9 @@
for identity in FDEL or []:
identity = identity.strip()
warnmsg = "<div class='del'>Please delete this note ({})</div>".format(identity)
- builder.add_note("en->tr", identity, warnmsg, warnmsg+" en->tr", "del")
- builder.add_note("tr->en", identity, warnmsg, warnmsg+" tr->en", "del")
- builder.add_note("irregular1", identity, warnmsg, warnmsg+" irregular1", "del")
- builder.add_note("irregular2", identity, warnmsg, warnmsg+" irregular2", "del")
- builder.add_note("irregular3", identity, warnmsg, warnmsg+" irregular3", "del")
- builder.add_note("singular", identity, warnmsg, warnmsg+" singular", "del")
- builder.add_note("plural", identity, warnmsg, warnmsg+" plural", "del")
+ builder.add_note(identity, warnmsg, warnmsg, warnmsg, "del")
+ builder.add_note_irr(identity, warnmsg, warnmsg, warnmsg, warnmsg, warnmsg, warnmsg, warnmsg, "del")
+ builder.add_note_pl(identity, warnmsg, warnmsg, warnmsg, warnmsg, "del")
for (headwords, translations) in DOM[1:]:
identity = headwords[0].headword
@@ -338,7 +452,7 @@
freqmsg = ",".join(freqtags)
freqmsg = "<div class='freq'>{:s}</div>".format(freqmsg)
buf = []
- v1, v2, v3 = (None, None, None)
+ v1, v2, v3, v2alt, v3alt = (None, None, None, None, None)
singular, plural = (None, None)
for hw in headwords:
buf.append("<div clsas='headword'>")
@@ -358,9 +472,15 @@
if 'v1' in hw.attrs:
v1 = (hw.headword, hw.pron)
if 'v2' in hw.attrs:
- v2 = (hw.headword, hw.pron)
+ if v2:
+ v2alt = (hw.headword, hw.pron)
+ else:
+ v2 = (hw.headword, hw.pron)
if 'v3' in hw.attrs:
- v3 = (hw.headword, hw.pron)
+ if v3:
+ v3alt = (hw.headword, hw.pron)
+ else:
+ v3 = (hw.headword, hw.pron)
if 's' in hw.attrs:
singular = (hw.headword, hw.pron)
if 'pl' in hw.attrs:
@@ -375,24 +495,24 @@
for sense in translations:
write_sense(buf, sense, with_examples = False)
reverse_from = "".join(buf) # without examples!!
- builder.add_note("en->tr", identity, direct_from + freqmsg, direct_to)
- builder.add_note("tr->en", identity, reverse_from, direct_from + freqmsg)
+ builder.add_note(identity, direct_from, direct_to, reverse_from)
if v1 and v2 and v3 and RICH_MODE:
- question = u"<div class='ask'>Find irregular verb:</div>"
riddle1 = u"<span class='headword'>{}</span> <span class='pron'>[{}]</span> <span class='attrs'>v1</span>".format(v1[0], v1[1])
riddle2 = u"<span class='headword'>{}</span> <span class='pron'>[{}]</span> <span class='attrs'>v2</span>".format(v2[0], v2[1])
riddle3 = u"<span class='headword'>{}</span> <span class='pron'>[{}]</span> <span class='attrs'>v3</span>".format(v3[0], v3[1])
- answer = direct_from + direct_to
- builder.add_note("irregular1", identity, question + riddle1 + freqmsg, answer)
- builder.add_note("irregular2", identity, question + riddle2 + freqmsg, answer)
- builder.add_note("irregular3", identity, question + riddle3 + freqmsg, answer)
+ if v2alt:
+ riddle2alt = u"<span class='headword'>{}</span> <span class='pron'>[{}]</span> <span class='attrs'>v2</span>".format(v2alt[0], v2alt[1])
+ else:
+ riddle2alt = ""
+ if v3alt:
+ riddle3alt = u"<span class='headword'>{}</span> <span class='pron'>[{}]</span> <span class='attrs'>v2</span>".format(v3alt[0], v3alt[1])
+ else:
+ riddle3alt = ""
+ builder.add_note_irr(identity, riddle1 + freqmsg, riddle2 + freqmsg, riddle2alt, riddle3 + freqmsg, riddle3alt, direct_from, direct_to)
if singular and plural and RICH_MODE:
- question = u"<div class='ask'>Find plural:</div>"
riddle_s = u"<span class='headword'>{}</span> <span class='pron'>[{}]</span> <span class='attrs'>s</span>".format(singular[0], singular[1])
riddle_pl = u"<span class='headword'>{}</span> <span class='pron'>[{}]</span> <span class='attrs'>pl</span>".format(plural[0], plural[1])
- answer = direct_from + direct_to
- builder.add_note("singular", identity, question + riddle_s + freqmsg, answer)
- builder.add_note("plural", identity, question + riddle_pl + freqmsg, answer)
+ builder.add_note_pl(identity, riddle_s + freqmsg, riddle_pl + freqmsg, direct_from, direct_to)
builder.export(FONAME)
finally: