mirror of
https://github.com/ankitects/anki.git
synced 2025-09-23 16:26:40 -04:00
place cards with corrupt/missing facts into new fact instead of deleting
This commit is contained in:
parent
154bf0cef4
commit
7ce661ac63
2 changed files with 56 additions and 21 deletions
66
anki/deck.py
66
anki/deck.py
|
@ -3220,12 +3220,39 @@ You can disable this check in Settings>Preferences>Network.""") % self.name())
|
||||||
# DB maintenance
|
# DB maintenance
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
def recoverCards(self, ids):
|
||||||
|
"Put cards with damaged facts into new facts."
|
||||||
|
# create a new model in case the user has modified a previous one
|
||||||
|
from anki.stdmodels import RecoveryModel
|
||||||
|
m = RecoveryModel()
|
||||||
|
last = self.currentModel
|
||||||
|
self.addModel(m)
|
||||||
|
def repl(s):
|
||||||
|
# strip field model text
|
||||||
|
return re.sub("<span class=\"fm.*?>(.*?)</span>", "\\1", s)
|
||||||
|
# add new facts, pointing old card at new fact
|
||||||
|
for (id, q, a) in self.s.all("""
|
||||||
|
select id, question, answer from cards
|
||||||
|
where id in %s""" % ids2str(ids)):
|
||||||
|
f = self.newFact()
|
||||||
|
f['Question'] = repl(q)
|
||||||
|
f['Answer'] = repl(a)
|
||||||
|
cards = self.addFact(f)
|
||||||
|
# delete the freshly created card and point old card to this fact
|
||||||
|
self.s.statement("delete from cards where id = :id",
|
||||||
|
id=f.cards[0].id)
|
||||||
|
self.s.statement("""
|
||||||
|
update cards set factId = :fid, cardModelId = :cmid, ordinal = 0
|
||||||
|
where id = :id""", fid=f.id, cmid=m.cardModels[0].id, id=id)
|
||||||
|
# restore old model
|
||||||
|
self.currentModel = last
|
||||||
|
|
||||||
def fixIntegrity(self, quick=False):
|
def fixIntegrity(self, quick=False):
|
||||||
"Fix some problems and rebuild caches. Caller must .reset()"
|
"Fix some problems and rebuild caches. Caller must .reset()"
|
||||||
self.s.commit()
|
self.s.commit()
|
||||||
self.resetUndo()
|
self.resetUndo()
|
||||||
problems = []
|
problems = []
|
||||||
deletedCards = []
|
recover = False
|
||||||
if quick:
|
if quick:
|
||||||
num = 4
|
num = 4
|
||||||
else:
|
else:
|
||||||
|
@ -3275,24 +3302,20 @@ facts.modelId = fieldModels.modelId and fieldModels.id not in
|
||||||
ids = self.s.column0("""
|
ids = self.s.column0("""
|
||||||
select id from cards where factId not in (select id from facts)""")
|
select id from cards where factId not in (select id from facts)""")
|
||||||
if ids:
|
if ids:
|
||||||
deletedCards.extend(self.s.all(
|
recover = True
|
||||||
"select question, answer from cards where id in %s" %
|
self.recoverCards(ids)
|
||||||
ids2str(ids)))
|
problems.append(ngettext("Recovered %d card with missing fact",
|
||||||
self.deleteCards(ids)
|
"Recovered %d cards with missing fact", len(ids)) %
|
||||||
problems.append(ngettext("Deleted %d card with missing fact",
|
|
||||||
"Deleted %d cards with missing fact", len(ids)) %
|
|
||||||
len(ids))
|
len(ids))
|
||||||
# cards missing a card model?
|
# cards missing a card model?
|
||||||
ids = self.s.column0("""
|
ids = self.s.column0("""
|
||||||
select id from cards where cardModelId not in
|
select id from cards where cardModelId not in
|
||||||
(select id from cardModels)""")
|
(select id from cardModels)""")
|
||||||
if ids:
|
if ids:
|
||||||
deletedCards.extend(self.s.all(
|
recover = True
|
||||||
"select question, answer from cards where id in %s" %
|
self.recoverCards(ids)
|
||||||
ids2str(ids)))
|
problems.append(ngettext("Recovered %d card with no card template",
|
||||||
self.deleteCards(ids)
|
"Recovered %d cards with no card template", len(ids)) %
|
||||||
problems.append(ngettext("Deleted %d card with no card template",
|
|
||||||
"Deleted %d cards with no card template", len(ids)) %
|
|
||||||
len(ids))
|
len(ids))
|
||||||
# cards with a card model from the wrong model
|
# cards with a card model from the wrong model
|
||||||
ids = self.s.column0("""
|
ids = self.s.column0("""
|
||||||
|
@ -3300,12 +3323,10 @@ select id from cards where cardModelId not in (select cm.id from
|
||||||
cardModels cm, facts f where cm.modelId = f.modelId and
|
cardModels cm, facts f where cm.modelId = f.modelId and
|
||||||
f.id = cards.factId)""")
|
f.id = cards.factId)""")
|
||||||
if ids:
|
if ids:
|
||||||
deletedCards.extend(self.s.all(
|
recover = True
|
||||||
"select question, answer from cards where id in %s" %
|
self.recoverCards(ids)
|
||||||
ids2str(ids)))
|
problems.append(ngettext("Recovered %d card with wrong card template",
|
||||||
self.deleteCards(ids)
|
"Recovered %d cards with wrong card template", len(ids)) %
|
||||||
problems.append(ngettext("Deleted %d card with wrong card template",
|
|
||||||
"Deleted %d cards with wrong card template", len(ids)) %
|
|
||||||
len(ids))
|
len(ids))
|
||||||
# facts missing a card?
|
# facts missing a card?
|
||||||
ids = self.deleteDanglingFacts()
|
ids = self.deleteDanglingFacts()
|
||||||
|
@ -3322,8 +3343,6 @@ select id from fields where factId not in (select id from facts)""")
|
||||||
problems.append(ngettext("Deleted %d dangling field",
|
problems.append(ngettext("Deleted %d dangling field",
|
||||||
"Deleted %d dangling fields", len(ids)) %
|
"Deleted %d dangling fields", len(ids)) %
|
||||||
len(ids))
|
len(ids))
|
||||||
for card in deletedCards:
|
|
||||||
problems.append(_("Deleted: ") + "%s %s" % tuple(card))
|
|
||||||
self.s.flush()
|
self.s.flush()
|
||||||
if not quick:
|
if not quick:
|
||||||
self.updateProgress()
|
self.updateProgress()
|
||||||
|
@ -3371,6 +3390,11 @@ where id = fieldModelId)""")
|
||||||
self.refreshSession()
|
self.refreshSession()
|
||||||
self.finishProgress()
|
self.finishProgress()
|
||||||
if problems:
|
if problems:
|
||||||
|
if recover:
|
||||||
|
problems.append("\n" + _("""\
|
||||||
|
Cards with corrupt or missing facts have been placed into new facts. \
|
||||||
|
Your scheduling info and card content has been preserved, but the \
|
||||||
|
original layout of the facts has been lost."""))
|
||||||
return "\n".join(problems)
|
return "\n".join(problems)
|
||||||
return "ok"
|
return "ok"
|
||||||
|
|
||||||
|
|
|
@ -38,3 +38,14 @@ def BasicModel():
|
||||||
return m
|
return m
|
||||||
|
|
||||||
models['Basic'] = BasicModel
|
models['Basic'] = BasicModel
|
||||||
|
|
||||||
|
# Recovery
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
def RecoveryModel():
|
||||||
|
m = Model(_('Recovery'))
|
||||||
|
m.addFieldModel(FieldModel(u'Question', False, False))
|
||||||
|
m.addFieldModel(FieldModel(u'Answer', False, False))
|
||||||
|
m.addCardModel(CardModel(u'Single', u'{{{Question}}}', u'{{{Answer}}}'))
|
||||||
|
m.tags = u"Recovery"
|
||||||
|
return m
|
||||||
|
|
Loading…
Reference in a new issue