import .colpkg in a background thread

This commit is contained in:
Damien Elmes 2020-03-06 14:55:15 +10:00
parent ad9dad8748
commit 8d429cd192

View file

@ -473,48 +473,57 @@ def replaceWithApkg(mw, file, backup):
mw.unloadCollection(lambda: _replaceWithApkg(mw, file, backup)) mw.unloadCollection(lambda: _replaceWithApkg(mw, file, backup))
def _replaceWithApkg(mw, file, backup): def _replaceWithApkg(mw, filename, backup):
mw.progress.start(immediate=True) mw.progress.start(immediate=True)
z = zipfile.ZipFile(file) def do_import():
z = zipfile.ZipFile(filename)
# v2 scheduler? # v2 scheduler?
colname = "collection.anki21" colname = "collection.anki21"
try: try:
z.getinfo(colname) z.getinfo(colname)
except KeyError: except KeyError:
colname = "collection.anki2" colname = "collection.anki2"
try:
with z.open(colname) as source, open(mw.pm.collectionPath(), "wb") as target: with z.open(colname) as source, open(mw.pm.collectionPath(), "wb") as target:
shutil.copyfileobj(source, target) shutil.copyfileobj(source, target)
except:
d = os.path.join(mw.pm.profileFolder(), "collection.media")
for n, (cStr, file) in enumerate(
json.loads(z.read("media").decode("utf8")).items()
):
mw.taskman.run_on_main(
lambda n=n: mw.progress.update(
ngettext("Processed %d media file", "Processed %d media files", n)
% n
)
)
size = z.getinfo(cStr).file_size
dest = os.path.join(d, unicodedata.normalize("NFC", file))
# if we have a matching file size
if os.path.exists(dest) and size == os.stat(dest).st_size:
continue
data = z.read(cStr)
open(dest, "wb").write(data)
z.close()
def on_done(future: Future):
mw.progress.finish() mw.progress.finish()
showWarning(_("The provided file is not a valid .apkg file."))
return try:
# because users don't have a backup of media, it's safer to import new future.result()
# data and rely on them running a media db check to get rid of any except Exception as e:
# unwanted media. in the future we might also want to deduplicate this print(e)
# step showWarning(_("The provided file is not a valid .apkg file."))
d = os.path.join(mw.pm.profileFolder(), "collection.media") return
for n, (cStr, file) in enumerate(
json.loads(z.read("media").decode("utf8")).items() if not mw.loadCollection():
): return
mw.progress.update( if backup:
ngettext("Processed %d media file", "Processed %d media files", n) % n mw.col.modSchema(check=False)
)
size = z.getinfo(cStr).file_size tooltip(_("Importing complete."))
dest = os.path.join(d, unicodedata.normalize("NFC", file))
# if we have a matching file size mw.taskman.run_in_background(do_import, on_done)
if os.path.exists(dest) and size == os.stat(dest).st_size:
continue
data = z.read(cStr)
open(dest, "wb").write(data)
z.close()
# reload
if not mw.loadCollection():
mw.progress.finish()
return
if backup:
mw.col.modSchema(check=False)
mw.progress.finish()