mirror of
https://github.com/ankitects/anki.git
synced 2025-09-25 01:06:35 -04:00
more scheduler updates
- reimplement reviewEarly and newEarly by replacing parts of the scheduler, instead of adding special conditions - remove references to isDue and priority (1,2,3,4) which is not necessary anymore - add option to switch between per-day scheduling and due now scheduling - newCardsToday() -> newCardsDoneToday() - don't decrement counts for suspended cards - make sure to update type when suspending/unsuspending - fix findCards() - set hardInterval = 1-1.1 on upgrade, or the default per day scheduling doesn't make sense
This commit is contained in:
parent
ad743d850d
commit
be4dea39b1
5 changed files with 113 additions and 79 deletions
|
@ -73,7 +73,6 @@ class Card(object):
|
||||||
self.id = genID()
|
self.id = genID()
|
||||||
# new cards start as new & due
|
# new cards start as new & due
|
||||||
self.type = 2
|
self.type = 2
|
||||||
self.isDue = True
|
|
||||||
self.timerStarted = False
|
self.timerStarted = False
|
||||||
self.timerStopped = False
|
self.timerStopped = False
|
||||||
self.modified = time.time()
|
self.modified = time.time()
|
||||||
|
@ -226,7 +225,7 @@ from cards where id = :id""", id=id)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def toDB(self, s):
|
def toDB(self, s):
|
||||||
"Write card to DB. Note that isDue assumes card is not spaced."
|
"Write card to DB."
|
||||||
if self.reps == 0:
|
if self.reps == 0:
|
||||||
self.type = 2
|
self.type = 2
|
||||||
elif self.successive:
|
elif self.successive:
|
||||||
|
@ -260,7 +259,7 @@ matureEase4=:matureEase4,
|
||||||
yesCount=:yesCount,
|
yesCount=:yesCount,
|
||||||
noCount=:noCount,
|
noCount=:noCount,
|
||||||
spaceUntil = :spaceUntil,
|
spaceUntil = :spaceUntil,
|
||||||
isDue = :isDue,
|
isDue = 0,
|
||||||
type = :type,
|
type = :type,
|
||||||
combinedDue = max(:spaceUntil, :due),
|
combinedDue = max(:spaceUntil, :due),
|
||||||
relativeDelay = 0,
|
relativeDelay = 0,
|
||||||
|
|
176
anki/deck.py
176
anki/deck.py
|
@ -143,14 +143,13 @@ class Deck(object):
|
||||||
self.sessionStartReps = 0
|
self.sessionStartReps = 0
|
||||||
self.sessionStartTime = 0
|
self.sessionStartTime = 0
|
||||||
self.lastSessionStart = 0
|
self.lastSessionStart = 0
|
||||||
self.newEarly = False
|
|
||||||
self.reviewEarly = False
|
|
||||||
self.updateCutoff()
|
self.updateCutoff()
|
||||||
self.setupStandardScheduler()
|
self.setupStandardScheduler()
|
||||||
# if most recent deck var not defined, make sure defaults are set
|
# if most recent deck var not defined, make sure defaults are set
|
||||||
if not self.s.scalar("select 1 from deckVars where key = 'leechFails'"):
|
if not self.s.scalar("select 1 from deckVars where key = 'perDay'"):
|
||||||
self.setVarDefault("suspendLeeches", True)
|
self.setVarDefault("suspendLeeches", True)
|
||||||
self.setVarDefault("leechFails", 16)
|
self.setVarDefault("leechFails", 16)
|
||||||
|
self.setVarDefault("perDay", True)
|
||||||
|
|
||||||
def modifiedSinceSave(self):
|
def modifiedSinceSave(self):
|
||||||
return self.modified > self.lastLoaded
|
return self.modified > self.lastLoaded
|
||||||
|
@ -166,6 +165,13 @@ class Deck(object):
|
||||||
self.rebuildRevCount = self._rebuildRevCount
|
self.rebuildRevCount = self._rebuildRevCount
|
||||||
self.rebuildNewCount = self._rebuildNewCount
|
self.rebuildNewCount = self._rebuildNewCount
|
||||||
self.requeueCard = self._requeueCard
|
self.requeueCard = self._requeueCard
|
||||||
|
self.timeForNewCard = self._timeForNewCard
|
||||||
|
self.updateNewCountToday = self._updateNewCountToday
|
||||||
|
self.finishScheduler = None
|
||||||
|
|
||||||
|
def _noop(self):
|
||||||
|
"Do nothing."
|
||||||
|
pass
|
||||||
|
|
||||||
def fillQueues(self):
|
def fillQueues(self):
|
||||||
self.fillFailedQueue()
|
self.fillFailedQueue()
|
||||||
|
@ -198,10 +204,10 @@ class Deck(object):
|
||||||
"and combinedDue < :lim", lim=self.dueCutoff)
|
"and combinedDue < :lim", lim=self.dueCutoff)
|
||||||
self.updateNewCountToday()
|
self.updateNewCountToday()
|
||||||
|
|
||||||
def updateNewCountToday(self):
|
def _updateNewCountToday(self):
|
||||||
self.newCountToday = max(min(
|
self.newCountToday = max(min(
|
||||||
self.newCount, self.newCardsPerDay -
|
self.newCount, self.newCardsPerDay -
|
||||||
self.newCardsToday()), 0)
|
self.newCardsDoneToday()), 0)
|
||||||
|
|
||||||
def _fillFailedQueue(self):
|
def _fillFailedQueue(self):
|
||||||
if self.failedSoonCount and not self.failedQueue:
|
if self.failedSoonCount and not self.failedQueue:
|
||||||
|
@ -295,8 +301,11 @@ end)""" + where)
|
||||||
"update cards set type = type + 3 where priority <= 0")
|
"update cards set type = type + 3 where priority <= 0")
|
||||||
|
|
||||||
def updateCutoff(self):
|
def updateCutoff(self):
|
||||||
|
if self.getBool("perDay"):
|
||||||
today = genToday(self) + datetime.timedelta(days=1)
|
today = genToday(self) + datetime.timedelta(days=1)
|
||||||
self.dueCutoff = time.mktime(today.timetuple())
|
self.dueCutoff = time.mktime(today.timetuple())
|
||||||
|
else:
|
||||||
|
self.dueCutoff = time.time()
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
# setup global/daily stats
|
# setup global/daily stats
|
||||||
|
@ -329,15 +338,55 @@ end)""" + where)
|
||||||
if genToday(self) != self._dailyStats.day:
|
if genToday(self) != self._dailyStats.day:
|
||||||
self._dailyStats = dailyStats(self)
|
self._dailyStats = dailyStats(self)
|
||||||
|
|
||||||
|
# Review early
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
def setupReviewEarlyScheduler(self):
|
||||||
|
self.fillRevQueue = self._fillRevEarlyQueue
|
||||||
|
self.rebuildRevCount = self._rebuildRevEarlyCount
|
||||||
|
self.finishScheduler = self._onReviewEarlyFinished
|
||||||
|
|
||||||
def resetAfterReviewEarly(self):
|
def resetAfterReviewEarly(self):
|
||||||
ids = self.s.column0("select id from cards where priority = -1")
|
ids = self.s.column0("select id from cards where priority = -1")
|
||||||
if ids:
|
if ids:
|
||||||
self.updatePriorities(ids)
|
self.updatePriorities(ids)
|
||||||
self.flushMod()
|
self.flushMod()
|
||||||
if self.reviewEarly or self.newEarly:
|
|
||||||
self.reviewEarly = False
|
def _onReviewEarlyFinished(self):
|
||||||
self.newEarly = False
|
# clean up buried cards
|
||||||
self.checkDue()
|
self.resetAfterReviewEarly()
|
||||||
|
# and go back to regular scheduler
|
||||||
|
self.setupStandardScheduler()
|
||||||
|
|
||||||
|
def _rebuildRevEarlyCount(self):
|
||||||
|
# in the future it would be nice to skip the first x days of due cards
|
||||||
|
extraLim = ""
|
||||||
|
self.revCount = self.s.scalar("""
|
||||||
|
select count() from cards where type = 1 and combinedDue > :now
|
||||||
|
%s""" % extraLim, now=self.dueCutoff)
|
||||||
|
|
||||||
|
def _fillRevEarlyQueue(self):
|
||||||
|
if self.revCount and not self.revQueue:
|
||||||
|
self.revQueue = self.s.all("""
|
||||||
|
select id, factId from cards where type = 1 and combinedDue > :lim
|
||||||
|
order by combinedDue limit 50""", lim=self.dueCutoff)
|
||||||
|
self.revQueue.reverse()
|
||||||
|
|
||||||
|
# Learn more
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
def setupLearnMoreScheduler(self):
|
||||||
|
self.rebuildNewCount = self._rebuildLearnMoreCount
|
||||||
|
self.updateNewCountToday = self._updateLearnMoreCountToday
|
||||||
|
self.finishScheduler = self.setupStandardScheduler
|
||||||
|
|
||||||
|
def _rebuildLearnMoreCount(self):
|
||||||
|
self.newCount = self.s.scalar("""
|
||||||
|
select count() from cards where type = 2 and combinedDue < :now
|
||||||
|
""", now=self.dueCutoff)
|
||||||
|
|
||||||
|
def _updateLearnMoreCountToday(self):
|
||||||
|
self.newCountToday = self.newCount
|
||||||
|
|
||||||
# Getting the next card
|
# Getting the next card
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
@ -348,7 +397,7 @@ end)""" + where)
|
||||||
if id:
|
if id:
|
||||||
return self.cardFromId(id, orm)
|
return self.cardFromId(id, orm)
|
||||||
|
|
||||||
def getCardId(self):
|
def getCardId(self, check=True):
|
||||||
"Return the next due card id, or None."
|
"Return the next due card id, or None."
|
||||||
self.checkDailyStats()
|
self.checkDailyStats()
|
||||||
self.fillQueues()
|
self.fillQueues()
|
||||||
|
@ -368,34 +417,28 @@ end)""" + where)
|
||||||
if self.revNoSpaced():
|
if self.revNoSpaced():
|
||||||
return self.revQueue[-1][0]
|
return self.revQueue[-1][0]
|
||||||
# new cards left?
|
# new cards left?
|
||||||
if self.newQueue:
|
if self.newCountToday:
|
||||||
return self.newQueue[-1][0]
|
return self.newQueue[-1][0]
|
||||||
# # review ahead?
|
|
||||||
# if self.reviewEarly:
|
|
||||||
# id = self.getCardIdAhead()
|
|
||||||
# if id:
|
|
||||||
# return id
|
|
||||||
# else:
|
|
||||||
# self.resetAfterReviewEarly()
|
|
||||||
# self.checkDue()
|
|
||||||
# display failed cards early/last
|
# display failed cards early/last
|
||||||
if self.showFailedLast() and self.failedQueue:
|
if self.showFailedLast() and self.failedQueue:
|
||||||
return self.failedQueue[-1][0]
|
return self.failedQueue[-1][0]
|
||||||
|
if check:
|
||||||
def getCardIdAhead(self):
|
# check for expired cards, or new day rollover
|
||||||
"Return the first card that would become due."
|
self.updateCutoff()
|
||||||
id = self.s.scalar("""
|
return self.getCardId(check=False)
|
||||||
select id from cards
|
# if we're in a custom scheduler, we may need to switch back
|
||||||
where type = 1 and isDue = 0 and priority in (1,2,3,4)
|
if self.finishScheduler:
|
||||||
order by combinedDue
|
self.finishScheduler()
|
||||||
limit 1""")
|
self.reset()
|
||||||
return id
|
return self.getCardId()
|
||||||
|
|
||||||
# Get card: helper functions
|
# Get card: helper functions
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def timeForNewCard(self):
|
def _timeForNewCard(self):
|
||||||
"True if it's time to display a new card when distributing."
|
"True if it's time to display a new card when distributing."
|
||||||
|
if not self.newCountToday:
|
||||||
|
return False
|
||||||
if self.newCardSpacing == NEW_CARDS_LAST:
|
if self.newCardSpacing == NEW_CARDS_LAST:
|
||||||
return False
|
return False
|
||||||
if self.newCardSpacing == NEW_CARDS_FIRST:
|
if self.newCardSpacing == NEW_CARDS_FIRST:
|
||||||
|
@ -406,7 +449,7 @@ limit 1""")
|
||||||
"select 1 from cards where id = :id and priority = 4",
|
"select 1 from cards where id = :id and priority = 4",
|
||||||
id = self.revQueue[-1][0]):
|
id = self.revQueue[-1][0]):
|
||||||
return False
|
return False
|
||||||
if self.newCardModulus and (self.newCountToday or self.newEarly):
|
if self.newCardModulus:
|
||||||
return self._dailyStats.reps % self.newCardModulus == 0
|
return self._dailyStats.reps % self.newCardModulus == 0
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
@ -515,7 +558,6 @@ where factId in (select factId from %s limit 60))""" % (new, new))
|
||||||
# only update if card was not new
|
# only update if card was not new
|
||||||
card.lastDue = card.due
|
card.lastDue = card.due
|
||||||
card.due = self.nextDue(card, ease, oldState)
|
card.due = self.nextDue(card, ease, oldState)
|
||||||
card.isDue = 0
|
|
||||||
card.lastFactor = card.factor
|
card.lastFactor = card.factor
|
||||||
if lastDelay >= 0:
|
if lastDelay >= 0:
|
||||||
# don't update factor if learning ahead
|
# don't update factor if learning ahead
|
||||||
|
@ -536,22 +578,16 @@ where factId = :fid and id != :id""", fid=card.factId, id=card.id) or 0
|
||||||
space += time.time()
|
space += time.time()
|
||||||
card.combinedDue = max(card.due, space)
|
card.combinedDue = max(card.due, space)
|
||||||
# check what other cards we've spaced
|
# check what other cards we've spaced
|
||||||
if self.reviewEarly:
|
|
||||||
extra = ""
|
|
||||||
else:
|
|
||||||
# if not reviewing early, make sure the current card is counted
|
|
||||||
# even if it was not due yet (it's a failed card)
|
|
||||||
extra = "or id = :cid"
|
|
||||||
for (type, count) in self.s.all("""
|
for (type, count) in self.s.all("""
|
||||||
select type, count(type) from cards
|
select type, count(type) from cards
|
||||||
where factId = :fid and
|
where factId = :fid and
|
||||||
(isDue = 1 %s)
|
(combinedDue < :now or id = :cid)
|
||||||
group by type""" % extra, fid=card.factId, cid=card.id):
|
group by type""", fid=card.factId, cid=card.id, now=self.dueCutoff):
|
||||||
if type == 0:
|
if type == 0:
|
||||||
self.failedSoonCount -= count
|
self.failedSoonCount -= count
|
||||||
elif type == 1:
|
elif type == 1:
|
||||||
self.revCount -= count
|
self.revCount -= count
|
||||||
else:
|
elif type == 2:
|
||||||
self.newCount -= count
|
self.newCount -= count
|
||||||
# bump failed count if necessary
|
# bump failed count if necessary
|
||||||
if ease == 1:
|
if ease == 1:
|
||||||
|
@ -561,15 +597,14 @@ group by type""" % extra, fid=card.factId, cid=card.id):
|
||||||
update cards set
|
update cards set
|
||||||
spaceUntil = :space,
|
spaceUntil = :space,
|
||||||
combinedDue = max(:space, due),
|
combinedDue = max(:space, due),
|
||||||
modified = :now,
|
modified = :now
|
||||||
isDue = 0
|
|
||||||
where id != :id and factId = :factId""",
|
where id != :id and factId = :factId""",
|
||||||
id=card.id, space=space, now=now, factId=card.factId)
|
id=card.id, space=space, now=now, factId=card.factId)
|
||||||
card.spaceUntil = 0
|
card.spaceUntil = 0
|
||||||
self.spacedFacts[card.factId] = space
|
self.spacedFacts[card.factId] = space
|
||||||
# temp suspend if learning ahead
|
# temp suspend if it's a review card & we're reviewing early
|
||||||
if self.reviewEarly and lastDelay < 0:
|
if oldSuc and lastDelay < 0:
|
||||||
if oldSuc or lastDelaySecs > self.delay0 or not self._showFailedLast():
|
if lastDelaySecs > self.delay0:
|
||||||
card.priority = -1
|
card.priority = -1
|
||||||
# card stats
|
# card stats
|
||||||
anki.cards.Card.updateStats(card, ease, oldState)
|
anki.cards.Card.updateStats(card, ease, oldState)
|
||||||
|
@ -715,7 +750,7 @@ factor = 2.5, reps = 0, successive = 0, averageTime = 0, reviewTime = 0,
|
||||||
youngEase0 = 0, youngEase1 = 0, youngEase2 = 0, youngEase3 = 0,
|
youngEase0 = 0, youngEase1 = 0, youngEase2 = 0, youngEase3 = 0,
|
||||||
youngEase4 = 0, matureEase0 = 0, matureEase1 = 0, matureEase2 = 0,
|
youngEase4 = 0, matureEase0 = 0, matureEase1 = 0, matureEase2 = 0,
|
||||||
matureEase3 = 0,matureEase4 = 0, yesCount = 0, noCount = 0,
|
matureEase3 = 0,matureEase4 = 0, yesCount = 0, noCount = 0,
|
||||||
spaceUntil = 0, isDue = 0, type = 2,
|
spaceUntil = 0, type = 2,
|
||||||
combinedDue = created, modified = :now, due = created
|
combinedDue = created, modified = :now, due = created
|
||||||
where id in %s""" % ids2str(ids), now=time.time(), new=0)
|
where id in %s""" % ids2str(ids), now=time.time(), new=0)
|
||||||
if self.newCardOrder == NEW_CARDS_RANDOM:
|
if self.newCardOrder == NEW_CARDS_RANDOM:
|
||||||
|
@ -772,8 +807,7 @@ reps = 1,
|
||||||
successive = 1,
|
successive = 1,
|
||||||
yesCount = 1,
|
yesCount = 1,
|
||||||
firstAnswered = :t,
|
firstAnswered = :t,
|
||||||
type = 1,
|
type = 1
|
||||||
isDue = 0
|
|
||||||
where id = :id""", vals)
|
where id = :id""", vals)
|
||||||
self.flushMod()
|
self.flushMod()
|
||||||
|
|
||||||
|
@ -783,9 +817,8 @@ where id = :id""", vals)
|
||||||
def nextDueMsg(self):
|
def nextDueMsg(self):
|
||||||
next = self.earliestTime()
|
next = self.earliestTime()
|
||||||
if next:
|
if next:
|
||||||
newCount = self.s.scalar("""
|
newCount = self.s.scalar(
|
||||||
select count() from cards where type = 2
|
"select count() from cards where type = 2")
|
||||||
and priority in (1,2,3,4)""")
|
|
||||||
newCardsTomorrow = min(newCount, self.newCardsPerDay)
|
newCardsTomorrow = min(newCount, self.newCardsPerDay)
|
||||||
cards = self.cardsDueBy(time.time() + 86400)
|
cards = self.cardsDueBy(time.time() + 86400)
|
||||||
msg = _('''\
|
msg = _('''\
|
||||||
|
@ -812,8 +845,8 @@ This may be in the past if the deck is not finished.
|
||||||
If the deck has no (enabled) cards, return None.
|
If the deck has no (enabled) cards, return None.
|
||||||
Ignore new cards."""
|
Ignore new cards."""
|
||||||
return self.s.scalar("""
|
return self.s.scalar("""
|
||||||
select combinedDue from cards where priority in (1,2,3,4) and
|
select combinedDue from cards where type in (0, 1)
|
||||||
type in (0, 1) order by combinedDue limit 1""")
|
order by combinedDue limit 1""")
|
||||||
|
|
||||||
def earliestTimeStr(self, next=None):
|
def earliestTimeStr(self, next=None):
|
||||||
"""Return the relative time to the earliest card as a string."""
|
"""Return the relative time to the earliest card as a string."""
|
||||||
|
@ -828,10 +861,9 @@ type in (0, 1) order by combinedDue limit 1""")
|
||||||
"Number of cards due at TIME. Ignore new cards"
|
"Number of cards due at TIME. Ignore new cards"
|
||||||
return self.s.scalar("""
|
return self.s.scalar("""
|
||||||
select count(id) from cards where combinedDue < :time
|
select count(id) from cards where combinedDue < :time
|
||||||
and priority in (1,2,3,4) and type in (0, 1)""", time=time)
|
and type in (0, 1)""", time=time)
|
||||||
|
|
||||||
def deckFinishedMsg(self):
|
def deckFinishedMsg(self):
|
||||||
self.resetAfterReviewEarly()
|
|
||||||
spaceSusp = ""
|
spaceSusp = ""
|
||||||
c= self.spacedCardCount()
|
c= self.spacedCardCount()
|
||||||
if c:
|
if c:
|
||||||
|
@ -944,9 +976,12 @@ group by cardTags.cardId""" % limit)
|
||||||
"update cards set priority = :pri %s where id in %s "
|
"update cards set priority = :pri %s where id in %s "
|
||||||
"and priority != :pri and priority >= -2") % (
|
"and priority != :pri and priority >= -2") % (
|
||||||
extra, ids2str(cs)), pri=pri, m=time.time())
|
extra, ids2str(cs)), pri=pri, m=time.time())
|
||||||
cnt = self.s.execute(
|
self.s.execute(
|
||||||
"update cards set isDue = 0 where type in (0,1,2) and "
|
"update cards set type = type + 3 where type in (0,1,2) and "
|
||||||
"priority = 0 and isDue = 1").rowcount
|
"priority = 0").rowcount
|
||||||
|
self.s.execute(
|
||||||
|
"update cards set type = type - 3 where type in (3,4,5) and "
|
||||||
|
"priority > 0").rowcount
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
def updatePriority(self, card):
|
def updatePriority(self, card):
|
||||||
|
@ -960,16 +995,17 @@ group by cardTags.cardId""" % limit)
|
||||||
def suspendCards(self, ids):
|
def suspendCards(self, ids):
|
||||||
self.startProgress()
|
self.startProgress()
|
||||||
self.s.statement(
|
self.s.statement(
|
||||||
"update cards set isDue=0, priority=-3, modified=:t "
|
"update cards set type = type + 3, priority=-3, modified=:t "
|
||||||
"where id in %s" % ids2str(ids), t=time.time())
|
"where type in (0,1,2) and id in %s" % ids2str(ids), t=time.time())
|
||||||
self.flushMod()
|
self.flushMod()
|
||||||
self.reset()
|
self.reset()
|
||||||
self.finishProgress()
|
self.finishProgress()
|
||||||
|
|
||||||
def unsuspendCards(self, ids):
|
def unsuspendCards(self, ids):
|
||||||
self.startProgress()
|
self.startProgress()
|
||||||
self.s.statement(
|
self.s.statement("""
|
||||||
"update cards set priority=0, modified=:t where id in %s" %
|
update cards set type = type - 3, priority=0, modified=:t
|
||||||
|
where type in (3,4,5) and id in %s""" %
|
||||||
ids2str(ids), t=time.time())
|
ids2str(ids), t=time.time())
|
||||||
self.updatePriorities(ids)
|
self.updatePriorities(ids)
|
||||||
self.flushMod()
|
self.flushMod()
|
||||||
|
@ -997,7 +1033,7 @@ select count(id) from cards where priority = 0""")
|
||||||
# Counts related to due cards
|
# Counts related to due cards
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def newCardsToday(self):
|
def newCardsDoneToday(self):
|
||||||
return (self._dailyStats.newEase0 +
|
return (self._dailyStats.newEase0 +
|
||||||
self._dailyStats.newEase1 +
|
self._dailyStats.newEase1 +
|
||||||
self._dailyStats.newEase2 +
|
self._dailyStats.newEase2 +
|
||||||
|
@ -1008,7 +1044,7 @@ select count(id) from cards where priority = 0""")
|
||||||
"Number of spaced new cards."
|
"Number of spaced new cards."
|
||||||
return self.s.scalar("""
|
return self.s.scalar("""
|
||||||
select count(cards.id) from cards where
|
select count(cards.id) from cards where
|
||||||
type = 2 and isDue = 0 and priority in (1,2,3,4) and combinedDue > :now
|
type = 2 and combinedDue > :now
|
||||||
and due < :now""", now=time.time())
|
and due < :now""", now=time.time())
|
||||||
|
|
||||||
def isEmpty(self):
|
def isEmpty(self):
|
||||||
|
@ -1993,8 +2029,9 @@ cardTags.tagId in %s""" % ids2str(ids)
|
||||||
qquery += "select id from cards where type = %d" % n
|
qquery += "select id from cards where type = %d" % n
|
||||||
elif token == "delayed":
|
elif token == "delayed":
|
||||||
qquery += ("select id from cards where "
|
qquery += ("select id from cards where "
|
||||||
"due < %d and isDue = 0 and "
|
"due < %d and combinedDue > %d and "
|
||||||
"priority in (1,2,3,4)") % time.time()
|
"type in (0,1,2)") % (
|
||||||
|
self.dueCutoff, self.dueCutoff)
|
||||||
elif token == "suspended":
|
elif token == "suspended":
|
||||||
qquery += ("select id from cards where "
|
qquery += ("select id from cards where "
|
||||||
"priority = -3")
|
"priority = -3")
|
||||||
|
@ -2003,7 +2040,7 @@ cardTags.tagId in %s""" % ids2str(ids)
|
||||||
"priority = 0")
|
"priority = 0")
|
||||||
else: # due
|
else: # due
|
||||||
qquery += ("select id from cards where "
|
qquery += ("select id from cards where "
|
||||||
"type in (0,1) and isDue = 1")
|
"type in (0,1) and combinedDue < %d") % self.dueCutoff
|
||||||
elif type == SEARCH_FID:
|
elif type == SEARCH_FID:
|
||||||
if fidquery:
|
if fidquery:
|
||||||
if isNeg:
|
if isNeg:
|
||||||
|
@ -2476,9 +2513,7 @@ select id from fields where factId not in (select id from facts)""")
|
||||||
problems.append(_("Deleted: ") + "%s %s" % tuple(card))
|
problems.append(_("Deleted: ") + "%s %s" % tuple(card))
|
||||||
self.s.flush()
|
self.s.flush()
|
||||||
if not quick:
|
if not quick:
|
||||||
# fix problems with cards being scheduled when not due
|
|
||||||
self.updateProgress()
|
self.updateProgress()
|
||||||
self.s.statement("update cards set isDue = 0")
|
|
||||||
# these sometimes end up null on upgrade
|
# these sometimes end up null on upgrade
|
||||||
self.s.statement("update models set source = 0 where source is null")
|
self.s.statement("update models set source = 0 where source is null")
|
||||||
self.s.statement(
|
self.s.statement(
|
||||||
|
@ -3399,6 +3434,9 @@ nextFactor, reps, thinkingTime, yesCount, noCount from reviewHistory""")
|
||||||
DeckStorage._addIndices(deck)
|
DeckStorage._addIndices(deck)
|
||||||
# new type handling
|
# new type handling
|
||||||
deck.rebuildTypes()
|
deck.rebuildTypes()
|
||||||
|
# per-day scheduling necessitates an increase here
|
||||||
|
deck.hardIntervalMin = 1
|
||||||
|
deck.hardIntervalMax = 1.1
|
||||||
deck.version = 44
|
deck.version = 44
|
||||||
deck.s.commit()
|
deck.s.commit()
|
||||||
# executing a pragma here is very slow on large decks, so we store
|
# executing a pragma here is very slow on large decks, so we store
|
||||||
|
|
|
@ -128,7 +128,6 @@ matureEase4 = 0,
|
||||||
yesCount = 0,
|
yesCount = 0,
|
||||||
noCount = 0,
|
noCount = 0,
|
||||||
spaceUntil = 0,
|
spaceUntil = 0,
|
||||||
isDue = 1,
|
|
||||||
type = 2,
|
type = 2,
|
||||||
combinedDue = created,
|
combinedDue = created,
|
||||||
modified = :now
|
modified = :now
|
||||||
|
|
|
@ -79,11 +79,10 @@ class DeckGraphs(object):
|
||||||
t = time.time()
|
t = time.time()
|
||||||
young = self.deck.s.all("""
|
young = self.deck.s.all("""
|
||||||
select interval, combinedDue
|
select interval, combinedDue
|
||||||
from cards where priority in (1,2,3,4) and
|
from cards where type in (0, 1) and interval <= 21""")
|
||||||
type in (0, 1) and interval <= 21""")
|
|
||||||
mature = self.deck.s.all("""
|
mature = self.deck.s.all("""
|
||||||
select interval, combinedDue
|
select interval, combinedDue
|
||||||
from cards where type = 1 and priority in (1,2,3,4) and interval > 21""")
|
from cards where type = 1 and interval > 21""")
|
||||||
|
|
||||||
for (src, dest) in [(young, daysYoung),
|
for (src, dest) in [(young, daysYoung),
|
||||||
(mature, daysMature)]:
|
(mature, daysMature)]:
|
||||||
|
|
|
@ -212,7 +212,6 @@ where factId in (%s)""" % ",".join([str(s) for s in factIds]))
|
||||||
data['tags'] = u""
|
data['tags'] = u""
|
||||||
self.cardIds.append(data['id'])
|
self.cardIds.append(data['id'])
|
||||||
data['combinedDue'] = data['due']
|
data['combinedDue'] = data['due']
|
||||||
data['isDue'] = data['combinedDue'] < time.time()
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def stripInvalid(self, cards):
|
def stripInvalid(self, cards):
|
||||||
|
|
Loading…
Reference in a new issue