allow updates to existing notes in .apkg import
This commit is contained in:
parent
f6c19ca0b4
commit
914f56dbc0
@ -9,8 +9,9 @@ from anki.importing.base import Importer
|
||||
from anki.lang import _
|
||||
from anki.lang import ngettext
|
||||
|
||||
MID = 2
|
||||
GUID = 1
|
||||
MID = 2
|
||||
MOD = 3
|
||||
|
||||
class Anki2Importer(Importer):
|
||||
|
||||
@ -63,6 +64,7 @@ class Anki2Importer(Importer):
|
||||
self._changedGuids = {}
|
||||
# iterate over source collection
|
||||
add = []
|
||||
update = []
|
||||
dirty = []
|
||||
usn = self.dst.usn()
|
||||
dupes = 0
|
||||
@ -85,22 +87,35 @@ class Anki2Importer(Importer):
|
||||
# note we have the added the guid
|
||||
self._notes[note[GUID]] = (note[0], note[3], note[MID])
|
||||
else:
|
||||
# a duplicate or changed schema - safe to update?
|
||||
dupes += 1
|
||||
## update existing note - not yet tested; for post 2.0
|
||||
# newer = note[3] > mod
|
||||
# if self.allowUpdate and self._mid(mid) == mid and newer:
|
||||
# localNid = self._notes[guid][0]
|
||||
# note[0] = localNid
|
||||
# note[4] = usn
|
||||
# add.append(note)
|
||||
# dirty.append(note[0])
|
||||
if self.allowUpdate and note[GUID] in self._notes:
|
||||
oldNid, oldMod, oldMid = self._notes[note[GUID]]
|
||||
# safe if note types identical
|
||||
if oldMid == note[MID]:
|
||||
# will update if incoming note more recent
|
||||
if oldMod < note[MOD]:
|
||||
# incoming note should use existing id
|
||||
note[0] = oldNid
|
||||
note[4] = usn
|
||||
note[6] = self._mungeMedia(note[MID], note[6])
|
||||
update.append(note)
|
||||
dirty.append(note[0])
|
||||
if dupes:
|
||||
self.log.append(_("Already in collection: %s.") % (ngettext(
|
||||
"%d note", "%d notes", dupes) % dupes))
|
||||
up = len(update)
|
||||
self.log.append(_("Updated %(a)d of %(b)d existing notes.") % dict(
|
||||
a=len(update), b=dupes))
|
||||
# export info for calling code
|
||||
self.dupes = dupes
|
||||
self.added = len(add)
|
||||
self.updated = len(update)
|
||||
# add to col
|
||||
self.dst.db.executemany(
|
||||
"insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)",
|
||||
add)
|
||||
self.dst.db.executemany(
|
||||
"insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)",
|
||||
update)
|
||||
self.dst.updateFieldCache(dirty)
|
||||
self.dst.tags.registerNotes(dirty)
|
||||
|
||||
|
BIN
tests/support/update1.apkg
Normal file
BIN
tests/support/update1.apkg
Normal file
Binary file not shown.
BIN
tests/support/update2.apkg
Normal file
BIN
tests/support/update2.apkg
Normal file
Binary file not shown.
@ -163,7 +163,6 @@ def test_anki1_diffmodels():
|
||||
assert after == before + 1
|
||||
assert beforeModels == len(dst.models.all())
|
||||
|
||||
|
||||
def test_suspended():
|
||||
# create a new empty deck
|
||||
dst = getEmptyDeck()
|
||||
@ -205,6 +204,33 @@ def test_anki2_diffmodels():
|
||||
assert after == before + 1
|
||||
assert dst.cardCount() == 3
|
||||
|
||||
def test_anki2_updates():
|
||||
# create a new empty deck
|
||||
dst = getEmptyDeck()
|
||||
tmp = getUpgradeDeckPath("update1.apkg")
|
||||
imp = AnkiPackageImporter(dst, tmp)
|
||||
imp.run()
|
||||
assert imp.dupes == 0
|
||||
assert imp.added == 1
|
||||
assert imp.updated == 0
|
||||
# importing again should be idempotent
|
||||
imp = AnkiPackageImporter(dst, tmp)
|
||||
imp.run()
|
||||
assert imp.dupes == 1
|
||||
assert imp.added == 0
|
||||
assert imp.updated == 0
|
||||
# importing a newer note should update
|
||||
assert dst.noteCount() == 1
|
||||
assert dst.db.scalar("select flds from notes").startswith("hello")
|
||||
tmp = getUpgradeDeckPath("update2.apkg")
|
||||
imp = AnkiPackageImporter(dst, tmp)
|
||||
imp.run()
|
||||
assert imp.dupes == 1
|
||||
assert imp.added == 0
|
||||
assert imp.updated == 1
|
||||
assert dst.noteCount() == 1
|
||||
assert dst.db.scalar("select flds from notes").startswith("goodbye")
|
||||
|
||||
def test_csv():
|
||||
deck = getEmptyDeck()
|
||||
file = unicode(os.path.join(testDir, "support/text-2fields.txt"))
|
||||
|
Loading…
Reference in New Issue
Block a user