def addCards(self, cards): "Add facts in bulk from foreign cards." # map tags field to attr try: idx = self.mapping.index(0) for c in cards: c.tags += " " + c.fields[idx] except ValueError: pass # add facts self.deck.updateProgress() factIds = [genID() for n in range(len(cards))] self.deck.s.execute(factsTable.insert(), [{'modelId': self.model.id, 'tags': canonifyTags(self.tagsToAdd + " " + cards[n].tags), 'id': factIds[n]} for n in range(len(cards))]) self.deck.factCount += len(factIds) self.deck.s.execute(""" delete from factsDeleted where factId in (%s)""" % ",".join([str(s) for s in factIds])) # add all the fields self.deck.updateProgress() for fm in self.model.fieldModels: try: index = self.mapping.index(fm) except ValueError: index = None data = [{'factId': factIds[m], 'fieldModelId': fm.id, 'ordinal': fm.ordinal, 'id': genID(), 'value': (index is not None and cards[m].fields[index] or u"")} for m in range(len(cards))] self.deck.s.execute(fieldsTable.insert(), data) # and cards self.deck.updateProgress() now = time.time() active = 0 for cm in self.model.cardModels: self._now = now if cm.active: active += 1 data = [self.addMeta({ 'id': genID(), 'factId': factIds[m], 'cardModelId': cm.id, 'ordinal': cm.ordinal, 'question': u"", 'answer': u"", 'type': 2},cards[m]) for m in range(len(cards))] self.deck.s.execute(cardsTable.insert(), data) self.deck.updateProgress() self.deck.updateCardsFromFactIds(factIds) self.deck.cardCount += len(cards) * active self.total = len(factIds)
def addCards(self, cards): "Add facts in bulk from foreign cards." # add facts factIds = [genID() for n in range(len(cards))] self.deck.s.execute(factsTable.insert(), [{'modelId': self.model.id, 'tags': self.tagsToAdd, 'id': factIds[n]} for n in range(len(cards))]) self.deck.s.execute(""" delete from factsDeleted where factId in (%s)""" % ",".join([str(s) for s in factIds])) # add all the fields for fm in self.model.fieldModels: try: index = self.mapping.index(fm) except ValueError: index = None data = [{'factId': factIds[m], 'fieldModelId': fm.id, 'ordinal': fm.ordinal, 'id': genID(), 'value': (index is not None and cards[m].fields[index] or u"")} for m in range(len(cards))] self.deck.s.execute(fieldsTable.insert(), data) # and cards now = time.time() for cm in self.model.cardModels: self._now = now if cm.active: data = [self.addMeta({ 'id': genID(), 'factId': factIds[m], 'cardModelId': cm.id, 'ordinal': cm.ordinal, 'question': cm.renderQASQL('q', factIds[m]), 'answer': cm.renderQASQL('a', factIds[m]), }, cards[m]) for m in range(len(cards))] self.deck.s.execute(cardsTable.insert(), data) self.total = len(factIds)
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 addCards(self, cards): "Add facts in bulk from foreign cards." # map tags field to attr try: idx = self.mapping.index(0) for c in cards: c.tags += " " + c.fields[idx] except ValueError: pass # add facts self.deck.updateProgress() factIds = [genID() for n in range(len(cards))] def fudgeCreated(d, tmp=[]): if not tmp: tmp.append(time.time()) else: tmp[0] += 0.00001 d['created'] = tmp[0] return d self.deck.s.execute(factsTable.insert(), [ fudgeCreated( { 'modelId': self.model.id, 'tags': canonifyTags(self.tagsToAdd + " " + cards[n].tags), 'id': factIds[n] }) for n in range(len(cards)) ]) self.deck.factCount += len(factIds) self.deck.s.execute(""" delete from factsDeleted where factId in (%s)""" % ",".join([str(s) for s in factIds])) # add all the fields self.deck.updateProgress() for fm in self.model.fieldModels: try: index = self.mapping.index(fm) except ValueError: index = None data = [{ 'factId': factIds[m], 'fieldModelId': fm.id, 'ordinal': fm.ordinal, 'id': genID(), 'value': (index is not None and cards[m].fields[index] or u"") } for m in range(len(cards))] self.deck.s.execute(fieldsTable.insert(), data) # and cards self.deck.updateProgress() now = time.time() active = 0 for cm in self.model.cardModels: self._now = now if cm.active: active += 1 data = [ self.addMeta( { 'id': genID(), 'factId': factIds[m], 'cardModelId': cm.id, 'ordinal': cm.ordinal, 'question': u"", 'answer': u"", 'type': 2 }, cards[m]) for m in range(len(cards)) ] self.deck.s.execute(cardsTable.insert(), data) self.deck.updateProgress() self.deck.updateCardsFromFactIds(factIds) self.deck.cardCount += len(cards) * active self.total = len(factIds)