Exemplo n.º 1
0
def postpone():
    i = QInputDialog.getInteger(mw, _("Postpone"),
                                _("Number of days to spread repetitions over:"),
                                2, 1)
    if i[1] and i[0] > 1:
        mw.deck.s.flush()
        q = mw.deck.s.all(
            "select id, interval, due from %s where reps > 0" % revCardOrder)
        size = len(q) / i[0] + 1
        days = 0
        count = -1
        cards = []
        now = time.time()
        for item in q:
            count += 1
            if count == size:
                count = 0
                days += 1
            seconds = 86400 * days
            # determine the current delay
            delay = now - item.due
            cards.append({'id': item[0],
                          'interval': item[1] + days + (delay / 86400.0),
                          'due': now + seconds})
        # apply changes
        mw.deck.s.execute("""
update cards set
interval = :interval,
due = :due,
combinedDue = max(:due, spaceUntil),
isDue = 0
where id = :id""", cards)
        # rebuild
        mw.reset()
Exemplo n.º 2
0
def moveTags():
    for fact in mw.deck.s.query(Fact).all():
        old = fact.tags
        fact.tags = canonifyTags(fact.tags + "," +
                                 ",".join([c.tags for c in fact.cards]))
        fact.setModified()
    mw.deck.setModified()
    mw.reset()
Exemplo n.º 3
0
def moveTags():
    for fact in mw.deck.s.query(Fact).all():
        old = fact.tags
        fact.tags = canonifyTags(fact.tags + "," + ",".join(
                                 [c.tags for c in fact.cards]))
        fact.setModified()
    mw.deck.setModified()
    mw.reset()
def doImport():
    # add an iknow model
    if not [m for m in mw.deck.models if m.name == 'Smart.fm']:
        m = Model(u'Smart.fm')
        m.addFieldModel(FieldModel(u'Expression', False, False))
        m.addFieldModel(FieldModel(u'Meaning', False, False))
        m.addFieldModel(FieldModel(u'Reading', False, False))
        m.addFieldModel(FieldModel(u'Audio', False, False))
        m.addFieldModel(FieldModel(u'Image', False, False))
        m.addCardModel(CardModel(
            u'Listening',
            u'Listen.%(Audio)s',
            u'%(Expression)s<br>%(Reading)s<br>%(Meaning)s<br>%(Image)s'))
        mw.deck.addModel(m)
    while 1:
        mw.reset()
        url = getOnlyText("Enter list URL:")
        if not url:
            return
        id = re.search("/lists/(\d+)", url).group(1)
        # get sentences
        f = urllib2.urlopen(
            "http://api.smart.fm/lists/%s/sentences.json" % id)
        d = simplejson.load(f)
        # add facts
        diag = QProgressDialog(_("Importing..."), "", 0, 0, mw)
        diag.setCancelButton(None)
        diag.setMaximum(len(d))
        diag.setMinimumDuration(0)
        for i, sen in enumerate(d):
            diag.setValue(i)
            diag.setLabelText(sen['text'])
            mw.app.processEvents()
            f = mw.deck.newFact()
            f['Expression'] = sen['text']
            f['Meaning'] = sen['translations'] and sen['translations'][0]['text'] or u""
            try:
                f['Reading'] = sen['transliterations']['Hrkt'] or u""
                # reading is sometimes missing
                if not f['Reading'] and kakasi:
                    f['Reading'] = kakasi.toFurigana(f['Expression'])
            except KeyError:
                f['Reading'] = u""
            if includeSounds and sen['sound']:
                (file, headers) = urllib.urlretrieve(sen['sound'])
                path = mw.deck.addMedia(file)
                f['Audio'] = u'[sound:%s]' % path
            else:
                f['Audio'] = u""
            if includeImages and sen['image']:
                (file, headers) = urllib.urlretrieve(sen['image'])
                path = mw.deck.addMedia(file)
                f['Image'] = u'<img src="%s">' % path
            else:
                f['Image'] = u""
            mw.deck.addFact(f)
        diag.cancel()
        mw.deck.save()
