mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
more robust anki1 upgrading & anki2 importing
- base the 2.0 model id on the 1.2 one so we don't get new models each time we reimport the file - when determining if we can reuse an existing note, it must have the same model id, and the model must have the same schema - make sure we check templates when determining schema - if schema has diverged, note needs new guid
This commit is contained in:
parent
6830ca99d9
commit
bd1c6d4395
6 changed files with 47 additions and 9 deletions
|
@ -4,7 +4,7 @@
|
|||
|
||||
import os
|
||||
from anki import Collection
|
||||
from anki.utils import intTime, splitFields, joinFields, checksum
|
||||
from anki.utils import intTime, splitFields, joinFields, checksum, guid64
|
||||
from anki.importing.base import Importer
|
||||
from anki.lang import _
|
||||
from anki.lang import ngettext
|
||||
|
@ -96,8 +96,24 @@ class Anki2Importer(Importer):
|
|||
# turn the db result into a mutable list
|
||||
note = list(note)
|
||||
guid, mid = note[1:3]
|
||||
# missing from local col?
|
||||
if guid not in self._notes:
|
||||
duplicate = False
|
||||
guidChange = False
|
||||
# do we have the same guid?
|
||||
if guid in self._notes:
|
||||
# and do they share the same model id?
|
||||
if self._notes[guid][2] == mid:
|
||||
# and do they share the same schema?
|
||||
srcM = self.src.models.get(mid)
|
||||
dstM = self.dst.models.get(self._notes[guid][2])
|
||||
if (self.src.models.scmhash(srcM) ==
|
||||
self.src.models.scmhash(dstM)):
|
||||
# then it's safe to treat as a duplicate
|
||||
duplicate = True
|
||||
if not duplicate:
|
||||
# not identical models, so we need to change guid
|
||||
guidChange = True
|
||||
# missing from local col or divergent model?
|
||||
if not duplicate:
|
||||
# get corresponding local model
|
||||
lmid = self._mid(mid)
|
||||
# ensure id is unique
|
||||
|
@ -111,11 +127,14 @@ class Anki2Importer(Importer):
|
|||
note[6] = self._mungeMedia(mid, note[6])
|
||||
add.append(note)
|
||||
dirty.append(note[0])
|
||||
# if it was originally the same as a note in this deck but the
|
||||
# models have diverged, we need to change the guid
|
||||
if guidChange:
|
||||
guid = guid64()
|
||||
# note we have the added note
|
||||
self._notes[guid] = (note[0], note[3], note[2])
|
||||
else:
|
||||
dupes += 1
|
||||
pass
|
||||
## update existing note - not yet tested; for post 2.0
|
||||
# newer = note[3] > mod
|
||||
# if self.allowUpdate and self._mid(mid) == mid and newer:
|
||||
|
|
|
@ -452,6 +452,8 @@ select id from notes where mid = ?)""" % " ".join(map),
|
|||
s = ""
|
||||
for f in m['flds']:
|
||||
s += f['name']
|
||||
for t in m['tmpls']:
|
||||
s += t['name']
|
||||
return fieldChecksum(s)
|
||||
|
||||
# Required field/text cache
|
||||
|
|
|
@ -341,11 +341,8 @@ insert or replace into col select id, cast(created as int), :t,
|
|||
mods = {}
|
||||
for row in db.all(
|
||||
"select id, name from models"):
|
||||
while 1:
|
||||
t = intTime(1000)
|
||||
if t not in times:
|
||||
times[t] = True
|
||||
break
|
||||
# use only first 31 bits
|
||||
t = abs(row[0]) >> 32
|
||||
m = anki.models.defaultModel.copy()
|
||||
m['id'] = t
|
||||
m['name'] = row[1]
|
||||
|
|
BIN
tests/support/diffmodels1.anki
Normal file
BIN
tests/support/diffmodels1.anki
Normal file
Binary file not shown.
BIN
tests/support/diffmodels2.anki
Normal file
BIN
tests/support/diffmodels2.anki
Normal file
Binary file not shown.
|
@ -138,6 +138,26 @@ def test_anki1():
|
|||
imp.run()
|
||||
check()
|
||||
|
||||
def test_anki1_diffmodels():
|
||||
# create a new empty deck
|
||||
dst = getEmptyDeck()
|
||||
# import the 1 card version of the model
|
||||
tmp = getUpgradeDeckPath("diffmodels1.anki")
|
||||
imp = Anki1Importer(dst, tmp)
|
||||
imp.run()
|
||||
before = dst.noteCount()
|
||||
# repeating the process should do nothing
|
||||
imp = Anki1Importer(dst, tmp)
|
||||
imp.run()
|
||||
assert before == dst.noteCount()
|
||||
# then the 2 card version
|
||||
tmp = getUpgradeDeckPath("diffmodels2.anki")
|
||||
imp = Anki1Importer(dst, tmp)
|
||||
imp.run()
|
||||
after = dst.noteCount()
|
||||
# as the model schemas differ, should have been imported as new model
|
||||
assert after == before + 1
|
||||
|
||||
def test_csv():
|
||||
deck = getEmptyDeck()
|
||||
file = unicode(os.path.join(testDir, "support/text-2fields.txt"))
|
||||
|
|
Loading…
Reference in a new issue