def regenerateKeywords(nids): mw.checkpoint("Bulk-add RTK Keywords") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) src = None for fld in srcFields: if fld in note: src = fld break if not src: # no src field continue dst = None for fld in dstFields: if fld in note: dst = fld break if not dst: # no dst field continue if note[dst]: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue try: note[dst] = getKeywordsFast(srcTxt) except Exception, e: raise note.flush()
def generateNotes(self): """Generate new notes""" state = "default" self.uniq_id = str(uuid.uuid4()).replace("-", "") self.occl_id = '%s-%s' % (self.uniq_id, self.occl_tp) (svg_node, layer_node) = self._getMnodesAndSetIds() if not self.mnode_ids: tooltip("No cards to generate.<br>\ Are you sure you set your masks correctly?") return False self.new_svg = svg_node.toxml() # write changes to svg omask_path = self._saveMask(self.new_svg, self.occl_id, "O") qmasks = self._generateMaskSVGsFor("Q") amasks = self._generateMaskSVGsFor("A") image_path = mw.col.media.addFile(self.image_path) img = fname2img(image_path) mw.checkpoint("Adding Image Occlusion Cards") for nr, idx in enumerate(self.mnode_indexes): note_id = self.mnode_ids[idx] self._saveMaskAndReturnNote(omask_path, qmasks[nr], amasks[nr], img, note_id) tooltip("%s %s <b>added</b>" % self._cardS(len(qmasks)), parent=None) return state
def addDelay(cids): (delay, delayResp) = getDelayWithResponse() if delay is None: if delayResp: showWarning("Please enter an integral number of days") return mw.checkpoint("Adding delay") mw.progress.start() ivlDelay = max( 0, round(delay * (getIntervalCoefficient() if delay > 0 else getIntervalForNegativeCoefficient()))) for cid in cids: card = mw.col.getCard(cid) if card.type != 2: continue card.ivl += ivlDelay if card.odid: # Also update cards in filtered decks card.odue += delay else: card.due += delay card.flush() mw.progress.finish() mw.col.reset() mw.reset() tooltip(_("""Delay added."""))
def bury_due_to_component(reviewer, ease=None): global log_message global due_characters global do_mw_reset day_zero = int(mw.col.crt / (24 * 3600)) today_in_days = int(datetime.now().timestamp() / (24 * 3600)) - day_zero # first we need to get the list with due characters if its empty: if due_characters == "": # print("Getting due characters... ") due_cards = mw.col.findCards( "deck:\"MandarinBanana Hanzis\" is:due -is:suspended -is:new") for due_id in due_cards: due_card = mw.col.getCard(due_id) due_note = due_card.note() due_characters += due_note["hanzi"] note = mw.reviewer.card.note() if "hanzi" in note.keys() and "elements" in note.keys(): character = note["hanzi"] elements = note["elements"] for element in elements: if element in due_characters: # bury the current note, because one of its elements is due. # Anki will pull out a new card after the mw.reset(). mw.checkpoint(_("Bury")) mw.col.sched.buryNote(mw.reviewer.card.nid) message = "Buried {} due to {}.".format(character, element) print(message) do_mw_reset = True # print("do_mw_reset in bury_due_to_component = {}".format(do_mw_reset)) # mw.reset() break
def import_from_json(): path = getFile(mw, "Org file to import", cb=None, dir=expanduser("~")) if not path: return with open(path, 'r') as f: content = f.read().decode('utf-8') entries = json.loads(content) import itertools get_deck = lambda e: e['deck'] entries = sorted(entries, key=get_deck) mw.checkpoint(_("Import")) logs = [] for deck_name, entries in itertools.groupby(entries, get_deck): # FIXME: If required we could group by model name also! importer = JsonImporter(mw.col, path, MODEL_NAME, deck_name) importer.initMapping() importer.run(list(entries)) if importer.log: logs.append('\n'.join(importer.log)) txt = _("Importing complete.") + "\n" txt += '\n'.join(logs) showText(txt) mw.reset()
def regenerateKeywords(nids): mw.checkpoint("Bulk-add RTK Keywords") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) src = None for fld in srcFields: if fld in note: src = fld break if not src: # no src field continue dst = None for fld in dstFields: if fld in note: dst = fld break if not dst: # no dst field continue if note[dst]: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue try: note[dst] = getKeywordsFast(srcTxt) # TODO: When Anki 2.1 comes out, change syntax to support Py 3.5 except Exception, e: raise note.flush()
def onClearFormatting(browser): """ Clears the formatting for every selected note. Also creates a restore point, allowing a single undo operation. Parameters ---------- browser : Browser the anki browser from which the function is called """ mw.checkpoint("Bulk-Clear Formatting") mw.progress.start() for nid in browser.selectedNotes(): note = mw.col.getNote(nid) def clearField(field): result = stripFormatting(field) # if result != field: # sys.stderr.write("Changed: \"" + field # + "\" ==> \"" + result + "\"") return result note.fields = map(clearField, note.fields) note.flush() mw.progress.finish() mw.reset()
def bulkAdd(browser): nids=browser.selectedNotes() mw.checkpoint("Bulk-add Tatoeba") mw.progress.start() #connect to database #connection = sqlite3.connect(databasePath) global cursor #cursor = connection.cursor() #For each seleccted card for nid in nids: note = mw.col.getNote(nid) #Check if we should do it #First check to see if the fields exist #If field check fails then cancel (does any field not exist and are all of them full? ##skip, deal with it in doNote #do the note if True == doNote(note): note.flush() #save cursor.close() mw.progress.finish() mw.reset()
def addKanjiWordsVocab_bulk(nid): mw.checkpoint("Add vocab to kanji cards") try: mw.progress.start() # For each seleccted card # now for each kanji card for id in kanjiCardsIndex: # look up card from the kanji hash array # get the kanji note kanjiNote = mw.col.getCard(kanjiCardsIndex[id]).note() # do the note and handle the results if False == doNote(kanjiNote): return flag return True except KeyError, e: mw.hDialog = hDialog = QMessageBox() hDialog.setText("Please make sure that these fields exist" + e) hDialog.exec_()
def addKDStories(nids): readStories() fields = [] anote=mw.col.getNote(nids[0]) #get the fields of the first note for (i, f) in anote.items(): fields.append(i) #get input/output fields from user expField = addinfofuncts.getKeyFromList("Select field to read from", "Read relevant kanji/expression from:", fields) if (expField is None): return compoundMeaning = addinfofuncts.getKeyFromList("Select field to write to", "Write compound information to:", fields) if (compoundMeaning is None): return Mnemonic = addinfofuncts.getKeyFromList("Select field to write to", "Write Mnemonic to:", fields) if (Mnemonic is None): return EngMeaning = addinfofuncts.getKeyFromList("Select field to write to", "Write English meanings to:", fields) if (EngMeaning is None): return mw.checkpoint("Add KD Stories") mw.progress.start() #For each seleccted card for nid in nids: note = mw.col.getNote(nid) srcTxt = mw.col.media.strip(note[expField]) if not srcTxt.strip(): continue #Add the data to the dst field kanjizz = extractKanji(note[expField]) if kanjiIndex.get(kanjizz): if kanjiIndex[kanjizz]['compound']: note[compoundMeaning] = kanjiIndex[kanjizz]['compound'].decode('utf8') else: note[compoundMeaning] = "" if kanjiIndex[kanjizz]['eng2meaning']: note[Mnemonic] = kanjiIndex[kanjizz]['eng2meaning'].decode('utf8') else: note[Mnemonic] = "" if kanjiIndex[kanjizz]['engmeaning']: note[EngMeaning] = kanjiIndex[kanjizz]['engmeaning'].decode('utf8') else: note[EngMeaning] = "" note.flush() mw.progress.finish() mw.reset()
def regeneratePronunciations(nids): mw.checkpoint("Bulk-add Pronunciations") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) # Check if this is a supported note type. If it is not, skip. # If no note type has been specified, we always continue the lookup proces. if config["noteTypes"] and not any(nt.lower() in note.model()['name'].lower() for nt in config["noteTypes"]): continue src, srcIdx, dst, dstIdx = get_src_dst_fields(note) if src is None or dst is None: continue if note[dst] and not config["regenerateReadings"]: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue note[dst] = getFormattedPronunciations(srcTxt) note.flush() mw.progress.finish() mw.reset()
def onDeckBrowserResetCards(did): if mw.col.decks.isDyn(did): tooltip("Can't reset scheduling for filtered/custom decks.") deck_name = mw.col.decks.name(did) cids = mw.col.decks.cids(did, children=True) if not cids: tooltip("Deck contains no cards.") return r = askUser("This will reset <b>ALL</b> scheduling information and " "progress in the deck '{}' and all of its subdecks ({} cards)." "<br><br>Are you sure you want to proceed?".format( deck_name, len(cids)), defaultno=True, title="Reset Card Scheduling") if not r: return mw.checkpoint("Reset selected deck") mw.progress.start() resetSelectedCardScheduling(cids) mw.progress.finish() mw.reset() tooltip("{} card(s) reset.".format(len(cids)), parent=mw)
def rename(old_name, new_name): SEPARATOR = get_config()["separator"] tags = mw.col.tags.all() rename_dict = {old_name: new_name} # {old : new} for tag in tags: parts = tag.split(SEPARATOR) for i in range(len(parts)): if old_name == SEPARATOR.join(parts[:i]): retained_stub = SEPARATOR.join(parts[i:len(parts)]) rename_dict[tag] = SEPARATOR.join([new_name, retained_stub]) mw.checkpoint("Rename Tag") mw.progress.start() nids = mw.col.db.list('select id from notes') for id in nids: note = mw.col.getNote(id) for k, v, in rename_dict.items(): if note.hasTag(k): note.delTag(k) note.addTag(v) note.flush() mw.reset() mw.progress.finish()
def r(): #debug(f"Call function defined thanks to ({map})") card = mw.reviewer.card note = card.note() if 'bury' in map and map[ 'bury']: #old config. May eventually be removed. map['action'] = 'bury note' del map['bury'] updateConfig() action = map.get('action', "") checkSuffix = { "bury card": " and Bury Card", "bury note": " and Bury Note", "suspend card": " and Suspend Card", }.get(action, "") mw.checkpoint("Add Tags" + checkSuffix) addTags(note, map['tags']) if action == "bury card": mw.col.sched.buryCards([card.id]) elif action == "bury note": mw.col.sched.buryNote(note.id) elif action == "suspend card": mw.col.sched.suspendCards([card.id]) if action: mw.reset() tooltipSuffix = { "bury card": " and buried card", "bury note": " and buried note", "suspend card": " and suspended card", }.get(action, "") tooltip(f'Added tag(s) "%s"{tooltipSuffix}' % map['tags'])
def regeneratePronunciations(nids): mw.checkpoint("Bulk-add Pronunciations") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) if "japanese" not in note.model()["name"].lower(): continue src, srcIdx, dst, dstIdx = get_src_dst_fields(note) if src is None or dst is None: continue if note[dst] and not regenerate_readings: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue prons = getPronunciations(srcTxt) note[dst] = " *** ".join(prons) note.flush() mw.progress.finish() mw.reset()
def regenerateKeywords(nids): mw.checkpoint("Bulk-add RTK Keywords") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) src = None for fld in srcFields: if fld in note: src = fld break if not src: # no src field continue dst = None for fld in dstFields: if fld in note: dst = fld break if not dst: # no dst field continue if note[dst] and not OVERRIDE: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue try: note[dst] = getKeywordsFast(srcTxt) except Exception as e: raise note.flush() mw.progress.finish() mw.reset()
def bulkAdd(browser): nids = browser.selectedNotes() mw.checkpoint("Bulk-add Tatoeba") mw.progress.start() #connect to database #connection = sqlite3.connect(databasePath) global cursor #cursor = connection.cursor() #For each seleccted card for nid in nids: note = mw.col.getNote(nid) #Check if we should do it #First check to see if the fields exist #If field check fails then cancel (does any field not exist and are all of them full? ##skip, deal with it in doNote #do the note if True == doNote(note): note.flush() #save cursor.close() mw.progress.finish() mw.reset()
def regeneratePronunciations(nids): mw.checkpoint("Bulk-add Pronunciations") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) # Check if this is a supported note type. If it is not, skip. # If no note type has been specified, we always continue the lookup proces. if config["noteTypes"] and not any( nt.lower() in note.model()['name'].lower() for nt in config["noteTypes"]): continue src, srcIdx, dst, dstIdx = get_src_dst_fields(note) if src is None or dst is None: continue if note[dst] and not config["regenerateReadings"]: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue note[dst] = getFormattedPronunciations(srcTxt) note.flush() mw.progress.finish() mw.reset()
def addKanjiSplits_bulk(nids): try: mw.checkpoint("Add Kanji Splits") mw.progress.start() # For each seleccted card for nid in nids: note = mw.col.getNote(nid) # do the note and handle the results if False == doNote(note): continue # Add the data to the dst field if True == doNote(note): note.flush() except KeyError: mw.hDialog = hDialog = QMessageBox() hDialog.setText( "Please make sure that these fields exist: 'Kanji Removed 1' ~ 'Kanji Removed 6', and 'Kanji Removed All'" ) hDialog.exec_() finally: mw.progress.finish() mw.reset()
def addImageFiles(nids): mw.checkpoint("Download Audio") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) if srcFieldKanji not in note: showInfo( f"No source field '{srcFieldKanji}' field found for kanji") continue # no source kanji field if dstFieldImage not in note: showInfo( f"No destination field '{dstFieldImage}' field found for audio" ) continue # no destination image field if note[dstFieldImage] and overwriteImages != "true": continue # already contains data (data, file_name) = imageDownload( note[srcFieldKanji]) # download the actual image if data: mw.col.media.writeData(file_name, data) # write to the collection note[ dstFieldImage] = '<img src="' + file_name + '" />' # make name for field note.flush() else: #showInfo("No sound found") continue mw.progress.finish() mw.reset()
def execute(self, action): mw.checkpoint(action) for cmd in self: try: self._parse(cmd, course=self.course, datasource=self.datasource) except Exception as x: msg = 'Undoing {0} due to error "{1}"'.format(action, x) if hasattr(x, 'cmd'): msg = msg + '\n\nWas processing command:\n{0}'.format( x.cmd) msg = msg + ''' ------------------------------------------------------------------ Please include the information below if reporting an error ------------------------------------------------------------------ {0}'''.format(traceback.format_exc()) showWarning(msg, title=self.course.name) mw.onUndo() return False if self._warnings: showWarning('\n'.join(self._warnings)) # refresh main view so changes are visible mw.reset() return True
def regeneratePhonetics(nids): mw.checkpoint(buttonText) mw.progress.start() for nid in nids: note = mw.col.getNote(nid) src = None for fld in srcFields: if fld in note: src = fld break if not src: # no src field continue dst = None for fld in dstFields: if fld in note: dst = fld break if not dst: # no dst field continue if note[dst]: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue try: note[dst] = getHighlightedPhonetics(srcTxt) except Exception, e: raise note.flush()
def importDeck(): mw.checkpoint("Import scheduling info") try: _importDeck() except: mw.col.db.rollback() raise
def onMenuEntry(): """Callback for our menu entry.""" dialog = KanjiVocabDialog() if dialog.exec_(): mw.progress.start(immediate=True) mw.progress.update(_("Tagging vocabulary cards")) mw.checkpoint(_("Tag vocabulary cards based on kanji")) tagged, not_tagged, kanji = tag_notes(col=mw.col, kanji_field=dialog.kanji_field, kanji_filter=dialog.kanji_filter, vocab_field=dialog.vocab_field, require_kanji=dialog.require_kanji, tags=dialog.tags, delete_tags=dialog.delete_tags) mw.progress.finish() # FIXME: Do we need to do something? #mw.deck.refreshSession() aqt.utils.showInfo("Applied tags on %u out of %u notes (based on %u kanji)." % ( len(tagged), len(tagged) + len(not_tagged), len(kanji)))
def convert_subdecks_to_tags(): """Main function to convert currently selected deck.""" parent_deck_id = mw.col.decks.selected() children_decks = mw.col.decks.children(parent_deck_id) mw.checkpoint(_("convert subdeck to tags")) for child_deck_name, child_deck_id in children_decks: # Reformat deck title into an appropriate tag tag = reformat_title(child_deck_name, SEPARATOR) # Get old card properties child_cids = mw.col.decks.cids(child_deck_id) mod = intTime() usn = mw.col.usn() str_cids = ids2str(child_cids) # Move cards to new deck if config option set if get_user_option("Merge decks", False): mw.col.db.execute( "update cards set usn=?, mod=?, did=? where id in " + str_cids, usn, mod, parent_deck_id) mw.col.decks.rem(child_deck_id) # New tag based on child deck name child_cards = (mw.col.getCard(cid) for cid in child_cids) child_nids = set(c.nid for c in child_cards) mw.col.tags.bulkAdd(list(child_nids), tag) mw.requireReset()
def regeneratePronunciations(nids): mw.checkpoint("Bulk-add Pronunciations") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) #if "japanese" not in note.model()['name'].lower(): # continue src, srcIdx, dst, dstIdx, snd, sndIdx, color, colorIdx = get_src_dst_fields( note) if not src or dst is None: continue if note[dst] and not config["regenerate_prons"]: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue color_src = mw.col.media.strip(note[color]) if color else '' note[src], note[dst], new_color_field, audio = multi_lookup( srcTxt, getPronunciations, colorTxt=color_src) if snd and audio: note[snd] = add_audio(audio) if color: note[color] = new_color_field note.flush() mw.progress.finish() mw.reset()
def _onTreeDeckRenameLeaf(self, item): mw.checkpoint(_("Rename Deck")) from aqt.utils import showWarning from anki.errors import DeckRenameError self.browser._lastSearchTxt = "" sel = mw.col.decks.byName(item.fullname) try: path, leaf = item.fullname.rsplit('::', 1) newName = path + '::' + getOnlyText(_("New deck name:"), default=leaf) except ValueError: newName = getOnlyText(_("New deck name:"), default=item.fullname) newName = newName.replace('"', "") if not newName or newName == item.fullname: return newName = unicodedata.normalize("NFC", newName) deck = mw.col.decks.get(sel["id"]) try: mw.col.decks.rename(deck, newName) except DeckRenameError as e: return showWarning(e.description) self._swapHighlight(item.type, item.fullname, newName) self._saveDecks() # self.highlight('deck',newName) mw.show() mw.reset(True)
def dropEvent(self, event): dragItem = event.source().currentItem() if not isinstance(dragItem.type, str): return dgType = dragItem.type if dgType not in self.node_state: event.setDropAction(Qt.IgnoreAction) event.accept() return QAbstractItemView.dropEvent(self, event) if not self.dropItem or \ self.dropItem.type == dgType or \ self.dropItem.type == dgType[:3]: #pin mw.checkpoint("Dragged " + dgType) dragName, dropName = self._getItemNames(dragItem) parse = mw.col.decks #used for parsing '::' separators cb = None if dgType in ("deck", "dyn"): self._deckDropEvent(dragName, dropName) elif dgType == "tag": cb = self.moveTag elif dgType == "model": cb = self.moveModel elif dgType[:3] in ("fav", "pin"): cb = self.moveFav if cb: self._strDropEvent(dragName, dropName, cb) self.node_state[dgType][dropName] = True mw.col.setMod() self.browser.buildTree()
def addKanjiSplits_bulk(nids): try: mw.checkpoint("Add Kanji Splits") mw.progress.start() # For each seleccted card for nid in nids: note = mw.col.getNote(nid) # do the note and handle the results if False == doNote(note): continue # Add the data to the dst field if True == doNote(note): note.flush() except KeyError: mw.hDialog = hDialog = QMessageBox() hDialog.setText("Please make sure that these fields exist: 'Kanji Removed 1' ~ 'Kanji Removed 6', and 'Kanji Removed All'") hDialog.exec_() finally: mw.progress.finish() mw.reset()
def onMenuEntry(): """Callback for our menu entry.""" dialog = KanjiVocabDialog() if dialog.exec_(): mw.progress.start(immediate=True) mw.progress.update(_("Tagging vocabulary cards")) mw.checkpoint(_("Tag vocabulary cards based on kanji")) tagged, not_tagged, kanji = tag_notes( col=mw.col, kanji_field=dialog.kanji_field, kanji_filter=dialog.kanji_filter, vocab_field=dialog.vocab_field, require_kanji=dialog.require_kanji, tags=dialog.tags, delete_tags=dialog.delete_tags) mw.progress.finish() # FIXME: Do we need to do something? #mw.deck.refreshSession() aqt.utils.showInfo( "Applied tags on %u out of %u notes (based on %u kanji)." % (len(tagged), len(tagged) + len(not_tagged), len(kanji)))
def decreaseDelay(cids): (percent, percentResp) = getPercentWithResponse() if percent is None: if percentResp: showWarning("Please enter an integral number of days{percentResp}") return mw.checkpoint("Decreasing percent") mw.progress.start() for cid in cids: card = mw.col.getCard(cid) whichDue = "odue" if card.odid else "due" if getattr(card, whichDue) < card.col.sched.today and not getUserOption("Also change late cards", False): continue if card.type != QUEUE_REV: continue curentIvl = card.ivl if getUserOption("Consider last review date", False) else getattr( card, whichDue) - card.col.sched.today decrease = curentIvl*(100-percent)/100 setattr(card, whichDue, getattr(card, whichDue)-decrease) card.ivl -= decrease card.flush() mw.progress.finish() mw.col.reset() mw.reset() tooltip(_("""Delay changed."""))
def bulkAddJDefs(nids): mw.checkpoint("Add JDefs") mw.progress.start() #For each seleccted card for nid in nids: note = mw.col.getNote(nid) #Check if we should do it #First check to see if the fields exist #If field check fails then cancel (does any field not exist and are all of them full? if not definitionField in note or \ not dictionaryForm in note or \ (note[definitionField] and \ note[dictionaryForm]): continue #do the note if True == doNote(note, 1): note.flush() #save mw.progress.finish() mw.reset()
def process(self, nids): if not nids: raise NoNoteError if not self.freq_list: raise NoListError self.stat = { "total": len(nids), "written": 0, "skipped": 0, "overwritten": 0, "notfound": 0, "nofield": 0, } #split dict and parse each piece more = split = 0 LEN = len(self.freq_list) while more < LEN: more = self.parseList(more) mw.checkpoint("Wordsworth") nids = self.processNotes(nids) split += 1 self.dict = None #Adjust stat count based on number of splits self.stat["nofield"] //= split matched = self.stat["written"] + self.stat["skipped"] self.stat["notfound"]=self.stat["total"]- \ matched-self.stat["nofield"]
def _updateExistingCards(checkpoint, nids, processFunc): updatedCount = 0 mw.checkpoint(checkpoint) mw.progress.start() for nid in nids: note = mw.col.getNote(nid) text_fields = set(note.keys()).intersection(TEXT_FIELDS_SET) if len(text_fields) == 0: continue text_field = text_fields.pop() text = note[text_field] newText, num = processFunc(text) if text != newText: note[text_field] = newText note.flush() updatedCount += num mw.progress.finish() mw.reset() spacesNotice = "" if FEATURES["nonBreakingSpaces"]: spacesNotice = " and replaced spaces inside clozes with non-breaking spaces" showInfo(u"Updated {0} cards (from {1} cloze notes){2}.".format( updatedCount, len(nids), spacesNotice))
def regeneratePronunciations(nids): mw.checkpoint("Bulk-add Pronunciations") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) if "japanese" not in note.model()['name'].lower(): continue src, srcIdx, dst, dstIdx = get_src_dst_fields(note) if src is None or dst is None: continue if note[dst] and not regenerate_readings: # already contains data, skip continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue prons = getPronunciations(srcTxt) note[dst] = " *** ".join(prons) note.flush() mw.progress.finish() mw.reset()
def createAnkiNote(hanziToAddNoteList, masterNoteModelFile): mw.checkpoint("Manual Create Note") mw.progress.start() # Get desired deck name from input box deckName = master_deckName if not deckName: return #deckName = deckName.replace('"', "") # Create new deck with name from input box deck = mw.col.decks.get(mw.col.decks.id(deckName)) # Copy notes for hanziNote in hanziToAddNoteList: showInfo("Found note: %s" % (str(hanziNote))) #note = mw.col.getNote(nid) model = masterNoteModelFile # Assign model to deck mw.col.decks.select(deck['id']) mw.col.decks.get(deck)['mid'] = model['id'] mw.col.decks.save(deck) # Assign deck to model mw.col.models.setCurrent(model) mw.col.models.current()['did'] = deck['id'] mw.col.models.save(model) # Create new note note_toAdd = mw.col.newNote() # Copy tags and fields (all model fields) from original note #note_toAdd.tags = note.tags #note_toAdd.fields = note.fields note_toAdd[master_Hanzi_SrcField] = hanziNote[1] note_toAdd[master_Traditional_Field] = hanziNote[2] note_toAdd[master_Freq_Field] = str(hanziNote[0]) note_toAdd[master_Pinyin_Field] = hanziNote[4] note_toAdd[master_Pinyin2_Field] = hanziNote[5] note_toAdd[master_meaning_Field] = hanziNote[6] note_toAdd[master_Auto_Sentence_SrcField] = hanziNote[8][0] note_toAdd[master_Auto_SR_SrcField] = hanziNote[8][1] note_toAdd[master_Auto_ST_SrcField] = hanziNote[8][2] note_toAdd[master_Auto_SA_SrcField] = hanziNote[8][3] note_toAdd[master_Auto_Synced_Hint_SrcField] = hanziNote[8][4] if len( hanziNote[8] ) >= 6 and Enable_Optional_Custom_MasterSlaveSyncFieldList == True: note_toAdd[hanziNote[8][5][0]] = hanziNote[8][5][1] # Refresh note and add to database note_toAdd.flush() mw.col.addNote(note_toAdd) # Reset collection and main window mw.col.reset() showInfo("collection has been reset") mw.progress.finish() mw.reset() showInfo("All done !")
def onManageModel(self): self.browser.editor.saveNow(self.hideEditor) mw.checkpoint("Manage model") import aqt.models aqt.models.Models(self.mw, self.browser) mw.col.setMod() self.browser.onReset() self.browser.maybeRefreshSidebar()
def addHeisigNumbers(nids): #get version to use version = getHeisigVersion() if version == False: return fields = [] anote=mw.col.getNote(nids[0]) #get the fields of the first note for (i, f) in anote.items(): fields.append(i) #get input/output fields from user expField = getKeyFromList("Select field to read from", "Read relevant kanji/expression from:", fields) if (expField is None): return heisigNumDstField = getKeyFromList("Select field to write to", "Write Heisig numbers to:", fields) if (heisigNumDstField is None): return mw.checkpoint("Add Heisig Numbers") mw.progress.start() readRTK() #For each seleccted card for nid in nids: note = mw.col.getNote(nid) src = None if expField in note: src = expField if not src: # no src field then next card continue dst = None if heisigNumDstField in note: dst = heisigNumDstField if not dst: # no dst field then skip card continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue #Add the data to the dst field num = joinseparator.join(lookupKanjiInfo(srcTxt, 'heisig'+version)) if num!=0: note[dst] = str(num) #sys.stderr.write("Results:" + note[dst]) note.flush() mw.progress.finish() mw.reset()
def mergeDupes(res): if not res: return mw.checkpoint(_("Merge Duplicates")) def update(ncc, nc): #if not mw.col.decks.current()['dyn']: # curdid = mw.col.decks.current()['id'] #else: curdid = nc.did mw.col.db.execute("update cards set did=?, mod=?, usn=?, type=?, queue=?, due=?, ivl=?, factor=?, reps=?, lapses=?, left=?, odue=0, odid=0 where id = ?", curdid, intTime(), mw.col.usn(), nc.type, nc.queue, nc.due, nc.ivl, nc.factor, nc.reps, nc.lapses, nc.left, ncc.id) for s, nidlist in res: note_copy = mw.col.newNote() for i, nid in enumerate(nidlist): n = mw.col.getNote(nid) note_copy.tags += n.tags # Because apparently it's nontrivial to retrive cards by ord# so force all cards to exist before we copy the scheduling for (name, value) in n.items(): if not n[name]: n[name] = "BLANK" n.flush() # Add note to database now to force anki to generate cards, then copy an initial state for the new cards if (i == 0): note_copy.fields = n.fields mw.col.addNote(note_copy) for ncc, nc in zip(note_copy.cards(), n.cards()): update(ncc, nc) for (name, value) in note_copy.items(): if value == "BLANK": note_copy[name] = "" if n[name] != "BLANK": if not value or value == "BLANK": note_copy[name] = n[name] continue arr = value.split(" / ") if (n[name] not in arr): note_copy[name] = value + " / " + n[name] for ncc, nc in zip(note_copy.cards(), n.cards()): if nc.ivl > ncc.ivl or nc.queue > ncc.queue: update(ncc, nc) note_copy.flush() mw.col.remNotes(nidlist) mw.col.tags.bulkRem([note_copy.id], _("duplicate")) mw.progress.finish() mw.col.reset() mw.reset() tooltip(_("Notes merged."))
def run(self, apiKey): """Import all available cards.""" mw.checkpoint("Import from SRS Collector") self._apiKey = apiKey data = self._downloadCardData() self._checkMeta(data["meta"]["anki_addon"]) if "card_models" in data: self._ensureCardModels(data["card_models"]) self._importCardsWithTempDir(data["cards"]) mw.col.autosave() mw.reset()
def formatFrameNumbers(nids): mw.checkpoint("Format frame numbers") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) (c,e) = clozeFields(note) # does it contain data? if not e or not note[e]: continue _formatFrameNumbers(note, c, e) mw.progress.finish() mw.reset()
def createClozes(nids): mw.checkpoint("Create clozes") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) (c,e) = clozeFields(note) # does it contain data? if not c or not e or not note[c] or not note[e]: continue _createClozes(note, c, e) mw.progress.finish() mw.reset()
def repositionCards(nids): mw.checkpoint("Reposition cards") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) (c,e) = clozeFields(note) # does it contain data? if not c or not e: continue _repositionCards(note, c, e) mw.progress.finish() mw.reset()
def addExtraStories(nids): readStories() fields = [] anote=mw.col.getNote(nids[0]) #get the fields of the first note for (i, f) in anote.items(): fields.append(i) #get input/output fields from user expField = addinfofuncts.getKeyFromList("Select field to read from", "Read relevant kanji/expression from:", fields) if (expField is None): return #get input/output fields from user story1DstField = addinfofuncts.getKeyFromList("Select field to write to", "Write extra story to:", fields) if (story1DstField is None): return #get input/output fields from user story2DstField = addinfofuncts.getKeyFromList("Select field to write to", "Write other extra story to:", fields) if (story2DstField is None): return mw.checkpoint("Add Extra Stories") mw.progress.start() #For each seleccted card for nid in nids: note = mw.col.getNote(nid) src = expField srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue #Add the data to the dst field kanjizz = extractKanji(note[src]) if kanjizz not in kanjiIndex: continue if kanjiIndex[kanjizz]: if kanjiIndex[kanjizz]['story1']: note[story1DstField] = kanjiIndex[kanjizz]['story1'].decode('utf8') else: note[story1DstField] = "" if kanjiIndex[kanjizz]['story2']: note[story2DstField] = kanjiIndex[kanjizz]['story2'].decode('utf8') else: note[story2DstField] = "" note.flush() mw.progress.finish() mw.reset()
def addKanjiKeywords_bulk(nids): fields = [] anote=mw.col.getNote(nids[0]) #get the fields of the first note for (i, f) in anote.items(): fields.append(i) #get input/output fields from user expField = getKeyFromList("Select field to read from", "Read relevant kanji/expression from:", fields) if (expField is None): return kanjiDstField = getKeyFromList("Select field to write to", "Write keywords to:", fields) if (heisigNumDstField is None): return mw.checkpoint("Add Heisig Keywords") readRTK() #set version version = '2010' #get output field #which numbering system do you want to use? mw.progress.start() #For each seleccted card for nid in nids: note = mw.col.getNote(nid) src = None if expField in note: src = expField if not src: # no src field then next card continue dst = None if kanjiDstField in note: dst = kanjiDstField if not dst: # no dst field then skip card continue #Add the data to the dst field if True == doNote(note, expField, kanjiDstField): note.flush() mw.progress.finish() mw.reset()
def updateNotes(self): """Update existing notes""" state = "default" self.uniq_id = self.opref['uniq_id'] self.occl_id = '%s-%s' % (self.uniq_id, self.occl_tp) omask_path = None self._findAllNotes() (svg_node, mlayer_node) = self._getMnodesAndSetIds(True) if not self.mnode_ids: tooltip("No shapes left. You can't delete all cards.<br>\ Are you sure you set your masks correctly?") return False mw.checkpoint("Editing Image Occlusion Cards") ret = self._deleteAndIdNotes(mlayer_node) if not ret: # confirmation window rejected return False else: (del_count, new_count) = ret self.new_svg = svg_node.toxml() # write changes to svg old_svg = self._getOriginalSvg() # load original svg if self.new_svg != old_svg or self.occl_tp != self.opref["occl_tp"]: # updated masks or occlusion type omask_path = self._saveMask(self.new_svg, self.occl_id, "O") qmasks = self._generateMaskSVGsFor("Q") amasks = self._generateMaskSVGsFor("A") state = "reset" image_path = mw.col.media.addFile(self.image_path) img = fname2img(image_path) logging.debug("mnode_indexes %s", self.mnode_indexes) for nr, idx in enumerate(self.mnode_indexes): logging.debug("=====================") logging.debug("nr %s", nr) logging.debug("idx %s", idx) note_id = self.mnode_ids[idx] logging.debug("note_id %s", note_id) logging.debug("self.nids %s", self.nids) nid = self.nids[note_id] logging.debug("nid %s", nid) if omask_path: self._saveMaskAndReturnNote(omask_path, qmasks[nr], amasks[nr], img, note_id, nid) else: self._saveMaskAndReturnNote(None, None, None, img, note_id, nid) self._showUpdateTooltip(del_count, new_count) return state
def bulkAddClozes(nids): mw.checkpoint("Bulk-add clozes") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) (c,e) = clozeFields(note) # does it contain data? if not c or not e or not note[c] or not note[e]: continue _formatFrameNumbers(note, c, e) _createClozes(note, c, e) _repositionCards(note, c, e) mw.progress.finish() mw.reset()
def regenerate_bulk_readings(note_ids): if not yomidict: raise Exception("Yomidict not working.") mw.checkpoint(MENU_NAME) mw.progress.start() for nid in note_ids: note = mw.col.getNote(nid) update_note(note) note.flush() mw.progress.finish() mw.reset()
def onEdit(): if not mw.reviewer.card: return showInfo("Please run this when a card is shown") m = mw.reviewer.card.model() t = mw.reviewer.card.template() if "canvas" in t['qfmt']: return mw.checkpoint("Embed Scratchpad") t['qfmt'] += '\n<br><div id="canvas"></div>' + "\n<script>%s</script>" % JS m['css'] += CSS mw.col.models.save(m) mw.col.setMod() mw.reset() showInfo("Scratchpad embedded.")
def regenerateFrameNumbers(nids): mw.checkpoint("Regenerate frame numbers") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) (c,e) = clozeFields(note) # right note type? if not c: continue clozeText = stripHTML(mw.col.media.strip(note[c])) note[e] = u' '.join([formatFrame(c) for c in extractKanji(clozeText)]) note.flush() mw.progress.finish() mw.reset()
def addKimExamples(nids): readExamples() mw.checkpoint("Add Kim Examples") mw.progress.start() # For each seleccted card for nid in nids: note = mw.col.getNote(nid) if note[expField] == "": continue doNote(note) note.flush() mw.progress.finish() mw.reset()
def addInfo(nids, sourceName): fields = [] anote=mw.col.getNote(nids[0]) #get the fields of the first note for (i, f) in anote.items(): fields.append(i) #get input/output fields from user expField = getKeyFromList("Select field to read from", "Read relevant kanji/expression from:", fields) if (expField is None): return infoDstField = getKeyFromList("Select field to write to", "Write {} to:".format(sourceName), fields) if (infoDstField is None): return mw.checkpoint("Add {} info".format(sourceName)) mw.progress.start() kanjiIndex = readInfo(sourceName) #For each seleccted card for nid in nids: note = mw.col.getNote(nid) src = None if expField in note: src = expField if not src: # no src field then next card continue dst = None if infoDstField in note: dst = infoDstField if not dst: # no dst field then skip card continue srcTxt = mw.col.media.strip(note[src]) if not srcTxt.strip(): continue #Add the data to the dst field num = joinseparator.join(lookupKanjiInfo(srcTxt, kanjiIndex, 'info')) if num!=0: note[dst] = str(num) #sys.stderr.write("Results:" + note[dst]) note.flush() mw.progress.finish() mw.reset()
def add_examples_bulk(nids): mw.checkpoint("Bulk-add Examples") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) # Find example sentences examples = find_examples_multiple(note, MAX_PERMANENT) if not examples: continue note[DEST_FIELD] = examples note.flush() mw.progress.finish() mw.reset()
def add_examples_bulk(nids): mw.checkpoint("Bulk-add Examples") mw.progress.start() for nid in nids: note = mw.col.getNote(nid) # Find example sentences try: examples = find_examples_multiple(note, config["maxPermanent"]) except NoExamplesFoundException: continue _set_fields(note, examples) note.flush() mw.progress.finish() mw.reset()
def onFixHTML(browser): nids = browser.selectedNotes() if not nids: showInfo("Please select some notes.") return mw.checkpoint("Fix Invalid HTML") mw.progress.start(immediate=True) try: changed = _onFixHTML(browser, nids) finally: mw.progress.finish() browser.model.reset() mw.requireReset() showInfo("Updated %d/%d notes." % (changed, len(nids)), parent=browser)