mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
add a flag to handle the legacy hook missing args case
And update a few more hooks.
This commit is contained in:
parent
b86ae31907
commit
d266dcd076
10 changed files with 93 additions and 24 deletions
|
@ -13,7 +13,6 @@ import anki # pylint: disable=unused-import
|
|||
from anki import hooks
|
||||
from anki.consts import *
|
||||
from anki.errors import DeckRenameError
|
||||
from anki.hooks import runHook
|
||||
from anki.lang import _
|
||||
from anki.utils import ids2str, intTime
|
||||
|
||||
|
@ -167,8 +166,6 @@ class DeckManager:
|
|||
self.save(g)
|
||||
self.maybeAddToActive()
|
||||
hooks.run_deck_created_hook(g)
|
||||
# legacy hook did not pass deck
|
||||
runHook("newDeck")
|
||||
return int(id)
|
||||
|
||||
def rem(self, did: int, cardsToo: bool = False, childrenToo: bool = True) -> None:
|
||||
|
|
|
@ -54,6 +54,7 @@ rendered_card_template_filter: List[
|
|||
str,
|
||||
]
|
||||
] = []
|
||||
sync_progress_message_hook: List[Callable[[str], None]] = []
|
||||
sync_stage_hook: List[Callable[[str], None]] = []
|
||||
tag_created_hook: List[Callable[[str], None]] = []
|
||||
|
||||
|
@ -78,6 +79,8 @@ def run_deck_created_hook(deck: Dict[str, Any]) -> None:
|
|||
# if the hook fails, remove it
|
||||
deck_created_hook.remove(hook)
|
||||
raise
|
||||
# legacy support
|
||||
runHook("newDeck")
|
||||
|
||||
|
||||
def run_exported_media_files_hook(count: int) -> None:
|
||||
|
@ -166,6 +169,8 @@ def run_note_type_created_hook(notetype: Dict[str, Any]) -> None:
|
|||
# if the hook fails, remove it
|
||||
note_type_created_hook.remove(hook)
|
||||
raise
|
||||
# legacy support
|
||||
runHook("newModel")
|
||||
|
||||
|
||||
def run_odue_invalid_hook() -> None:
|
||||
|
@ -222,6 +227,18 @@ def run_rendered_card_template_filter(
|
|||
return text
|
||||
|
||||
|
||||
def run_sync_progress_message_hook(msg: str) -> None:
|
||||
for hook in sync_progress_message_hook:
|
||||
try:
|
||||
hook(msg)
|
||||
except:
|
||||
# if the hook fails, remove it
|
||||
sync_progress_message_hook.remove(hook)
|
||||
raise
|
||||
# legacy support
|
||||
runHook("syncMsg", msg)
|
||||
|
||||
|
||||
def run_sync_stage_hook(stage: str) -> None:
|
||||
for hook in sync_stage_hook:
|
||||
try:
|
||||
|
@ -230,6 +247,8 @@ def run_sync_stage_hook(stage: str) -> None:
|
|||
# if the hook fails, remove it
|
||||
sync_stage_hook.remove(hook)
|
||||
raise
|
||||
# legacy support
|
||||
runHook("sync", stage)
|
||||
|
||||
|
||||
def run_tag_created_hook(tag: str) -> None:
|
||||
|
@ -240,6 +259,8 @@ def run_tag_created_hook(tag: str) -> None:
|
|||
# if the hook fails, remove it
|
||||
tag_created_hook.remove(hook)
|
||||
raise
|
||||
# legacy support
|
||||
runHook("newTag")
|
||||
|
||||
|
||||
# @@AUTOGEN@@
|
||||
|
|
|
@ -22,6 +22,8 @@ class Hook:
|
|||
return_type: Optional[str] = None
|
||||
# if add-ons may be relying on the legacy hook name, add it here
|
||||
legacy_hook: Optional[str] = None
|
||||
# if legacy hook takes no arguments but the new hook does, set this
|
||||
legacy_no_args: bool = False
|
||||
|
||||
def callable(self) -> str:
|
||||
"Convert args into a Callable."
|
||||
|
@ -63,6 +65,13 @@ class Hook:
|
|||
# hook
|
||||
return self.hook_fire_code()
|
||||
|
||||
def legacy_args(self) -> str:
|
||||
if self.legacy_no_args:
|
||||
# hook name only
|
||||
return f'"{self.legacy_hook}"'
|
||||
else:
|
||||
return ", ".join([f'"{self.legacy_hook}"'] + self.arg_names())
|
||||
|
||||
def hook_fire_code(self) -> str:
|
||||
arg_names = self.arg_names()
|
||||
out = f"""\
|
||||
|
@ -76,10 +85,9 @@ def run_{self.full_name()}({", ".join(self.args or [])}) -> None:
|
|||
raise
|
||||
"""
|
||||
if self.legacy_hook:
|
||||
args = ", ".join([f'"{self.legacy_hook}"'] + arg_names)
|
||||
out += f"""\
|
||||
# legacy support
|
||||
runHook({args})
|
||||
runHook({self.legacy_args()})
|
||||
"""
|
||||
return out + "\n\n"
|
||||
|
||||
|
@ -96,10 +104,9 @@ def run_{self.full_name()}({", ".join(self.args or [])}) -> {self.return_type}:
|
|||
raise
|
||||
"""
|
||||
if self.legacy_hook:
|
||||
args = ", ".join([f'"{self.legacy_hook}"'] + arg_names)
|
||||
out += f"""\
|
||||
# legacy support
|
||||
runFilter({args})
|
||||
runFilter({self.legacy_args()})
|
||||
"""
|
||||
|
||||
out += f"""\
|
||||
|
|
|
@ -12,7 +12,6 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
|||
import anki # pylint: disable=unused-import
|
||||
from anki import hooks
|
||||
from anki.consts import *
|
||||
from anki.hooks import runHook
|
||||
from anki.lang import _
|
||||
from anki.types import Field, NoteType, Template
|
||||
from anki.utils import checksum, ids2str, intTime, joinFields, splitFields
|
||||
|
@ -109,8 +108,6 @@ class ModelManager:
|
|||
self._syncTemplates(m)
|
||||
self.changed = True
|
||||
hooks.run_note_type_created_hook(m)
|
||||
# legacy hook did not pass note type
|
||||
runHook("newModel")
|
||||
|
||||
def flush(self) -> None:
|
||||
"Flush the registry if any models were changed."
|
||||
|
|
|
@ -19,7 +19,6 @@ from anki.db import DB, DBError
|
|||
from anki.utils import checksum, devMode, ids2str, intTime, platDesc, versionWithBuild
|
||||
|
||||
from . import hooks
|
||||
from .hooks import runHook
|
||||
from .lang import ngettext
|
||||
|
||||
# syncing vars
|
||||
|
@ -836,8 +835,7 @@ class MediaSyncer:
|
|||
if not fnames:
|
||||
break
|
||||
|
||||
runHook(
|
||||
"syncMsg",
|
||||
hooks.run_sync_progress_message_hook(
|
||||
ngettext(
|
||||
"%d media change to upload", "%d media changes to upload", toSend
|
||||
)
|
||||
|
@ -888,8 +886,7 @@ class MediaSyncer:
|
|||
fnames = fnames[cnt:]
|
||||
|
||||
n = self.downloadCount
|
||||
runHook(
|
||||
"syncMsg",
|
||||
hooks.run_sync_progress_message_hook(
|
||||
ngettext("%d media file downloaded", "%d media files downloaded", n)
|
||||
% n,
|
||||
)
|
||||
|
|
|
@ -17,7 +17,6 @@ from typing import Callable, Dict, List, Tuple
|
|||
|
||||
import anki # pylint: disable=unused-import
|
||||
from anki import hooks
|
||||
from anki.hooks import runHook
|
||||
from anki.utils import ids2str, intTime
|
||||
|
||||
|
||||
|
@ -52,7 +51,6 @@ class TagManager:
|
|||
self.changed = True
|
||||
if found:
|
||||
hooks.run_tag_created_hook(t) # pylint: disable=undefined-loop-variable
|
||||
runHook("newTag")
|
||||
|
||||
def all(self) -> List:
|
||||
return list(self.tags.keys())
|
||||
|
|
|
@ -25,7 +25,12 @@ hooks = [
|
|||
args=["col: anki.storage._Collection", "ids: List[int]"],
|
||||
legacy_hook="remNotes",
|
||||
),
|
||||
Hook(name="deck_created", args=["deck: Dict[str, Any]"]),
|
||||
Hook(
|
||||
name="deck_created",
|
||||
args=["deck: Dict[str, Any]"],
|
||||
legacy_hook="newDeck",
|
||||
legacy_no_args=True,
|
||||
),
|
||||
Hook(name="exported_media_files", args=["count: int"]),
|
||||
Hook(
|
||||
name="create_exporters_list",
|
||||
|
@ -37,11 +42,19 @@ hooks = [
|
|||
args=["searches: Dict[str, Callable]"],
|
||||
legacy_hook="search",
|
||||
),
|
||||
Hook(name="note_type_created", args=["notetype: Dict[str, Any]"]),
|
||||
Hook(name="sync_stage", args=["stage: str"]),
|
||||
Hook(
|
||||
name="note_type_created",
|
||||
args=["notetype: Dict[str, Any]"],
|
||||
legacy_hook="newModel",
|
||||
legacy_no_args=True,
|
||||
),
|
||||
Hook(name="sync_stage", args=["stage: str"], legacy_hook="sync"),
|
||||
Hook(name="sync_progress_message", args=["msg: str"], legacy_hook="syncMsg"),
|
||||
Hook(name="http_data_sent", args=["bytes: int"]),
|
||||
Hook(name="http_data_received", args=["bytes: int"]),
|
||||
Hook(name="tag_created", args=["tag: str"]),
|
||||
Hook(
|
||||
name="tag_created", args=["tag: str"], legacy_hook="newTag", legacy_no_args=True
|
||||
),
|
||||
Hook(
|
||||
name="modify_fields_for_rendering",
|
||||
args=["fields: Dict[str, str]", "notetype: Dict[str, Any]", "data: QAData",],
|
||||
|
|
|
@ -9,6 +9,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import Any, Callable, Dict, List # pylint: disable=unused-import
|
||||
|
||||
from anki.cards import Card
|
||||
from anki.hooks import runFilter, runHook # pylint: disable=unused-import
|
||||
|
||||
# New hook/filter handling
|
||||
|
@ -20,6 +21,8 @@ from anki.hooks import runFilter, runHook # pylint: disable=unused-import
|
|||
|
||||
mpv_idle_hook: List[Callable[[], None]] = []
|
||||
mpv_will_play_hook: List[Callable[[str], None]] = []
|
||||
reviewer_showing_answer_hook: List[Callable[[Card], None]] = []
|
||||
reviewer_showing_question_hook: List[Callable[[Card], None]] = []
|
||||
|
||||
|
||||
def run_mpv_idle_hook() -> None:
|
||||
|
@ -44,4 +47,28 @@ def run_mpv_will_play_hook(file: str) -> None:
|
|||
runHook("mpvWillPlay", file)
|
||||
|
||||
|
||||
def run_reviewer_showing_answer_hook(card: Card) -> None:
|
||||
for hook in reviewer_showing_answer_hook:
|
||||
try:
|
||||
hook(card)
|
||||
except:
|
||||
# if the hook fails, remove it
|
||||
reviewer_showing_answer_hook.remove(hook)
|
||||
raise
|
||||
# legacy support
|
||||
runHook("showAnswer")
|
||||
|
||||
|
||||
def run_reviewer_showing_question_hook(card: Card) -> None:
|
||||
for hook in reviewer_showing_question_hook:
|
||||
try:
|
||||
hook(card)
|
||||
except:
|
||||
# if the hook fails, remove it
|
||||
reviewer_showing_question_hook.remove(hook)
|
||||
raise
|
||||
# legacy support
|
||||
runHook("showQuestion")
|
||||
|
||||
|
||||
# @@AUTOGEN@@
|
||||
|
|
|
@ -16,7 +16,7 @@ from anki.cards import Card
|
|||
from anki.hooks import runFilter, runHook
|
||||
from anki.lang import _, ngettext
|
||||
from anki.utils import bodyClass, stripHTML
|
||||
from aqt import AnkiQt
|
||||
from aqt import AnkiQt, gui_hooks
|
||||
from aqt.qt import *
|
||||
from aqt.sound import clearAudioQueue, getAudio, play, playFromText
|
||||
from aqt.utils import (
|
||||
|
@ -200,7 +200,7 @@ The front of this card is empty. Please run Tools>Empty Cards."""
|
|||
if self.typeCorrect:
|
||||
self.mw.web.setFocus()
|
||||
# user hook
|
||||
runHook("showQuestion")
|
||||
gui_hooks.run_reviewer_showing_question_hook(c)
|
||||
|
||||
def autoplay(self, card):
|
||||
return self.mw.col.decks.confForDid(card.odid or card.did)["autoplay"]
|
||||
|
@ -235,7 +235,7 @@ The front of this card is empty. Please run Tools>Empty Cards."""
|
|||
self.web.eval("_showAnswer(%s);" % json.dumps(a))
|
||||
self._showEaseButtons()
|
||||
# user hook
|
||||
runHook("showAnswer")
|
||||
gui_hooks.run_reviewer_showing_answer_hook(c)
|
||||
|
||||
# Answering a card
|
||||
############################################################
|
||||
|
|
|
@ -15,6 +15,18 @@ from anki.hooks_gen import Hook, update_file
|
|||
hooks = [
|
||||
Hook(name="mpv_idle"),
|
||||
Hook(name="mpv_will_play", args=["file: str"], legacy_hook="mpvWillPlay"),
|
||||
Hook(
|
||||
name="reviewer_showing_question",
|
||||
args=["card: Card"],
|
||||
legacy_hook="showQuestion",
|
||||
legacy_no_args=True,
|
||||
),
|
||||
Hook(
|
||||
name="reviewer_showing_answer",
|
||||
args=["card: Card"],
|
||||
legacy_hook="showAnswer",
|
||||
legacy_no_args=True,
|
||||
),
|
||||
]
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Reference in a new issue