From e49211c5b63106dbb5e3e59fb79abf186cc9d7eb Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 17 Mar 2011 08:25:16 +0900 Subject: [PATCH] add edue to cards The 'entry due' is the due time of a failed card before it enters the learning queue. When the card graduates or is removed, it has its old due time restored. We could pull this from the revlog, but it's cheaper to do it this way. --- anki/cards.py | 11 +++++++---- anki/sched.py | 12 ++++++++++-- anki/storage.py | 14 +++++++++----- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/anki/cards.py b/anki/cards.py index 2e6858871..6fed4f948 100644 --- a/anki/cards.py +++ b/anki/cards.py @@ -14,7 +14,7 @@ MAX_TIMER = 60 # Queue: 0=learning, 1=due, 2=new # -1=suspended, -2=user buried, -3=sched buried # Due is used differently for different queues. -# - new queue: fact id +# - new queue: fact id or random int # - rev queue: integer day # - lrn queue: integer timestamp @@ -41,6 +41,7 @@ class Card(object): self.lapses = 0 self.grade = 0 self.cycles = 0 + self.edue = 0 self.data = "" def load(self): @@ -60,6 +61,7 @@ class Card(object): self.lapses, self.grade, self.cycles, + self.edue, self.data) = self.deck.db.first( "select * from cards where id = ?", self.id) @@ -68,7 +70,7 @@ class Card(object): self.deck.db.execute( """ insert or replace into cards values -(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", +(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", self.id, self.fid, self.gid, @@ -85,6 +87,7 @@ insert or replace into cards values self.lapses, self.grade, self.cycles, + self.edue, self.data) def flushSched(self): @@ -92,10 +95,10 @@ insert or replace into cards values self.deck.db.execute( """update cards set mod=?, type=?, queue=?, due=?, ivl=?, factor=?, reps=?, -streak=?, lapses=?, grade=?, cycles=? where id = ?""", +streak=?, lapses=?, grade=?, cycles=?, edue=? where id = ?""", self.mod, self.type, self.queue, self.due, self.ivl, self.factor, self.reps, self.streak, self.lapses, - self.grade, self.cycles, self.id) + self.grade, self.cycles, self.edue, self.id) def q(self): return self._getQA()['q'] diff --git a/anki/sched.py b/anki/sched.py index fe83b08c6..781a1290b 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -204,8 +204,8 @@ limit %d""" % self.learnLimit, lim=self.dayCutoff) card.queue = 1 card.type = 1 if card.type == 1: - # failed, nothing else to do - pass + # failed; put back entry due + card.due = card.edue else: self.rescheduleNew(card, conf, early) @@ -230,6 +230,14 @@ limit %d""" % self.learnLimit, lim=self.dayCutoff) self.delayForGrade(conf, max(0, card.grade-1)), leaving, card.timeTaken(), 0) + def removeFailed(self): + "Remove failed cards from the learning queue." + self.deck.db.execute(""" +update cards set +due = edue, queue = 1 +where queue = 0 and type = 1 +""") + # Reviews ########################################################################## diff --git a/anki/storage.py b/anki/storage.py index 37a66956b..8a092cc8e 100644 --- a/anki/storage.py +++ b/anki/storage.py @@ -84,6 +84,7 @@ create table if not exists cards ( lapses integer not null, grade integer not null, cycles integer not null, + edue integer not null, data text not null ); @@ -247,7 +248,7 @@ def _upgradeSchema(db): db.execute(""" insert into cards select rowid, factId, cardModelId, 1, cast(created as int), cast(modified as int), relativeDelay, type, due, cast(interval as int), -cast(factor*1000 as int), reps, successive, noCount, 0, 0, "" from cards2 +cast(factor*1000 as int), reps, successive, noCount, 0, 0, 0, "" from cards2 order by created""") db.execute("drop table cards2") @@ -293,7 +294,7 @@ from facts order by created""") row.append(minimizeHTML("\x1f".join([x[1] for x in sorted(fields[oldid])]))) data.append(row) # use the new order to rewrite fact ids in cards table - _insertWithIdChange(db, map, 1, "cards", 17) + _insertWithIdChange(db, map, 1, "cards", 18) # and put the facts into the new table db.execute("drop table facts") _addSchema(db, False) @@ -494,12 +495,15 @@ def _postSchemaUpgrade(deck): # rewrite due times for new cards deck.db.execute(""" update cards set due = fid where type=2""") - # convert due cards into day-based due + # and failed cards + deck.db.execute("update cards set edue = ? where type = 0", + deck.sched.today+1) + # and due cards deck.db.execute(""" update cards set due = cast( (case when due < :stamp then 0 else 1 end) + -((due-:stamp)/86400) as int)+:today where type -between 0 and 1""", stamp=deck.sched.dayCutoff, today=deck.sched.today) +((due-:stamp)/86400) as int)+:today where type = 1 +""", stamp=deck.sched.dayCutoff, today=deck.sched.today) # update insertion id deck.conf['nextFid'] = deck.db.scalar("select max(id) from facts")+1 deck.conf['nextCid'] = deck.db.scalar("select max(id) from cards")+1