예제 #1
0
def answerCard_before(self, ease):
    checked = False

    if ease == 1:
        tags = self.mw.reviewer.card.note().stringTags()
        if self.card.template()["name"] == "Translation":
            if tags.find("pt") != -1:
                checked = True
            else:
                checked = False
        elif self.card.template()["name"] == "Forward":
            if tags.find("pf") != -1:
                checked = True
            else:
                checked = False
        elif self.card.template()["name"] == "Reverse":
            if tags.find("pb") != -1:
                checked = True
            else:
                checked = False

    if checked:
        self.state = None
        tooltip("Defered Card!")
    else:
        l = self._answerButtonList()
        a = [item for item in l if item[0] == ease]
        if len(a) > 0:
            tooltip(a[0][1])
예제 #2
0
    def saveMedia(self):
        if self.checkCb.isChecked():
            # ignore the media code
            if self.code not in Setup.config['codesIgnored']:
                Setup.config['codesIgnored'].append(self.code)
                Setup.saveConfigToDisk()
                tooltip('Current dictionary was ignored, click on reset to restore should you need it again')
                self.importRes = False
                self.close()
                return

        folder = self.pathEdit.text().strip()

        # remove the trailing / or \ 
        if folder.endswith('/') or folder.endswith('\\'):
            folder = folder[:-1]

        fullPath = os.path.join(self.pathEdit.text(), self.filename)
        if not (os.path.exists(fullPath) and os.path.exists(folder)):
            msg = QMessageBox(self)
            msg.setText("Folder doesn't exist or doesn't contain the needed media, please select again")
            msg.setWindowTitle("Directory selected is not the right one")
            msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
            msg.exec_()
            return

        Setup.config['addressMap'][self.code] = folder
        Setup.saveConfigToDisk()
        self.importRes = True
        tooltip('Media import completed')
        self.close()
예제 #3
0
파일: main.py 프로젝트: terrisage/Anki
 def onDelete():
     saveGeom(diag, "emptyCards")
     QDialog.accept(diag)
     self.checkpoint(_("Delete Empty"))
     self.col.remCards(cids)
     tooltip(ngettext("%d card deleted.", "%d cards deleted.", len(cids)) % len(cids))
     self.reset()
예제 #4
0
def on_search_for_selection(web_view):
    sel_encode = selected_text_as_query(web_view).encode('utf8', 'ignore')
    #need to do this the long way around to avoid double % encoding
    url = QUrl.fromEncoded(SEARCH_URL % urllib.quote(sel_encode))
    #openLink(SEARCH_URL + sel_encode)
    tooltip(_("Loading..."), period=1000)
    QDesktopServices.openUrl(url)
예제 #5
0
파일: main.py 프로젝트: terrisage/Anki
 def __init__(self, app, profileManager, args):
     QMainWindow.__init__(self)
     self.state = "startup"
     aqt.mw = self
     self.app = app
     self.pm = profileManager
     # running 2.0 for the first time?
     if self.pm.meta['firstRun']:
         # load the new deck user profile
         self.pm.load(self.pm.profiles()[0])
         self.pm.meta['firstRun'] = False
         self.pm.save()
     # init rest of app
     self.safeMode = self.app.queryKeyboardModifiers() & Qt.ShiftModifier
     try:
         self.setupUI()
         self.setupAddons()
     except:
         showInfo(_("Error during startup:\n%s") % traceback.format_exc())
         sys.exit(1)
     # must call this after ui set up
     if self.safeMode:
         tooltip(_("Shift key was held down. Skipping automatic "
                 "syncing and add-on loading."))
     # were we given a file to import?
     if args and args[0]:
         self.onAppMsg(args[0])
     # Load profile in a timer so we can let the window finish init and not
     # close on profile load error.
     self.progress.timer(10, self.setupProfile, False)
예제 #6
0
 def accept(self):
     self.exporter.includeSched = (
         self.frm.includeSched.isChecked())
     self.exporter.includeMedia = (
         self.frm.includeMedia.isChecked())
     self.exporter.includeTags = (
         self.frm.includeTags.isChecked())
     if not self.frm.deck.currentIndex():
         self.exporter.did = None
     else:
         name = self.decks[self.frm.deck.currentIndex()]
         self.exporter.did = self.col.decks.id(name)
     if (self.isApkg and self.exporter.includeSched and not
         self.exporter.did):
         verbatim = True
         # it's a verbatim apkg export, so place on desktop instead of
         # choosing file
         file = os.path.join(QDesktopServices.storageLocation(
             QDesktopServices.DesktopLocation), "collection.apkg")
         if os.path.exists(file):
             if not askUser(
                 _("%s already exists on your desktop. Overwrite it?")%
                 "collection.apkg"):
                 return
     else:
         verbatim = False
         # Get deck name and remove invalid filename characters
         deck_name = self.decks[self.frm.deck.currentIndex()]
         deck_name = re.sub('[\\\\/?<>:*|"^]', '_', deck_name)
         filename = os.path.join(aqt.mw.pm.base,
                                 u'{0}{1}'.format(deck_name, self.exporter.ext))
         while 1:
             file = getSaveFile(self, _("Export"), "export",
                                self.exporter.key, self.exporter.ext,
                                fname=filename)
             if not file:
                 return
             if checkInvalidFilename(os.path.basename(file), dirsep=False):
                 continue
             break
     self.hide()
     if file:
         self.mw.progress.start(immediate=True)
         try:
             f = open(file, "wb")
             f.close()
         except (OSError, IOError), e:
             showWarning(_("Couldn't save file: %s") % unicode(e))
         else:
             os.unlink(file)
             self.exporter.exportInto(file)
             if verbatim:
                 msg = _("A file called collection.apkg was saved on your desktop.")
                 period = 5000
             else:
                 period = 3000
                 msg = ngettext("%d card exported.", "%d cards exported.", \
                             self.exporter.count) % self.exporter.count
             tooltip(msg, period=period)
         finally:
예제 #7
0
 def _linkHandler(self, url):
     if url == "study":
         self.mw.col.startTimebox()
         self.mw.moveToState("review")
         if self.mw.state == "overview":
             tooltip(_("No cards are due yet."))
     elif url == "anki":
         print "anki menu"
     elif url == "opts":
         self.mw.onDeckConf()
     elif url == "cram":
         deck = self.mw.col.decks.current()
         self.mw.onCram("'deck:%s'" % deck['name'])
     elif url == "refresh":
         self.mw.col.sched.rebuildDyn()
         self.mw.reset()
     elif url == "empty":
         self.mw.col.sched.emptyDyn(self.mw.col.decks.selected())
         self.mw.reset()
     elif url == "decks":
         self.mw.moveToState("deckBrowser")
     elif url == "review":
         openLink(aqt.appShared+"info/%s?v=%s"%(self.sid, self.sidVer))
     elif url == "studymore":
         self.onStudyMore()
     elif url.lower().startswith("http"):
         openLink(url)