Exemplo n.º 5
0
    def addClicked(self):
        try:
            model = self.ensureKanjiModelExists()

            fact = mw.deck.newFact(model)
            #TODO pull data from UI field
            fact[u'Kanji'] = self.currentKanji
            fact[u'HeisigFrameID'] = u"heisig:%s" % self.currentKanjiFrame
            fact[u'Keyword'] = unicode(self.fld_keyword.text())
            fact[u'Story'] = unicode(self.fld_story.toPlainText())
            fact[u'PrimitiveMeanings'] = unicode(
                self.fld_primitives.toPlainText())

            strokeDiagramPath = os.path.join(mw.pluginsFolder(),
                                             u'JPdictionaryFiles', u'sod-utf8',
                                             self.currentKanji + u'.png')
            if os.path.exists(strokeDiagramPath):
                ankiDiagramPath = mw.deck.addMedia(strokeDiagramPath)
                fact[u'Image_StrokeOrderDiagram'] = u'<img src="%s"/>' % (
                    ankiDiagramPath)
            else:
                fact[u'Image_StrokeOrderDiagram'] = u""

            strokeAnimationPath = os.path.join(mw.pluginsFolder(),
                                               u'JPdictionaryFiles',
                                               u'soda-utf8',
                                               self.currentKanji + u'.gif')
            if os.path.exists(strokeAnimationPath):
                ankiAnimationPath = mw.deck.addMedia(strokeAnimationPath)
                fact[u'Image_StrokeOrderAnimation'] = u'<img src="%s" />' % (
                    ankiAnimationPath)
            else:
                fact[u'Image_StrokeOrderAnimation'] = u""

            newfact = mw.deck.addFact(fact)
            thecard = None
            for card in newfact.cards:
                thecard = mw.deck.cardFromId(card.id)
                mw.deck.answerCard(thecard, 2)
            mw.deck.save()
            mw.reset()
            self.statusLabel.setText("Added card for kanji: %s" %
                                     self.currentKanji)
            self.reviewerWidget.addQuestionAnswerForReview(
                unicode(self.fld_keyword.text()), self.currentKanji)
            self.incrementKanji()
        except:
            logpath = os.path.join(mw.pluginsFolder(), "log-rtk-importer.txt")
            log = open(logpath, 'a')
            log.write(traceback.format_exc())
            log.flush()
            log.close()
            QMessageBox.warning(
                mw, "Warning",
                "Your card may contain duplicate data. Please check that you have the correct keyword and that you haven't re-used the keyword or story before by accident. If you are sure there is no duplicate, then please contact the developer."
            )
Exemplo n.º 6
0
def tagCurrentCard(tag):
    mw.deck.setUndoStart(_("Suspend"))
    mw.currentCard.fact.tags = addTags(tag, mw.currentCard.fact.tags)
    mw.currentCard.fact.setModified()
    for card in mw.currentCard.fact.cards:
        mw.deck.updatePriority(card)
    mw.deck.setModified()
    mw.lastScheduledTime = None
    mw.reset()
    mw.deck.setUndoEnd(_("Suspend"))
Exemplo n.º 7
0
def markAndDelete():
    undo = _("MarkDelete")
    mw.deck.setUndoStart(undo)
    mw.currentCard.fact.tags = canonifyTags(mw.currentCard.fact.tags + "," +
                                            "MarkDelete")
    mw.currentCard.fact.setModified()
    mw.deck.updateFactTags([mw.currentCard.fact.id])
    mw.deck.deleteCard(mw.currentCard.id)
    mw.reset()
    mw.deck.setUndoEnd(undo)
