mirror of
https://github.com/ankitects/anki.git
synced 2025-09-24 00:36:38 -04:00
add ability to update fields when importing
This commit is contained in:
parent
dd00d1a5e1
commit
e3dd736460
3 changed files with 119 additions and 1 deletions
|
@ -18,8 +18,8 @@ from anki.cards import cardsTable
|
|||
from anki.facts import factsTable, fieldsTable
|
||||
from anki.lang import _
|
||||
from anki.utils import genID, canonifyTags
|
||||
from anki.utils import canonifyTags, ids2str
|
||||
from anki.errors import *
|
||||
from anki.utils import canonifyTags
|
||||
from anki.deck import NEW_CARDS_RANDOM
|
||||
|
||||
# Base importer
|
||||
|
@ -35,6 +35,9 @@ class Importer(object):
|
|||
|
||||
needMapper = True
|
||||
tagDuplicates = False
|
||||
# if set, update instead of regular importing
|
||||
# (foreignCardFieldIndex, fieldModelId)
|
||||
updateKey = None
|
||||
multipleCardsAllowed = True
|
||||
needDelimiter = False
|
||||
|
||||
|
@ -49,6 +52,8 @@ class Importer(object):
|
|||
|
||||
def doImport(self):
|
||||
"Import. Caller must .reset()"
|
||||
if self.updateKey is not None:
|
||||
return self.doUpdate()
|
||||
random = self.deck.newCardOrder == NEW_CARDS_RANDOM
|
||||
num = 7
|
||||
if random:
|
||||
|
@ -68,6 +73,85 @@ class Importer(object):
|
|||
if c:
|
||||
self.deck.setModified()
|
||||
|
||||
def doUpdate(self):
|
||||
self.deck.startProgress(8)
|
||||
# grab the data from the external file
|
||||
self.deck.updateProgress(_("Updating..."))
|
||||
cards = self.foreignCards()
|
||||
# grab data from db
|
||||
self.deck.updateProgress()
|
||||
fields = self.deck.s.all("""
|
||||
select factId, value from fields where fieldModelId = :id
|
||||
and value != ''""",
|
||||
id=self.updateKey[1])
|
||||
# hash it
|
||||
self.deck.updateProgress()
|
||||
vhash = {}
|
||||
fids = []
|
||||
for (fid, val) in fields:
|
||||
fids.append(fid)
|
||||
vhash[val] = fid
|
||||
# prepare tags
|
||||
tagsIdx = None
|
||||
try:
|
||||
tagsIdx = self.mapping.index(0)
|
||||
for c in cards:
|
||||
c.tags = canonifyTags(self.tagsToAdd + " " + c.fields[tagsIdx])
|
||||
except ValueError:
|
||||
pass
|
||||
# look for matches
|
||||
self.deck.updateProgress()
|
||||
upcards = []
|
||||
newcards = []
|
||||
for c in cards:
|
||||
v = c.fields[self.updateKey[0]]
|
||||
if v in vhash:
|
||||
# ignore empty keys
|
||||
if v:
|
||||
# fid, card
|
||||
upcards.append((vhash[v], c))
|
||||
else:
|
||||
newcards.append(c)
|
||||
# update fields
|
||||
for fm in self.model.fieldModels:
|
||||
if fm.id == self.updateKey[1]:
|
||||
# don't update key
|
||||
continue
|
||||
try:
|
||||
index = self.mapping.index(fm)
|
||||
except ValueError:
|
||||
# not mapped
|
||||
continue
|
||||
data = [{'fid': fid,
|
||||
'fmid': fm.id,
|
||||
'v': c.fields[index]}
|
||||
for (fid, c) in upcards]
|
||||
self.deck.s.execute("""
|
||||
update fields set value = :v where factId = :fid and fieldModelId = :fmid""",
|
||||
data)
|
||||
# update tags
|
||||
self.deck.updateProgress()
|
||||
if tagsIdx:
|
||||
data = [{'factId': fid,
|
||||
'tags': c.fields[tagsIdx]}
|
||||
for (fid, c) in upcards]
|
||||
self.deck.s.execute(
|
||||
"update facts set tags = :t where id = :fid",
|
||||
data)
|
||||
# rebuild caches
|
||||
self.deck.updateProgress()
|
||||
cids = self.deck.s.column0(
|
||||
"select id from cards where factId in %s" %
|
||||
ids2str(fids))
|
||||
self.deck.updateCardTags(cids)
|
||||
self.deck.updateProgress()
|
||||
self.deck.updatePriorities(cids)
|
||||
self.deck.updateProgress()
|
||||
self.deck.updateCardsFromFactIds(fids)
|
||||
self.total = len(fids)
|
||||
self.deck.setModified()
|
||||
self.deck.finishProgress()
|
||||
|
||||
def fields(self):
|
||||
"The number of fields."
|
||||
return 0
|
||||
|
|
11
tests/importing/text-update.txt
Normal file
11
tests/importing/text-update.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
# this is a test file
|
||||
|
||||
食べる to ate
|
||||
む to drink
|
||||
テスト testing
|
||||
to eat 食べる
|
||||
飲む to drink
|
||||
多すぎる too many fields
|
||||
not, enough, fields
|
||||
遊ぶ
|
||||
to play
|
|
@ -114,3 +114,26 @@ def test_dingsbums():
|
|||
i.doImport()
|
||||
assert 7 == i.total
|
||||
deck.s.close()
|
||||
|
||||
def test_updating():
|
||||
# get the standard csv deck first
|
||||
deck = DeckStorage.Deck()
|
||||
deck.addModel(BasicModel())
|
||||
file = unicode(os.path.join(testDir, "importing/text-2fields.txt"))
|
||||
i = csvfile.TextImporter(deck, file)
|
||||
i.doImport()
|
||||
# now update
|
||||
file = unicode(os.path.join(testDir, "importing/text-update.txt"))
|
||||
i = csvfile.TextImporter(deck, file)
|
||||
# first field
|
||||
i.updateKey = (0, deck.currentModel.fieldModels[0].id)
|
||||
i.multipleCardsAllowed = False
|
||||
i.doImport()
|
||||
ans = deck.s.scalar(
|
||||
u"select answer from cards where question like '%食べる%'")
|
||||
assert "to ate" in ans
|
||||
# try again with tags
|
||||
i.updateKey = (0, deck.currentModel.fieldModels[0].id)
|
||||
i.mapping[1] = 0
|
||||
i.doImport()
|
||||
deck.s.close()
|
||||
|
|
Loading…
Reference in a new issue