예제 #8
0
 def accept(self):
     file = getSaveFile(
         self, _("Export"), "export",
         self.exporter.key, self.exporter.ext)
     self.hide()
     if file:
         self.exporter.includeSched = (
             self.frm.includeSched.isChecked())
         self.exporter.includeMedia = (
             self.frm.includeMedia.isChecked())
         self.exporter.includeTags = (
             self.frm.includeTags.isChecked())
         if not self.frm.deck.currentIndex():
             self.exporter.did = None
         else:
             name = self.decks[self.frm.deck.currentIndex()]
             self.exporter.did = self.col.decks.id(name)
         self.mw.progress.start(immediate=True)
         try:
             f = open(file, "wb")
             f.close()
         except (OSError, IOError), e:
             showWarning(_("Couldn't save file: %s") % unicode(e))
         else:
             os.unlink(file)
             self.exporter.exportInto(file)
             tooltip(_("%d exported.") % self.exporter.count)
         finally:
예제 #9
0
파일: main.py 프로젝트: dae/anki
 def __init__(self, app, profileManager, opts, args):
     QMainWindow.__init__(self)
     self.state = "startup"
     self.opts = opts
     aqt.mw = self
     self.app = app
     self.pm = profileManager
     # init rest of app
     self.safeMode = self.app.queryKeyboardModifiers() & Qt.ShiftModifier
     try:
         self.setupUI()
         self.setupAddons()
     except:
         showInfo(_("Error during startup:\n%s") % traceback.format_exc())
         sys.exit(1)
     # must call this after ui set up
     if self.safeMode:
         tooltip(_("Shift key was held down. Skipping automatic "
                 "syncing and add-on loading."))
     # were we given a file to import?
     if args and args[0]:
         self.onAppMsg(args[0])
     # Load profile in a timer so we can let the window finish init and not
     # close on profile load error.
     if isWin:
         fn = self.setupProfileAfterWebviewsLoaded
     else:
         fn = self.setupProfile
     self.progress.timer(10, fn, False, requiresCollection=False)
예제 #10
0
파일: addons.py 프로젝트: terrisage/Anki
    def accept(self):
        QDialog.accept(self)

        # get codes
        try:
            ids = [int(n) for n in self.form.code.text().split()]
        except ValueError:
            showWarning(_("Invalid code."))
            return

        errors = []

        self.mw.progress.start(immediate=True)
        for n in ids:
            ret = download(self.mw, n)
            if ret[0] == "error":
                errors.append(_("Error downloading %(id)s: %(error)s") % dict(id=n, error=ret[1]))
                continue
            data, fname = ret
            self.mw.addonManager.install(data, fname)
        self.mw.progress.finish()
        if not errors:
            tooltip(_("Download successful. Please restart Anki."), period=3000)
        else:
            showWarning("\n".join(errors))
def historyRestore(self, mode, sorted_res, model):
    n = self.currentField
    field = model['flds'][n]['name']
    last_val = {}
    keys = []
    for nid in sorted_res[:100]:
        oldNote = self.note.col.getNote(nid)
        if field in oldNote:
            html = oldNote[field]
        else:
            try:
                html = oldNote.fields[n]
            except IndexError:
                pass
        if html.strip():
            text = stripHTML(html)
        else:
            text = None
        if text and text not in last_val:
            keys.append(text)
            last_val[text] = html
    if not last_val:
        tooltip("No prior entries for this field found.")
        return False
    txt = "Set field to:"
    (text, ret) = myGetField(self.parentWindow, 
            txt, keys, title="Field History")
    if not ret or not text.strip() or text not in last_val:
        return False
    self.note[field] = last_val[text]
예제 #12
0
def download_for_note(note=False, ask_user=False):
    """
    Download audio for all fields.

    Download audio for all fields of the note passed in or the current
    note. When ask_user is true, show a dialog that lets the user
    modify these texts.
    """
    card = None
    if not note:
        try:
            card = mw.reviewer.card
            note = card.note()
        except:
            return
    field_data = get_note_fields(note, get_empty=ask_user)
    if not field_data:
        # Complain before we show the empty dialog.
        tooltip(u'Nothing to download.')
        return
    language_code = get_language_code(card=card, note=note)
    if ask_user:
        try:
            field_data, language_code = update_data(field_data, language_code)
        except RuntimeError as rte:
            if 'cancel' in str(rte):
                # User canceled. No need for the "Nothing downloaded"
                # message.
                return
            else:
                # Don't know how to handle this after all
                raise
    do_download(note, field_data, language_code)
    def addNote(self, data):
        "Takes model, deck, fields, tags. If deck is missing, use current deck."
        col = mw.col

        print "adding:", data
        
        # get model and deck
        model = col.models.byName(data["model"])
        if not data["deck"]:
            deck_id = col.conf["curDeck"]
        else:
            deck_id = col.decks.id(data["deck"])

        # make note
        note = notes.Note(col, model=model)
        note.model()["did"] = deck_id        
        
        # you can specify fewer fields if you want, but not *more*
        if len(data["fields"]) > len(note.fields):
            raise Exception("received too many fields")
        for i, f in enumerate(data["fields"]):
            note.fields[i] = f
            
        if data["tags"]:
            for tag in data["tags"].split():
                note.addTag(tag)

        # add note
        col.addNote(note)
        col.save()
        utils.tooltip("Note added.")
        return True
