mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
don't need a separate migration package; the rest is std import
This commit is contained in:
parent
76960abd75
commit
1ba75e8dc9
5 changed files with 82 additions and 85 deletions
|
@ -341,12 +341,10 @@ where factId in (%s)""" % ",".join([str(s) for s in factIds]))
|
||||||
|
|
||||||
from anki.importing.csvfile import TextImporter
|
from anki.importing.csvfile import TextImporter
|
||||||
from anki.importing.anki10 import Anki10Importer
|
from anki.importing.anki10 import Anki10Importer
|
||||||
from anki.importing.mnemosyne10 import Mnemosyne10Importer
|
|
||||||
from anki.importing.supermemo_xml import SupermemoXmlImporter
|
from anki.importing.supermemo_xml import SupermemoXmlImporter
|
||||||
|
|
||||||
Importers = (
|
Importers = (
|
||||||
(_("Text separated by tabs or semicolons (*)"), TextImporter),
|
(_("Text separated by tabs or semicolons (*)"), TextImporter),
|
||||||
(_("Anki Deck (*.anki)"), Anki10Importer),
|
(_("Anki Deck (*.anki)"), Anki10Importer),
|
||||||
(_("Mnemosyne Deck (*.mem)"), Mnemosyne10Importer),
|
|
||||||
(_("Supermemo XML export (*.xml)"), SupermemoXmlImporter),
|
(_("Supermemo XML export (*.xml)"), SupermemoXmlImporter),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright: Damien Elmes <anki@ichi2.net>
|
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
||||||
|
|
||||||
class Migrator(object):
|
|
||||||
|
|
||||||
def __init__(self, deck):
|
|
||||||
pass
|
|
|
@ -1,68 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
# Copyright: Damien Elmes <anki@ichi2.net>
|
|
||||||
# License: GNU AGPL, version 3 or later; http://www.gnu.org/copyleft/agpl.html
|
|
||||||
|
|
||||||
from anki.db import DB
|
|
||||||
|
|
||||||
def check(path):
|
|
||||||
"True if deck looks ok."
|
|
||||||
db = DB(path)
|
|
||||||
# corrupt?
|
|
||||||
try:
|
|
||||||
if db.scalar("pragma integrity_check") != "ok":
|
|
||||||
return
|
|
||||||
except:
|
|
||||||
return
|
|
||||||
# old version?
|
|
||||||
if db.scalar("select version from decks") != 65:
|
|
||||||
return
|
|
||||||
# fields missing a field model?
|
|
||||||
if db.list("""
|
|
||||||
select id from fields where fieldModelId not in (
|
|
||||||
select distinct id from fieldModels)"""):
|
|
||||||
return
|
|
||||||
# facts missing a field?
|
|
||||||
if db.list("""
|
|
||||||
select distinct facts.id from facts, fieldModels where
|
|
||||||
facts.modelId = fieldModels.modelId and fieldModels.id not in
|
|
||||||
(select fieldModelId from fields where factId = facts.id)"""):
|
|
||||||
return
|
|
||||||
# cards missing a fact?
|
|
||||||
if db.list("""
|
|
||||||
select id from cards where factId not in (select id from facts)"""):
|
|
||||||
return
|
|
||||||
# cards missing a card model?
|
|
||||||
if db.list("""
|
|
||||||
select id from cards where cardModelId not in
|
|
||||||
(select id from cardModels)"""):
|
|
||||||
return
|
|
||||||
# cards with a card model from the wrong model?
|
|
||||||
if db.list("""
|
|
||||||
select id from cards where cardModelId not in (select cm.id from
|
|
||||||
cardModels cm, facts f where cm.modelId = f.modelId and
|
|
||||||
f.id = cards.factId)"""):
|
|
||||||
return
|
|
||||||
# facts missing a card?
|
|
||||||
if db.list("""
|
|
||||||
select facts.id from facts
|
|
||||||
where facts.id not in (select distinct factId from cards)"""):
|
|
||||||
return
|
|
||||||
# dangling fields?
|
|
||||||
if db.list("""
|
|
||||||
select id from fields where factId not in (select id from facts)"""):
|
|
||||||
return
|
|
||||||
# fields without matching interval
|
|
||||||
if db.list("""
|
|
||||||
select id from fields where ordinal != (select ordinal from fieldModels
|
|
||||||
where id = fieldModelId)"""):
|
|
||||||
return
|
|
||||||
# incorrect types
|
|
||||||
if db.list("""
|
|
||||||
select id from cards where relativeDelay != (case
|
|
||||||
when successive then 1 when reps then 0 else 2 end)"""):
|
|
||||||
return
|
|
||||||
if db.list("""
|
|
||||||
select id from cards where type != (case
|
|
||||||
when type >= 0 then relativeDelay else relativeDelay - 3 end)"""):
|
|
||||||
return
|
|
||||||
return True
|
|
|
@ -14,9 +14,9 @@ from anki.storage import _addSchema, _getDeckVars, _addDeckVars, \
|
||||||
#
|
#
|
||||||
# Upgrading is the first step in migrating to 2.0. The ids are temporary and
|
# Upgrading is the first step in migrating to 2.0. The ids are temporary and
|
||||||
# may not be unique across multiple decks. After each of a user's v1.2 decks
|
# may not be unique across multiple decks. After each of a user's v1.2 decks
|
||||||
# are upgraded, they need to be merged.
|
# are upgraded, they need to be merged via the import code.
|
||||||
#
|
#
|
||||||
# Caller should have called check() on path before using this.
|
# Caller should have called check() on path before calling upgrade().
|
||||||
#
|
#
|
||||||
|
|
||||||
class Upgrader(object):
|
class Upgrader(object):
|
||||||
|
@ -24,6 +24,9 @@ class Upgrader(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# Upgrading
|
||||||
|
######################################################################
|
||||||
|
|
||||||
def upgrade(self, path):
|
def upgrade(self, path):
|
||||||
self.path = path
|
self.path = path
|
||||||
self._openDB(path)
|
self._openDB(path)
|
||||||
|
@ -32,6 +35,78 @@ class Upgrader(object):
|
||||||
self._upgradeDeck()
|
self._upgradeDeck()
|
||||||
return self.deck
|
return self.deck
|
||||||
|
|
||||||
|
# Integrity checking
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
def check(self, path):
|
||||||
|
"True if deck looks ok."
|
||||||
|
with DB(path) as db:
|
||||||
|
return self._check(db)
|
||||||
|
|
||||||
|
def _check(self, db):
|
||||||
|
# corrupt?
|
||||||
|
try:
|
||||||
|
if db.scalar("pragma integrity_check") != "ok":
|
||||||
|
return
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
# old version?
|
||||||
|
if db.scalar("select version from decks") != 65:
|
||||||
|
return
|
||||||
|
# fields missing a field model?
|
||||||
|
if db.list("""
|
||||||
|
select id from fields where fieldModelId not in (
|
||||||
|
select distinct id from fieldModels)"""):
|
||||||
|
return
|
||||||
|
# facts missing a field?
|
||||||
|
if db.list("""
|
||||||
|
select distinct facts.id from facts, fieldModels where
|
||||||
|
facts.modelId = fieldModels.modelId and fieldModels.id not in
|
||||||
|
(select fieldModelId from fields where factId = facts.id)"""):
|
||||||
|
return
|
||||||
|
# cards missing a fact?
|
||||||
|
if db.list("""
|
||||||
|
select id from cards where factId not in (select id from facts)"""):
|
||||||
|
return
|
||||||
|
# cards missing a card model?
|
||||||
|
if db.list("""
|
||||||
|
select id from cards where cardModelId not in
|
||||||
|
(select id from cardModels)"""):
|
||||||
|
return
|
||||||
|
# cards with a card model from the wrong model?
|
||||||
|
if db.list("""
|
||||||
|
select id from cards where cardModelId not in (select cm.id from
|
||||||
|
cardModels cm, facts f where cm.modelId = f.modelId and
|
||||||
|
f.id = cards.factId)"""):
|
||||||
|
return
|
||||||
|
# facts missing a card?
|
||||||
|
if db.list("""
|
||||||
|
select facts.id from facts
|
||||||
|
where facts.id not in (select distinct factId from cards)"""):
|
||||||
|
return
|
||||||
|
# dangling fields?
|
||||||
|
if db.list("""
|
||||||
|
select id from fields where factId not in (select id from facts)"""):
|
||||||
|
return
|
||||||
|
# fields without matching interval
|
||||||
|
if db.list("""
|
||||||
|
select id from fields where ordinal != (select ordinal from fieldModels
|
||||||
|
where id = fieldModelId)"""):
|
||||||
|
return
|
||||||
|
# incorrect types
|
||||||
|
if db.list("""
|
||||||
|
select id from cards where relativeDelay != (case
|
||||||
|
when successive then 1 when reps then 0 else 2 end)"""):
|
||||||
|
return
|
||||||
|
if db.list("""
|
||||||
|
select id from cards where type != (case
|
||||||
|
when type >= 0 then relativeDelay else relativeDelay - 3 end)"""):
|
||||||
|
return
|
||||||
|
return True
|
||||||
|
|
||||||
|
# DB/Deck opening
|
||||||
|
######################################################################
|
||||||
|
|
||||||
def _openDB(self, path):
|
def _openDB(self, path):
|
||||||
self.tmppath = namedtmp(os.path.basename(path))
|
self.tmppath = namedtmp(os.path.basename(path))
|
||||||
shutil.copy(path, self.tmppath)
|
shutil.copy(path, self.tmppath)
|
|
@ -3,15 +3,15 @@
|
||||||
import datetime
|
import datetime
|
||||||
from anki.consts import *
|
from anki.consts import *
|
||||||
from shared import getUpgradeDeckPath
|
from shared import getUpgradeDeckPath
|
||||||
from anki.migration.checker import check
|
from anki.upgrade import Upgrader
|
||||||
from anki.migration.upgrader import Upgrader
|
|
||||||
|
|
||||||
def test_checker():
|
def test_check():
|
||||||
dst = getUpgradeDeckPath()
|
dst = getUpgradeDeckPath()
|
||||||
assert check(dst)
|
u = Upgrader()
|
||||||
|
assert u.check(dst)
|
||||||
# if it's corrupted, will fail
|
# if it's corrupted, will fail
|
||||||
open(dst, "w+").write("foo")
|
open(dst, "w+").write("foo")
|
||||||
assert not check(dst)
|
assert not u.check(dst)
|
||||||
|
|
||||||
def test_upgrade():
|
def test_upgrade():
|
||||||
dst = getUpgradeDeckPath()
|
dst = getUpgradeDeckPath()
|
Loading…
Reference in a new issue