# HG changeset patch # User Oleksandr Gavenko # Date 1478951708 -7200 # Node ID e330e7f195b797e934f23a33d2d63c52e6eb3f3b # Parent e3266e096360166714c253c41dff9e0bcf84048a Switched to new models for notes in order to use Anki feature of preventing showing related card on same day. But I decided to separate plural and irregular verb forms from main articles... diff -r e3266e096360 -r e330e7f195b7 py/gadict_srs_anki.py --- 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'] = '
{{Front}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Back}}
' + collection.models.addTemplate(model, tmpl) - tmpl = collection.models.newTemplate('From -> To') - tmpl['qfmt'] = '
{{From}}
' - tmpl['afmt'] = '{{FrontSide}}
{{To}}
' + tmpl = collection.models.newTemplate('SafeBack -> Front') + tmpl['qfmt'] = '
{{SafeBack}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Front}}
' + 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"
Find irregular verb:
" + + tmpl = collection.models.newTemplate('V1 -> Back') + tmpl['qfmt'] = question + '
{{V1}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Front}}
{{Back}}
' + collection.models.addTemplate(model, tmpl) + + tmpl = collection.models.newTemplate('V2 -> Back') + tmpl['qfmt'] = question + '
{{V2}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Front}}
{{Back}}
' 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 + '
{{V3}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Front}}
{{Back}}
' + collection.models.addTemplate(model, tmpl) + + tmpl = collection.models.newTemplate('V2alt -> Back') + tmpl['qfmt'] = question + '
{{V2alt}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Front}}
{{Back}}
' + collection.models.addTemplate(model, tmpl) + + tmpl = collection.models.newTemplate('V3alt -> Back') + tmpl['qfmt'] = question + '
{{V3alt}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Front}}
{{Back}}
' + 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"
Find singular/plural form:
" - def guid(self, type_, headword): + tmpl = collection.models.newTemplate('Singular -> Back') + tmpl['qfmt'] = question + '
{{Singular}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Front}}
{{Back}}
' + collection.models.addTemplate(model, tmpl) + + tmpl = collection.models.newTemplate('Plural -> Back') + tmpl['qfmt'] = question + '
{{Plural}}
' + tmpl['afmt'] = '{{FrontSide}}
{{Front}}
{{Back}}
' + 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 = "
Please delete this note ({})
".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 = "
{:s}
".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("
") @@ -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"
Find irregular verb:
" riddle1 = u"{} [{}] v1".format(v1[0], v1[1]) riddle2 = u"{} [{}] v2".format(v2[0], v2[1]) riddle3 = u"{} [{}] v3".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"{} [{}] v2".format(v2alt[0], v2alt[1]) + else: + riddle2alt = "" + if v3alt: + riddle3alt = u"{} [{}] v2".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"
Find plural:
" riddle_s = u"{} [{}] s".format(singular[0], singular[1]) riddle_pl = u"{} [{}] pl".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: