diff --git a/anki/importing/anki2.py b/anki/importing/anki2.py index 0b41ad804..7ccd8835b 100644 --- a/anki/importing/anki2.py +++ b/anki/importing/anki2.py @@ -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: diff --git a/anki/models.py b/anki/models.py index e6ca38c67..e4044875d 100644 --- a/anki/models.py +++ b/anki/models.py @@ -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 diff --git a/anki/upgrade.py b/anki/upgrade.py index 259720586..4434ec541 100644 --- a/anki/upgrade.py +++ b/anki/upgrade.py @@ -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] diff --git a/tests/support/diffmodels1.anki b/tests/support/diffmodels1.anki new file mode 100644 index 000000000..aa2103b05 Binary files /dev/null and b/tests/support/diffmodels1.anki differ diff --git a/tests/support/diffmodels2.anki b/tests/support/diffmodels2.anki new file mode 100644 index 000000000..0f921c90a Binary files /dev/null and b/tests/support/diffmodels2.anki differ diff --git a/tests/test_importing.py b/tests/test_importing.py index a40e68bb2..023996b3f 100644 --- a/tests/test_importing.py +++ b/tests/test_importing.py @@ -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"))