diff --git a/anki/cram.py b/anki/cram.py index 7fe0ecdd1..9247ab36e 100644 --- a/anki/cram.py +++ b/anki/cram.py @@ -2,117 +2,23 @@ # Copyright: Damien Elmes # License: GNU GPL, version 3 or later; http://www.gnu.org/copyleft/gpl.html +from anki.utils import ids2str from anki.sched import Scheduler class CramScheduler(Scheduler): + name = "cram" - # Cramming - ########################################################################## + def __init__(self, deck, gids, order): + Scheduler.__init__(self, deck) + self.gids = gids + self.order = order + self.reset() - def setupCramScheduler(self, active, order): - self.getCardId = self._getCramCardId - self.activeCramTags = active - self.cramOrder = order - self.rebuildNewCount = self._rebuildCramNewCount - self.rebuildRevCount = self._rebuildCramCount - self.rebuildLrnCount = self._rebuildLrnCramCount - self.fillRevQueue = self._fillCramQueue - self.fillLrnQueue = self._fillLrnCramQueue - self.finishScheduler = self.setupStandardScheduler - self.lrnCramQueue = [] - print "requeue cram" - self.requeueCard = self._requeueCramCard - self.cardQueue = self._cramCardQueue - self.answerCard = self._answerCramCard - self.spaceCards = self._spaceCramCards - # reuse review early's code - self.answerPreSave = self._cramPreSave - self.cardLimit = self._cramCardLimit - self.scheduler = "cram" + def reset(self): + pass - def _cramPreSave(self, card, ease): - # prevent it from appearing in next queue fill - card.lastInterval = self.cramLastInterval - card.type = -3 + def getCard(self): + pass - def _spaceCramCards(self, card): - self.spacedFacts[card.factId] = time.time() + self.newSpacing - - def _answerCramCard(self, card, ease): - self.cramLastInterval = card.lastInterval - self._answerCard(card, ease) - if ease == 1: - self.lrnCramQueue.insert(0, [card.id, card.factId]) - - def _getCramCardId(self, check=True): - self.checkDay() - self.fillQueues() - if self.lrnCardMax and self.learnCount >= self.lrnCardMax: - return self.lrnQueue[-1][0] - # card due for review? - if self.revNoSpaced(): - return self.revQueue[-1][0] - if self.lrnQueue: - return self.lrnQueue[-1][0] - if check: - # collapse spaced cards before reverting back to old scheduler - self.reset() - return self.getCardId(False) - # if we're in a custom scheduler, we may need to switch back - if self.finishScheduler: - self.finishScheduler() - self.reset() - return self.getCardId() - - def _cramCardQueue(self, card): - if self.revQueue and self.revQueue[-1][0] == card.id: - return 1 - else: - return 0 - - def _requeueCramCard(self, card, oldSuc): - if self.cardQueue(card) == 1: - self.revQueue.pop() - else: - self.lrnCramQueue.pop() - - def _rebuildCramNewCount(self): - self.newAvail = 0 - self.newCount = 0 - - def _cramCardLimit(self, active, inactive, sql): - # inactive is (currently) ignored - if isinstance(active, list): - return sql.replace( - "where", "where +c.id in " + ids2str(active) + " and") - else: - yes = parseTags(active) - if yes: - yids = tagIds(self.db, yes).values() - return sql.replace( - "where ", - "where +c.id in (select cardId from cardTags where " - "tagId in %s) and " % ids2str(yids)) - else: - return sql - - def _fillCramQueue(self): - if self.revCount and not self.revQueue: - self.revQueue = self.db.all(self.cardLimit( - self.activeCramTags, "", """ -select id, factId from cards c -where queue between 0 and 2 -order by %s -limit %s""" % (self.cramOrder, self.queueLimit))) - self.revQueue.reverse() - - def _rebuildCramCount(self): - self.revCount = self.db.scalar(self.cardLimit( - self.activeCramTags, "", - "select count(*) from cards c where queue between 0 and 2")) - - def _rebuildLrnCramCount(self): - self.learnCount = len(self.lrnCramQueue) - - def _fillLrnCramQueue(self): - self.lrnQueue = self.lrnCramQueue + def answerCard(self): + pass diff --git a/anki/deck.py b/anki/deck.py index f2ba167ed..d085cf7c6 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -14,7 +14,7 @@ from anki.media import MediaRegistry from anki.consts import * import anki.latex # sets up hook -import anki.cards, anki.facts, anki.models, anki.template +import anki.cards, anki.facts, anki.models, anki.template, anki.cram # Settings related to queue building. These may be loaded without the rest of # the config to check due counts faster on mobile clients. @@ -72,7 +72,8 @@ class _Deck(object): self.lastSessionStart = 0 # counter for reps since deck open self.reps = 0 - self.sched = Scheduler(self) + self._stdSched = Scheduler(self) + self.sched = self._stdSched self.media = MediaRegistry(self) def name(self): @@ -714,6 +715,18 @@ select conf from gconf where id = (select gcid from groups where id = ?)""", self.disableSyncing() return True + # Schedulers and cramming + ########################################################################## + + def stdSched(self): + if self.sched.name != "std": + self.sched.onClose() + self.sched = self._stdSched + + def cramGroups(self, gids, order="mod"): + self.stdSched() + self.sched = anki.cram.CramScheduler(self, gids, order) + # Undo/redo ########################################################################## diff --git a/anki/sched.py b/anki/sched.py index 164635c19..49bc8002c 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -13,10 +13,10 @@ from anki.hooks import runHook # the standard Anki scheduler class Scheduler(object): + name = "std" def __init__(self, deck): self.deck = deck self.db = deck.db - self.name = "main" self.queueLimit = 200 self.reportLimit = 1000 self._updateCutoff() @@ -274,7 +274,7 @@ queue = 1 %s and due <= :lim limit %d)""" % ( def _resetReview(self): self._resetReviewCount() - self.revQueue = self.db.all(""" + self.revQueue = self.db.list(""" select id from cards where queue = 1 %s and due <= :lim order by %s limit %d""" % ( self._groupLimit("rev"), self._revOrder(), self.queueLimit), diff --git a/tests/test_sched.py b/tests/test_sched.py index 3a9b87921..a17fc8c18 100644 --- a/tests/test_sched.py +++ b/tests/test_sched.py @@ -300,3 +300,15 @@ def test_misc(): d.sched.answerCard(c, 2) assert d.sched.timeToday() > 0 assert d.sched.repsToday() == 1 + +def test_cram(): + d = getEmptyDeck() + f = d.newFact() + f['Front'] = u"one" + d.addFact(f) + f = d.newFact() + f['Front'] = u"two" + d.addFact(f) + d.cramGroups(1) + +