예제 #14
0
def get_preferred_valid_entries(editor, word):
    collegiate_url = "http://www.dictionaryapi.com/api/v1/references/collegiate/xml/" + \
                     urllib.parse.quote_plus(word) + "?key=" + MERRIAM_WEBSTER_API_KEY
    medical_url = "https://www.dictionaryapi.com/api/references/medical/v2/xml/" + \
                  urllib.parse.quote_plus(word) + "?key=" + MERRIAM_WEBSTER_MEDICAL_API_KEY
    all_collegiate_entries = get_entries_from_api(word, collegiate_url)
    all_medical_entries = get_entries_from_api(word, medical_url)

    potential_unified = set()
    if PREFERRED_DICTIONARY == "COLLEGIATE":
        entries = filter_entries_lower_and_potential(word, all_collegiate_entries)
        potential_unified |= entries.potential
        if not entries.valid:
            entries = filter_entries_lower_and_potential(word, all_medical_entries)
            potential_unified |= entries.potential
    else:
        entries = filter_entries_lower_and_potential(word, all_medical_entries)
        potential_unified |= entries.potential
        if not entries.valid:
            entries = filter_entries_lower_and_potential(word, all_collegiate_entries)
            potential_unified |= entries.potential

    if not entries.valid:
        potential = " Potential matches: " + ", ".join(potential_unified)
        tooltip("No entry found in Merriam-Webster dictionary for word '%s'.%s" %
                (word, potential if entries.potential else ""))
        _focus_zero_field(editor)
    return entries.valid
 def convertNotes(self, nids):
     """Main note conversion method"""
     nids_by_nr = {}
     skipped = 0
     (io_nids, filtered) = self.filterSelected(nids)
     for nid in io_nids:
         note = mw.col.getNote(nid)
         (uniq_id, note_nr) = self.getDataFromNamingScheme(note)
         if uniq_id == False:
             logging.debug("Skipping note that couldn't be parsed: %s", nid)
             skipped += 1
             continue
         occl_tp = self.getOcclTypeAndNodes(note)
         occl_id = uniq_id + '-' + occl_tp
         if occl_id == self.occl_id_last:
             logging.debug(
                 "Skipping note that we've just converted: %s", nid)
             continue
         self.occl_id_last = occl_id
         for nid in self.findByNoteId(uniq_id):
             note = mw.col.getNote(nid)
             (uniq_id, note_nr) = self.getDataFromNamingScheme(note)
             if uniq_id == False:
                 logging.debug(
                     "Skipping note that couldn't be parsed: %s", nid)
                 skipped += 1
                 continue
             nids_by_nr[int(note_nr)] = nid
         self.idAndCorrelateNotes(nids_by_nr, occl_id)
     converted = len(io_nids)
     tooltip("<b>%i</b> notes updated, <b>%i</b> skipped"
             % (converted - skipped, filtered + skipped))
예제 #16
0
def on_lookup_wadoku_selection():
    u"""Wrapper to look up the expression at Wadoku and catch value errors."""
    try:
        # Empty list (or possibly 'None')  means selection
        lookup_wadoku([])
    except ValueError as ve:
        tooltip(str(ve))
예제 #17
0
파일: reviewer.py 프로젝트: kchien/ankiqt
 def nextCard(self):
     if self.cardQueue:
         # undone/edited cards to show
         c = self.cardQueue.pop()
         c.startTimer()
         self.hadCardQueue = True
     else:
         if self.hadCardQueue:
             # the undone/edited cards may be sitting in the regular queue;
             # need to reset
             self.mw.col.reset()
             self.hadCardQueue = False
         c = self.mw.col.sched.getCard()
     self.card = c
     clearAudioQueue()
     if not c:
         self.mw.moveToState("overview")
         return
     if self._reps is None or self._reps % 100 == 0:
         # we recycle the webview periodically so webkit can free memory
         self._initWeb()
     else:
         self._showQuestion()
     elapsed = self.mw.col.timeboxReached()
     if elapsed:
         tooltip(_("%(cards)d cards studied in %(mins)s minutes.") %
                 dict(cards=elapsed[1], mins=elapsed[0]/60))
         self.mw.col.startTimebox()
예제 #18
0
파일: editor.py 프로젝트: WangHanbin/anki
    def onCloze(self):
        # check that the model is set up for cloze deletion
        if not re.search("{{(.*:)*cloze:", self.note.model()["tmpls"][0]["qfmt"]):
            if self.addMode:
                tooltip(_("Warning, cloze deletions will not work until " "you switch the type at the top to Cloze."))
            else:
                showInfo(
                    _(
                        """\
To make a cloze deletion on an existing note, you need to change it \
to a cloze type first, via Edit>Change Note Type."""
                    )
                )
                return
        # find the highest existing cloze
        highest = 0
        for name, val in self.note.items():
            m = re.findall("\{\{c(\d+)::", val)
            if m:
                highest = max(highest, sorted([int(x) for x in m])[-1])
        # reuse last?
        if not self.mw.app.keyboardModifiers() & Qt.AltModifier:
            highest += 1
        # must start at 1
        highest = max(1, highest)
        self.web.eval("wrap('{{c%d::', '}}');" % highest)
예제 #19
0
    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
예제 #20
0
def gui_add_QA_note(fnames_q, fnames_a, media_dir, tags, svg_fname,
                     fname_original, header, footer, did):
    col = mw.col
    mm = col.models
    if not mm.byName(IMAGE_QA_MODEL_NAME): # first time addon is run
        add_image_QA_model(col)
    m = mm.byName(IMAGE_QA_MODEL_NAME)
        
    nrOfNotes = add_QA_note(col, fnames_q, fnames_a,
                            tags, media_dir, svg_fname,
                            fname_original, header, footer, did)
    rm_media_dir(media_dir) # removes the media and the directory
    
    #  We must update the GUI so that the user knows that cards have
    # been added.  When the GUI is updated, the number of new cards
    # changes, and it provides the feedback we want.
    # If we want more feedback, we can add a tooltip that tells the
    # user how many cards have been added.
    # The way to update the GUI will depend on the state
    # of the main window. There are four states (from what I understand):
    #  - "review"
    #  - "overview"
    #  - "deckBrowser"
    #  - "resetRequired" (we will treat this one like "deckBrowser)
    if mw.state == "review":
        mw.reviewer.show()
    elif mw.state == "overview":
        mw.overview.refresh()
    else:
        mw.deckBrowser.refresh() # this shows the browser even if the
          # main window is in state "resetRequired", which in my
          # opinion is a good thing
    utils.tooltip(notes_added_message(nrOfNotes))
예제 #21
0
    def getNewImage(self, parent=None, noclip=False):
        """Get image from file selection or clipboard"""
        if noclip:
            clip = None
        else:
            clip = QApplication.clipboard()
        if clip and clip.mimeData().imageData():
            handle, image_path = tempfile.mkstemp(suffix='.png')
            clip.image().save(image_path)
            clip.clear()
            if os.stat(image_path).st_size == 0:
                # workaround for a clipboard bug
                return self.getNewImage(noclip=True)
            else:
                return str(image_path)

        # retrieve last used image directory
        prev_image_dir = self.lconf["dir"]
        if not prev_image_dir or not os.path.isdir(prev_image_dir):
            prev_image_dir = IO_HOME

        image_path = QFileDialog.getOpenFileName(parent,
                                                 "Select an Image", prev_image_dir,
                                                 "Image Files (*.png *jpg *.jpeg *.gif)")
        if image_path:
            image_path = image_path[0]

        if not image_path:
            return None
        elif not os.path.isfile(image_path):
            tooltip("Invalid image file path")
            return False
        else:
            self.lconf["dir"] = os.path.dirname(image_path)
            return image_path
