From d24cb66be9e8afd80e3af52fe7e3caf0d2fdb655 Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 16 Apr 2020 09:00:49 +1000 Subject: [PATCH] downgrade manually - A regular collection open/close no longer goes through the upgrade/downgrade steps each time. This avoids wasted cycles, and will become more important in the future when decks and note types are split into separate tables. - Added a downgrade button to the profiles screen to downgrade all profiles and close the app. - Downgrading is still automatic when exporting/doing a full sync. --- qt/aqt/main.py | 19 +++++++++++++++---- qt/aqt/profiles.py | 18 +++++++++++++++++- qt/designer/profiles.ui | 7 +++++++ 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/qt/aqt/main.py b/qt/aqt/main.py index 73a8ccd27..02a146982 100644 --- a/qt/aqt/main.py +++ b/qt/aqt/main.py @@ -214,6 +214,7 @@ class AnkiQt(QMainWindow): f.delete_2.clicked.connect(self.onRemProfile) f.profiles.currentRowChanged.connect(self.onProfileRowChange) f.statusbar.setVisible(False) + f.downgrade_button.clicked.connect(self._on_downgrade) # enter key opens profile QShortcut(QKeySequence("Return"), d, activated=self.onOpenProfile) # type: ignore self.refreshProfilesList() @@ -343,6 +344,18 @@ close the profile or restart Anki.""" self.onOpenProfile() + def _on_downgrade(self): + self.progress.start() + profiles = self.pm.profiles() + def downgrade(): + self.pm.downgrade(profiles) + def on_done(future): + self.progress.finish() + future.result() + showInfo("Profiles can now be opened with an older version of Anki.") + self.profileDiag.close() + self.taskman.run_in_background(downgrade, on_done) + def loadProfile(self, onsuccess: Optional[Callable] = None) -> None: self.maybeAutoSync() @@ -440,8 +453,6 @@ close the profile or restart Anki.""" # Collection load/unload ########################################################################## - downgrade_on_close = True - def loadCollection(self) -> bool: try: self._loadCollection() @@ -452,7 +463,7 @@ close the profile or restart Anki.""" # clean up open collection if possible if self.col: try: - self.col.close(save=False, downgrade=self.downgrade_on_close) + self.col.close(save=False, downgrade=False) except: pass self.col = None @@ -507,7 +518,7 @@ close the profile or restart Anki.""" except: corrupt = True try: - self.col.close(downgrade=self.downgrade_on_close) + self.col.close(downgrade=False) except Exception as e: print(e) corrupt = True diff --git a/qt/aqt/profiles.py b/qt/aqt/profiles.py index 5ca697625..d9796ebd6 100644 --- a/qt/aqt/profiles.py +++ b/qt/aqt/profiles.py @@ -11,13 +11,14 @@ import locale import pickle import random import shutil -from typing import Any, Dict, Optional +from typing import Any, Dict, Optional, List from send2trash import send2trash import anki.lang import aqt.forms import aqt.sound +from anki import Collection from anki.db import DB from anki.lang import _, without_unicode_isolation from anki.utils import intTime, isMac, isWin @@ -275,6 +276,21 @@ and no other programs are accessing your profile folders, then try again.""" def collectionPath(self): return os.path.join(self.profileFolder(), "collection.anki2") + # Downgrade + ###################################################################### + + def downgrade(self, profiles=List[str]): + for name in profiles: + path = os.path.join(self.base, name, "collection.anki2") + if not os.path.exists(path): + continue + with DB(path) as db: + if db.scalar("select ver from col") == 11: + # nothing to do + continue + c = Collection(path) + c.close(save=False, downgrade=True) + # Helpers ###################################################################### diff --git a/qt/designer/profiles.ui b/qt/designer/profiles.ui index 17f257b59..df24d557d 100644 --- a/qt/designer/profiles.ui +++ b/qt/designer/profiles.ui @@ -88,6 +88,13 @@ + + + + Downgrade && Quit + + +