def write_deck_to_file(path): basename = os.path.basename(path) name = os.path.splitext(basename)[0] deck_name = name.replace("_", " ").title() deck = genanki.Deck(hash(deck_name), deck_name) with open(path) as f: notes = yaml.load(f, Loader=yaml.FullLoader) seen = set() for note_data in notes: note_id = note_data["id"] note_cloze = note_data["cloze"] note_tags = note_data["tags"] if note_id in seen: sys.exit("duplicate id {} found".format(note_id)) if not cloze_note_regex.match(note_cloze): sys.exit( "note id {} with cloze '{}' doesn't match expected format". format(note_id, note_cloze)) print(note_data) note = genanki.Note(guid=genanki.guid_for(note_id), fields=[note_cloze], tags=note_tags, model=genanki.CLOZE_MODEL) deck.add_note(note) seen.add(note_id) genanki.Package(deck).write_to_file("{}.apkg".format(name))
def guid(self): # match the format used by hsk_flashcards_rust, normally we'd just do guid_for(simp, trad, pinyin) return genanki.guid_for(' '.join([ 'kerrick hsk', self.fields[0], # simp self.fields[1], # trad self.fields[2], # pinyin ]))
def add_note(self, note_id: str, note_question: str, note_answer: str, note_files: list): """ Add an anki note/card :param note_id: The id of the note :param note_question: The question :param note_answer: The answer :param note_files: The connected files """ # Concatenate all files for the export later self.files.update(note_files) # If the note has no id assign one with the unique question/answer if note_id is '': note_id = genanki.guid_for(note_question, note_answer) if debug: print("No note id was found, generate random id:", note_id) # Append the current note to the note matrix self.note_matrix.append([ note_id, note_question.replace('\n', '<br>').replace('\r', ''), note_answer.replace('\n', '<br>').replace('\r', '') ]) # Remove all the custom file paths from the cards for anki for remove_file_path in remove_file_paths: note_question = note_question\ .replace('"' + remove_file_path + '/', '"') note_answer = note_answer\ .replace('"' + remove_file_path + '/', '"') # Fix source codes source_code_regex = r"<pre.*?>(.*)</pre>" note_answer = re.sub(source_code_regex, self.source_code_replace, note_answer) note_question = re.sub(source_code_regex, self.source_code_replace, note_question) # Unicode decode note_question = note_question.encode('utf-8', 'xmlcharrefreplace')\ .decode('utf-8')\ .replace("Ä", "Ä").replace("ä", "ä")\ .replace("Ö", "Ö").replace("ö", "ö")\ .replace("Ü", "Ü").replace("ü", "ü")\ .replace("ß", "ß") note_answer = note_answer.encode('utf-8', 'xmlcharrefreplace')\ .decode('utf-8') \ .replace("Ä", "Ä").replace("ä", "ä")\ .replace("Ö", "Ö").replace("ö", "ö")\ .replace("Ü", "Ü").replace("ü", "ü")\ .replace("ß", "ß") # Add the note to the deck self.deck.add_note( genanki.Note(guid=note_id, model=self.model, fields=[note_question, note_answer])) if debug: print("note added", note_id, note_question, note_answer, note_files)
def __init__(self, deck_id, model=None, fields=None, sort_field=None, tags=None): guid = genanki.guid_for(fields[0], deck_id) if fields is not None: fields.append(guid) super().__init__(model=model, fields=fields, sort_field=sort_field, tags=tags, guid=guid)
def create_anki_note(self, datum, deck, model, subject): """Create Anki note from translated WaniKani data using genanki. This translates from internal representation to genanki representation so that genanki could be replaced if needed.""" fields_dict = self.fields_translators[subject](datum) srs = self.translate_srs(datum, deck) fields = [fields_dict[field['name']] for field in model.fields] note = genanki.Note(model=model, fields=fields) note.guid = genanki.guid_for(*[fields_dict['Characters'], subject]) note.tags = ['WKLevel_' + fields_dict['Level']] note.set_card_options(srs) return note
def run(path): basename = os.path.basename(path) name = os.path.splitext(basename)[0] deck_name = name.replace("_", " ").title() deck = genanki.Deck(hash(deck_name), deck_name) with open(path) as f: text = yaml.load(f, Loader=yaml.FullLoader) notes = get_notes(text) generated = datetime.today().strftime("%Y-%m-%d_%H:%M:%S") for (id, note) in notes: print(note) genaki_note = genanki.Note(guid=genanki.guid_for(id), sort_field=id, tags=["generated_" + generated], fields=[note], model=genanki.CLOZE_MODEL) deck.add_note(genaki_note) genanki.Package(deck).write_to_file("./dist/{}.apkg".format(name))
def get_anki_note(item, model, template): fmt = item.meta['format'] if fmt == 'data/dictionary': tags = template['Tags']['template'].render(**item.data).split(' ') _id = template['ID']['template'].render(**item.data) elif fmt == 'data/text': tags = template['Tags']['template'].render(Text=item.data).split(' ') _id = template['ID']['template'].render(Text=item.data) elif fmt == 'data/list': tags = template['Tags']['template'].render(Items=item.data).split(' ') _id = template['ID']['template'].render(Items=item.data) else: raise Exception('Unsupported item format: {fmt}'.format(fmt=fmt)) tags.insert(0, item.meta['file']) fields = [] for f in model.fields: fieldname = f['name'] tpl = template[fieldname]['template'] if fmt == 'data/dictionary': contents = tpl.render(**item.data) elif fmt == 'data/text': contents = tpl.render(text=item.data) elif fmt == 'data/list': contents = tpl.render(items=item.data) if template[fieldname]['markdown']: contents = md.convert(contents) md.reset() fields.append(contents) # print(fields) return Note(guid=guid_for(_id), model=model, fields=fields, tags=tags)
def guid(self): # Hash by leetcode task handle return genanki.guid_for(self.fields[2])
def guid(self): # Only use the simplified hanzi as a card identifier. return genanki.guid_for(self.fields[0])
def guid(self): return genanki.guid_for( self.fields[0] ) # only hash title field, so that we can update cards
def guid(self): return genanki.guid_for(self.kanji, self.kana)
def guid(self): # These can actually match across decks and models, so be careful! If you use the # same guid for notes in another model/deck, you'll confuse Anki on import. return genanki.guid_for('verb_conjugation', self.kanji, self.kana, self.group)
def guid(self): return genanki.guid_for(self.fields[1]) # only hash the hanzi field
fields=[ { 'name': 'Question' }, { 'name': 'Answer' }, ], templates=[ { 'name': 'Card 1', 'qfmt': '{{Question}}', 'afmt': '{{FrontSide}}<hr id="answer">{{Answer}}', }, ]) for i, string in enumerate(Questions): MyNote = genanki.Note(model=my_model, fields=[str(Questions[i]), " "]) MyNote.guid = genanki.guid_for(1, 2) MyNote.sort_field = "null" my_deck.add_note(MyNote) # class MyNote(genanki.Note): # self.model = None # @property # def guid(self): # return genanki.guid_for(self.fields[0], self.fields[1]) genanki.Package(my_deck).write_to_file('outfiles/{0}.apkg'.format( str(deckName)))
def guid(self): return genanki.guid_for(deck_name, self.fields[0], self.fields[1], self.fields[3])
def guid(self): return genanki.guid_for(self.fields[2], self.fields[4], self.fields[5])
def guid(self): # Don't hash random strings, only identifier: songtitle & part_number return genanki.guid_for(self.fields[1], self.fields[2])
def guid(self): return genanki.guid_for(self.fields[0], self.model.model_id)
def guid(self) -> Any: return genanki.guid_for(self.fields[0])
def guid(self): return genanki.guid_for(self.fields[0]) # th
def guid(self): return genanki.guid_for(*self.fields[:2])