예제 #22
0
파일: reviewer.py 프로젝트: mstange/anki
 def nextCard(self):
     elapsed = self.mw.col.timeboxReached()
     if elapsed:
         part1 = ngettext("%d card studied in", "%d cards studied in", elapsed[1]) % elapsed[1]
         part2 = ngettext("%s minute.", "%s minutes.", elapsed[0]/60) % (elapsed[0]/60)
         tooltip("%s %s" % (part1, part2), period=5000)
         self.mw.col.startTimebox()
     if self.cardQueue:
         # undone/edited cards to show
         c = self.cardQueue.pop()
         c.startTimer()
         self.hadCardQueue = True
     else:
         if self.hadCardQueue:
             # the undone/edited cards may be sitting in the regular queue;
             # need to reset
             self.mw.col.reset()
             self.hadCardQueue = False
         c = self.mw.col.sched.getCard()
     self.card = c
     clearAudioQueue()
     if not c:
         self.mw.moveToState("overview")
         return
     if self._reps is None or self._reps % 100 == 0:
         # we recycle the webview periodically so webkit can free memory
         self._initWeb()
     else:
         self._showQuestion()
예제 #23
0
    def accept(self):
        "On close, create notes from the contents of the poem editor."
        title = self.form.titleBox.text().strip()
        tags = self.mw.col.tags.canonify(
            self.mw.col.tags.split(self.form.tagsBox.text()))
        text = process_text(self.form.textBox.toPlainText().strip())
        if not title.strip():
            showWarning("You must enter a title for this poem.")
            return
        if self.mw.col.findNotes('"note:%s" "Title:%s"'
                                 % (lpcg_models.NAME, title)):
            showWarning("You already have a poem by that title in your "
                        "database. Please check to see if you've already "
                        "added it, or use a different name.")
            return
        if not text:
            showWarning("There's nothing to generate cards from! "
                        "Please type a poem in the box, or use the "
                        '"open file" button to import a text file.')
            return

        notes_generated = self._genNotes(title, tags, text)
        if notes_generated:
            super(LPCGDialog, self).accept()
            self.mw.reset()
            tooltip("%i notes added." % notes_generated)
예제 #24
0
def on_lookup_forvo_expression():
    u"""Wrapper to look up the expression at Forvo and catch value errors."""
    try:
        lookup_forvo(expression_fields)
    except ValueError as ve:
        tooltip(str(ve))
    except AttributeError:
        tooltip(u'Error during lookup. (No note?)')
예제 #25
0
파일: deckconf.py 프로젝트: bqv/anki
 def setChildren(self):
     if not askUser(_("Set all decks below %s to this option group?") % self.deck["name"]):
         return
     for did in self.childDids:
         deck = self.mw.col.decks.get(did)
         deck["conf"] = self.deck["conf"]
         self.mw.col.decks.save(deck)
     tooltip(ngettext("%d deck updated.", "%d decks updated.", len(self.childDids)) % len(self.childDids))
예제 #26
0
def rescheduleRevReward(self, card, ease):
    """Increase ease factor as reward for straight"""
    dconf = self.col.decks.confForDid(card.did)
    if dconf.get('straitReward'):
        count = checkStrait(self, card, ease)
        if ease == 3 and count > 0 and count % STRAIT == STRAIT - 1:
            card.factor = max(1300, card.factor+REWARD)
            tooltip(str(count+1) + PRAISE + str(card.factor/10))
예제 #27
0
def on_lookup_wadoku_meaning():
    u"""Wrapper to look up the expression at Wadoku and catch value errors."""
    try:
        lookup_wadoku(meaning_fields)
    except ValueError as ve:
        tooltip(str(ve))
    except AttributeError:
        tooltip(u'Error during lookup. (No note?)')
예제 #28
0
def do_download(note, field_data_list, language, hide_text=False):
    """
    Download audio data.

    Go through the list of words and list of sites and download each
    word from each site. Then call a function that asks the user what
    to do.
    """
    retrieved_entries = []
    for field_data in field_data_list:
        if field_data.empty:
            continue
        for dloader in downloaders:
            # Use a public variable to set the language.
            dloader.language = language
            try:
                # Make it easer inside the downloader. If anything
                # goes wrong, don't catch, or raise whatever you want.
                dloader.download_files(field_data)
            except:
                #  # Uncomment this raise while testing a new
                #  # downloaders.  Also comment out all the others in the
                #  # downloaders list in downloaders.__init__
                # raise
                continue
            retrieved_entries += dloader.downloads_list
    # Significantly changed the logic. Put all entries in one
    # list, do stuff with that list of DownloadEntries.
    try:
        retrieved_entries = review_entries(note, retrieved_entries, hide_text)
        # Now just the dialog, which sets the fields in the entries
    except ValueError as ve:
        tooltip(str(ve))
    except RuntimeError as rte:
        if 'cancel' in str(rte):
            for entry in retrieved_entries:
                entry.action = Action.Delete
        else:
            raise
    for entry in retrieved_entries:
        entry.dispatch(note)
    if any(entry.action == Action.Add for entry in retrieved_entries):
        note.flush()
        # We have to do different things here, for download during
        # review, we should reload the card and replay. When we are in
        # the add dialog, we do a field update there.
        rnote = None
        try:
            rnote = mw.reviewer.card.note()
        except AttributeError:
            # Could not get the note of the reviewer's card. Probably
            # not reviewing at all.
            return
        if note == rnote:
            # The note we have is the one we were reviewing, so,
            # reload and replay
            mw.reviewer.card.load()
            mw.reviewer.replayAudio()
예제 #29
0
파일: webview.py 프로젝트: Glutanimate/anki
    def _onHeight(self, qvar):
        if qvar is None:
            tooltip(_("Error connecting to local port. Retrying..."))
            from aqt import mw
            mw.progress.timer(2000, mw.reset, False)
            return

        height = math.ceil(qvar*self.zoomFactor())
        self.setFixedHeight(height)
예제 #30
0
 def onDelete(self):
     self.mw.checkpoint(_("Delete"))
     cnt = len(self.card.note().cards())
     self.mw.col.remNotes([self.card.note().id])
     self.mw.reset()
     tooltip(ngettext(
         "Note and its %d card deleted.",
         "Note and its %d cards deleted.",
         cnt) % cnt)
예제 #31
0
 def bury_current_note(self) -> None:
     bury_notes(
         parent=self.mw,
         note_ids=[self.card.nid],
     ).success(
         lambda _: tooltip(tr.studying_note_buried())).run_in_background()
예제 #32
0
 def bury_current_card(self) -> None:
     bury_cards(
         parent=self.mw,
         card_ids=[self.card.id],
     ).success(
         lambda _: tooltip(tr.studying_card_buried())).run_in_background()
