def add_word(word, model): # TODO: Use picture_name and sound_name to check # if update is needed and don't download media if not collection = mw.col note = notes.Note(collection, model) note = fill_note(word, note) # TODO: Rewrite to use is_duplicate() dupes = collection.findDupes("en", word['wd']) # a hack to support words with apostrophes note_dupes1 = collection.findNotes("en:'%s'" % word['wd']) note_dupes2 = collection.findNotes('en:"%s"' % word['wd']) note_dupes = note_dupes1 + note_dupes2 if not dupes and not note_dupes: collection.addNote(note) # TODO: Update notes if translation or tags (user wordsets) changed elif (note['picture_name'] or note['sound_name']) and note_dupes: # update existing notes with new pictures and sounds in case # they have been changed in LinguaLeo's UI for nid in note_dupes: note_in_db = notes.Note(collection, id=nid) # a dirty hack below until a new field in the model is introduced # put a space before or after a *sound* field of an existing note if you want it to be updated # if a note has no picture or sound, it will be updated anyway # TODO: Check if hack is still needed, remove if not sound_name = note_in_db['sound_name'] sound_name = sound_name.replace(" ", " ") note_needs_update = sound_name != sound_name.strip() if note['picture_name'] and ( note_needs_update or not note_in_db['picture_name'].strip()): note_in_db['picture_name'] = note['picture_name'] if note['sound_name'] and (note_needs_update or not note_in_db['sound_name'].strip()): note_in_db['sound_name'] = note['sound_name'] note_in_db.flush()
def addNote(self, deckId, model, expression, meaning, reading): note = notes.Note(self.mw.col, model) note.model()['did'] = deckId note['Expression'] = expression note['Meaning'] = meaning note['Reading'] = reading self.mw.col.addNote(note)
def create_note(coll, conf): model = coll.models.byName(conf['model']) note = notes.Note(coll, model) note.guid = conf['guid'] for fld, val in conf['fields'].items(): note[fld] = val coll.addNote(note)
def import_clippings(): # get the file to be imported path = getFile(mw, 'Open Kindle clippings', cb=None, filter='Clippings file (*.txt *.html)', key='KindleHighlights') if not path: return # get the lowered extension of the file ext = os.path.splitext(path)[1][1:].lower() if ext == 'txt': matched_ones, unmatched_ones = parse_text_clippings(path) elif ext == 'html': # TODO Import from html return else: raise RuntimeError(f'Unknown extension in path: {path!r}') # transfer to note type deck = mw.col.decks.byName('English') model = mw.col.models.byName('Plain Text') for std_clipping in matched_ones: note = notes.Note(mw.col, model) note.model()['did'] = deck['id'] note['Mother Language'] = std_clipping.quote note['Provenance'] = std_clipping.title + ' by ' + std_clipping.author mw.col.addNote(note) if unmatched_ones: showText( f'The following {len(unmatched_ones)} clippings could not be parsed:\n\n' + '\n==========\n'.join(unmatched_ones) )
def add_word_to_collection(word_entry, collection): model = prepare_model(mw.col, fields, styles.model_css) note = notes.Note(collection, model) note = fill_note(word_entry, note) collection.addNote(note)
def extract(self): mw.viewManager.saveScrollPosition(); #Copy text or html to clipboard and show (later will create card) if(len(mw.web.selectedText()) > 0): mw.web.triggerPageAction(QWebPage.Copy); clipboard = QApplication.clipboard(); mimeData = clipboard.mimeData(); #Highlight the text in the original document self.highlightSelectedText(self.highlightColor, self.doHighlightFont); card = mw.reviewer.card cur_note = card.note() col = mw.col deckName = col.decks.get(card.did)['name'] model = col.models.byName(IREAD_MODEL_NAME) new_note = notes.Note(col, model) new_note.tags = cur_note.tags #setField(new_note, TITLE_FIELD_NAME, getField(cur_note, TITLE_FIELD_NAME)) setField(new_note, TEXT_FIELD_NAME, mimeData.html()) setField(new_note, SOURCE_FIELD_NAME, getField(cur_note, SOURCE_FIELD_NAME)) self.editCurrent = editcurrent.EditCurrent(mw) self.addCards = addcards.AddCards(mw) self.addCards.editor.setNote(new_note) self.addCards.deckChooser.deck.setText(deckName) self.addCards.modelChooser.models.setText(IREAD_MODEL_NAME)
def doMediaImport(): # Raise the main dialog for the add-on and retrieve its result when closed. (path, model, fieldMap, ok) = ImportSettingsDialog().getDialogResult() if not ok: return # Get the MediaImport deck id (auto-created if it doesn't exist) did = mw.col.decks.id('MediaImport') # Passing in a unicode path to os.walk gives us unicode results. # We won't walk the path - we only want the top-level files. (root, dirs, files) = os.walk(unicode(path)).next() mw.progress.start(max=len(files), parent=mw, immediate=True) newCount = 0 failure = False for i, fileName in enumerate(files): note = notes.Note(mw.col, model) note.model()['did'] = did mediaName, ext = os.path.splitext(fileName) ext = ext[1:].lower() path = os.path.join(root, fileName) if ext is None or ext not in AUDIO + IMAGE: # Skip files with no extension and non-media files continue # Add the file to the media collection and get its name fname = mw.col.media.addFile(path) # Now we populate each field according to the mapping selected for field, idx in fieldMap.iteritems(): action = ACTIONS[idx] if action == '': continue elif action == "Media": if ext in AUDIO: note[field] = u'[sound:%s]' % fname elif ext in IMAGE: note[field] = u'<img src="%s">' % fname elif action == "File Name": note[field] = mediaName elif action == "File Name (full)": note[field] = fileName elif action == "Extension": note[field] = ext elif action == "Sequence": note[field] = str(i) if not mw.col.addNote(note): # No cards were generated - probably bad template. No point # trying to import anymore. failure = True break newCount += 1 mw.progress.update(value=i) mw.progress.finish() mw.deckBrowser.refresh() if failure: showFailureDialog() else: showCompletionDialog(newCount)
def createNote(self, selectedText): self.textManager.highlight(self.currentQuickKey['bgColor'], self.currentQuickKey['textColor']) newModel = mw.col.models.byName(self.currentQuickKey['modelName']) newNote = notes.Note(mw.col, newModel) setField(newNote, self.currentQuickKey['fieldName'], selectedText) card = mw.reviewer.card currentNote = card.note() tags = currentNote.stringTags() # Sets tags for the note, but still have to set them in the editor # if show dialog (see below) newNote.setTagsFromStr(tags) for f in newModel['flds']: if self.settings['sourceField'] == f['name']: setField(newNote, self.settings['sourceField'], getField(currentNote, self.settings['sourceField'])) if self.currentQuickKey['editExtract']: addCards = AddCards(mw) addCards.editor.setNote(newNote) if newNote.stringTags(): addCards.editor.tags.setText(newNote.stringTags().strip()) addCards.modelChooser.models.setText( self.currentQuickKey['modelName']) addCards.deckChooser.deck.setText( self.currentQuickKey['deckName']) else: deckId = mw.col.decks.byName(self.currentQuickKey['deckName'])['id'] newNote.model()['did'] = deckId ret = newNote.dupeOrEmpty() if ret == 1: showWarning(_( 'The first field is empty.'), help='AddItems#AddError') return cards = mw.col.addNote(newNote) if not cards: showWarning(_('''\ The input you have provided would make an empty \ question on all cards.'''), help='AddItems') return clearAudioQueue() mw.col.autosave() tooltip(_('Added')) if self.currentQuickKey['editSource']: EditCurrent(mw)
def add_word(word, model): # TODO: Use picture_name and sound_name to check # if update is needed and don't download media if not collection = mw.col note = notes.Note(collection, model) note = fill_note(word, note) # TODO: Rewrite to use is_duplicate() #word_value = word.get('wordValue') if word.get('wordValue') else 'NO_WORD_VALUE' #dupes = collection.findDupes("en", word_value) ## a hack to support words with apostrophes #note_dupes1 = collection.findNotes("en:'%s'" % word_value) #note_dupes2 = collection.findNotes('en:"%s"' % word_value) #note_dupes = note_dupes1 + note_dupes2 collection.addNote(note)
def add_QA_note(col, fname_q, fname_a, tags, fname_svg, fname_original, header, footer, did): m = col.models.byName(IMAGE_QA_MODEL_NAME) m['did'] = did n = notes.Note(col, model=m) n["Question"] = fname2img(fname_q) n["Footer"] = footer n["Header"] = header n["Original Image"] = fname2img(fname_original) n["SVG"] = fname2img(fname_svg) n["Answer"] = fname2img(fname_a) for tag in tags: n.addTag(tag) col.addNote(n) return n
def new_note(self): current_note = self.extended_notes[self.current_note_index] self.hide_main_tab(current_note) model = mw.col.models.byName(current_note.model()['name']) model["did"] = current_note.model()['did'] note = notes.Note(mw.col, model) note[model['flds'][0]['name']] = 'new' mw.col.addNote(note) for tag in current_note.tags: note.addTag(tag) self.extended_notes.append(ExtendedNote(note)) self.current_note_index = len(self.extended_notes) - 1 self.add_note(self.extended_notes[-1]) self.dirty[self.extended_notes[-1]] = True self.show_main_tab(self.extended_notes[-1])
def writeToDeck(self): # Pop up a Progress Dialog progress = aqt.progress.ProgressManager(self) progress.start(label=_("Adding Cards..."), immediate=True) # Add each created image to the media folder uniDirName = unicode(self.imagesDir) listFiles = os.listdir(uniDirName) for fileName in listFiles: filePath = unicode(os.path.join(uniDirName, fileName)) mw.col.media.addFile(filePath) # Configure so notes are written to selected deck deck = mw.col.decks.byName(self.deckName) did = deck['id'] # The crucial data to write a note to a deck is the did of the # model (saved as _model in the Note class). Create that here model = mw.col.models.byName("Basic") model['did'] = did newCount = 0 # Create a card (4 images) for each person on the map for i in range(0, len(listFiles) / 4): qWindow, qPerson, aPerson, aWindow = self.findNoteTuple( listFiles, i) # Create and add the note note = notes.Note(mw.col, model) print "qWindow: " + qWindow print "aPerson: " + aPerson note['Front'] = u"<img src='" + qWindow + "'>" note['Front'] += u"<img src='" + qPerson + "'>" note['Back'] = u"<img src='" + aPerson + "'>" note['Back'] += u"<img src='" + aWindow + "'>" newCount += mw.col.addNote(note) progress.finish() # Popup to tell users that cards were added tooltip(_("Added %d Notes" % newCount), period=2000) # Remove images folder shutil.rmtree(self.imagesDir) # Reset the GUI to show updated card counts etc mw.reset()
def add_QA_note(col, fname_q, fname_a, tags, fname_svg, fname_original, header, footer, did): m = col.models.byName(IMAGE_QA_MODEL_NAME) m['did'] = did n = notes.Note(col, model=m) n.fields = [ fname2img(fname_q), fname2img(fname_a), fname2img(fname_svg), fname2img(fname_original), header, footer ] for tag in tags: n.addTag(tag) col.addNote(n) return n
def import_images(directory, decName, tags, move, rename): # first of all, copy all images into anki's media directory getName = lambda x: x if not rename else createNewName(x) copy_move = shutil.move if move else shutil.copy files = [ (new_fName, getFileNames(directory, f, new_fName) ) # generates filename as ky and old and new adress as a tuple for f in sorted(os.listdir(directory)) for new_fName in [getName(f)] # generate new name or use old name if isImageFile(f, directory) ] filesCount = len(files) if not filesCount: return # create new deck and custom model model = mw.col.models.byName("Basic2") did = mw.col.decks.id(decName) txt = u""" <div><img src="{0}" /></div> """ for f, path in files: note = notes.Note(mw.col, model) note.model()['did'] = did note["Front"] = txt.format(f) note["Back"] = "" tagList = mw.col.tags.split(tags) for tag in tagList: note.addTag(tag) mw.app.processEvents() mw.col.addNote(note) copy_move(*path) mw.col.reset() mw.reset() tooltip("{0} images Imported...".format(filesCount))
def autoFill(): models = mw.col.models #Search for the Autofiller model, and grab it m = models.byName("Autofiller") #if our Autofiller model doesn't exist, create one if m == None: #create a new model and add it to the list of models m = models.new(_("Autofiller")) models.addField(m, models.newField(_("Search Term"))) models.addField(m, models.newField(_("PinoyDict"))) models.addField(m, models.newField(_("TagalogLessons"))) models.addField(m, models.newField(_("Diksiyonaryo"))) #Create a card template. 'qfmt' is the front side of the card, 'afmt' the back t = models.newTemplate(_("Autofiller")) t['qfmt'] = "{{" + _("Search Term") + "}}" t['afmt'] = "{{" + _("Search Term") + "}}\n\n<hr id=answer>{{" + _( "PinoyDict") + "}}<br>\n" + "{{" + _( "TagalogLessons") + "}}<br>\n" + "{{" + _( "Diksiyonaryo") + "}}" models.addTemplate(m, t) #necessary? models.add(m) #necessary? n = notes.Note(mw.col, m) #populate fields of note with the definitions results = tagscrape.translate("din") n.fields[0] = "din" n.fields[1] = results[0] n.fields[2] = results[1] n.fields[3] = results[2] #add note to the collection mw.col.addNote(n) tooltip("Added autofilled note")
def quickAddCards(self, quickKeyModel): self.saveScrollPosition() hasSelection = 0 selectedText = '' #Copy text or html to clipboard if selected, else just use clipboard contents (user could hit Ctrl-C in a web browser instead) if (len(mw.web.selectedText()) > 0): hasSelection = 1 mw.web.triggerPageAction(QWebPage.Copy) clipboard = QApplication.clipboard() mimeData = clipboard.mimeData() selectedText = mimeData.html() #Highlight the text in the original document. This is only useful for cards with long texts like IRead2. Other card models will ignore. if (quickKeyModel.get('color', None) != None): runHook("highlightText", quickKeyModel['color'], quickKeyModel.get('colorText', 'false')) #Create new note with selected model and deck new_model = mw.col.models.byName(quickKeyModel['modelName']) new_note = notes.Note(mw.col, new_model) self.setField(new_note, quickKeyModel['fieldName'], selectedText) #Add tags and copy source fields from source card, if applicable if (mw.reviewer.card): card = mw.reviewer.card cur_note = card.note() tags = cur_note.stringTags() new_note.setTagsFromStr(tags) #sets tags for the note, but still have to set them in the editor if show dialog (see below) SOURCE_FIELD_NAME = 'Source' TITLE_FIELD_NAME = 'Title' self.setField(new_note, SOURCE_FIELD_NAME, self.getField(cur_note, SOURCE_FIELD_NAME)) self.setField(new_note, TITLE_FIELD_NAME, self.getField(cur_note, TITLE_FIELD_NAME)) #This is very specific to IRead2 Model and should be generalized or moved elsewhere IREAD_MODEL_NAME = 'IRead2' TEXT_FIELD_NAME = 'Text' SOURCE_FIELD_NAME = 'Source' DECK_FIELD_NAME = 'Anki Deck' MODEL_FIELD_NAME = 'Model' if (mw.reviewer.card.model()['name'] == IREAD_MODEL_NAME): for f in new_model['flds']: if (SOURCE_FIELD_NAME == f['name']): self.setField( new_note, SOURCE_FIELD_NAME, self.getField(cur_note, SOURCE_FIELD_NAME)) #if(quickKeyModel['modelName'] == IREAD_MODEL_NAME): # self.setField(new_note, SOURCE_FIELD_NAME, self.getField(cur_note, SOURCE_FIELD_NAME)) # self.setField(new_note, MODEL_FIELD_NAME, self.getField(cur_note, MODEL_FIELD_NAME)) # self.setField(new_note, DECK_FIELD_NAME, self.getField(cur_note, DECK_FIELD_NAME)) #If shortcut said NOT to show AddCards dialog, then skip it. if (quickKeyModel['showEditor'] == 0): if (hasSelection == 1): new_note.model()['did'] = mw.col.decks.byName( quickKeyModel['deckName'])['id'] ret = new_note.dupeOrEmpty() if ret == 1: showWarning(_("The first field is empty."), help="AddItems#AddError") return cards = mw.col.addNote(new_note) if not cards: showWarning(_("""\ The input you have provided would make an empty \ question on all cards."""), help="AddItems") return # stop anything playing clearAudioQueue() mw.col.autosave() tooltip(_("Added"), period=500) #Else show the add cards dialog else: self.acsCount += 1 if (quickKeyModel['showEditCurrent'] == 1): self.editCurrent = editcurrent.EditCurrent(mw) self.addCards = addcards.AddCards(mw) self.addCards.editor.setNote(new_note) if (new_note.stringTags() != None): self.addCards.editor.tags.setText( new_note.stringTags().strip()) #Not sure why doesn't get set automatically since note has associated tags, but ... self.addCards.modelChooser.models.setText( quickKeyModel['modelName']) self.addCards.deckChooser.deck.setText(quickKeyModel['deckName'])
# -*- coding: utf-8 -*- import sys from PyQt4 import QtGui from anki import notes from aqt import mw from fetch_image_tools.fetch_image import MainDialog # sys.path.append('/home/mehdi/working_laptop/anki_fetch_images') # sys.path.append(os.path.join(os.getcwd(), 'Anki/addons/sepahkar')) n1 = notes.Note(mw.col, mw.english_model) n1.set_values([u'علی', 'v2', 'v3']) n2 = notes.Note(mw.col, mw.english_model) n2.set_values(['reza', 'v2', 'v3']) # n3 = notes.Note('hasan', Language.english, ['Word', 'Definition', 'Pronunciation'], ['hasan', 'v2', 'v3']) # n4 = Note('hosein', Language.english, ['f1', 'f2', 'f3'], ['hosein', 'v2', 'v3']) # n5 = Note('roghaieh', Language.english, ['f1', 'f2', 'f3'], ['roghaieh', 'v2', 'v3']) notes2 = [n1, n2] app = QtGui.QApplication(sys.argv) w = MainDialog(notes2) w.show() app.exec_()
def doMediaImport(): # Raise the main dialog for the add-on and retrieve its result when closed. (media_path, model, fieldList, ok) = ImportSettingsDialog().getDialogResult() if not ok: return # Get the MediaImport deck id (auto-created if it doesn't exist) did = mw.col.decks.id('MediaImport') if not isinstance(media_path[0], list): # a folder, not file(s), has been chosen # We won't walk the path - we only want the top-level files. (root, dirs, files) = next(os.walk(media_path)) else: # file(s), not folder, has been chosen files = media_path[0] mw.progress.start(max=len(files), parent=mw, immediate=True) newCount = 0 failure = False for i, fileName in enumerate(files): note = notes.Note(mw.col, model) note.model()['did'] = did mediaName, ext = os.path.splitext(fileName) ext = ext[1:].lower() if not isinstance(media_path[0], list): # a folder, not file(s), has been chosen path = os.path.join(root, fileName) else: # file(s), not folder, has been chosen path = fileName if ext is None or ext not in AUDIO + IMAGE: # Skip files with no extension and non-media files continue # Add the file to the media collection and get its name fname = mw.col.media.addFile(path) # Now we populate each field according to the mapping selected for (field, actionIdx, special) in fieldList: action = ACTIONS[actionIdx] if action == '': continue elif action == "Media": if ext in AUDIO: data = u'[sound:%s]' % fname elif ext in IMAGE: data = u'<img src="%s">' % fname elif action == "File Name": data = mediaName elif action == "File Name (full)": data = fileName elif action == "Extension": data = ext elif action == 'Extension-1': data = os.path.splitext(mediaName)[1][1:] elif action == "Sequence": data = str(i) if special and field == "Tags": note.tags.append(data) else: note[field] = data if not mw.col.addNote(note): # No cards were generated - probably bad template. No point # trying to import anymore. failure = True break newCount += 1 mw.progress.update(value=i) mw.progress.finish() mw.deckBrowser.refresh() if failure: showFailureDialog() else: showCompletionDialog(newCount)
def doImport(): # Raise the main dialog for the add-on and retrieve its result when closed. level = 2 (file, did, model, fieldList, ok) = ImportSettingsDialog().getDialogResult() if not ok: return if os.path.splitext(file)[-1] == '.html': # ACTIONS += ['标签'] f = open(file, encoding = 'utf-8', mode = 'r') source = f.read() f.close() mediaDir = os.path.splitext(file)[0] + '.resources' # 检查同目录下是否有 Evernote 自动生成的 .resources 目录,如果有则导入媒体文件,如果没有则不导入 if os.path.exists(mediaDir): mediaList = os.listdir(mediaDir) else: mediaList = [] mediaDict = {} for media in mediaList: mediaExt = os.path.splitext(media)[-1][1:].lower() if os.path.isfile(file) and mediaExt in AUDIO + IMAGE: mediaPath = os.path.join(mediaDir, media) mediaName = mw.col.media.addFile(mediaPath) mediaRelativePath = os.path.join(os.path.basename(mediaDir), media) if mediaExt in AUDIO: mediaDict[mediaRelativePath] = (mediaName, 'AUDIO') else: mediaDict[mediaRelativePath] = (mediaName, 'IMAGE') source = addMediaPointer(source, mediaDict) QAList = getQAFromHTML(source) tagList = getTagsFromHTML(source) elif os.path.splitext(file)[-1] == '.md': f = open(file, encoding = 'utf-8', mode = 'r') source = f.read() f.close() QAList = getQAFromMarkdown(source, level) metaDict = getMetaFromMarkdowm(source) # ACTIONS += metaDict.keys() mw.progress.start(max=len(QAList), parent=mw, immediate=True) newCount = 0 for i, QA in enumerate(QAList): note = notes.Note(mw.col, model) note.model()['did'] = did for (field, actionIdx, special) in fieldList: action = ACTIONS[actionIdx] if not action: continue elif action == '问题': data = QA[0] elif action == '答案': data = QA[1] elif action == '标签': data = ' '.join(tagList) else: data = metaDict[action] if special and field == 'Tags': note.tags.append(data) else: note[field] = data if not mw.col.addNote(note): showFailureDialog('无法访问 Anki 数据库') return newCount += 1 mw.progress.update(value=i) mw.progress.finish() # 刷新界面,使得卡组显示新增的卡片数 mw.reset() showCompletionDialog(newCount)
def on_import(self): from . import _try_ext_module total_new = 0 total_dup = 0 for i, _ in enumerate(self.yield_one_word()): (id, word, stem, lang, added_tm, usage, title, authors, category) = _ # region save new cards try: note = notes.Note(mw.col, mw.col.models.models[str(self.model['id'])]) except KeyError: continue note.model()['did'] = self.deck['id'] qry_word = stem if stem else word if word else '' if _try_ext_module(): mdx_files = self.MDXFiles else: mdx_files = [self.mdx, ] mdx_files = [m for m in mdx_files if os.path.isfile(m)] if not any(mdx_files): ret = askUser( _trans("ALERT FOR MISSING MDX"), self, defaultno=False, title=_trans("ANKINDLE") ) if not ret: break dict_nm = '' dict_data = '' for mdx_file in mdx_files: self.builder = mdict_query.IndexBuilder(mdx_file) self.builder.get_header() self.builder.check_build() try: mdx_dict = readmdict.MDX(mdx_file, only_header=True) self.builder._encoding = mdx_dict._encoding except MemoryError: showInfo(_trans("MDX MEMORY ERROR"), self, type="warning", title=_trans("ANKINDLE")) continue except TypeError: showInfo(_trans("MDX TYPE ERROR"), self, type="warning", title=_trans("ANKINDLE")) continue dict_nm = os.path.splitext(os.path.basename(mdx_dict._fname))[0] self.missed_css = set() dict_data = self.get_html(qry_word, self.builder) # copy css files if dict_data: mdx_dict_dir = os.path.split(mdx_file)[0] include_mdx_extras = ['.CSS', '.JS'] for root, dirs, files in os.walk(mdx_dict_dir): for _mfile in [css for css in files if os.path.splitext(css) [1].strip().upper() in include_mdx_extras]: _nfile = _mfile if _mfile in self.missed_css: _nfile = "_" + _mfile shutil.copy( os.path.join(root, _mfile), _nfile ) break _usage = self.adapt_to_anki(usage.replace(word, u"<b>%s</b>" % word)) if usage else '' try: _id_in_field = re.sub("[^0-9a-zA-Z]", "", qry_word + usage).strip().upper() except TypeError: return False def update_note(_note): _note.fields[_note._fieldOrd('id')] = _id_in_field if _id_in_field else '' _note.fields[_note._fieldOrd('word')] = word if word else '' _note.fields[_note._fieldOrd('stem')] = stem if stem else '' _note.fields[_note._fieldOrd('lang')] = lang if lang else '' _note.fields[_note._fieldOrd('creation_tm')] = added_tm if added_tm else '' _note.fields[_note._fieldOrd('usage')] = _usage if _usage else '' _note.fields[_note._fieldOrd('title')] = title if title else '' _note.fields[_note._fieldOrd('authors')] = authors if authors else '' _note.fields[_note._fieldOrd('mdx_dict')] = dict_data try: _note.fields[_note._fieldOrd('mdx_name')] = dict_nm except KeyError: pass return True if update_note(note): if note.dupeOrEmpty() != 2: mw.col.addNote(note) total_new += 1 else: total_dup += 1 mw.col.autosave() # endregion mw.moveToState("deckBrowser") showText(_trans("CREATED AND DUPLICATES") % (total_new, total_dup), self)
def quickAdd(self, quickKey): if not viewingIrText(): return hasSelection = False selectedText = '' if len(mw.web.selectedText()) > 0: hasSelection = True mw.web.triggerPageAction(QWebPage.Copy) clipboard = QApplication.clipboard() mimeData = clipboard.mimeData() if quickKey['plainText']: selectedText = mimeData.text() else: selectedText = mimeData.html() self.highlightText(quickKey['bgColor'], quickKey['textColor']) # Create new note with selected model and deck newModel = mw.col.models.byName(quickKey['modelName']) newNote = notes.Note(mw.col, newModel) setField(newNote, quickKey['fieldName'], selectedText) card = mw.reviewer.card currentNote = card.note() tags = currentNote.stringTags() # Sets tags for the note, but still have to set them in the editor # if show dialog (see below) newNote.setTagsFromStr(tags) for f in newModel['flds']: if SOURCE_FIELD_NAME == f['name']: setField(newNote, SOURCE_FIELD_NAME, getField(currentNote, SOURCE_FIELD_NAME)) if quickKey['editExtract']: self.acsCount += 1 addCards = addcards.AddCards(mw) addCards.editor.setNote(newNote) if newNote.stringTags(): addCards.editor.tags.setText(newNote.stringTags().strip()) addCards.modelChooser.models.setText(quickKey['modelName']) addCards.deckChooser.deck.setText(quickKey['deckName']) elif hasSelection: deckId = mw.col.decks.byName(quickKey['deckName'])['id'] newNote.model()['did'] = deckId ret = newNote.dupeOrEmpty() if ret == 1: showWarning(_('The first field is empty.'), help='AddItems#AddError') return cards = mw.col.addNote(newNote) if not cards: showWarning(_('''\ The input you have provided would make an empty \ question on all cards.'''), help='AddItems') return clearAudioQueue() mw.col.autosave() tooltip(_('Added')) if quickKey['editSource']: self.editCurrent = editcurrent.EditCurrent(mw)
def do_import(): """ Get the user settings from settingsForm, then do importing """ # Raise the settings window for the add-on and retrieve its result when closed. (dir_path, prov, deck_name, model_name, field_map, tags, ok) = SettingsDialog().get_result() if not ok: return deck = mw.col.decks.byName(deck_name) model = mw.col.models.byName(model_name) # Initialize audio_files, std_image_files, sub_files = [], [], [] is_import_failed = False card_count = 0 # Locate work directory os.chdir(dir_path) # Firstly, get new file name standard prefix according to provenance std_prefix = prov.replace(' ', '.') # We won't walk the path - we only want the top-level files. file_names = os.listdir(dir_path) # Start importing progress mw.progress.start(max=len(file_names), parent=mw) p = 0 # To classify files for f in file_names: file_root, ext = os.path.splitext(f) _ext = ext[1:].lower() if _ext in AUDIO_TYPES: audio_files.append((file_root, ext)) elif _ext in SUB_TYPES: sub_files.append((file_root, ext)) elif _ext in IMAGE_TYPES: # Copy image files to collection.media with standardized name std_name = std_prefix + '.image-' + str(time.time()) + ext copyfile(f, std_name) std_image_files.append(std_name) p += 1 else: p += 1 # Update progress mw.progress.update(value=p) # Create a note for each audio file, and add it to Anki collection for i, (root, ext) in enumerate(audio_files): std_root = std_prefix + '.audio' + '(' + str(i + 1) + ')' + '-' + str(time.time()) std_name = std_root + ext copyfile(root + ext, std_name) mw.col.media.addFile(std_name) os.remove(std_name) # Create a new note note = notes.Note(mw.col, model) note.model()['did'] = deck['id'] # Get subtitle file content try: # Find the corespondent sub file sub_ext = sub_files[[r[0] for r in sub_files].index(root)][1] # Opening with utf-8-sig encoding, which will remove BOM (Byte order mark) if it exists with open(root + sub_ext, mode='r', encoding='utf-8-sig') as f: line = re.sub(r'\[[0-9:.]+\]', '', f.read()) line = re.sub(r'\n+', r'<br>', line) # Update progress p += 1 # If sub file not found, index(root) will raise ValueError except ValueError: line = '' # Fill fields for field, option_idx in field_map.items(): data = '' option = FILLING_OPTIONS[option_idx] if option == FILL_NOTHING: continue elif option == FILL_FILENAME: data = std_root elif option == FILL_PROV: data = prov elif option == FILL_AUDIO: data = u'[sound:%s]' % std_name elif option == FILL_LINE: data = line elif option == FILL_IMAGE: if std_image_files: image = random.choice(std_image_files) mw.col.media.addFile(image) data = u'<img src="%s">' % image # Assign value to field note[field] = data # Add Tags for tag in tags: note.tags.append(tag) # Add to collection if not mw.col.addNote(note): # No cards were generated - probably bad template. No point to import anymore. is_import_failed = True break card_count += 1 p += 1 # Update progress mw.progress.update(value=p) # Delete std_image_files for image in std_image_files: os.remove(image) # At the end mw.progress.finish() mw.deckBrowser.refresh() if is_import_failed: show_failure_dialog() else: show_completion_dialog(card_count, deck_name)