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 __init__(self, model=None): self.model = model self.id = genID() if model: for fm in model.fieldModels: self.fields.append(Field(fm)) self.new = True
def __init__(self, fact=None, cardModel=None, created=None): self.tags = u"" self.id = genID() # new cards start as new & due self.type = 2 self.isDue = True self.timerStarted = False self.timerStopped = False self.modified = time.time() if created: self.created = created self.due = created else: self.due = self.modified self.combinedDue = self.due if fact: self.fact = fact if cardModel: self.cardModel = cardModel # for non-orm use self.cardModelId = cardModel.id self.ordinal = cardModel.ordinal d = {} for f in self.fact.model.fieldModels: d[f.name] = (f.id, self.fact[f.name]) qa = formatQA(None, fact.modelId, d, self.splitTags(), cardModel) self.question = qa['question'] self.answer = qa['answer']
def copy(self): new = FieldModel() for p in class_mapper(FieldModel).iterate_properties: setattr(new, p.key, getattr(self, p.key)) new.id = genID() new.model = None return new
def __init__(self, fact=None, cardModel=None, due=None): self.tags = u"" self.id = genID() # new cards start as new & due self.type = 2 self.isDue = True self.timerStarted = False self.timerStopped = False self.modified = time.time() if due: self.due = due else: self.due = self.modified self.combinedDue = self.due if fact: self.fact = fact if cardModel: self.cardModel = cardModel # for non-orm use self.cardModelId = cardModel.id self.ordinal = cardModel.ordinal d = {} for f in self.fact.model.fieldModels: d[f.name] = (f.id, self.fact[f.name]) qa = formatQA(None, fact.modelId, d, self.splitTags(), cardModel) self.question = qa['question'] self.answer = qa['answer']
def __init__(self, name=u"", description=u"", qformat=u"q", aformat=u"a", active=True): self.name = name self.description = description self.qformat = qformat self.aformat = aformat self.active = active self.id = genID()
def __init__(self, fact=None, cardModel=None): self.tags = u"" self.id = genID() if fact: self.fact = fact if cardModel: self.cardModel = cardModel self.ordinal = cardModel.ordinal self.question = cardModel.renderQA(self, self.fact, "question") self.answer = cardModel.renderQA(self, self.fact, "answer")
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 imgLink(deck, latex, build=True): "Parse LATEX and return a HTML image representing the output." latex = latexOrig.mungeLatex(latex) (ok, img) = latexOrig.imageForLatex(deck, latex, build) if ok: deck.s.statement(""" insert or replace into media values (:id, :fn, 0, :t, '', 'latex')""", id=genID(), fn=img, t=time.time()) if ok: return '<img src="%s">' % img else: return img
def run(): db = mw.deck.s mw.startProgress() # gather old ids data = [] for id in db.column0("select id from facts"): data.append(dict(new=genID(), old=id)) # update facts db.statements("update facts set id = :new where id = :old", data) # fields db.statements("update fields set id = random(), factId = :new where factId = :old", data) # cards db.statements("update cards set id = random(), factId = :new where factId = :old", data) mw.finishProgress() mw.deck.setModified() mw.deck.save() showInfo("Done.")
def updateMediaCount(deck, file, count=1): mdir = deck.mediaDir() if deck.s.scalar( "select 1 from media where filename = :file", file=file): deck.s.statement( "update media set size = size + :c, created = :t where filename = :file", file=file, c=count, t=time.time()) elif count > 0: try: sum = unicode( checksum(open(os.path.join(mdir, file), "rb").read())) except: sum = u"" deck.s.statement(""" insert into media (id, filename, size, created, originalPath, description) values (:id, :file, :c, :mod, :sum, '')""", id=genID(), file=file, c=count, mod=time.time(), sum=sum)
def copyToMedia(deck, path): """Copy PATH to MEDIADIR, and return new filename. Update media table. If file already exists, don't copy.""" origPath = path description = os.path.splitext(os.path.basename(path))[0] newBase = mediaFilename(path) new = os.path.join(deck.mediaDir(create=True), newBase) # copy if not existing if not os.path.exists(new): if new.lower() == path.lower(): # case insensitive filesystems suck os.rename(path, new) else: shutil.copy2(path, new) newSize = os.stat(new)[stat.ST_SIZE] if not deck.s.scalar( "select 1 from media where filename = :f", f=newBase): # if the user has modified a hashed file, try to remember the old # filename old = deck.s.scalar( "select originalPath from media where filename = :s", s=os.path.basename(origPath)) if old: origPath = old description = os.path.splitext(os.path.basename(origPath))[0] try: path = unicode(path, sys.getfilesystemencoding()) except TypeError: pass deck.s.statement(""" insert into media (id, filename, size, created, originalPath, description) values (:id, :filename, :size, :created, :originalPath, :description)""", id=genID(), filename=newBase, size=newSize, created=time.time(), originalPath=origPath, description=description) deck.flushMod() return newBase
def copyToMedia(deck, path): """Copy PATH to MEDIADIR, and return new filename. Update media table. If file already exists, don't copy.""" origPath = path description = os.path.splitext(os.path.basename(path))[0] newBase = mediaFilename(path) new = os.path.join(deck.mediaDir(create=True), newBase) # copy if not existing if not os.path.exists(new): if new.lower() == path.lower(): # case insensitive filesystems suck os.rename(path, new) else: shutil.copy2(path, new) newSize = os.stat(new)[stat.ST_SIZE] if not deck.s.scalar("select 1 from media where filename = :f", f=newBase): # if the user has modified a hashed file, try to remember the old # filename old = deck.s.scalar( "select originalPath from media where filename = :s", s=os.path.basename(origPath)) if old: origPath = old description = os.path.splitext(os.path.basename(origPath))[0] try: path = unicode(path, sys.getfilesystemencoding()) except TypeError: pass deck.s.statement(""" insert into media (id, filename, size, created, originalPath, description) values (:id, :filename, :size, :created, :originalPath, :description)""", id=genID(), filename=newBase, size=newSize, created=time.time(), originalPath=origPath, description=description) deck.flushMod() return newBase
def run(): db = mw.deck.s mw.startProgress() # gather old ids data = [] for id in db.column0("select id from facts"): data.append(dict(new=genID(), old=id)) # update facts db.statements("update facts set id = :new where id = :old", data) # fields db.statements( "update fields set id = random(), factId = :new where factId = :old", data) # cards db.statements( "update cards set id = random(), factId = :new where factId = :old", data) mw.finishProgress() mw.deck.setModified() mw.deck.save() showInfo("Done.")
def __init__(self, fact=None, cardModel=None, created=None): self.tags = u"" self.id = genID() # new cards start as new & due self.type = 2 self.relativeDelay = self.type self.timerStarted = False self.timerStopped = False self.modified = time.time() if created: self.created = created self.due = created else: self.due = self.modified self.combinedDue = self.due if fact: self.fact = fact if cardModel: self.cardModel = cardModel # for non-orm use self.cardModelId = cardModel.id self.ordinal = cardModel.ordinal
def __init__(self, name=u"", required=True, unique=True): self.name = name self.required = required self.unique = unique self.id = genID()
def __init__(self, fieldModel=None): if fieldModel: self.fieldModel = fieldModel self.ordinal = fieldModel.ordinal self.value = u"" self.id = genID()
def defaults(self): fields = { 'iconSize': 32, 'syncOnLoad': True, 'syncOnClose': True, 'syncInMsgBox': False, 'checkForUpdates': True, 'interfaceLang': "", 'syncUsername': "", 'syncPassword': "", 'showFontPreview': False, 'showToolbar': True, 'recentDeckPaths': [], 'saveAfterAnswer': True, 'saveAfterAnswerNum': 10, 'saveAfterAdding': True, 'saveAfterAddingNum': 1, 'saveOnClose': True, 'mainWindowGeom': None, 'mainWindowState': None, 'suppressUpdate': False, 'suppressEstimates': False, 'showLastCardInterval': False, 'showLastCardContent': False, 'showTrayIcon': False, 'showTimer': True, 'simpleToolbar': True, 'scrollToAnswer': True, 'qaDivider': True, 'splitQA': True, 'sortIndex': 0, 'addZeroSpace': False, 'alternativeTheme': False, 'showStudyScreen': True, 'showStudyOptions': False, 'showStudyStats': True, 'showCardTimer': True, 'standaloneWindows': True, 'extraNewCards': 5, 'randomizeOnCram': True, 'created': time.time(), 'id': genID(), 'editorReverseOrder': False, 'editFontFamily': 'Arial', 'editFontSize': 12, 'editLineSize': 20, 'factEditorAdvanced': False, 'typeAnswerFontSize': 20, 'showProgress': True, 'recentColours': ["#000000", "#0000ff"], 'preventEditUntilAnswer': False, 'numBackups': 30, 'proxyHost': '', 'proxyPort': 8080, 'proxyUser': '', 'proxyPass': '', 'loadLastDeck': False, 'deckBrowserRefreshPeriod': 3600, 'deckBrowserOrder': 0, } for (k,v) in fields.items(): if not self.has_key(k): self[k] = v if not self['interfaceLang']: # guess interface and target languages (lang, enc) = locale.getdefaultlocale() self['interfaceLang'] = lang
def __init__(self, name=u"", qformat=u"q", aformat=u"a", active=True): self.name = name self.qformat = qformat self.aformat = aformat self.active = active self.id = genID()
def defaults(self): fields = { 'addZeroSpace': False, 'alternativeTheme': False, 'autoplaySounds': True, 'checkForUpdates': True, 'colourTimes': True, 'created': time.time(), 'deckBrowserNameLength': 30, 'deckBrowserOrder': 0, 'deckBrowserRefreshPeriod': 3600, 'deleteMedia': False, 'documentDir': u"", 'dropboxPublicFolder': u"", 'editFontFamily': 'Arial', 'editFontSize': 12, 'editLineSize': 20, 'editorReverseOrder': False, 'extraNewCards': 5, 'factEditorAdvanced': False, 'forceLTR': False, 'iconSize': 32, 'id': genID(), 'interfaceLang': "", 'lastMsg': -1, 'loadLastDeck': False, 'mainWindowGeom': None, 'mainWindowState': None, # one of empty, 'dropbox', or path used as prefix 'mediaLocation': "", 'mainWindowState': None, 'numBackups': 30, 'optimizeSmall': False, 'preserveKeyboard': True, 'preventEditUntilAnswer': False, 'proxyHost': '', 'proxyPass': '', 'proxyPort': 8080, 'proxyUser': '', 'qaDivider': True, 'randomizeOnCram': True, 'recentColours': ["#000000", "#0000ff"], 'recentDeckPaths': [], 'repeatQuestionAudio': True, 'saveAfterAdding': True, 'saveAfterAddingNum': 1, 'saveAfterAnswer': True, 'saveAfterAnswerNum': 10, 'saveOnClose': True, 'scrollToAnswer': True, 'showCardTimer': True, 'showFontPreview': False, 'showLastCardContent': False, 'showLastCardInterval': False, 'showProgress': True, 'showStudyScreen': True, 'showStudyStats': True, 'showTimer': True, 'showToolbar': True, 'showTrayIcon': False, 'sortIndex': 0, 'splitQA': True, 'standaloneWindows': True, 'stripHTML': True, 'studyOptionsScreen': 0, 'suppressEstimates': False, 'suppressUpdate': False, 'syncDisableWhenMoved': True, 'syncInMsgBox': False, 'syncOnLoad': False, 'syncOnProgramOpen': True, 'syncPassword': "", 'syncUsername': "", } # disable sync on deck load when upgrading if not self.has_key("syncOnProgramOpen"): self['syncOnLoad'] = False self['syncOnClose'] = False for (k,v) in fields.items(): if not self.has_key(k): self[k] = v if not self['interfaceLang']: # guess interface and target languages (lang, enc) = locale.getdefaultlocale() self['interfaceLang'] = lang
def defaults(self): fields = { 'addZeroSpace': False, 'alternativeTheme': False, 'autoplaySounds': True, 'checkForUpdates': True, 'colourTimes': True, 'created': time.time(), 'deckBrowserNameLength': 30, 'deckBrowserOrder': 0, 'deckBrowserRefreshPeriod': 3600, 'deleteMedia': False, 'documentDir': u"", 'dropboxPublicFolder': u"", 'editFontFamily': 'Arial', 'editFontSize': 12, 'editLineSize': 20, 'editorReverseOrder': False, 'extraNewCards': 5, 'factEditorAdvanced': False, 'forceLTR': False, 'iconSize': 32, 'id': genID(), 'interfaceLang': "", 'lastMsg': -1, 'loadLastDeck': False, 'mainWindowGeom': None, 'mainWindowState': None, # one of empty, 'dropbox', or path used as prefix 'mediaLocation': "", 'mainWindowState': None, 'numBackups': 30, 'optimizeSmall': False, 'preserveKeyboard': True, 'preventEditUntilAnswer': False, 'proxyHost': '', 'proxyPass': '', 'proxyPort': 8080, 'proxyUser': '', 'qaDivider': True, 'randomizeOnCram': True, 'recentColours': ["#000000", "#0000ff"], 'recentDeckPaths': [], 'repeatQuestionAudio': True, 'saveAfterAdding': True, 'saveAfterAddingNum': 1, 'saveAfterAnswer': True, 'saveAfterAnswerNum': 10, 'saveOnClose': True, 'scrollToAnswer': True, 'showCardTimer': True, 'showFontPreview': False, 'showLastCardContent': False, 'showLastCardInterval': False, 'showProgress': True, 'showStudyScreen': True, 'showStudyStats': True, 'showTimer': True, 'showToolbar': True, 'showTrayIcon': False, 'sortIndex': 0, 'splitQA': True, 'standaloneWindows': True, 'stripHTML': True, 'studyOptionsScreen': 0, 'suppressEstimates': False, 'suppressUpdate': False, 'syncDisableWhenMoved': True, 'syncInMsgBox': False, 'syncOnLoad': False, 'syncOnProgramOpen': True, 'syncPassword': "", 'syncUsername': "", 'typeAnswerFontSize': 20, } # disable sync on deck load when upgrading if not self.has_key("syncOnProgramOpen"): self['syncOnLoad'] = False self['syncOnClose'] = False for (k, v) in fields.items(): if not self.has_key(k): self[k] = v if not self['interfaceLang']: # guess interface and target languages (lang, enc) = locale.getdefaultlocale() self['interfaceLang'] = lang
def defaults(self): fields = { "addZeroSpace": False, "alternativeTheme": False, "checkForUpdates": True, "colourTimes": True, "created": time.time(), "deckBrowserNameLength": 30, "deckBrowserOrder": 0, "deckBrowserRefreshPeriod": 3600, "deleteMedia": False, "documentDir": u"", "editFontFamily": "Arial", "editFontSize": 12, "editLineSize": 20, "editorReverseOrder": False, "extraNewCards": 5, "factEditorAdvanced": False, "forceLTR": False, "iconSize": 32, "id": genID(), "interfaceLang": "", "loadLastDeck": False, "mainWindowGeom": None, "mainWindowState": None, "numBackups": 30, "preventEditUntilAnswer": False, "proxyHost": "", "proxyPass": "", "proxyPort": 8080, "proxyUser": "", "qaDivider": True, "randomizeOnCram": True, "recentColours": ["#000000", "#0000ff"], "recentDeckPaths": [], "repeatQuestionAudio": True, "saveAfterAdding": True, "saveAfterAddingNum": 1, "saveAfterAnswer": True, "saveAfterAnswerNum": 10, "saveOnClose": True, "scrollToAnswer": True, "showCardTimer": True, "showFontPreview": False, "showLastCardContent": False, "showLastCardInterval": False, "showProgress": True, "showStudyOptions": False, "showStudyScreen": True, "showStudyStats": True, "showTimer": True, "showToolbar": True, "showTrayIcon": False, "simpleToolbar": True, "sortIndex": 0, "splitQA": True, "standaloneWindows": True, "suppressEstimates": False, "suppressUpdate": False, "syncInMsgBox": False, "syncOnClose": False, "syncOnLoad": False, "syncOnProgramClose": True, "syncOnProgramOpen": True, "syncPassword": "", "syncUsername": "", "typeAnswerFontSize": 20, } # disable sync on deck load when upgrading if not self.has_key("syncOnProgramOpen"): self["syncOnLoad"] = False self["syncOnClose"] = False for (k, v) in fields.items(): if not self.has_key(k): self[k] = v if not self["interfaceLang"]: # guess interface and target languages (lang, enc) = locale.getdefaultlocale() self["interfaceLang"] = lang
def __init__(self, name=u""): self.name = name self.id = genID()
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)
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 __init__(self, name=u"", description=u""): self.name = name self.description = description self.id = genID()