예제 #33
0
파일: card.py 프로젝트: rye761/anki
def set_card_deck(*, parent: QWidget, card_ids: Sequence[CardId],
                  deck_id: DeckId) -> CollectionOp[OpChangesWithCount]:
    return CollectionOp(
        parent, lambda col: col.set_deck(card_ids, deck_id)).success(
            lambda out: tooltip(tr.browsing_cards_updated(count=out.count),
                                parent=parent))
예제 #34
0
def update_ICRP_sentences():
    global log_message
    tooltip("Updating ICRP sentences... ")
    chinese_dictionary = read_cedict()
    cedict_keys = list(chinese_dictionary.keys())

    # get all seen Chinese characters:
    ids = mw.col.findCards("note:Hanzi -is:suspended -is:new")
    known_hanzis = []
    for card_id in ids:
        hanzi = mw.col.getCard(card_id).note()["hanzi"]
        known_hanzis.append(hanzi)
    # print(known_hanzis)

    # get all seen Chinese words:
    ids = mw.col.findCards("note:Word -is:suspended -is:new")
    known_words = []
    for card_id in ids:
        word = mw.col.getCard(card_id).note()["hanzis"]
        known_words.append(word)
    # print(known_words)

    # iterate over the ICRP sentences:
    ids = mw.col.findCards("note:Sentence")
    for card_id in ids:
        table = "<table>\n"
        card = mw.col.getCard(card_id)
        note = card.note()

        # assigning vocabulary:
        sentence = note["Sentence"]
        print(sentence)
        while len(sentence) > 0:
            end_index = len(sentence)
            while end_index > 0:
                part = sentence[0:end_index]
                result = chinese_dictionary[part]
                if len(result) > 0:
                    ktag = ""
                    if end_index > 1:
                        if part in known_words:
                            ktag = " class=\"known\""
                    else:
                        if part in known_hanzis:
                            ktag = " class=\"known\""
                    for entry in result:
                        table += "<tr{}>".format(ktag)
                        if part != entry[0]:
                            table += "<td class=\"hanzi small\">{}({})</td>".format(
                                part, entry[0])
                        else:
                            table += "<td class=\"hanzi small\">{}</td>".format(
                                part)
                        table += "<td class=\"pinyin\">{}</td>".format(
                            entry[1])
                        table += "<td class=\"translation\">{}</td>".format(
                            (" / ").join(entry[2]))
                        table += "</tr>\n"
                end_index -= 1
            sentence = sentence[1:]
        table += "</table>"
        note["Vocabulary"] = table
        note.flush()

        # creating {{Sentence with pinyin}}:
        sentence = note["Sentence"]
        sentence_with_pinyin = ""
        for character in sentence:
            pinyins = []
            if character in known_hanzis:
                ktag = " known"
            else:
                ktag = ""
            result = chinese_dictionary[character]
            for entry in result:
                pinyins.append(entry[1])
            color = list(set([x[-1] for x in pinyins]))
            if len(color) == 1:
                color_class = " color{}".format(color[0])
            else:
                color_class = ""
            sentence_with_pinyin += "<div class=\"hanzi_with_pinyin{}\">".format(
                ktag)
            sentence_with_pinyin += "<div class=\"hanzi{}\">{}</div>".format(
                color_class, character)
            uniqe_pinyins = sorted(list(set([x.lower() for x in pinyins])))
            pinyin_divs = ("").join([
                "<div class=\"pinyin_div color{}\">{}</div>".format(x[-1], x)
                for x in uniqe_pinyins
            ])
            sentence_with_pinyin += "<div class=\"pinyins_div\">{}</div></div>\n".format(
                pinyin_divs)
        note["Sentence with pinyin"] = sentence_with_pinyin
        note.flush()

    tooltip("Update complete!")
    return
예제 #35
0
def print_log_message(reviewer, ease=None):
    global log_message
    if len(log_message) > 0:
        tooltip(log_message)
        log_message = ""
 def remove_all_from_queue(self):
     empty_priority_list()
     self.fill_list(self.t_view_left, [], with_nums = True)
     self.tabs.currentWidget().refresh()
     tooltip(f"Queue emptied.")
예제 #37
0
 def reopen(self, mw):
     tooltip("Please finish editing the existing card first.")
     self.onReset()
예제 #38
0
def onCloze(self, _old):
    model = self.note.model()
    # If the model is set up for cloze deletion, then defer to Anki's implementation.
    if re.search('{{(.*:)*cloze:', model['tmpls'][0]['qfmt']):
        return _old(self)
    else:
        # Check if field is non-empty, in which case it can be clozed.
        if self.note.fields[self.currentField]:
            current_field_name = model["flds"][self.currentField]["name"]
            if current_field_name.endswith("Cloze"):
                content = self.note.fields[self.currentField]
                cloze_nums = get_cloze_nums(content)

                # Determine what cloze number the currently highlighted text should get.
                if cloze_nums:
                    next_cloze_num = max(cloze_nums)
                    # Unless we are reusing, then increment to the next greatest cloze number.
                    if not self.mw.app.keyboardModifiers() & Qt.AltModifier:
                        next_cloze_num += 1
                else:
                    next_cloze_num = 1

                commands = ["wrap('((c{}::', '))')".format(next_cloze_num)]

                cloze_nums.add(next_cloze_num)

                cloze_field_update_commands, found_cloze_nums = \
                    update_cloze_fields(self, cloze_nums=cloze_nums, cloze_field_name=current_field_name, model=model)

                commands.extend(cloze_field_update_commands)

                missing_cloze_num = cloze_nums - found_cloze_nums

                self.web.eval(";".join(commands) + ";")

                if missing_cloze_num:
                    tooltip("Not enough cloze fields.  Missing: {}".format(
                        ", ".join(current_field_name + str(n)
                                  for n in sorted(missing_cloze_num))))
            else:
                tooltip("Cannot cloze unless field ends in name Cloze")
        else:
            # If the field is empty, then to be helpful we can check if it ends in Cloze and in that case
            # copy from another field without Cloze.  For example, when ExpressionCloze is the current
            # field and it is empty, we will copy from the Expression field.

            current_field_name = model["flds"][self.currentField]["name"]
            if current_field_name.endswith("Cloze"):
                other_field_name = current_field_name[:-len("Cloze")]
                other_field_name_ord = next(
                    (f["ord"]
                     for f in model["flds"] if f["name"] == other_field_name),
                    None)
                if other_field_name_ord is not None:
                    content = self.note.fields[other_field_name_ord]
                    self.web.eval("setFormat('inserthtml', {});".format(
                        json.dumps(content)))
                else:
                    tooltip(
                        "Cannot populate empty field {} because other field {} was not found to copy from"
                        .format(current_field_name, other_field_name))
            else:
                tooltip(
                    "Cannot populate empty field {} because name does not end in Cloze"
                    .format(current_field_name))
