From 2243b691cc102c17269bf66d300dd8016905457b Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sun, 17 Apr 2011 08:04:02 +0900 Subject: [PATCH] add full search to ignore formatting --- anki/deck.py | 4 ++-- anki/find.py | 28 +++++++++++++++++++++------- tests/test_find.py | 9 +++++++++ 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/anki/deck.py b/anki/deck.py index e1b57cf12..367fbafab 100644 --- a/anki/deck.py +++ b/anki/deck.py @@ -638,8 +638,8 @@ update facts set tags = :t, mod = :n where id = :id""", [fix(row) for row in res # Finding cards ########################################################################## - def findCards(self, query): - return anki.find.Finder(self).findCards(query) + def findCards(self, query, full=False): + return anki.find.Finder(self).findCards(query, full) def findReplace(self, fids, src, dst, regex=None, field=None, fold=True): return anki.find.findReplace(self, fids, src, dst, regex, field, fold) diff --git a/anki/find.py b/anki/find.py index 3086fd6a2..fe8afcd8e 100644 --- a/anki/find.py +++ b/anki/find.py @@ -3,7 +3,7 @@ # License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import re -from anki.utils import ids2str, splitFields, joinFields +from anki.utils import ids2str, splitFields, joinFields, stripHTML SEARCH_TAG = 0 SEARCH_TYPE = 1 @@ -37,9 +37,10 @@ class Finder(object): def __init__(self, deck): self.deck = deck - def findCards(self, query): + def findCards(self, query, full=False): "Return a list of card ids for QUERY." self.query = query + self.full = full self._findLimits() if not self.lims['valid']: return [] @@ -161,9 +162,19 @@ order by %s""" % (lim, sort) def _findText(self, val, neg, c): val = val.replace("*", "%") extra = "not" if neg else "" - self.lims['args']["_text_%d"%c] = "%"+val+"%" - self.lims['fact'].append("flds %s like :_text_%d escape '\\'" % ( - extra, c)) + if not self.full: + self.lims['args']["_text_%d"%c] = "%"+val+"%" + self.lims['fact'].append("flds %s like :_text_%d escape '\\'" % ( + extra, c)) + else: + # in the future we may want to apply this at the end to speed up + # the case where there are other limits + fids = [] + for fid, flds in self.deck.db.execute( + "select id, flds from facts"): + if val in stripHTML(flds): + fids.append(fid) + self.lims['fact'].append("id in " + ids2str(fids)) def _findFids(self, val): self.lims['fact'].append("id in (%s)" % val) @@ -229,10 +240,13 @@ order by %s""" % (lim, sort) select id, mid, flds from facts where mid in %s and flds like ? escape '\\'""" % ( ids2str(mods.keys())), - value): + "%" if self.full else value): flds = splitFields(flds) ord = mods[mid][1] - if re.search(regex, flds[ord]): + str = flds[ord] + if self.full: + str = stripHTML(str) + if re.search(regex, str): fids.append(id) extra = "not" if isNeg else "" self.lims['fact'].append("id %s in %s" % (extra, ids2str(fids))) diff --git a/tests/test_find.py b/tests/test_find.py index 8fad54e2b..0434b5985 100644 --- a/tests/test_find.py +++ b/tests/test_find.py @@ -101,6 +101,15 @@ def test_findCards(): assert len(deck.findCards("group:default")) == 5 assert len(deck.findCards("-group:default")) == 0 assert len(deck.findCards("-group:foo")) == 5 + # full search + f = deck.newFact() + f['Front'] = u'helloworld' + f['Back'] = u'' + deck.addFact(f) + assert len(deck.findCards("helloworld")) == 0 + assert len(deck.findCards("helloworld", full=True)) == 1 + assert len(deck.findCards("front:helloworld")) == 0 + assert len(deck.findCards("front:helloworld", full=True)) == 1 def test_findReplace(): deck = getEmptyDeck()