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