예제 #39
0
def importFile(mw, file):
    importer = None
    done = False
    for i in importing.Importers:
        if done:
            break
        for mext in re.findall("[( ]?\*\.(.+?)[) ]", i[0]):
            if file.endswith("." + mext):
                importer = i[1]
                done = True
                break
    if not importer:
        # if no matches, assume TSV
        importer = importing.Importers[0][1]
    importer = importer(mw.col, file)
    # need to show import dialog?
    if importer.needMapper:
        # make sure we can load the file first
        mw.progress.start(immediate=True)
        try:
            importer.open()
        except UnicodeDecodeError:
            showUnicodeWarning()
            return
        except Exception as e:
            msg = repr(str(e))
            if msg == "'unknownFormat'":
                if file.endswith(".anki2"):
                    showWarning(
                        _("""\
.anki2 files are not designed for importing. If you're trying to restore from a \
backup, please see the 'Backups' section of the user manual."""))
                else:
                    showWarning(_("Unknown file format."))
            else:
                msg = _("Import failed. Debugging info:\n")
                msg += str(traceback.format_exc())
                showText(msg)
            return
        finally:
            mw.progress.finish()
        diag = ImportDialog(mw, importer)
    else:
        # if it's an apkg/zip, first test it's a valid file
        if importer.__class__.__name__ == "AnkiPackageImporter":
            try:
                z = zipfile.ZipFile(importer.file)
                z.getinfo("collection.anki2")
            except:
                showWarning(invalidZipMsg())
                return
            # we need to ask whether to import/replace
            if not setupApkgImport(mw, importer):
                return
        mw.progress.start(immediate=True)
        try:
            importer.run()
        except zipfile.BadZipfile:
            showWarning(invalidZipMsg())
        except Exception as e:
            err = repr(str(e))
            if "invalidFile" in err:
                msg = _("""\
Invalid file. Please restore from backup.""")
                showWarning(msg)
            elif "invalidTempFolder" in err:
                showWarning(mw.errorHandler.tempFolderMsg())
            elif "readonly" in err:
                showWarning(_("""\
Unable to import from a read-only file."""))
            else:
                msg = _("Import failed.\n")
                msg += str(traceback.format_exc())
                showText(msg)
        else:
            log = "\n".join(importer.log)
            if "\n" not in log:
                tooltip(log)
            else:
                showText(log)
        finally:
            mw.progress.finish()
        mw.reset()
예제 #40
0
    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'])
예제 #41
0
파일: sync.py 프로젝트: xiaoronglv/anki
    def onEvent(self, evt, *args):
        pu = self.mw.progress.update
        if evt == "badAuth":
            tooltip(
                _("AnkiWeb ID or password was incorrect; please try again."),
                parent=self.mw)
            # blank the key so we prompt user again
            self.pm.profile['syncKey'] = None
            self.pm.save()
        elif evt == "corrupt":
            pass
        elif evt == "newKey":
            self.pm.profile['syncKey'] = args[0]
            self.pm.save()
        elif evt == "offline":
            tooltip(_("Syncing failed; internet offline."))
        elif evt == "upbad":
            self._didFullUp = False
            self._checkFailed()
        elif evt == "sync":
            m = None
            t = args[0]
            if t == "login":
                m = _("Syncing...")
            elif t == "upload":
                self._didFullUp = True
                m = _("Uploading to AnkiWeb...")
            elif t == "download":
                m = _("Downloading from AnkiWeb...")
            elif t == "sanity":
                m = _("Checking...")
            elif t == "findMedia":
                m = _("Checking media...")
            elif t == "upgradeRequired":
                showText(
                    _("""\
Please visit AnkiWeb, upgrade your deck, then try again."""))
            if m:
                self.label = m
                self._updateLabel()
        elif evt == "syncMsg":
            self.label = args[0]
            self._updateLabel()
        elif evt == "error":
            self._didError = True
            showText(_("Syncing failed:\n%s") % self._rewriteError(args[0]))
        elif evt == "clockOff":
            self._clockOff()
        elif evt == "checkFailed":
            self._checkFailed()
        elif evt == "mediaSanity":
            showWarning(
                _("""\
A problem occurred while syncing media. Please use Tools>Check Media, then \
sync again to correct the issue."""))
        elif evt == "noChanges":
            pass
        elif evt == "fullSync":
            self._confirmFullSync()
        elif evt == "send":
            # posted events not guaranteed to arrive in order
            self.sentBytes = max(self.sentBytes, int(args[0]))
            self._updateLabel()
        elif evt == "recv":
            self.recvBytes = max(self.recvBytes, int(args[0]))
            self._updateLabel()
예제 #42
0
 def onRestoreDefaults(self) -> None:
     default_conf = self.mgr.addonConfigDefaults(self.addon)
     self.updateText(default_conf)
     tooltip(_("Restored defaults"), parent=self)
예제 #43
0
파일: reviewer.py 프로젝트: yuhkih/anki
 def onSuspend(self) -> None:
     self.mw.checkpoint(_("Suspend"))
     self.mw.col.sched.suspendCards([c.id for c in self.card.note().cards()])
     tooltip(_("Note suspended."))
     self.mw.reset()
예제 #44
0
    def processNote(self, deckName):
        self.window.debug.appendPlainText("Processing Notes")
        deck = mw.col.decks.get(mw.col.decks.id(deckName))

        # create custom model
        model = self.addCustomModel(deckName, mw.col)

        # assign custom model to new deck
        mw.col.decks.select(deck["id"])
        mw.col.decks.get(deck)["mid"] = model["id"]
        mw.col.decks.save(deck)

        # assign new deck to custom model
        mw.col.models.setCurrent(model)
        mw.col.models.current()["did"] = deck["id"]
        mw.col.models.save(model)

        # start creating notes
        if self.new:
            for term in self.new:
                note = mw.col.newNote()
                note['term'] = term['term']
                note['definition'] = term['definition']
                note['uk'] = term['uk']
                note['us'] = term['us']
                if term['phrases'][0]:
                    for index, phrase in enumerate(term['phrases']):
                        note['phrase' + str(index)] = phrase
                        note['phrase_explain' +
                             str(index)] = term['phrases_explains'][index]
                        note['pplaceHolder' + str(index)] = "Tap To View"
                if term['sentences'][0]:
                    for index, sentence in enumerate(term['sentences']):
                        note['sentence' + str(index)] = sentence
                        note['sentence_explain' +
                             str(index)] = term['sentences_explains'][index]
                        note['splaceHolder' + str(index)] = "Tap To View"
                if term['image']:
                    if self.window.downloadimage.isChecked():
                        note[
                            'image'] = "<img src = 'Deck2Anki/{}.jpg'>".format(
                                term['image'])
                    else:
                        note['image'] = "<img src ='{}' >".format(
                            term['image'])

                mw.col.addNote(note)
            mw.col.fixIntegrity()
            mw.col.reset()
            mw.reset()

        # start deleting notes
        if self.deleted:
            for term in self.deleted:
                cardID = mw.col.findCards("term:" + term)
                deckID = mw.col.decks.id(deckName)
                for cid in cardID:
                    nid = mw.col.db.scalar(
                        "select nid from cards where id = ? and did = ?", cid,
                        deckID)
                    if nid is not None:
                        mw.col.db.execute("delete from cards where id =?", cid)
                        mw.col.db.execute("delete from notes where id =?", nid)
            mw.col.fixIntegrity()
            mw.col.reset()
            mw.reset()
        self.window.debug.appendPlainText("Notes processed")
        tooltip('Added : ' + str(len(self.new)) + '<br><br>Deleted : ' +
                str(len(self.deleted)),
                period=3000)
