From f2fffce6d1e29bd1dfa8415ecbd41ef0419eac9e Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Fri, 21 Sep 2012 15:42:30 +0900 Subject: [PATCH] handle conflicts in apkg import as well --- anki/importing/apkg.py | 21 ++++++++++++++++----- tests/support/media.apkg | Bin 0 -> 2509 bytes tests/test_importing.py | 22 +++++++++++++++++++--- 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 tests/support/media.apkg diff --git a/anki/importing/apkg.py b/anki/importing/apkg.py index 29944790f..877e8a939 100644 --- a/anki/importing/apkg.py +++ b/anki/importing/apkg.py @@ -10,16 +10,27 @@ class AnkiPackageImporter(Anki2Importer): def run(self): # extract the deck from the zip file - z = zipfile.ZipFile(self.file) + self.zip = z = zipfile.ZipFile(self.file) col = z.read("collection.anki2") colpath = tmpfile(suffix=".anki2") open(colpath, "wb").write(col) - # pass it to the anki2 importer self.file = colpath + # we need the media dict in advance, and we'll need a map of fname -> + # number to use during the import + self.nameToNum = {} + for k, v in json.loads(z.read("media")).items(): + self.nameToNum[v] = k + # run anki2 importer Anki2Importer.run(self) - # import media - media = json.loads(z.read("media")) - for c, file in media.items(): + # import static media + for file, c in self.nameToNum.items(): + if not file.startswith("_"): + continue path = os.path.join(self.col.media.dir(), file) if not os.path.exists(path): open(path, "wb").write(z.read(c)) + + def _srcMediaData(self, fname): + if fname in self.nameToNum: + return self.zip.read(self.nameToNum[fname]) + return None diff --git a/tests/support/media.apkg b/tests/support/media.apkg new file mode 100644 index 0000000000000000000000000000000000000000..2a727f9a2c96e2362bc5a3ef32483815a8d15465 GIT binary patch literal 2509 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 c&|`N^NaCjX`T7aHJ=wEzGB literal 0 HcmV?d00001 diff --git a/tests/test_importing.py b/tests/test_importing.py index 59da147e9..17e78bc06 100644 --- a/tests/test_importing.py +++ b/tests/test_importing.py @@ -6,7 +6,7 @@ from anki.upgrade import Upgrader from anki.utils import ids2str from anki.errors import * from anki.importing import Anki1Importer, Anki2Importer, TextImporter, \ - SupermemoXmlImporter, MnemosyneImporter + SupermemoXmlImporter, MnemosyneImporter, AnkiPackageImporter from anki.notes import Note from anki.db import * @@ -50,7 +50,6 @@ def test_anki2(): imp.run() check() assert len(os.listdir(dst.media.dir())) == 1 - #print dst.path def test_anki2_mediadupes(): tmp = getEmptyDeck() @@ -97,7 +96,24 @@ def test_anki2_mediadupes(): n = empty.getNote(empty.db.scalar("select id from notes")) assert "_" in n.fields[0] - #print dst.path +def test_apkg(): + tmp = getEmptyDeck() + apkg = unicode(os.path.join(testDir, "support/media.apkg")) + imp = AnkiPackageImporter(tmp, apkg) + assert os.listdir(tmp.media.dir()) == [] + imp.run() + assert os.listdir(tmp.media.dir()) == ['foo.wav'] + # importing again should be idempotent in terms of media + tmp.remCards(tmp.db.list("select id from cards")) + imp = AnkiPackageImporter(tmp, apkg) + imp.run() + assert os.listdir(tmp.media.dir()) == ['foo.wav'] + # but if the local file has different data, it will rename + tmp.remCards(tmp.db.list("select id from cards")) + open(os.path.join(tmp.media.dir(), "foo.wav"), "w").write("xyz") + imp = AnkiPackageImporter(tmp, apkg) + imp.run() + assert len(os.listdir(tmp.media.dir())) == 2 def test_anki1(): # get the deck path to import