mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
refactor model copying
This commit is contained in:
parent
b1bf50c677
commit
cbdb283b20
3 changed files with 51 additions and 34 deletions
|
@ -22,10 +22,10 @@ class Anki2Importer(Importer):
|
|||
needMapper = False
|
||||
groupPrefix = None
|
||||
needCards = True
|
||||
flagModels = False
|
||||
|
||||
def run(self, media=None):
|
||||
self.dst = self.deck
|
||||
self.src = Deck(self.file, queue=False)
|
||||
self._prepareDecks()
|
||||
if media is not None:
|
||||
# Anki1 importer has provided us with a custom media folder
|
||||
self.src.media._dir = media
|
||||
|
@ -34,6 +34,10 @@ class Anki2Importer(Importer):
|
|||
finally:
|
||||
self.src.close(save=False)
|
||||
|
||||
def _prepareDecks(self):
|
||||
self.dst = self.deck
|
||||
self.src = Deck(self.file, queue=False)
|
||||
|
||||
def _import(self):
|
||||
self._groups = {}
|
||||
self._prepareTS()
|
||||
|
@ -91,34 +95,44 @@ class Anki2Importer(Importer):
|
|||
|
||||
def _prepareModels(self):
|
||||
"Prepare index of schema hashes."
|
||||
self._srcModels = {}
|
||||
self._dstModels = {}
|
||||
self._dstHashes = {}
|
||||
for m in self.dst.models.all():
|
||||
h = self.dst.models.scmhash(m)
|
||||
mid = int(m['id'])
|
||||
self._dstHashes[h] = mid
|
||||
self._dstModels[mid] = h
|
||||
for m in self.src.models.all():
|
||||
mid = int(m['id'])
|
||||
self._srcModels[mid] = self.src.models.scmhash(m)
|
||||
self._modelMap = {}
|
||||
|
||||
def _mid(self, mid):
|
||||
"Return local id for remote MID."
|
||||
hash = self._srcModels[mid]
|
||||
dmid = self._dstHashes.get(hash)
|
||||
if dmid:
|
||||
# dst deck already has this model
|
||||
return dmid
|
||||
# need to add to local and update index
|
||||
m = self.dst.models._add(self.src.models.get(mid))
|
||||
# need to save so the css is updated
|
||||
self.dst.models.save(m)
|
||||
h = self.dst.models.scmhash(m)
|
||||
mid = int(m['id'])
|
||||
self._dstModels[mid] = h
|
||||
self._dstHashes[h] = mid
|
||||
return mid
|
||||
# already processed this mid?
|
||||
if mid in self._modelMap:
|
||||
return self._modelMap[mid]
|
||||
src = self.src.models.get(mid).copy()
|
||||
if self.flagModels:
|
||||
src['needWizard'] = True
|
||||
# if it doesn't exist, we'll copy it over, preserving id
|
||||
if not self.dst.models.have(mid):
|
||||
self.dst.models.update(src)
|
||||
# make sure to bump usn
|
||||
self.dst.models.save(src)
|
||||
self._modelMap[mid] = mid
|
||||
return mid
|
||||
# if it does exist, do the schema match?
|
||||
dst = self.dst.models.get(mid)
|
||||
dhash = self.src.models.scmhash(dst)
|
||||
if self.src.models.scmhash(src) == dhash:
|
||||
# reuse without modification
|
||||
self._modelMap[mid] = mid
|
||||
return mid
|
||||
# try any alternative versions
|
||||
vers = src.get("vers")
|
||||
for v in vers:
|
||||
m = self.src.models.get(v)
|
||||
if self.src.models.scmhash(m) == dhash:
|
||||
# valid alternate found; use that
|
||||
self._modelMap[mid] = m['id']
|
||||
return m['id']
|
||||
# need to add a new alternate version, with new id
|
||||
self.dst.models._add(src)
|
||||
if vers:
|
||||
dst['vers'].append(src['id'])
|
||||
else:
|
||||
dst['vers'] = [src['id']]
|
||||
|
||||
# Groups
|
||||
######################################################################
|
||||
|
@ -158,19 +172,20 @@ class Anki2Importer(Importer):
|
|||
# loop through src
|
||||
cards = []
|
||||
revlog = []
|
||||
print "fixme: need to check schema issues in card import"
|
||||
for card in self.src.db.execute(
|
||||
"select f.guid, f.mid, c.* from cards c, facts f "
|
||||
"where c.fid = f.id"):
|
||||
guid = card[0]
|
||||
shash = self._srcModels[card[1]]
|
||||
# does the card's fact exist in dst deck?
|
||||
if guid not in self._facts:
|
||||
continue
|
||||
dfid = self._facts[guid]
|
||||
# does the fact share the same schema?
|
||||
mid = self._facts[guid][2]
|
||||
if shash != self._dstModels[mid]:
|
||||
continue
|
||||
# shash = self._srcModels[card[1]]
|
||||
# mid = self._facts[guid][2]
|
||||
# if shash != self._dstModels[mid]:
|
||||
# continue
|
||||
# does the card already exist in the dst deck?
|
||||
ord = card[5]
|
||||
if (guid, ord) in self._cards:
|
||||
|
|
|
@ -31,6 +31,7 @@ defaultModel = {
|
|||
'latexPost': "\\end{document}",
|
||||
'mod': 0,
|
||||
'usn': 0,
|
||||
'vers': [],
|
||||
}
|
||||
|
||||
defaultField = {
|
||||
|
@ -166,6 +167,9 @@ select id from cards where fid in (select id from facts where mid = ?)""",
|
|||
break
|
||||
m['id'] = id
|
||||
|
||||
def have(self, id):
|
||||
return str(id) in self.models
|
||||
|
||||
# Tools
|
||||
##################################################
|
||||
|
||||
|
@ -426,11 +430,8 @@ select id from facts where mid = ?)""" % " ".join(map),
|
|||
|
||||
def scmhash(self, m):
|
||||
"Return a hash of the schema, to see if models are compatible."
|
||||
s = m['name']
|
||||
for f in m['flds']:
|
||||
s += f['name']
|
||||
for t in m['tmpls']:
|
||||
s += t['name']
|
||||
return fieldChecksum(s)
|
||||
|
||||
# Required field/text cache
|
||||
|
|
|
@ -46,6 +46,7 @@ def test_anki2():
|
|||
"select count() from cards where fid not in (select id from facts)")
|
||||
assert not dst.db.scalar(
|
||||
"select count() from revlog where cid not in (select id from cards)")
|
||||
assert dst.fixIntegrity().startswith("Database rebuilt")
|
||||
check()
|
||||
# importing should be idempotent
|
||||
imp.run()
|
||||
|
|
Loading…
Reference in a new issue