예제 #45
0
 def accept(self):
     self.exporter.includeSched = (self.frm.includeSched.isChecked())
     self.exporter.includeMedia = (self.frm.includeMedia.isChecked())
     self.exporter.includeTags = (self.frm.includeTags.isChecked())
     if not self.frm.deck.currentIndex():
         self.exporter.did = None
     else:
         name = self.decks[self.frm.deck.currentIndex()]
         self.exporter.did = self.col.decks.id(name)
     if (self.isApkg and self.exporter.includeSched
             and not self.exporter.did):
         verbatim = True
         # it's a verbatim apkg export, so place on desktop instead of
         # choosing file; use homedir if no desktop
         usingHomedir = False
         file = os.path.join(
             QDesktopServices.storageLocation(
                 QDesktopServices.DesktopLocation), "collection.apkg")
         if not os.path.exists(os.path.dirname(file)):
             usingHomedir = True
             file = os.path.join(
                 QDesktopServices.storageLocation(
                     QDesktopServices.HomeLocation), "collection.apkg")
         if os.path.exists(file):
             if usingHomedir:
                 question = _(
                     "%s already exists in your home directory. Overwrite it?"
                 )
             else:
                 question = _(
                     "%s already exists on your desktop. Overwrite it?")
             if not askUser(question % "collection.apkg"):
                 return
     else:
         verbatim = False
         # Get deck name and remove invalid filename characters
         deck_name = self.decks[self.frm.deck.currentIndex()]
         deck_name = re.sub('[\\\\/?<>:*|"^]', '_', deck_name)
         filename = os.path.join(
             aqt.mw.pm.base, u'{0}{1}'.format(deck_name, self.exporter.ext))
         while 1:
             file = getSaveFile(self,
                                _("Export"),
                                "export",
                                self.exporter.key,
                                self.exporter.ext,
                                fname=filename)
             if not file:
                 return
             if checkInvalidFilename(os.path.basename(file), dirsep=False):
                 continue
             break
     self.hide()
     if file:
         self.mw.progress.start(immediate=True)
         try:
             f = open(file, "wb")
             f.close()
         except (OSError, IOError), e:
             showWarning(_("Couldn't save file: %s") % unicode(e))
         else:
             os.unlink(file)
             exportedMedia = lambda cnt: self.mw.progress.update(
                 label=ngettext("Exported %d media file",
                                "Exported %d media files", cnt) % cnt)
             addHook("exportedMediaFiles", exportedMedia)
             self.exporter.exportInto(file)
             remHook("exportedMediaFiles", exportedMedia)
             if verbatim:
                 if usingHomedir:
                     msg = _(
                         "A file called %s was saved in your home directory."
                     )
                 else:
                     msg = _("A file called %s was saved on your desktop.")
                 msg = msg % "collection.apkg"
                 period = 5000
             else:
                 period = 3000
                 if self.isTextNote:
                     msg = ngettext(
                         "%d note exported.", "%d notes exported.",
                         self.exporter.count) % self.exporter.count
                 else:
                     msg = ngettext(
                         "%d card exported.", "%d cards exported.",
                         self.exporter.count) % self.exporter.count
             tooltip(msg, period=period)
         finally:
예제 #46
0
파일: reviewer.py 프로젝트: zimsys/anki
 def onReplayRecorded(self):
     if not self._recordedAudio:
         return tooltip(_("You haven't recorded your voice yet."))
     clearAudioQueue()
     play(self._recordedAudio)
예제 #47
0
def post( st ): # :: State -> State
    tooltip(_( 'Tagged {} notes containing morphemes in the selected db with "{}" '.format(st['noteCount'], st['tags']) ) )
    return st
예제 #48
0
파일: reviewer.py 프로젝트: zimsys/anki
 def onBuryNote(self):
     self.mw.checkpoint(_("Bury"))
     self.mw.col.sched.buryNote(self.card.nid)
     self.mw.reset()
     tooltip(_("Note buried."))
예제 #49
0
def answerCard_before(self, ease):
    l = self._answerButtonList()
    a = [item for item in l if item[0] == ease]
    if len(a) > 0:
        tooltip(a[0][1])
예제 #50
0
파일: reviewer.py 프로젝트: zimsys/anki
 def onBuryCard(self):
     self.mw.checkpoint(_("Bury"))
     self.mw.col.sched.buryCards([self.card.id])
     self.mw.reset()
     tooltip(_("Card buried."))
예제 #51
0
파일: reviewer.py 프로젝트: zimsys/anki
 def onSuspendCard(self):
     self.mw.checkpoint(_("Suspend"))
     self.mw.col.sched.suspendCards([self.card.id])
     tooltip(_("Card suspended."))
     self.mw.reset()
