mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 06:22:22 -04:00
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.
This commit is contained in:
parent
a6b676039b
commit
d24cb66be9
3 changed files with 39 additions and 5 deletions
|
@ -214,6 +214,7 @@ class AnkiQt(QMainWindow):
|
||||||
f.delete_2.clicked.connect(self.onRemProfile)
|
f.delete_2.clicked.connect(self.onRemProfile)
|
||||||
f.profiles.currentRowChanged.connect(self.onProfileRowChange)
|
f.profiles.currentRowChanged.connect(self.onProfileRowChange)
|
||||||
f.statusbar.setVisible(False)
|
f.statusbar.setVisible(False)
|
||||||
|
f.downgrade_button.clicked.connect(self._on_downgrade)
|
||||||
# enter key opens profile
|
# enter key opens profile
|
||||||
QShortcut(QKeySequence("Return"), d, activated=self.onOpenProfile) # type: ignore
|
QShortcut(QKeySequence("Return"), d, activated=self.onOpenProfile) # type: ignore
|
||||||
self.refreshProfilesList()
|
self.refreshProfilesList()
|
||||||
|
@ -343,6 +344,18 @@ close the profile or restart Anki."""
|
||||||
|
|
||||||
self.onOpenProfile()
|
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:
|
def loadProfile(self, onsuccess: Optional[Callable] = None) -> None:
|
||||||
self.maybeAutoSync()
|
self.maybeAutoSync()
|
||||||
|
|
||||||
|
@ -440,8 +453,6 @@ close the profile or restart Anki."""
|
||||||
# Collection load/unload
|
# Collection load/unload
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
downgrade_on_close = True
|
|
||||||
|
|
||||||
def loadCollection(self) -> bool:
|
def loadCollection(self) -> bool:
|
||||||
try:
|
try:
|
||||||
self._loadCollection()
|
self._loadCollection()
|
||||||
|
@ -452,7 +463,7 @@ close the profile or restart Anki."""
|
||||||
# clean up open collection if possible
|
# clean up open collection if possible
|
||||||
if self.col:
|
if self.col:
|
||||||
try:
|
try:
|
||||||
self.col.close(save=False, downgrade=self.downgrade_on_close)
|
self.col.close(save=False, downgrade=False)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
self.col = None
|
self.col = None
|
||||||
|
@ -507,7 +518,7 @@ close the profile or restart Anki."""
|
||||||
except:
|
except:
|
||||||
corrupt = True
|
corrupt = True
|
||||||
try:
|
try:
|
||||||
self.col.close(downgrade=self.downgrade_on_close)
|
self.col.close(downgrade=False)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
corrupt = True
|
corrupt = True
|
||||||
|
|
|
@ -11,13 +11,14 @@ import locale
|
||||||
import pickle
|
import pickle
|
||||||
import random
|
import random
|
||||||
import shutil
|
import shutil
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional, List
|
||||||
|
|
||||||
from send2trash import send2trash
|
from send2trash import send2trash
|
||||||
|
|
||||||
import anki.lang
|
import anki.lang
|
||||||
import aqt.forms
|
import aqt.forms
|
||||||
import aqt.sound
|
import aqt.sound
|
||||||
|
from anki import Collection
|
||||||
from anki.db import DB
|
from anki.db import DB
|
||||||
from anki.lang import _, without_unicode_isolation
|
from anki.lang import _, without_unicode_isolation
|
||||||
from anki.utils import intTime, isMac, isWin
|
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):
|
def collectionPath(self):
|
||||||
return os.path.join(self.profileFolder(), "collection.anki2")
|
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
|
# Helpers
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="downgrade_button">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">Downgrade && Quit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
Loading…
Reference in a new issue