def doExport(self, file): cardIds = self.cardIds() self.deck.startProgress() self.deck.updateProgress(_("Exporting...")) facts = self.deck.s.all(""" select factId, value, facts.created from facts, fields where facts.id in (select distinct factId from cards where cards.id in %s) and facts.id = fields.factId order by factId, ordinal""" % ids2str(cardIds)) txt = "" self.deck.updateProgress() if self.includeTags: self.factTags = dict( self.deck.s.all("select id, tags from facts where id in %s" % ids2str([fact[0] for fact in facts]))) groups = itertools.groupby(facts, itemgetter(0)) groups = [[x for x in y[1]] for y in groups] groups = [(group[0][2], "\t".join([self.escapeText(x[1]) for x in group]) + self.tags(group[0][0])) for group in groups] self.deck.updateProgress() groups.sort(key=itemgetter(0)) out = [ret[1] for ret in groups] self.count = len(out) out = "\n".join(out) file.write(out.encode("utf-8")) self.deck.finishProgress()
def localSummary(self): cardIds = self.cardIds() cStrIds = ids2str(cardIds) cards = self.deck.s.all(""" select id, modified from cards where id in %s""" % cStrIds) facts = self.deck.s.all(""" select facts.id, facts.modified from cards, facts where facts.id = cards.factId and cards.id in %s""" % cStrIds) models = self.deck.s.all(""" select models.id, models.modified from models, facts where facts.modelId = models.id and facts.id in %s""" % ids2str([f[0] for f in facts])) media = self.deck.s.all(""" select id, created from media""") return { # cards "cards": cards, "delcards": [], # facts "facts": facts, "delfacts": [], # models "models": models, "delmodels": [], # media "media": media, "delmedia": [], }
def doExport(self, file): cardIds = self.cardIds() self.deck.startProgress() self.deck.updateProgress(_("Exporting...")) facts = self.deck.s.all(""" select factId, value, facts.created from facts, fields where facts.id in (select distinct factId from cards where cards.id in %s) and facts.id = fields.factId order by factId, ordinal""" % ids2str(cardIds)) txt = "" self.deck.updateProgress() if self.includeTags: self.factTags = dict(self.deck.s.all( "select id, tags from facts where id in %s" % ids2str([fact[0] for fact in facts]))) groups = itertools.groupby(facts, itemgetter(0)) groups = [[x for x in y[1]] for y in groups] groups = [(group[0][2], "\t".join([self.escapeText(x[1]) for x in group]) + self.tags(group[0][0])) for group in groups] self.deck.updateProgress() groups.sort(key=itemgetter(0)) out = [ret[1] for ret in groups] self.count = len(out) out = "\n".join(out) file.write(out.encode("utf-8")) self.deck.finishProgress()
def doExport(self, file): ids = self.cardIds() strids = ids2str(ids) self.deck.startProgress((len(ids) + 1) / 50) self.deck.updateProgress(_("Exporting...")) cards = self.deck.s.all(""" select cards.question, cards.answer, cards.id from cards where cards.id in %s order by cards.created""" % strids) self.deck.updateProgress() if self.includeTags: self.cardTags = dict( self.deck.s.all(""" select cards.id, facts.tags from cards, facts where cards.factId = facts.id and cards.id in %s order by cards.created""" % strids)) out = u"\n".join([ "%s\t%s%s" % (self.escapeText(c[0], removeFields=True), self.escapeText(c[1], removeFields=True), self.tags(c[2])) for c in cards ]) if out: out += "\n" file.write(out.encode("utf-8")) self.deck.finishProgress()
def doExport(self, file): ids = self.cardIds() strids = ids2str(ids) self.deck.startProgress((len(ids) + 1) / 50) self.deck.updateProgress(_("Exporting...")) cards = self.deck.s.all(""" select cards.question, cards.answer, cards.id from cards where cards.id in %s order by cards.created""" % strids) self.deck.updateProgress() if self.includeTags: self.cardTags = dict(self.deck.s.all(""" select cards.id, facts.tags from cards, facts where cards.factId = facts.id and cards.id in %s order by cards.created""" % strids)) out = u"\n".join(["%s\t%s%s" % ( self.escapeText(c[0], removeFields=True), self.escapeText(c[1], removeFields=True), self.tags(c[2])) for c in cards]) if out: out += "\n" file.write(out.encode("utf-8")) self.deck.finishProgress()
def getCards(self, ids): return self.realLists( self.deck.s.all(""" select id, factId, cardModelId, created, modified, tags, ordinal, priority, interval, lastInterval, due, lastDue, factor, firstAnswered, reps, successive, averageTime, reviewTime, youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, yesCount, noCount, question, answer, lastFactor, spaceUntil, type, combinedDue, relativeDelay from cards where id in %s""" % ids2str(ids)))
def deleteMedia(self, ids): sids = ids2str(ids) files = self.deck.s.column0( "select filename from media where id in %s" % sids) self.deck.s.statement(""" insert into mediaDeleted select id, :now from media where media.id in %s""" % sids, now=time.time()) self.deck.s.execute("delete from media where id in %s" % sids)
def getMedia(self, ids): return [ tuple(row) for row in self.deck.s.all( """ select id, filename, size, created, originalPath, description from media where id in %s""" % ids2str(ids) ) ]
def updateFacts(self, factsdict): facts = factsdict['facts'] fields = factsdict['fields'] if not facts: return # update facts first dlist = [{ 'id': f[0], 'modelId': f[1], 'created': f[2], 'modified': f[3], 'tags': f[4], 'spaceUntil': f[5] or "", 'lastCardId': f[6] } for f in facts] self.deck.s.execute( """ insert or replace into facts (id, modelId, created, modified, tags, spaceUntil, lastCardId) values (:id, :modelId, :created, :modified, :tags, :spaceUntil, :lastCardId)""", dlist) # now fields dlist = [{ 'id': f[0], 'factId': f[1], 'fieldModelId': f[2], 'ordinal': f[3], 'value': f[4] } for f in fields] # delete local fields since ids may have changed self.deck.s.execute("delete from fields where factId in %s" % ids2str([f[0] for f in facts])) # then update self.deck.s.execute( """ insert into fields (id, factId, fieldModelId, ordinal, value) values (:id, :factId, :fieldModelId, :ordinal, :value)""", dlist) self.deck.s.statement("delete from factsDeleted where factId in %s" % ids2str([f[0] for f in facts]))
def deleteMedia(self, ids): sids = ids2str(ids) files = self.deck.s.column0("select filename from media where id in %s" % sids) self.deck.s.statement( """ insert into mediaDeleted select id, :now from media where media.id in %s""" % sids, now=time.time(), ) self.deck.s.execute("delete from media where id in %s" % sids)
def updateModels(self, models): for model in models: local = self.getModel(model["id"]) # avoid overwriting any existing card/field models fms = model["fieldModels"] del model["fieldModels"] cms = model["cardModels"] del model["cardModels"] self.applyDict(local, model) self.mergeFieldModels(local, fms) self.mergeCardModels(local, cms) self.deck.s.statement("delete from modelsDeleted where modelId in %s" % ids2str([m["id"] for m in models]))
def updateFacts(self, factsdict): facts = factsdict["facts"] fields = factsdict["fields"] if not facts: return # update facts first dlist = [ { "id": f[0], "modelId": f[1], "created": f[2], "modified": f[3], "tags": f[4], "spaceUntil": f[5] or "", "lastCardId": f[6], } for f in facts ] self.deck.s.execute( """ insert or replace into facts (id, modelId, created, modified, tags, spaceUntil, lastCardId) values (:id, :modelId, :created, :modified, :tags, :spaceUntil, :lastCardId)""", dlist, ) # now fields dlist = [{"id": f[0], "factId": f[1], "fieldModelId": f[2], "ordinal": f[3], "value": f[4]} for f in fields] # delete local fields since ids may have changed self.deck.s.execute("delete from fields where factId in %s" % ids2str([f[0] for f in facts])) # then update self.deck.s.execute( """ insert into fields (id, factId, fieldModelId, ordinal, value) values (:id, :factId, :fieldModelId, :ordinal, :value)""", dlist, ) self.deck.s.statement("delete from factsDeleted where factId in %s" % ids2str([f[0] for f in facts]))
def cardIds(self): "Return all cards, limited by tags or provided ids." if self.limitCardIds: return self.limitCardIds if not self.limitTags: cards = self.deck.s.column0("select id from cards") else: d = tagIds(self.deck.s, self.limitTags, create=False) cards = self.deck.s.column0( "select cardId from cardTags where tagid in %s" % ids2str(d.values())) self.count = len(cards) return cards
def updateModels(self, models): for model in models: local = self.getModel(model['id']) # avoid overwriting any existing card/field models fms = model['fieldModels'] del model['fieldModels'] cms = model['cardModels'] del model['cardModels'] self.applyDict(local, model) self.mergeFieldModels(local, fms) self.mergeCardModels(local, cms) self.deck.s.statement("delete from modelsDeleted where modelId in %s" % ids2str([m['id'] for m in models]))
def getCards(self, ids): return self.realLists( self.deck.s.all( """ select id, factId, cardModelId, created, modified, tags, ordinal, priority, interval, lastInterval, due, lastDue, factor, firstAnswered, reps, successive, averageTime, reviewTime, youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, yesCount, noCount, question, answer, lastFactor, spaceUntil, type, combinedDue, relativeDelay from cards where id in %s""" % ids2str(ids) ) )
def updateOneWayCards(self, cards): if not cards: return t = time.time() dlist = [ {"id": c[0], "factId": c[1], "cardModelId": c[2], "ordinal": c[3], "created": c[4], "t": t} for c in cards ] # add any missing cards self.deck.s.statements( """ insert or ignore into cards (id, factId, cardModelId, created, modified, tags, ordinal, priority, interval, lastInterval, due, lastDue, factor, firstAnswered, reps, successive, averageTime, reviewTime, youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, yesCount, noCount, question, answer, lastFactor, spaceUntil, isDue, type, combinedDue, relativeDelay) values (:id, :factId, :cardModelId, :created, :t, "", :ordinal, 1, 0, 0, :created, 0, 2.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 2.5, 0, 0, 2, :t, 2)""", dlist, ) # update q/as models = dict( self.deck.s.all( """ select cards.id, models.id from cards, facts, models where cards.factId = facts.id and facts.modelId = models.id and cards.id in %s""" % ids2str([c[0] for c in cards]) ) ) self.deck.s.flush() self.deck.updateCardQACache([(c[0], c[2], c[1], models[c[0]]) for c in cards]) # rebuild priorities on client cardIds = [c[0] for c in cards] self.deck.updateCardTags(cardIds) self.rebuildPriorities(cardIds)
def updateOneWayCards(self, cards): if not cards: return t = time.time() dlist = [{ 'id': c[0], 'factId': c[1], 'cardModelId': c[2], 'ordinal': c[3], 'created': c[4], 't': t } for c in cards] # add any missing cards self.deck.s.statements( """ insert or ignore into cards (id, factId, cardModelId, created, modified, tags, ordinal, priority, interval, lastInterval, due, lastDue, factor, firstAnswered, reps, successive, averageTime, reviewTime, youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, yesCount, noCount, question, answer, lastFactor, spaceUntil, isDue, type, combinedDue, relativeDelay) values (:id, :factId, :cardModelId, :created, :t, "", :ordinal, 1, 0, 0, :created, 0, 2.5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 2.5, 0, 0, 2, :t, 2)""", dlist) # update q/as models = dict( self.deck.s.all(""" select cards.id, models.id from cards, facts, models where cards.factId = facts.id and facts.modelId = models.id and cards.id in %s""" % ids2str([c[0] for c in cards]))) self.deck.s.flush() self.deck.updateCardQACache([(c[0], c[2], c[1], models[c[0]]) for c in cards]) # rebuild priorities on client cardIds = [c[0] for c in cards] self.deck.updateCardTags(cardIds) self.rebuildPriorities(cardIds)
def updateMedia(self, media): meta = [] for m in media: # build meta meta.append( {"id": m[0], "filename": m[1], "size": m[2], "created": m[3], "originalPath": m[4], "description": m[5]} ) # apply metadata if meta: self.deck.s.statements( """ insert or replace into media (id, filename, size, created, originalPath, description) values (:id, :filename, :size, :created, :originalPath, :description)""", meta, ) self.deck.s.statement("delete from mediaDeleted where mediaId in %s" % ids2str([m[0] for m in media]))
def getFacts(self, ids, updateModified=False): if updateModified: modified = time.time() else: modified = "modified" factIds = ids2str(ids) return { 'facts': self.realLists( self.deck.s.all(""" select id, modelId, created, %s, tags, spaceUntil, lastCardId from facts where id in %s""" % (modified, factIds))), 'fields': self.realLists( self.deck.s.all(""" select id, factId, fieldModelId, ordinal, value from fields where factId in %s""" % factIds)) }
def updateMedia(self, media): meta = [] for m in media: # build meta meta.append({ 'id': m[0], 'filename': m[1], 'size': m[2], 'created': m[3], 'originalPath': m[4], 'description': m[5] }) # apply metadata if meta: self.deck.s.statements( """ insert or replace into media (id, filename, size, created, originalPath, description) values (:id, :filename, :size, :created, :originalPath, :description)""", meta) self.deck.s.statement("delete from mediaDeleted where mediaId in %s" % ids2str([m[0] for m in media]))
def getFacts(self, ids, updateModified=False): if updateModified: modified = time.time() else: modified = "modified" factIds = ids2str(ids) return { "facts": self.realLists( self.deck.s.all( """ select id, modelId, created, %s, tags, spaceUntil, lastCardId from facts where id in %s""" % (modified, factIds) ) ), "fields": self.realLists( self.deck.s.all( """ select id, factId, fieldModelId, ordinal, value from fields where factId in %s""" % factIds ) ), }
def updateCards(self, cards): if not cards: return # FIXME: older clients won't send this, so this is temp compat code def getType(row): if len(row) > 36: return row[36] if row[15]: return 1 elif row[14]: return 0 return 2 dlist = [ { "id": c[0], "factId": c[1], "cardModelId": c[2], "created": c[3], "modified": c[4], "tags": c[5], "ordinal": c[6], "priority": c[7], "interval": c[8], "lastInterval": c[9], "due": c[10], "lastDue": c[11], "factor": c[12], "firstAnswered": c[13], "reps": c[14], "successive": c[15], "averageTime": c[16], "reviewTime": c[17], "youngEase0": c[18], "youngEase1": c[19], "youngEase2": c[20], "youngEase3": c[21], "youngEase4": c[22], "matureEase0": c[23], "matureEase1": c[24], "matureEase2": c[25], "matureEase3": c[26], "matureEase4": c[27], "yesCount": c[28], "noCount": c[29], "question": c[30], "answer": c[31], "lastFactor": c[32], "spaceUntil": c[33], "type": c[34], "combinedDue": c[35], "rd": getType(c), } for c in cards ] self.deck.s.execute( """ insert or replace into cards (id, factId, cardModelId, created, modified, tags, ordinal, priority, interval, lastInterval, due, lastDue, factor, firstAnswered, reps, successive, averageTime, reviewTime, youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, yesCount, noCount, question, answer, lastFactor, spaceUntil, type, combinedDue, relativeDelay, isDue) values (:id, :factId, :cardModelId, :created, :modified, :tags, :ordinal, :priority, :interval, :lastInterval, :due, :lastDue, :factor, :firstAnswered, :reps, :successive, :averageTime, :reviewTime, :youngEase0, :youngEase1, :youngEase2, :youngEase3, :youngEase4, :matureEase0, :matureEase1, :matureEase2, :matureEase3, :matureEase4, :yesCount, :noCount, :question, :answer, :lastFactor, :spaceUntil, :type, :combinedDue, :rd, 0)""", dlist, ) self.deck.s.statement("delete from cardsDeleted where cardId in %s" % ids2str([c[0] for c in cards]))
def getOneWayCards(self, ids): "The minimum information necessary to generate one way cards." return self.deck.s.all( "select id, factId, cardModelId, ordinal, created from cards " "where id in %s" % ids2str(ids))
def getMedia(self, ids): return [ tuple(row) for row in self.deck.s.all(""" select id, filename, size, created, originalPath, description from media where id in %s""" % ids2str(ids)) ]
def updateCards(self, cards): if not cards: return # FIXME: older clients won't send this, so this is temp compat code def getType(row): if len(row) > 36: return row[36] if row[15]: return 1 elif row[14]: return 0 return 2 dlist = [{ 'id': c[0], 'factId': c[1], 'cardModelId': c[2], 'created': c[3], 'modified': c[4], 'tags': c[5], 'ordinal': c[6], 'priority': c[7], 'interval': c[8], 'lastInterval': c[9], 'due': c[10], 'lastDue': c[11], 'factor': c[12], 'firstAnswered': c[13], 'reps': c[14], 'successive': c[15], 'averageTime': c[16], 'reviewTime': c[17], 'youngEase0': c[18], 'youngEase1': c[19], 'youngEase2': c[20], 'youngEase3': c[21], 'youngEase4': c[22], 'matureEase0': c[23], 'matureEase1': c[24], 'matureEase2': c[25], 'matureEase3': c[26], 'matureEase4': c[27], 'yesCount': c[28], 'noCount': c[29], 'question': c[30], 'answer': c[31], 'lastFactor': c[32], 'spaceUntil': c[33], 'type': c[34], 'combinedDue': c[35], 'rd': getType(c) } for c in cards] self.deck.s.execute( """ insert or replace into cards (id, factId, cardModelId, created, modified, tags, ordinal, priority, interval, lastInterval, due, lastDue, factor, firstAnswered, reps, successive, averageTime, reviewTime, youngEase0, youngEase1, youngEase2, youngEase3, youngEase4, matureEase0, matureEase1, matureEase2, matureEase3, matureEase4, yesCount, noCount, question, answer, lastFactor, spaceUntil, type, combinedDue, relativeDelay, isDue) values (:id, :factId, :cardModelId, :created, :modified, :tags, :ordinal, :priority, :interval, :lastInterval, :due, :lastDue, :factor, :firstAnswered, :reps, :successive, :averageTime, :reviewTime, :youngEase0, :youngEase1, :youngEase2, :youngEase3, :youngEase4, :matureEase0, :matureEase1, :matureEase2, :matureEase3, :matureEase4, :yesCount, :noCount, :question, :answer, :lastFactor, :spaceUntil, :type, :combinedDue, :rd, 0)""", dlist) self.deck.s.statement("delete from cardsDeleted where cardId in %s" % ids2str([c[0] for c in cards]))
def getOneWayCards(self, ids): "The minimum information necessary to generate one way cards." return self.deck.s.all( "select id, factId, cardModelId, ordinal, created from cards " "where id in %s" % ids2str(ids) )