예제 #52
0
    def on_syncBtn_clicked(self):

        failedGenerator = (self.newWordListWidget.item(row).data(Qt.UserRole) is None for row in range(self.newWordListWidget.count()))
        if any(failedGenerator):
            if not askUser('存在未查询或失败的单词,确定要加入单词本吗?\n 你可以选择失败的单词点击 "查询按钮" 来重试。'):
                return

        currentConfig = self.getAndSaveCurrentConfig()
        model = getOrCreateModel(MODEL_NAME)
        getOrCreateModelCardTemplate(model, 'default')
        deck = getOrCreateDeck(self.deckComboBox.currentText())

        logger.info('同步点击')
        audiosDownloadTasks = []
        newWordCount = self.newWordListWidget.count()

        # 判断是否需要下载发音
        if currentConfig['noPron']:
            logger.info('不下载发音')
            whichPron = None
        else:
            whichPron = 'AmEPron' if self.AmEPronRadioButton.isChecked() else 'BrEPron'
            logger.info(f'下载发音{whichPron}')

        added = 0
        for row in range(newWordCount):
            wordItem = self.newWordListWidget.item(row)
            wordItemData = wordItem.data(Qt.UserRole)
            if wordItemData:
                addNoteToDeck(deck, model, currentConfig, wordItemData)
                added += 1
                # 添加发音任务
                if whichPron and wordItemData.get(whichPron):
                    audiosDownloadTasks.append((f"{whichPron}_{wordItemData['term']}.mp3", wordItemData[whichPron],))
        mw.reset()

        logger.info(f'发音下载任务:{audiosDownloadTasks}')

        if audiosDownloadTasks:
            self.syncBtn.setEnabled(False)
            self.progressBar.setValue(0)
            self.progressBar.setMaximum(len(audiosDownloadTasks))
            if self.audioDownloadThread is not None:
                self.audioDownloadThread.requestInterruption()
                self.audioDownloadThread.quit()
                self.audioDownloadThread.wait()

            self.audioDownloadThread = QThread(self)
            self.audioDownloadThread.start()
            self.audioDownloadWorker = AudioDownloadWorker(audiosDownloadTasks)
            self.audioDownloadWorker.moveToThread(self.audioDownloadThread)
            self.audioDownloadWorker.tick.connect(lambda: self.progressBar.setValue(self.progressBar.value() + 1))
            self.audioDownloadWorker.start.connect(self.audioDownloadWorker.run)
            self.audioDownloadWorker.done.connect(lambda: tooltip(f'发音下载完成'))
            self.audioDownloadWorker.done.connect(self.audioDownloadThread.quit)
            self.audioDownloadWorker.start.emit()

        self.newWordListWidget.clear()

        needToDeleteWordItems = [
            self.needDeleteWordListWidget.item(row)
            for row in range(self.needDeleteWordListWidget.count())
            if self.needDeleteWordListWidget.item(row).checkState() == Qt.Checked
        ]
        needToDeleteWords = [i.text() for i in needToDeleteWordItems]

        deleted = 0

        if needToDeleteWords and askUser(f'确定要删除这些单词吗:{needToDeleteWords[:3]}...({len(needToDeleteWords)}个)', title='Dict2Anki', parent=self):
            needToDeleteWordNoteIds = getNotes(needToDeleteWords, currentConfig['deck'])
            mw.col.remNotes(needToDeleteWordNoteIds)
            deleted += 1
            mw.col.reset()
            mw.reset()
            for item in needToDeleteWordItems:
                self.needDeleteWordListWidget.takeItem(self.needDeleteWordListWidget.row(item))
            logger.info('删除完成')
        logger.info('完成')

        if not audiosDownloadTasks:
            tooltip(f'添加{added}个笔记\n删除{deleted}个笔记')
def notify_user(cnt, oldname, newfilename):
    s = f'Updated file location/reference in {cnt} note{"s" if cnt > 1 else ""}: <br> from {oldname} to {newfilename}'
    tooltip(s, period=6000)
예제 #54
0
파일: exporting.py 프로젝트: solarmist/anki
    def accept(self):
        self.exporter.includeSched = (self.frm.includeSched.isChecked())
        self.exporter.includeMedia = (self.frm.includeMedia.isChecked())
        self.exporter.includeTags = (self.frm.includeTags.isChecked())
        self.exporter.includeHTML = (self.frm.includeHTML.isChecked())
        if not self.frm.deck.currentIndex():
            self.exporter.did = None
        else:
            name = self.decks[self.frm.deck.currentIndex()]
            self.exporter.did = self.col.decks.id(name)
        if self.isVerbatim:
            name = time.strftime("-%Y-%m-%d@%H-%M-%S",
                                 time.localtime(time.time()))
            deck_name = _("collection") + name
        else:
            # Get deck name and remove invalid filename characters
            deck_name = self.decks[self.frm.deck.currentIndex()]
            deck_name = re.sub('[\\\\/?<>:*|"^]', '_', deck_name)

        if not self.isVerbatim and self.isApkg and self.exporter.includeSched and self.col.schedVer(
        ) == 2:
            showInfo(
                "Please switch to the regular scheduler before exporting a single deck .apkg with scheduling."
            )
            return

        filename = '{0}{1}'.format(deck_name, self.exporter.ext)
        while 1:
            file = getSaveFile(self,
                               _("Export"),
                               "export",
                               self.exporter.key,
                               self.exporter.ext,
                               fname=filename)
            if not file:
                return
            if checkInvalidFilename(os.path.basename(file), dirsep=False):
                continue
            break
        self.hide()
        if file:
            self.mw.progress.start(immediate=True)
            try:
                f = open(file, "wb")
                f.close()
            except (OSError, IOError) as e:
                showWarning(_("Couldn't save file: %s") % str(e))
            else:
                os.unlink(file)
                exportedMedia = lambda cnt: self.mw.progress.update(
                    label=ngettext("Exported %d media file",
                                   "Exported %d media files", cnt) % cnt)
                addHook("exportedMediaFiles", exportedMedia)
                self.exporter.exportInto(file)
                remHook("exportedMediaFiles", exportedMedia)
                period = 3000
                if self.isVerbatim:
                    msg = _("Collection exported.")
                else:
                    if self.isTextNote:
                        msg = ngettext(
                            "%d note exported.", "%d notes exported.",
                            self.exporter.count) % self.exporter.count
                    else:
                        msg = ngettext(
                            "%d card exported.", "%d cards exported.",
                            self.exporter.count) % self.exporter.count
                tooltip(msg, period=period)
            finally:
                self.mw.progress.finish()
        QDialog.accept(self)
예제 #55
0
 def onReplayRecorded(self) -> None:
     if not self._recordedAudio:
         tooltip(tr.studying_you_havent_recorded_your_voice_yet())
         return
     av_player.play_file(self._recordedAudio)
예제 #56
0
파일: reviewer.py 프로젝트: mgmanzella/anki
 def onReplayRecorded(self):
     if not self._recordedAudio:
         return tooltip(_("You haven't recorded your voice yet."))
     av_player.play_file(self._recordedAudio)
예제 #57
0
 def check_for_updates(self) -> None:
     tooltip(_("Checking..."))
     check_and_prompt_for_updates(self, self.mgr, self.after_downloading)
예제 #58
0
 def after_downloading(self, log: List[DownloadLogEntry]) -> None:
     self.redrawAddons()
     if log:
         show_log_to_user(self, log)
     else:
         tooltip(_("No updates available."))
예제 #59
0
파일: reviewer.py 프로젝트: yuhkih/anki
 def onLeech(self, card: Card) -> None:
     # for now
     s = _("Card was a leech.")
     if card.queue < 0:
         s += " " + _("It has been suspended.")
     tooltip(s)
예제 #60
0
 def suspend_current_note(self) -> None:
     suspend_note(
         parent=self.mw,
         note_ids=[self.card.nid],
     ).success(lambda _: tooltip(tr.studying_note_suspended())
               ).run_in_background()