Exemplo n.º 8
0
def markAndDelete():
    undo = _("MarkDelete")
    mw.deck.setUndoStart(undo)
    mw.currentCard.fact.tags = canonifyTags(mw.currentCard.fact.tags +
                                            "," + "MarkDelete")
    mw.currentCard.fact.setModified()
    mw.deck.updateFactTags([mw.currentCard.fact.id])
    mw.deck.deleteCard(mw.currentCard.id)
    mw.reset()
    mw.deck.setUndoEnd(undo)
 def addClicked(self):
     try:
         model = self.ensureKanjiModelExists()
         
         fact = mw.deck.newFact(model)
         #TODO pull data from UI field
         fact[u'Kanji'] = self.currentKanji
         fact[u'HeisigFrameID'] = u"heisig:%s" % self.currentKanjiFrame
         fact[u'Keyword'] = unicode(self.fld_keyword.text())
         fact[u'Story'] = unicode(self.fld_story.toPlainText())
         fact[u'PrimitiveMeanings'] = unicode(self.fld_primitives.toPlainText())
         
         strokeDiagramPath = os.path.join(mw.pluginsFolder(), u'JPdictionaryFiles', u'sod-utf8', self.currentKanji + u'.png')
         if os.path.exists(strokeDiagramPath):
             ankiDiagramPath = mw.deck.addMedia(strokeDiagramPath)
             fact[u'Image_StrokeOrderDiagram'] = u'<img src="%s"/>' % (ankiDiagramPath)
         else:
             fact[u'Image_StrokeOrderDiagram'] = u""
         
         strokeAnimationPath = os.path.join(mw.pluginsFolder(), u'JPdictionaryFiles', u'soda-utf8', self.currentKanji + u'.gif')
         if os.path.exists(strokeAnimationPath):
             ankiAnimationPath = mw.deck.addMedia(strokeAnimationPath)
             fact[u'Image_StrokeOrderAnimation'] = u'<img src="%s" />' % (ankiAnimationPath)
         else:
             fact[u'Image_StrokeOrderAnimation'] = u""
         
         newfact = mw.deck.addFact(fact)
         thecard = None
         for card in newfact.cards:
             thecard = mw.deck.cardFromId(card.id)
             mw.deck.answerCard(thecard, 2)
         mw.deck.save()
         mw.reset()
         self.statusLabel.setText("Added card for kanji: %s" % self.currentKanji)
         self.reviewerWidget.addQuestionAnswerForReview(unicode(self.fld_keyword.text()), self.currentKanji)
         self.incrementKanji()
     except:
         logpath = os.path.join(mw.pluginsFolder(), "log-rtk-importer.txt")
         log = open(logpath, 'a')
         log.write(traceback.format_exc())
         log.flush()
         log.close()
         QMessageBox.warning(mw, "Warning","Your card may contain duplicate data. Please check that you have the correct keyword and that you haven't re-used the keyword or story before by accident. If you are sure there is no duplicate, then please contact the developer.")
Exemplo n.º 10
0
def postpone():
    i = QInputDialog.getInteger(mw, _("Postpone"),
                                _("Number of days to spread repetitions over:"),
                                2, 1)
    if i[1] and i[0] > 1:
        mw.deck.s.flush()
        d = mw.deck
        q = d.s.all(
            d.cardLimit(
            "revActive", "revInactive", """
select c.id, interval, combinedDue from cards c where
type = 1 and combinedDue < :lim order by priority desc, combinedDue
"""), lim=d.dueCutoff)
        size = len(q) / i[0] + 1
        days = 0
        count = -1
        cards = []
        now = time.time()
        for item in q:
            count += 1
            if count == size:
                count = 0
                days += 1
            seconds = 86400 * days
            # determine the current delay
            delay = now - item.combinedDue
            cards.append({'id': item[0],
                          'interval': item[1] + days + (delay / 86400.0),
                          'due': now + seconds})
        # apply changes
        d.s.execute("""
update cards set
interval = :interval,
combinedDue = :due,
isDue = 0
where id = :id""", cards)
        # rebuild
        d.flushMod()
        mw.reset()
