diff --git a/anki/deck.py b/anki/deck.py index 8c691988a..96843daf0 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -620,6 +620,41 @@ select conf from gconf where id = (select gcid from groups where id = ?)""", def setActiveGroups(self, type, list): self.qconf[type+"Groups"] = list + def setGroup(self, cids, gid): + self.db.execute( + "update cards set gid = ? where id in "+ids2str(cids), gid) + + # Tag-based selective study + ########################################################################## + + def selTagFids(self, yes, no): + l = [] + # find facts that match yes + lim = "" + args = [] + query = "select id from facts" + if not yes and not no: + pass + else: + if yes: + lim += " or ".join(["tags like ?" for t in yes]) + args += ['%% %s %%' % t for t in yes] + if no: + lim2 = " and ".join(["tags not like ?" for t in no]) + if lim: + lim = "(%s) and %s" % (lim, lim2) + else: + lim = lim2 + args += ['%% %s %%' % t for t in no] + query += " where " + lim + return self.db.list(query, *args) + + def setGroupForTags(self, yes, no, gid): + fids = self.selTagFids(yes, no) + self.db.execute( + "update cards set gid = ? where fid in "+ids2str(fids), + gid) + # Finding cards ########################################################################## diff --git a/anki/facts.py b/anki/facts.py index 4fb5278af..bf73f06b6 100644 --- a/anki/facts.py +++ b/anki/facts.py @@ -5,7 +5,7 @@ import time from anki.errors import AnkiError from anki.utils import stripHTMLMedia, fieldChecksum, intTime, \ - addTags, delTags, joinFields, splitFields, ids2str, parseTags + joinFields, splitFields, ids2str, parseTags, joinTags, hasTag class Fact(object): @@ -22,7 +22,7 @@ class Fact(object): self.mid = model.id self.crt = intTime() self.mod = self.crt - self.tags = "" + self.tags = [] self._fields = [""] * len(self._model.fields) self.data = "" self._fmap = self._model.fieldMap() @@ -37,20 +37,22 @@ class Fact(object): self.data) = self.deck.db.first(""" select mid, gid, crt, mod, tags, flds, data from facts where id = ?""", self.id) self._fields = splitFields(self._fields) + self.tags = parseTags(self.tags) self._model = self.deck.getModel(self.mid) def flush(self): self.mod = intTime() # facts table sfld = self._fields[self._model.sortIdx()] + tags = joinTags(self.tags) res = self.deck.db.execute(""" insert or replace into facts values (?, ?, ?, ?, ?, ?, ?, ?, ?)""", self.id, self.mid, self.gid, self.crt, - self.mod, self.tags, self.joinedFields(), + self.mod, tags, self.joinedFields(), sfld, self.data) self.id = res.lastrowid self.updateFieldChecksums() - self.deck.registerTags(parseTags(self.tags)) + self.deck.registerTags(self.tags) def joinedFields(self): return joinFields(self._fields) @@ -102,11 +104,8 @@ insert or replace into facts values (?, ?, ?, ?, ?, ?, ?, ?, ?)""", # Tags ################################################## - def addTags(self, tags): - self.tags = addTags(tags, self.tags) - - def delTags(self, tags): - self.tags = delTags(tags, self.tags) + def hasTag(self, tag): + return hasTag(tag, self.tags) # Unique/duplicate checks ################################################## diff --git a/anki/models.py b/anki/models.py index 5757a3fb4..d9181fa03 100644 --- a/anki/models.py +++ b/anki/models.py @@ -35,7 +35,7 @@ defaultTemplate = { 'hideQ': False, 'align': 0, 'bg': "#000", - 'emptyAns': None, + 'emptyAns': True, 'typeAns': None, 'gid': None } diff --git a/tests/test_deck.py b/tests/test_deck.py index 81b5c7a66..23d91861c 100644 --- a/tests/test_deck.py +++ b/tests/test_deck.py @@ -148,3 +148,27 @@ def test_groups(): # set new cards to only 'another group' deck.setActiveGroups('new', [3]) assert deck.activeGroups('new') == [3] + +def test_selective(): + deck = getEmptyDeck() + f = deck.newFact() + f['Front'] = u"1"; f.tags = ["one", "three"] + deck.addFact(f) + f = deck.newFact() + f['Front'] = u"2"; f.tags = ["two", "three", "four"] + deck.addFact(f) + f = deck.newFact() + f['Front'] = u"3"; f.tags = ["one", "two", "three", "four"] + deck.addFact(f) + assert len(deck.selTagFids(["one"], [])) == 2 + assert len(deck.selTagFids(["three"], [])) == 3 + assert len(deck.selTagFids([], ["three"])) == 0 + assert len(deck.selTagFids(["one"], ["three"])) == 0 + assert len(deck.selTagFids(["one"], ["two"])) == 1 + assert len(deck.selTagFids(["two", "three"], [])) == 3 + assert len(deck.selTagFids(["two", "three"], ["one"])) == 1 + assert len(deck.selTagFids(["one", "three"], ["two", "four"])) == 1 + deck.setGroupForTags(["three"], [], 3) + assert deck.db.scalar("select count() from cards where gid = 3") == 3 + deck.setGroupForTags(["one"], [], 2) + assert deck.db.scalar("select count() from cards where gid = 2") == 2 diff --git a/tests/test_find.py b/tests/test_find.py index 6239de11b..736330e4f 100644 --- a/tests/test_find.py +++ b/tests/test_find.py @@ -7,12 +7,12 @@ def test_findCards(): f = deck.newFact() f['Front'] = u'dog' f['Back'] = u'cat' - f.addTags(u"monkey") + f.tags.append(u"monkey") deck.addFact(f) f = deck.newFact() f['Front'] = u'goats are fun' f['Back'] = u'sheep' - f.addTags(u"sheep goat horse") + f.tags.append(u"sheep goat horse") deck.addFact(f) f = deck.newFact() f['Front'] = u'cat'