From 04ff4cc3fc575e2cc37718618affa54b4983b65d Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 26 Oct 2013 10:53:15 +0900 Subject: [PATCH 1/9] make 's' translatable in stats thanks to "lumininous spice" for the heads up --- anki/stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anki/stats.py b/anki/stats.py index 8171a4ae6..7db78a411 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -356,7 +356,7 @@ group by day order by day""" % (self._limit(), lim), perMin = ngettext("%d card/minute", "%d cards/minute", perMin) % perMin self._line( i, _("Average answer time"), - "%0.1fs (%s)" % ((tot*60)/total, perMin)) + _("%(a)0.1fs (%(b)s)" % dict(a=(tot*60)/total, b=perMin))) return self._lineTbl(i), int(tot) def _splitRepData(self, data, spec): From 41a5f4eb4edf405489b0fb655f242b1b4a9420cf Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 26 Oct 2013 10:53:27 +0900 Subject: [PATCH 2/9] work around a font issue on osx10.9 --- aqt/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aqt/__init__.py b/aqt/__init__.py index 76e24bcbd..b0c1efff8 100644 --- a/aqt/__init__.py +++ b/aqt/__init__.py @@ -201,6 +201,9 @@ def run(): rd = os.path.abspath(moduleDir + "/../../..") QCoreApplication.setLibraryPaths([rd]) + if isMac: + QFont.insertSubstitution(".Lucida Grande UI", "Lucida Grande") + # create the app app = AnkiApp(sys.argv) QCoreApplication.setApplicationName("Anki") From 5f0ef85044adde4665ee9187a8d8b5e0106facb4 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 30 Oct 2013 21:10:25 +0900 Subject: [PATCH 3/9] fix reversed check in media --- anki/media.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anki/media.py b/anki/media.py index 3560278a2..d44065117 100644 --- a/anki/media.py +++ b/anki/media.py @@ -228,7 +228,7 @@ class MediaManager(object): nfcFile = unicodedata.normalize("NFC", file) # we enforce NFC fs encoding on non-macs; on macs we'll have gotten # NFD so we use the above variable for comparing references - if not isMac and local: + if not isMac and not local: if file != nfcFile: # delete if we already have the NFC form, otherwise rename if os.path.exists(nfcFile): From 3348b091d0ee86f267302549a18b98114ffe497c Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 30 Oct 2013 22:42:32 +0900 Subject: [PATCH 4/9] tweak logging - log only sched getCard(), not all getCard calls - don't log sched.today unless it's changed --- anki/collection.py | 7 ++----- anki/notes.py | 2 +- anki/sched.py | 6 +++++- aqt/browser.py | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/anki/collection.py b/anki/collection.py index 2af345bb9..4f9a92059 100644 --- a/anki/collection.py +++ b/anki/collection.py @@ -205,11 +205,8 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""", # Object creation helpers ########################################################################## - def getCard(self, id, log=True): - c = anki.cards.Card(self, id) - if log: - self.log(c, stack=1) - return c + def getCard(self, id): + return anki.cards.Card(self, id) def getNote(self, id): return anki.notes.Note(self, id=id) diff --git a/anki/notes.py b/anki/notes.py index d1f54a7b6..16be73e0a 100644 --- a/anki/notes.py +++ b/anki/notes.py @@ -69,7 +69,7 @@ insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)""", return joinFields(self.fields) def cards(self): - return [self.col.getCard(id, log=False) for id in self.col.db.list( + return [self.col.getCard(id) for id in self.col.db.list( "select id from cards where nid = ? order by ord", self.id)] def model(self): diff --git a/anki/sched.py b/anki/sched.py index 505ab47bb..12cd092ea 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -30,6 +30,7 @@ class Scheduler(object): self.queueLimit = 50 self.reportLimit = 1000 self.reps = 0 + self.today = None self._haveQueues = False self._updateCutoff() @@ -40,6 +41,7 @@ class Scheduler(object): self.reset() card = self._getCard() if card: + self.col.log(card) if not self._burySiblingsOnAnswer: self._burySiblings(card) self.reps += 1 @@ -1118,11 +1120,13 @@ did = ?, queue = %s, due = ?, mod = ?, usn = ? where id = ?""" % queue, data) ########################################################################## def _updateCutoff(self): + oldToday = self.today # days since col created self.today = int((time.time() - self.col.crt) // 86400) # end of day cutoff self.dayCutoff = self.col.crt + (self.today+1)*86400 - self.col.log(self.today, self.dayCutoff) + if oldToday != self.today: + self.col.log(self.today, self.dayCutoff) # update all daily counts, but don't save decks to prevent needless # conflicts. we'll save on card answer instead def update(g): diff --git a/aqt/browser.py b/aqt/browser.py index defe4fce9..91c4b5644 100644 --- a/aqt/browser.py +++ b/aqt/browser.py @@ -45,7 +45,7 @@ class DataModel(QAbstractTableModel): def getCard(self, index): id = self.cards[index.row()] if not id in self.cardObjs: - self.cardObjs[id] = self.col.getCard(id, log=False) + self.cardObjs[id] = self.col.getCard(id) return self.cardObjs[id] def refreshNote(self, note): From d8149910ebf7ee722791d7c928f4fa2407d945e1 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 30 Oct 2013 23:07:21 +0900 Subject: [PATCH 5/9] don't terminate review abruptly when sibs removed from queue --- anki/sched.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/anki/sched.py b/anki/sched.py index 12cd092ea..82d78414d 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -49,7 +49,6 @@ class Scheduler(object): return card def reset(self): - deck = self.col.decks.current() self._updateCutoff() self._resetLrn() self._resetRev() @@ -369,8 +368,12 @@ select id from cards where did = ? and queue = 0 limit ?""", did, lim) return True # nothing left in the deck; move to next self._newDids.pop(0) - # if count>0 but queue empty, the other cards were buried - self.newCount = 0 + if self.newCount: + # if we didn't get a card but the count is non-zero, + # we need to check again for any cards that were + # removed from the queue but not buried + self._resetNew() + return self._fillNew() def _getNewCard(self): if self._fillNew(): @@ -774,8 +777,12 @@ did = ? and queue = 2 and due <= ? limit ?""", return True # nothing left in the deck; move to next self._revDids.pop(0) - # if count>0 but queue empty, the other cards were buried - self.revCount = 0 + if self.revCount: + # if we didn't get a card but the count is non-zero, + # we need to check again for any cards that were + # removed from the queue but not buried + self._resetRev() + return self._fillRev() def _getRevCard(self): if self._fillRev(): From e5d7a69631b6c61808b291f3838a1bbff517d1f5 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Wed, 30 Oct 2013 23:28:52 +0900 Subject: [PATCH 6/9] fix an issue where non-new cards were not reset on export only happened for cards in a filtered deck --- anki/sched.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/anki/sched.py b/anki/sched.py index 82d78414d..8562cd34d 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -1359,11 +1359,17 @@ usn=:usn, mod=:mod, factor=:fact where id=:id and odid=0 and queue >=0""", def resetCards(self, ids): "Completely reset cards for export." + sids = ids2str(ids) + # we want to avoid resetting due number of existing new cards on export nonNew = self.col.db.list( "select id from cards where id in %s and (queue != 0 or type != 0)" - % ids2str(ids)) + % sids) + # reset all cards self.col.db.execute( - "update cards set reps=0, lapses=0 where id in " + ids2str(nonNew)) + "update cards set reps=0,lapses=0,odid=0,odue=0" + " where id in %s" % sids + ) + # and forget any non-new cards, changing their due numbers self.forgetCards(nonNew) self.col.log(ids) From 32147b2d762c688311e5f2ba862a2a2c9e08d10c Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 1 Nov 2013 03:09:20 +0900 Subject: [PATCH 7/9] buggy i18n def --- anki/stats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anki/stats.py b/anki/stats.py index 7db78a411..bddf6119a 100644 --- a/anki/stats.py +++ b/anki/stats.py @@ -356,7 +356,7 @@ group by day order by day""" % (self._limit(), lim), perMin = ngettext("%d card/minute", "%d cards/minute", perMin) % perMin self._line( i, _("Average answer time"), - _("%(a)0.1fs (%(b)s)" % dict(a=(tot*60)/total, b=perMin))) + _("%(a)0.1fs (%(b)s)") % dict(a=(tot*60)/total, b=perMin)) return self._lineTbl(i), int(tot) def _splitRepData(self, data, spec): From 1f3a57104cf7551474a4778692bb59c42fe94636 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 1 Nov 2013 17:32:02 +0900 Subject: [PATCH 8/9] fix new cards not being shown in new order --- anki/sched.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anki/sched.py b/anki/sched.py index 8562cd34d..790a494bf 100644 --- a/anki/sched.py +++ b/anki/sched.py @@ -362,7 +362,7 @@ did = ? and queue = 0 limit ?)""", did, lim) if lim: # fill the queue with the current did self._newQueue = self.col.db.list(""" -select id from cards where did = ? and queue = 0 limit ?""", did, lim) +select id from cards where did = ? and queue = 0 order by due limit ?""", did, lim) if self._newQueue: self._newQueue.reverse() return True From 6d69c5e292747cf305b8cad495f4185fb9b6455a Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 1 Nov 2013 18:19:30 +0900 Subject: [PATCH 9/9] bump version --- anki/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/anki/__init__.py b/anki/__init__.py index a789cc53f..ac63909cc 100644 --- a/anki/__init__.py +++ b/anki/__init__.py @@ -2,7 +2,9 @@ # Copyright: Damien Elmes # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html -import sys, os, platform +import sys +import os +import platform if sys.version_info[0] > 2: raise Exception("Anki should be run with Python 2") @@ -28,6 +30,6 @@ if arch[1] == "ELF": sys.path.insert(0, os.path.join(ext, "py2.%d-%s" % ( sys.version_info[1], arch[0][0:2]))) -version="2.0.15" # build scripts grep this line, so preserve formatting +version="2.0.16" # build scripts grep this line, so preserve formatting from anki.storage import Collection __all__ = ["Collection"]