Exemplo n.º 11
0
def runImport(modelManager, importSettings):
    progress = ProgressTracker(os.path.join(mw.pluginsFolder(), "iknow-smartfm-log.txt"))
    try:
        importSettings.saveToConfig()
        iknow = SmartFMAPI()
        iknowList = iknow.list(importSettings.listId)
        try:
            if iknowList.language and iknowList.language == "ja":
                modelManager.tagModelsAsJapanese()
        except:
            progress.logMsg("Error trying to tag models as Japanese")
            progress.logMsg(traceback.format_exc())
            pass
        iknow.setCallback(progress.downloadCallback)
        items = iknow.listItems(importSettings.listId, (importSettings.importVocab or importSettings.includeItemMeaning), importSettings.importSentences)
        progress.preImportResetProgress(len(items))
        totalImported = 0
        totalDup = 0
        totalFormattingErrors = 0
        totalImportedByType = {"item" : 0, "sentence" : 0}
        for i, item in enumerate(items):
            if importSettings.maxItems > 0 and totalImported >= importSettings.maxItems:
                break
            if not importSettings.importSentences and item.type == "sentence":
                continue
            if not importSettings.importVocab and item.type == "item":
                continue
            if formatIknowItemPreImport(item, iknowList, importSettings, iknowList.isBilingual(), progress):
                progress.importCallback(i, item.expression)
                if importIknowItem(item, modelManager.sentenceModel, modelManager.vocabModel, importSettings, progress):
                    totalImported += 1
                    totalImportedByType[item.type] = totalImportedByType[item.type] + 1
                else:
                    totalDup += 1
            else:
                totalFormattingErrors += 1
        progress.dialog.cancel()
        progress.close()
        mw.deck.save()
        resultStr = "Import complete. Imported %s items, %s sentences, and skipped %s duplicates." % (totalImportedByType["item"], totalImportedByType["sentence"], totalDup)
        if totalFormattingErrors > 0:
            resultStr += " %s items were skipped because there was no translation available on smart.fm." % totalFormattingErrors
        QMessageBox.information(mw, "Summary", resultStr)
        mw.reset(mw.mainWin)
    except AudioDownloadError:
        progress.logMsg(traceback.format_exc())
        progress.dialog.cancel()
        progress.close()
        QMessageBox.warning(mw, "Warning", "Data for one item could not be retrieved even after several retries. This may be caused by a slower internet connection or smart.fm's (occasionally slow) servers. Please try your import again.")
        mw.reset(mw.mainWin)
    except AddMediaException:
        progress.logMsg(traceback.format_exc())
        progress.dialog.cancel()
        progress.close()
        QMessageBox.warning(mw, "Warning", "Anki was unable to add an audio file to your deck. This may be caused by a problem with Anki, the smart.fm! plugin, or both. Please inform the plugin developer.")
        mw.reset(mw.mainWin)
    except SmartFMDownloadError:
        progress.logMsg(traceback.format_exc())
        progress.dialog.cancel()
        progress.close()
        QMessageBox.warning(mw,"Warning","There was a problem retrieving data from Smart.fm. When you hit 'OK', a browser window will open to check that you can reach smart.fm.<br /><br />If this browser window shows an error, then please wait for smart.fm to be fixed, and try importing cards again. If there is no error in the browser window and you see some content relevant to your study list, please notify the plugin developer at http://github.com/ridisculous/anki-iknow-importer/issues")
        try:
            QDesktopServices.openUrl(QUrl(iknow.lastUrlFetched))
        except:
            pass
        mw.reset(mw.mainWin)
    except:
        progress.logMsg(traceback.format_exc())
        progress.dialog.cancel()
        progress.close()
        QMessageBox.warning(mw, "Warning", "There was an unknown error importing items. Please contact the plugin developer at http://github.com/ridisculous/anki-iknow-importer/issues<br /><br />Please be sure to include the file 'iknow-smartfm-log.txt' from your plugins directory with a description of what you tried to do before this error.")
        mw.reset(mw.mainWin)