mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 22:12:21 -04:00
Add add-on installation hooks (#2523)
* Add add-on installation hooks * Fix GUI code run in background thread deleteAddon() is run in the background in the update routine so it shouldn't containg any GUI code. * Add a hint to the docstrings (dae)
This commit is contained in:
parent
93e1a6be22
commit
c87f62487b
2 changed files with 35 additions and 20 deletions
|
@ -426,7 +426,9 @@ class AddonManager:
|
||||||
conflicts = manifest.get("conflicts", [])
|
conflicts = manifest.get("conflicts", [])
|
||||||
found_conflicts = self._disableConflicting(package, conflicts)
|
found_conflicts = self._disableConflicting(package, conflicts)
|
||||||
meta = self.addonMeta(package)
|
meta = self.addonMeta(package)
|
||||||
|
gui_hooks.addon_manager_will_install_addon(self, package)
|
||||||
self._install(package, zfile)
|
self._install(package, zfile)
|
||||||
|
gui_hooks.addon_manager_did_install_addon(self, package)
|
||||||
|
|
||||||
schema = self._manifest_schema["properties"]
|
schema = self._manifest_schema["properties"]
|
||||||
manifest_meta = {
|
manifest_meta = {
|
||||||
|
@ -450,10 +452,11 @@ class AddonManager:
|
||||||
base = self.addonsFolder(module)
|
base = self.addonsFolder(module)
|
||||||
if os.path.exists(base):
|
if os.path.exists(base):
|
||||||
self.backupUserFiles(module)
|
self.backupUserFiles(module)
|
||||||
if not self.deleteAddon(module):
|
try:
|
||||||
|
self.deleteAddon(module)
|
||||||
|
except Exception:
|
||||||
self.restoreUserFiles(module)
|
self.restoreUserFiles(module)
|
||||||
return
|
raise
|
||||||
|
|
||||||
os.mkdir(base)
|
os.mkdir(base)
|
||||||
self.restoreUserFiles(module)
|
self.restoreUserFiles(module)
|
||||||
|
|
||||||
|
@ -469,17 +472,8 @@ class AddonManager:
|
||||||
continue
|
continue
|
||||||
zfile.extract(n, base)
|
zfile.extract(n, base)
|
||||||
|
|
||||||
# true on success
|
def deleteAddon(self, module: str) -> None:
|
||||||
def deleteAddon(self, module: str) -> bool:
|
send_to_trash(Path(self.addonsFolder(module)))
|
||||||
try:
|
|
||||||
send_to_trash(Path(self.addonsFolder(module)))
|
|
||||||
return True
|
|
||||||
except OSError as e:
|
|
||||||
showWarning(
|
|
||||||
tr.addons_unable_to_update_or_delete_addon(val=str(e)),
|
|
||||||
textFormat="plain",
|
|
||||||
)
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Processing local add-on files
|
# Processing local add-on files
|
||||||
######################################################################
|
######################################################################
|
||||||
|
@ -912,12 +906,17 @@ class AddonsDialog(QDialog):
|
||||||
if not askUser(tr.addons_delete_the_numd_selected_addon(count=len(selected))):
|
if not askUser(tr.addons_delete_the_numd_selected_addon(count=len(selected))):
|
||||||
return
|
return
|
||||||
gui_hooks.addons_dialog_will_delete_addons(self, selected)
|
gui_hooks.addons_dialog_will_delete_addons(self, selected)
|
||||||
for module in selected:
|
try:
|
||||||
# doing this before deleting, as `enabled` is always True afterwards
|
for module in selected:
|
||||||
if self.mgr.addon_meta(module).enabled:
|
# doing this before deleting, as `enabled` is always True afterwards
|
||||||
self._require_restart = True
|
if self.mgr.addon_meta(module).enabled:
|
||||||
if not self.mgr.deleteAddon(module):
|
self._require_restart = True
|
||||||
break
|
self.mgr.deleteAddon(module)
|
||||||
|
except OSError as e:
|
||||||
|
showWarning(
|
||||||
|
tr.addons_unable_to_update_or_delete_addon(val=str(e)),
|
||||||
|
textFormat="plain",
|
||||||
|
)
|
||||||
self.form.addonList.clearSelection()
|
self.form.addonList.clearSelection()
|
||||||
self.redrawAddons()
|
self.redrawAddons()
|
||||||
|
|
||||||
|
|
|
@ -1211,6 +1211,22 @@ gui_hooks.webview_did_inject_style_into_page.append(mytest)
|
||||||
args=["dialog: aqt.addons.AddonsDialog", "ids: list[str]"],
|
args=["dialog: aqt.addons.AddonsDialog", "ids: list[str]"],
|
||||||
doc="""Allows doing an action before an add-on is deleted.""",
|
doc="""Allows doing an action before an add-on is deleted.""",
|
||||||
),
|
),
|
||||||
|
Hook(
|
||||||
|
name="addon_manager_will_install_addon",
|
||||||
|
args=["manager: aqt.addons.AddonManager", "module: str"],
|
||||||
|
doc="""Called before installing or updating an addon.
|
||||||
|
|
||||||
|
Can be used to release DB connections or open files that
|
||||||
|
would prevent an update from succeeding.""",
|
||||||
|
),
|
||||||
|
Hook(
|
||||||
|
name="addon_manager_did_install_addon",
|
||||||
|
args=["manager: aqt.addons.AddonManager", "module: str"],
|
||||||
|
doc="""Called after installing or updating an addon.
|
||||||
|
|
||||||
|
Can be used to restore DB connections or open files after
|
||||||
|
an add-on has been updated.""",
|
||||||
|
),
|
||||||
# Model
|
# Model
|
||||||
###################
|
###################
|
||||||
Hook(
|
Hook(
|
||||||
|
|
Loading…
Reference in a new issue