ffd392de21
* Accept iterables as inputs to backend methods * Shift add-on check to backend; use new endpoint The new endpoint will return info on a suitable branch if found, instead of returning all branches. This simplifies the frontend code, and means that you can now drop support for certain versions without it also remotely disabling the add-on for people who are running one of the excluded versions, like in https://forums.ankiweb.net/t/prevent-add-ons-from-being-disabled-remote-stealthily-surreptitiously/33427 * Bump version to 23.09 This changes Anki's version numbering system to year.month.patch, as previously mentioned on https://forums.ankiweb.net/t/use-a-different-versioning-system-semver-perhaps/20046/5 This is shaping up to be a big release, with the introduction of FSRS and image occlusion, and it seems like a good time to be finally updating the version scheme as well. AnkiWeb has been updated to understand the new format, and add-on authors will now specify version compatibility using the full version number, as can be seen here: https://ankiweb.net/shared/info/3918629684 * Shift update check to backend, and tidy up update.py * Use the shared client for sync connections too
76 lines
2.5 KiB
Python
76 lines
2.5 KiB
Python
# Copyright: Ankitects Pty Ltd and contributors
|
|
# License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|
|
|
import aqt
|
|
from anki.buildinfo import buildhash
|
|
from anki.collection import CheckForUpdateResponse, Collection
|
|
from anki.utils import dev_mode, int_time, int_version, plat_desc
|
|
from aqt.operations import QueryOp
|
|
from aqt.qt import *
|
|
from aqt.utils import openLink, show_warning, showText, tr
|
|
|
|
|
|
def check_for_update() -> None:
|
|
from aqt import mw
|
|
|
|
def do_check(_col: Collection) -> CheckForUpdateResponse:
|
|
return mw.backend.check_for_update(
|
|
version=int_version(),
|
|
buildhash=buildhash,
|
|
os=plat_desc(),
|
|
install_id=mw.pm.meta["id"],
|
|
last_message_id=max(0, mw.pm.meta["lastMsg"]),
|
|
)
|
|
|
|
def on_done(resp: CheckForUpdateResponse) -> None:
|
|
# is clock off?
|
|
if not dev_mode:
|
|
diff = abs(resp.current_time - int_time())
|
|
if diff > 300:
|
|
diff_text = tr.qt_misc_second(count=diff)
|
|
warn = (
|
|
tr.qt_misc_in_order_to_ensure_your_collection(val="%s") % diff_text
|
|
)
|
|
show_warning(warn)
|
|
mw.app.closeAllWindows()
|
|
return
|
|
# should we show a message?
|
|
if msg := resp.message:
|
|
showText(msg, parent=mw, type="html")
|
|
mw.pm.meta["lastMsg"] = resp.last_message_id
|
|
# has Anki been updated?
|
|
if ver := resp.new_version:
|
|
prompt_to_update(mw, ver)
|
|
|
|
def on_fail(exc: Exception) -> None:
|
|
print(f"update check failed: {exc}")
|
|
|
|
QueryOp(parent=mw, op=do_check, success=on_done).failure(
|
|
on_fail
|
|
).run_in_background()
|
|
|
|
|
|
def prompt_to_update(mw: aqt.AnkiQt, ver: str) -> None:
|
|
msg = (
|
|
tr.qt_misc_anki_updatedanki_has_been_released(val=ver)
|
|
+ tr.qt_misc_would_you_like_to_download_it()
|
|
)
|
|
|
|
msgbox = QMessageBox(mw)
|
|
msgbox.setStandardButtons(
|
|
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
|
|
)
|
|
msgbox.setIcon(QMessageBox.Icon.Information)
|
|
msgbox.setText(msg)
|
|
|
|
button = QPushButton(tr.qt_misc_ignore_this_update())
|
|
msgbox.addButton(button, QMessageBox.ButtonRole.RejectRole)
|
|
msgbox.setDefaultButton(QMessageBox.StandardButton.Yes)
|
|
ret = msgbox.exec()
|
|
|
|
if msgbox.clickedButton() == button:
|
|
# ignore this update
|
|
mw.pm.meta["suppressUpdate"] = ver
|
|
elif ret == QMessageBox.StandardButton.Yes:
|
|
openLink(aqt.appWebsiteDownloadSection)
|