def JapaneseModel(): m = Model(_("Japanese")) # expression f = FieldModel(u'Expression', True, True) font = u"Mincho" f.quizFontSize = 50 f.quizFontFamily = font f.editFontFamily = font m.addFieldModel(f) # meaning m.addFieldModel(FieldModel(u'Meaning', False, False)) # reading f = FieldModel(u'Reading', False, False) font = u"Arial" f.quizFontSize = 50 f.quizFontFamily = font f.editFontFamily = font m.addFieldModel(f) m.addCardModel(CardModel(u"Recognition", u"%(Expression)s", u"%(Reading)s<br>%(Meaning)s")) m.addCardModel(CardModel(u"Recall", u"%(Meaning)s", u"%(Reading)s", active=False)) m.tags = u"Japanese" return m
def JpEnViModel(): m = Model(_("JpEnVi")) # expression f = FieldModel(u'Japanese', True, True) font = u"Mincho" f.quizFontSize = 50 f.quizFontFamily = font f.editFontFamily = font m.addFieldModel(f) # meaning f = FieldModel(u'English', False, False) font = u"Mincho" f.quizFontSize = 20 f.quizFontFamily = font f.editFontFamily = font m.addFieldModel(f) # reading f = FieldModel(u'Sino-Vietnamese', False, False) #for Kanji only (?) font = u"Arial" f.quizFontSize = 20 f.quizFontFamily = font f.editFontFamily = font m.addFieldModel(f) #vietnamese f = FieldModel(u'Vietnamese', False, False) font = u"Mincho" f.quizFontSize = 20 f.quizFontFamily = font f.editFontFamily = font m.addFieldModel(f) f = FieldModel(u'Example', False, False) font = u"Mincho" f.quizFontSize = 20 f.quizFontFamily = font f.editFontFamily = font m.addFieldModel(f) m.addCardModel( CardModel( u"Recognition", u"%(Japanese)s", u"<div align='left'>English</div><hr> <br> %(English)s <div align='left'>Sino-Vietnamese</div><hr><br>%(Sino-Vietnamese)s <div align='left'>Vietnamese</div><hr><br>%(Vietnamese)s <div align='left'>Examples from tratu.vn</div><hr><br>%(Example)s" )) m.addCardModel( CardModel(u"Recall", u"%(Vietnamese)s", u"%(Japanese)s", active=False)) m.tags = u"JpEnVi, JpEnVi_offline" return m
def HeisigModel(): m = Model(_("Heisig"), _(""" A format suitable for Heisig's "Remembering the Kanji". You are tested from the keyword to the kanji. Layout of the test is based on the great work at http://kanji.koohii.com/ The link in the question will list user-contributed stories. A free login is required.""".strip())) font = u"Mincho" f = FieldModel(u'Kanji') f.quizFontSize = 150 f.quizFontFamily = font f.editFontFamily = font m.addFieldModel(f) m.addFieldModel(FieldModel(u'Keyword')) m.addFieldModel(FieldModel(u'Story', u"", False, False)) m.addFieldModel(FieldModel(u'Stroke count', u"", False, False)) m.addFieldModel(FieldModel(u'Heisig number', required=False)) m.addFieldModel(FieldModel(u'Lesson number', u"", False, False)) m.addCardModel(CardModel( u"Production", _("From the keyword to the Kanji."), u"<a href=\"http://kanji.koohii.com/study?framenum=" u"%(text:Heisig number)s\">%(Keyword)s</a><br>", u"%(Kanji)s<br><table width=150><tr><td align=left>" u"画数%(Stroke count)s</td><td align=right>" u"%(Heisig number)s</td></tr></table>")) m.tags = u"Heisig" return m
def JapaneseModel(): m = Model(_("Japanese"), _(""" The reading field is automatically generated by default, and shows the reading for the expression. For words that are normally written in hiragana or katakana and don't need a reading, you can put the word in the expression field, and leave the reading field blank. A reading will will not automatically be generated for words written in only hiragana or katakana. Note that the automatic generation of meaning is not perfect, and should be checked before adding cards.""".strip())) # expression f = FieldModel(u'Expression', _('A word or expression written in Kanji.'), True, True) font = u"Mincho" f.quizFontSize = 72 f.quizFontFamily = font f.editFontFamily = font f.features = u"Reading source" m.addFieldModel(f) # meaning m.addFieldModel(FieldModel( u'Meaning', _('A description in your native language, or Japanese'), True, True)) # reading f = FieldModel(u'Reading', _('Automatically generated by default.'), False, False) f.quizFontFamily = font f.editFontFamily = font f.features = u"Reading destination" m.addFieldModel(f) m.addCardModel(CardModel(u"Production", _( "Actively test your recall by producing the target expression"), u"%(Meaning)s", u"%(Expression)s<br>%(Reading)s")) m.addCardModel(CardModel(u"Recognition", _( "Test your ability to recognize the target expression"), u"%(Expression)s", u"%(Reading)s<br>%(Meaning)s")) m.features = u"Japanese" m.tags = u"Japanese" return m
def doImport(self): oldDeck = load(self.file) maybeUpgrade(oldDeck) # mappings for old->new ids cardModels = {} fieldModels = {} # start with the models s = self.deck.s deck = self.deck import types def uni(txt): if txt is None: return txt if not isinstance(txt, types.UnicodeType): txt = unicode(txt, "utf-8") return txt for oldModel in oldDeck.facts.models: model = Model(uni(oldModel.name), uni(oldModel.description)) model.id = oldModel.id model.tags = u", ".join(oldModel.tags) model.features = u", ".join(oldModel.decorators) model.created = oldModel.created model.modified = oldModel.modified deck.newCardOrder = min(1, oldModel.position) deck.addModel(model) # fields for oldField in oldModel.fields: fieldModel = FieldModel(uni(oldField.name), uni(oldField.description), oldField.name in oldModel.required, oldField.name in oldModel.unique) fieldModel.features = u", ".join(oldField.features) fieldModel.quizFontFamily = uni(oldField.display['quiz']['fontFamily']) fieldModel.quizFontSize = oldField.display['quiz']['fontSize'] fieldModel.quizFontColour = uni(oldField.display['quiz']['fontColour']) fieldModel.editFontFamily = uni(oldField.display['edit']['fontFamily']) fieldModel.editFontSize = oldField.display['edit']['fontSize'] fieldModel.id = oldField.id model.addFieldModel(fieldModel) s.flush() # we need the id fieldModels[id(oldField)] = fieldModel # card models for oldCard in oldModel.allcards: cardModel = CardModel(uni(oldCard.name), uni(oldCard.description), uni(oldCard.qformat), uni(oldCard.aformat)) cardModel.active = oldCard in oldModel.cards cardModel.questionInAnswer = oldCard.questionInAnswer cardModel.id = oldCard.id model.spacing = 0.25 cardModel.questionFontFamily = uni(oldCard.display['question']['fontFamily']) cardModel.questionFontSize = oldCard.display['question']['fontSize'] cardModel.questionFontColour = uni(oldCard.display['question']['fontColour']) cardModel.questionAlign = oldCard.display['question']['align'] cardModel.answerFontFamily = uni(oldCard.display['answer']['fontFamily']) cardModel.answerFontSize = oldCard.display['answer']['fontSize'] cardModel.answerFontColour = uni(oldCard.display['answer']['fontColour']) cardModel.answerAlign = oldCard.display['answer']['align'] cardModel.lastFontFamily = uni(oldCard.display['last']['fontFamily']) cardModel.lastFontSize = oldCard.display['last']['fontSize'] cardModel.lastFontColour = uni(oldCard.display['last']['fontColour']) cardModel.editQuestionFontFamily = ( uni(oldCard.display['editQuestion']['fontFamily'])) cardModel.editQuestionFontSize = ( oldCard.display['editQuestion']['fontSize']) cardModel.editAnswerFontFamily = ( uni(oldCard.display['editAnswer']['fontFamily'])) cardModel.editAnswerFontSize = ( oldCard.display['editAnswer']['fontSize']) model.addCardModel(cardModel) s.flush() # we need the id cardModels[id(oldCard)] = cardModel # facts def getSpace(lastCard, lastAnswered): if not lastCard: return 0 return lastAnswered + lastCard.delay def getLastCardId(fact): if not fact.lastCard: return None ret = [c.id for c in fact.cards if c.model.id == fact.lastCard.id] if ret: return ret[0] d = [{'id': f.id, 'modelId': f.model.id, 'created': f.created, 'modified': f.modified, 'tags': u",".join(f.tags), 'spaceUntil': getSpace(f.lastCard, f.lastAnswered), 'lastCardId': getLastCardId(f) } for f in oldDeck.facts] if d: s.execute(factsTable.insert(), d) self.total = len(oldDeck.facts) # fields in facts toAdd = [] for oldFact in oldDeck.facts: for field in oldFact.model.fields: toAdd.append({'factId': oldFact.id, 'id': genID(), 'fieldModelId': fieldModels[id(field)].id, 'ordinal': fieldModels[id(field)].ordinal, 'value': uni(oldFact.get(field.name, u""))}) if toAdd: s.execute(fieldsTable.insert(), toAdd) # cards class FakeObj(object): pass fake = FakeObj() fake.fact = FakeObj() fake.fact.model = FakeObj() fake.cardModel = FakeObj() def renderQA(c, type): fake.tags = u", ".join(c.tags) fake.fact.tags = u", ".join(c.fact.tags) fake.fact.model.tags = u", ".join(c.fact.model.tags) fake.cardModel.name = c.model.name return cardModels[id(c.model)].renderQA(fake, c.fact, type) d = [{'id': c.id, 'created': c.created, 'modified': c.modified, 'factId': c.fact.id, 'ordinal': cardModels[id(c.model)].ordinal, 'cardModelId': cardModels[id(c.model)].id, 'tags': u", ".join(c.tags), 'factor': 2.5, 'firstAnswered': c.firstAnswered, 'interval': c.interval, 'lastInterval': c.lastInterval, 'modified': c.modified, 'due': c.nextTime, 'lastDue': c.lastTime, 'reps': c.total, 'question': renderQA(c, 'question'), 'answer': renderQA(c, 'answer'), 'averageTime': c.stats['averageTime'], 'reviewTime': c.stats['totalTime'], 'yesCount': (c.stats['new']['yes'] + c.stats['young']['yes'] + c.stats['old']['yes']), 'noCount': (c.stats['new']['no'] + c.stats['young']['no'] + c.stats['old']['no']), 'successive': c.stats['successivelyCorrect']} for c in oldDeck] if d: s.execute(cardsTable.insert(), d) # scheduler deck.description = uni(oldDeck.description) deck.created = oldDeck.created deck.maxScheduleTime = oldDeck.sched.maxScheduleTime deck.hardIntervalMin = oldDeck.sched.hardInterval[0] deck.hardIntervalMax = oldDeck.sched.hardInterval[1] deck.midIntervalMin = oldDeck.sched.midInterval[0] deck.midIntervalMax = oldDeck.sched.midInterval[1] deck.easyIntervalMin = oldDeck.sched.easyInterval[0] deck.easyIntervalMax = oldDeck.sched.easyInterval[1] deck.delay0 = oldDeck.sched.delay0 deck.delay1 = oldDeck.sched.delay1 deck.delay2 = oldDeck.sched.delay2 deck.collapseTime = 3600 # oldDeck.sched.collapse deck.highPriority = u", ".join(oldDeck.sched.highPriority) deck.medPriority = u", ".join(oldDeck.sched.medPriority) deck.lowPriority = u", ".join(oldDeck.sched.lowPriority) deck.suspended = u", ".join(oldDeck.sched.suspendedTags) # scheduler global stats stats = Stats(STATS_LIFE) stats.day = datetime.date.fromtimestamp(oldDeck.created) stats.averageTime = oldDeck.sched.globalStats['averageTime'] stats.reviewTime = oldDeck.sched.globalStats['totalTime'] stats.distractedTime = 0 stats.distractedReps = 0 stats.newEase0 = oldDeck.sched.easeStats.get('new', {}).get(0, 0) stats.newEase1 = oldDeck.sched.easeStats.get('new', {}).get(1, 0) stats.newEase2 = oldDeck.sched.easeStats.get('new', {}).get(2, 0) stats.newEase3 = oldDeck.sched.easeStats.get('new', {}).get(3, 0) stats.newEase4 = oldDeck.sched.easeStats.get('new', {}).get(4, 0) stats.youngEase0 = oldDeck.sched.easeStats.get('young', {}).get(0, 0) stats.youngEase1 = oldDeck.sched.easeStats.get('young', {}).get(1, 0) stats.youngEase2 = oldDeck.sched.easeStats.get('young', {}).get(2, 0) stats.youngEase3 = oldDeck.sched.easeStats.get('young', {}).get(3, 0) stats.youngEase4 = oldDeck.sched.easeStats.get('young', {}).get(4, 0) stats.matureEase0 = oldDeck.sched.easeStats.get('old', {}).get(0, 0) stats.matureEase1 = oldDeck.sched.easeStats.get('old', {}).get(1, 0) stats.matureEase2 = oldDeck.sched.easeStats.get('old', {}).get(2, 0) stats.matureEase3 = oldDeck.sched.easeStats.get('old', {}).get(3, 0) stats.matureEase4 = oldDeck.sched.easeStats.get('old', {}).get(4, 0) yesCount = (oldDeck.sched.globalStats['new']['yes'] + oldDeck.sched.globalStats['young']['yes'] + oldDeck.sched.globalStats['old']['yes']) noCount = (oldDeck.sched.globalStats['new']['no'] + oldDeck.sched.globalStats['young']['no'] + oldDeck.sched.globalStats['old']['no']) stats.reps = yesCount + noCount s.save(stats) # ignore daily stats & history, they make no sense on new version s.flush() deck.updateAllPriorities() # save without updating mod time deck.modified = oldDeck.modified deck.lastLoaded = deck.modified deck.s.commit() deck.save()
def saveConfig(self): interface = self.interface if interface.languageCombo.currentIndex() <= 0: # Error : marked in red + Error message return if interface.expressionCombo.currentIndex() <= 0: # Error : marked in red + Error message return if interface.defintionCB.isChecked() and interface.definitionCombo.currentIndex() <= 0: # Error : ... return mainVBox = interface.mainVBox deck = interface.deck realDeck = AnkiHelper.getDeck(deck.path) # Save Fields for fieldsGrid in interface.fieldsComponents: isEnabled = fieldsGrid[0].isChecked() value = str(fieldsGrid[1].text()) key = str(fieldsGrid[0].text()) numeric = deck.fields[key][2] models = realDeck.models deck.fields[key] = (value, isEnabled, numeric) if isEnabled: for model in models: field = FieldModel(unicode(value, "utf-8"), False, False) font = u"Arial" field.quizFontSize = 22 field.quizFontFamily = font field.editFontSize = 20 field.editFontFamily = font field.numeric = numeric log("add fields") try: fieldModelAlreadyAdded = False for fieldModel in model.fieldModels: if fieldModel.name == value: fieldModelAlreadyAdded = True break if not fieldModelAlreadyAdded: realDeck.addFieldModel(model, field) except Exception as e: log(e) else: for model in models: try: fieldToDelete = None for fieldModel in model.fieldModels: if fieldModel.name == value: fieldToDelete = fieldModel break if fieldToDelete != None: realDeck.deleteFieldModel(model, fieldToDelete) except Exception as e: log(e) self.decksService.changeLanguage(interface.deck, unicode(interface.languageCombo.currentText())) deck.matureTreshold = int(str(interface.matureEdit.text())) deck.knownTreshold = int(str(interface.knownEdit.text())) deck.learnTreshold = int(str(interface.learnEdit.text())) deck.expressionField = str(interface.expressionCombo.currentText()) bsPosListWidget = interface.bsPosListWidget disabledPosList = list() items = bsPosListWidget.findItems("*", Qt.MatchWrap | Qt.MatchWildcard) for item in items: log(item) disabledPosList.append(unicode(item.text())) deck.posOptions["disabledPos"] = disabledPosList if interface.defintionCB.isChecked(): deck.definitionField = str(interface.definitionCombo.currentText()) if interface.definitionKeyCombo.currentIndex() > 0: deck.definitionKeyField = str(interface.definitionKeyCombo.currentText()) else: deck.definitionKeyField = None self.decksService.updateDeck(deck) realDeck.save() realDeck.close() interface.parent.refreshAll() interface.close()