mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
tweak the hook names in anki/
still a work in progress
This commit is contained in:
parent
eb6723a2ee
commit
b2f756f1b7
22 changed files with 412 additions and 406 deletions
|
@ -87,7 +87,7 @@ class Card:
|
||||||
self.usn = self.col.usn()
|
self.usn = self.col.usn()
|
||||||
# bug check
|
# bug check
|
||||||
if self.queue == 2 and self.odue and not self.col.decks.isDyn(self.did):
|
if self.queue == 2 and self.odue and not self.col.decks.isDyn(self.did):
|
||||||
hooks.odue_invalid_hook()
|
hooks.card_odue_was_invalid_hook()
|
||||||
assert self.due < 4294967296
|
assert self.due < 4294967296
|
||||||
self.col.db.execute(
|
self.col.db.execute(
|
||||||
"""
|
"""
|
||||||
|
@ -119,7 +119,7 @@ insert or replace into cards values
|
||||||
self.usn = self.col.usn()
|
self.usn = self.col.usn()
|
||||||
# bug checks
|
# bug checks
|
||||||
if self.queue == 2 and self.odue and not self.col.decks.isDyn(self.did):
|
if self.queue == 2 and self.odue and not self.col.decks.isDyn(self.did):
|
||||||
hooks.odue_invalid_hook()
|
hooks.card_odue_was_invalid_hook()
|
||||||
assert self.due < 4294967296
|
assert self.due < 4294967296
|
||||||
self.col.db.execute(
|
self.col.db.execute(
|
||||||
"""update cards set
|
"""update cards set
|
||||||
|
|
|
@ -272,7 +272,7 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
|
||||||
def modSchema(self, check: bool) -> None:
|
def modSchema(self, check: bool) -> None:
|
||||||
"Mark schema modified. Call this first so user can abort if necessary."
|
"Mark schema modified. Call this first so user can abort if necessary."
|
||||||
if not self.schemaChanged():
|
if not self.schemaChanged():
|
||||||
if check and not hooks.mod_schema_filter(proceed=True):
|
if check and not hooks.schema_will_change_filter(proceed=True):
|
||||||
raise AnkiError("abortSchemaMod")
|
raise AnkiError("abortSchemaMod")
|
||||||
self.scm = intTime(1000)
|
self.scm = intTime(1000)
|
||||||
self.setMod()
|
self.setMod()
|
||||||
|
@ -372,7 +372,7 @@ crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
|
||||||
strids = ids2str(ids)
|
strids = ids2str(ids)
|
||||||
# we need to log these independently of cards, as one side may have
|
# we need to log these independently of cards, as one side may have
|
||||||
# more card templates
|
# more card templates
|
||||||
hooks.remove_notes_hook(self, ids)
|
hooks.notes_will_delete_hook(self, ids)
|
||||||
self._logRem(ids, REM_NOTE)
|
self._logRem(ids, REM_NOTE)
|
||||||
self.db.execute("delete from notes where id in %s" % strids)
|
self.db.execute("delete from notes where id in %s" % strids)
|
||||||
|
|
||||||
|
@ -665,12 +665,12 @@ where c.nid = n.id and c.id in %s group by nid"""
|
||||||
fields["c%d" % (card_ord + 1)] = "1"
|
fields["c%d" % (card_ord + 1)] = "1"
|
||||||
|
|
||||||
# allow add-ons to modify the available fields
|
# allow add-ons to modify the available fields
|
||||||
hooks.modify_fields_for_rendering_hook(fields, model, data)
|
hooks.fields_will_render_hook(fields, model, data)
|
||||||
fields = runFilter("mungeFields", fields, model, data, self) # legacy
|
fields = runFilter("mungeFields", fields, model, data, self) # legacy
|
||||||
|
|
||||||
# and the template prior to rendering
|
# and the template prior to rendering
|
||||||
qfmt = hooks.original_card_template_filter(qfmt, True)
|
qfmt = hooks.card_template_will_render_filter(qfmt, True)
|
||||||
afmt = hooks.original_card_template_filter(afmt, False)
|
afmt = hooks.card_template_will_render_filter(afmt, False)
|
||||||
|
|
||||||
# render fields
|
# render fields
|
||||||
qatext = render_card(self, qfmt, afmt, fields, card_ord)
|
qatext = render_card(self, qfmt, afmt, fields, card_ord)
|
||||||
|
@ -678,7 +678,7 @@ where c.nid = n.id and c.id in %s group by nid"""
|
||||||
|
|
||||||
# allow add-ons to modify the generated result
|
# allow add-ons to modify the generated result
|
||||||
for type in "q", "a":
|
for type in "q", "a":
|
||||||
ret[type] = hooks.rendered_card_template_filter(
|
ret[type] = hooks.card_template_did_render_filter(
|
||||||
ret[type], type, fields, model, data, self
|
ret[type], type, fields, model, data, self
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -165,7 +165,7 @@ class DeckManager:
|
||||||
self.decks[str(id)] = g
|
self.decks[str(id)] = g
|
||||||
self.save(g)
|
self.save(g)
|
||||||
self.maybeAddToActive()
|
self.maybeAddToActive()
|
||||||
hooks.deck_created_hook(g)
|
hooks.deck_did_create_hook(g)
|
||||||
return int(id)
|
return int(id)
|
||||||
|
|
||||||
def rem(self, did: int, cardsToo: bool = False, childrenToo: bool = True) -> None:
|
def rem(self, did: int, cardsToo: bool = False, childrenToo: bool = True) -> None:
|
||||||
|
|
|
@ -347,7 +347,7 @@ class AnkiPackageExporter(AnkiExporter):
|
||||||
else:
|
else:
|
||||||
z.write(mpath, cStr, zipfile.ZIP_STORED)
|
z.write(mpath, cStr, zipfile.ZIP_STORED)
|
||||||
media[cStr] = unicodedata.normalize("NFC", file)
|
media[cStr] = unicodedata.normalize("NFC", file)
|
||||||
hooks.exported_media_files_hook(c)
|
hooks.media_files_did_export_hook(c)
|
||||||
|
|
||||||
return media
|
return media
|
||||||
|
|
||||||
|
@ -417,5 +417,5 @@ def exporters() -> List[Tuple[str, Any]]:
|
||||||
id(TextNoteExporter),
|
id(TextNoteExporter),
|
||||||
id(TextCardExporter),
|
id(TextCardExporter),
|
||||||
]
|
]
|
||||||
hooks.create_exporters_list_hook(exps)
|
hooks.exporters_list_did_create_hook(exps)
|
||||||
return exps
|
return exps
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Finder:
|
||||||
flag=self._findFlag,
|
flag=self._findFlag,
|
||||||
)
|
)
|
||||||
self.search["is"] = self._findCardState
|
self.search["is"] = self._findCardState
|
||||||
hooks.prepare_searches_hook(self.search)
|
hooks.search_terms_did_prepare_hook(self.search)
|
||||||
|
|
||||||
def findCards(self, query, order=False) -> Any:
|
def findCards(self, query, order=False) -> Any:
|
||||||
"Return a list of card ids for QUERY."
|
"Return a list of card ids for QUERY."
|
||||||
|
|
|
@ -25,167 +25,10 @@ from anki.types import QAData
|
||||||
# The code in this section is automatically generated - any edits you make
|
# The code in this section is automatically generated - any edits you make
|
||||||
# will be lost. To add new hooks, see ../tools/genhooks.py
|
# will be lost. To add new hooks, see ../tools/genhooks.py
|
||||||
#
|
#
|
||||||
# To use an existing hook such as leech_hook, you would call the following
|
|
||||||
# in your code:
|
|
||||||
#
|
|
||||||
# from anki import hooks
|
|
||||||
# hooks.leech_hook.append(myfunc)
|
|
||||||
#
|
|
||||||
# @@AUTOGEN@@
|
# @@AUTOGEN@@
|
||||||
|
|
||||||
|
|
||||||
class _CreateExportersListHook:
|
class _CardDidLeechHook:
|
||||||
_hooks: List[Callable[[List[Tuple[str, Any]]], None]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[List[Tuple[str, Any]]], None]) -> None:
|
|
||||||
"""(exporters: List[Tuple[str, Any]])"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[List[Tuple[str, Any]]], None]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, exporters: List[Tuple[str, Any]]) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(exporters)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
# legacy support
|
|
||||||
runHook("exportersList", exporters)
|
|
||||||
|
|
||||||
|
|
||||||
create_exporters_list_hook = _CreateExportersListHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _DeckCreatedHook:
|
|
||||||
_hooks: List[Callable[[Dict[str, Any]], None]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
|
||||||
"""(deck: Dict[str, Any])"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, deck: Dict[str, Any]) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(deck)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
# legacy support
|
|
||||||
runHook("newDeck")
|
|
||||||
|
|
||||||
|
|
||||||
deck_created_hook = _DeckCreatedHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _ExportedMediaFilesHook:
|
|
||||||
_hooks: List[Callable[[int], None]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[int], None]) -> None:
|
|
||||||
"""(count: int)"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[int], None]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, count: int) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(count)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
exported_media_files_hook = _ExportedMediaFilesHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _FieldReplacementFilter:
|
|
||||||
_hooks: List[Callable[[str, str, str, Dict[str, str]], str]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[str, str, str, Dict[str, str]], str]) -> None:
|
|
||||||
"""(field_text: str, field_name: str, filter_name: str, fields: Dict[str, str])"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[str, str, str, Dict[str, str]], str]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(
|
|
||||||
self, field_text: str, field_name: str, filter_name: str, fields: Dict[str, str]
|
|
||||||
) -> str:
|
|
||||||
for filter in self._hooks:
|
|
||||||
try:
|
|
||||||
field_text = filter(field_text, field_name, filter_name, fields)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(filter)
|
|
||||||
raise
|
|
||||||
return field_text
|
|
||||||
|
|
||||||
|
|
||||||
field_replacement_filter = _FieldReplacementFilter()
|
|
||||||
|
|
||||||
|
|
||||||
class _HttpDataReceivedHook:
|
|
||||||
_hooks: List[Callable[[int], None]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[int], None]) -> None:
|
|
||||||
"""(bytes: int)"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[int], None]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, bytes: int) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(bytes)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
http_data_received_hook = _HttpDataReceivedHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _HttpDataSentHook:
|
|
||||||
_hooks: List[Callable[[int], None]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[int], None]) -> None:
|
|
||||||
"""(bytes: int)"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[int], None]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, bytes: int) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(bytes)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
http_data_sent_hook = _HttpDataSentHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _LeechHook:
|
|
||||||
_hooks: List[Callable[[Card], None]] = []
|
_hooks: List[Callable[[Card], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[Card], None]) -> None:
|
def append(self, cb: Callable[[Card], None]) -> None:
|
||||||
|
@ -208,91 +51,10 @@ class _LeechHook:
|
||||||
runHook("leech", card)
|
runHook("leech", card)
|
||||||
|
|
||||||
|
|
||||||
leech_hook = _LeechHook()
|
card_did_leech_hook = _CardDidLeechHook()
|
||||||
|
|
||||||
|
|
||||||
class _ModSchemaFilter:
|
class _CardOdueWasInvalidHook:
|
||||||
_hooks: List[Callable[[bool], bool]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[bool], bool]) -> None:
|
|
||||||
"""(proceed: bool)"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[bool], bool]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, proceed: bool) -> bool:
|
|
||||||
for filter in self._hooks:
|
|
||||||
try:
|
|
||||||
proceed = filter(proceed)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(filter)
|
|
||||||
raise
|
|
||||||
return proceed
|
|
||||||
|
|
||||||
|
|
||||||
mod_schema_filter = _ModSchemaFilter()
|
|
||||||
|
|
||||||
|
|
||||||
class _ModifyFieldsForRenderingHook:
|
|
||||||
_hooks: List[Callable[[Dict[str, str], Dict[str, Any], QAData], None]] = []
|
|
||||||
|
|
||||||
def append(
|
|
||||||
self, cb: Callable[[Dict[str, str], Dict[str, Any], QAData], None]
|
|
||||||
) -> None:
|
|
||||||
"""(fields: Dict[str, str], notetype: Dict[str, Any], data: QAData)"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(
|
|
||||||
self, cb: Callable[[Dict[str, str], Dict[str, Any], QAData], None]
|
|
||||||
) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(
|
|
||||||
self, fields: Dict[str, str], notetype: Dict[str, Any], data: QAData
|
|
||||||
) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(fields, notetype, data)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
modify_fields_for_rendering_hook = _ModifyFieldsForRenderingHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _NoteTypeCreatedHook:
|
|
||||||
_hooks: List[Callable[[Dict[str, Any]], None]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
|
||||||
"""(notetype: Dict[str, Any])"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, notetype: Dict[str, Any]) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(notetype)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
# legacy support
|
|
||||||
runHook("newModel")
|
|
||||||
|
|
||||||
|
|
||||||
note_type_created_hook = _NoteTypeCreatedHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _OdueInvalidHook:
|
|
||||||
_hooks: List[Callable[[], None]] = []
|
_hooks: List[Callable[[], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[], None]) -> None:
|
def append(self, cb: Callable[[], None]) -> None:
|
||||||
|
@ -313,91 +75,12 @@ class _OdueInvalidHook:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
odue_invalid_hook = _OdueInvalidHook()
|
card_odue_was_invalid_hook = _CardOdueWasInvalidHook()
|
||||||
|
|
||||||
|
|
||||||
class _OriginalCardTemplateFilter:
|
class _CardTemplateDidRenderFilter:
|
||||||
_hooks: List[Callable[[str, bool], str]] = []
|
"""Can modify the resulting text after rendering completes."""
|
||||||
|
|
||||||
def append(self, cb: Callable[[str, bool], str]) -> None:
|
|
||||||
"""(template: str, question_side: bool)"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[str, bool], str]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, template: str, question_side: bool) -> str:
|
|
||||||
for filter in self._hooks:
|
|
||||||
try:
|
|
||||||
template = filter(template, question_side)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(filter)
|
|
||||||
raise
|
|
||||||
return template
|
|
||||||
|
|
||||||
|
|
||||||
original_card_template_filter = _OriginalCardTemplateFilter()
|
|
||||||
|
|
||||||
|
|
||||||
class _PrepareSearchesHook:
|
|
||||||
_hooks: List[Callable[[Dict[str, Callable]], None]] = []
|
|
||||||
|
|
||||||
def append(self, cb: Callable[[Dict[str, Callable]], None]) -> None:
|
|
||||||
"""(searches: Dict[str, Callable])"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(self, cb: Callable[[Dict[str, Callable]], None]) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, searches: Dict[str, Callable]) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(searches)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
# legacy support
|
|
||||||
runHook("search", searches)
|
|
||||||
|
|
||||||
|
|
||||||
prepare_searches_hook = _PrepareSearchesHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _RemoveNotesHook:
|
|
||||||
_hooks: List[Callable[["anki.storage._Collection", List[int]], None]] = []
|
|
||||||
|
|
||||||
def append(
|
|
||||||
self, cb: Callable[["anki.storage._Collection", List[int]], None]
|
|
||||||
) -> None:
|
|
||||||
"""(col: anki.storage._Collection, ids: List[int])"""
|
|
||||||
self._hooks.append(cb)
|
|
||||||
|
|
||||||
def remove(
|
|
||||||
self, cb: Callable[["anki.storage._Collection", List[int]], None]
|
|
||||||
) -> None:
|
|
||||||
if cb in self._hooks:
|
|
||||||
self._hooks.remove(cb)
|
|
||||||
|
|
||||||
def __call__(self, col: anki.storage._Collection, ids: List[int]) -> None:
|
|
||||||
for hook in self._hooks:
|
|
||||||
try:
|
|
||||||
hook(col, ids)
|
|
||||||
except:
|
|
||||||
# if the hook fails, remove it
|
|
||||||
self._hooks.remove(hook)
|
|
||||||
raise
|
|
||||||
# legacy support
|
|
||||||
runHook("remNotes", col, ids)
|
|
||||||
|
|
||||||
|
|
||||||
remove_notes_hook = _RemoveNotesHook()
|
|
||||||
|
|
||||||
|
|
||||||
class _RenderedCardTemplateFilter:
|
|
||||||
_hooks: List[
|
_hooks: List[
|
||||||
Callable[
|
Callable[
|
||||||
[
|
[
|
||||||
|
@ -467,10 +150,327 @@ class _RenderedCardTemplateFilter:
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
rendered_card_template_filter = _RenderedCardTemplateFilter()
|
card_template_did_render_filter = _CardTemplateDidRenderFilter()
|
||||||
|
|
||||||
|
|
||||||
class _SyncProgressMessageHook:
|
class _CardTemplateFilterWillApplyFilter:
|
||||||
|
_hooks: List[Callable[[str, str, str, Dict[str, str]], str]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[str, str, str, Dict[str, str]], str]) -> None:
|
||||||
|
"""(field_text: str, field_name: str, filter_name: str, fields: Dict[str, str])"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[str, str, str, Dict[str, str]], str]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(
|
||||||
|
self, field_text: str, field_name: str, filter_name: str, fields: Dict[str, str]
|
||||||
|
) -> str:
|
||||||
|
for filter in self._hooks:
|
||||||
|
try:
|
||||||
|
field_text = filter(field_text, field_name, filter_name, fields)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(filter)
|
||||||
|
raise
|
||||||
|
return field_text
|
||||||
|
|
||||||
|
|
||||||
|
card_template_filter_will_apply_filter = _CardTemplateFilterWillApplyFilter()
|
||||||
|
|
||||||
|
|
||||||
|
class _CardTemplateWillRenderFilter:
|
||||||
|
"""Can modify the the card template used for rendering."""
|
||||||
|
|
||||||
|
_hooks: List[Callable[[str, bool], str]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[str, bool], str]) -> None:
|
||||||
|
"""(template: str, question_side: bool)"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[str, bool], str]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, template: str, question_side: bool) -> str:
|
||||||
|
for filter in self._hooks:
|
||||||
|
try:
|
||||||
|
template = filter(template, question_side)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(filter)
|
||||||
|
raise
|
||||||
|
return template
|
||||||
|
|
||||||
|
|
||||||
|
card_template_will_render_filter = _CardTemplateWillRenderFilter()
|
||||||
|
|
||||||
|
|
||||||
|
class _DeckDidCreateHook:
|
||||||
|
_hooks: List[Callable[[Dict[str, Any]], None]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
||||||
|
"""(deck: Dict[str, Any])"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, deck: Dict[str, Any]) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(deck)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
# legacy support
|
||||||
|
runHook("newDeck")
|
||||||
|
|
||||||
|
|
||||||
|
deck_did_create_hook = _DeckDidCreateHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _ExportersListDidCreateHook:
|
||||||
|
_hooks: List[Callable[[List[Tuple[str, Any]]], None]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[List[Tuple[str, Any]]], None]) -> None:
|
||||||
|
"""(exporters: List[Tuple[str, Any]])"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[List[Tuple[str, Any]]], None]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, exporters: List[Tuple[str, Any]]) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(exporters)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
# legacy support
|
||||||
|
runHook("exportersList", exporters)
|
||||||
|
|
||||||
|
|
||||||
|
exporters_list_did_create_hook = _ExportersListDidCreateHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _FieldsWillRenderHook:
|
||||||
|
"""Can modify the available fields prior to rendering."""
|
||||||
|
|
||||||
|
_hooks: List[Callable[[Dict[str, str], Dict[str, Any], QAData], None]] = []
|
||||||
|
|
||||||
|
def append(
|
||||||
|
self, cb: Callable[[Dict[str, str], Dict[str, Any], QAData], None]
|
||||||
|
) -> None:
|
||||||
|
"""(fields: Dict[str, str], notetype: Dict[str, Any], data: QAData)"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(
|
||||||
|
self, cb: Callable[[Dict[str, str], Dict[str, Any], QAData], None]
|
||||||
|
) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(
|
||||||
|
self, fields: Dict[str, str], notetype: Dict[str, Any], data: QAData
|
||||||
|
) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(fields, notetype, data)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
fields_will_render_hook = _FieldsWillRenderHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _HttpDataDidReceiveHook:
|
||||||
|
_hooks: List[Callable[[int], None]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[int], None]) -> None:
|
||||||
|
"""(bytes: int)"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[int], None]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, bytes: int) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(bytes)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
http_data_did_receive_hook = _HttpDataDidReceiveHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _HttpDataDidSendHook:
|
||||||
|
_hooks: List[Callable[[int], None]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[int], None]) -> None:
|
||||||
|
"""(bytes: int)"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[int], None]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, bytes: int) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(bytes)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
http_data_did_send_hook = _HttpDataDidSendHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _MediaFilesDidExportHook:
|
||||||
|
_hooks: List[Callable[[int], None]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[int], None]) -> None:
|
||||||
|
"""(count: int)"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[int], None]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, count: int) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(count)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
media_files_did_export_hook = _MediaFilesDidExportHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _NoteTypeDidCreateHook:
|
||||||
|
_hooks: List[Callable[[Dict[str, Any]], None]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
||||||
|
"""(notetype: Dict[str, Any])"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[Dict[str, Any]], None]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, notetype: Dict[str, Any]) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(notetype)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
# legacy support
|
||||||
|
runHook("newModel")
|
||||||
|
|
||||||
|
|
||||||
|
note_type_did_create_hook = _NoteTypeDidCreateHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _NotesWillDeleteHook:
|
||||||
|
_hooks: List[Callable[["anki.storage._Collection", List[int]], None]] = []
|
||||||
|
|
||||||
|
def append(
|
||||||
|
self, cb: Callable[["anki.storage._Collection", List[int]], None]
|
||||||
|
) -> None:
|
||||||
|
"""(col: anki.storage._Collection, ids: List[int])"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(
|
||||||
|
self, cb: Callable[["anki.storage._Collection", List[int]], None]
|
||||||
|
) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, col: anki.storage._Collection, ids: List[int]) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(col, ids)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
# legacy support
|
||||||
|
runHook("remNotes", col, ids)
|
||||||
|
|
||||||
|
|
||||||
|
notes_will_delete_hook = _NotesWillDeleteHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _SchemaWillChangeFilter:
|
||||||
|
_hooks: List[Callable[[bool], bool]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[bool], bool]) -> None:
|
||||||
|
"""(proceed: bool)"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[bool], bool]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, proceed: bool) -> bool:
|
||||||
|
for filter in self._hooks:
|
||||||
|
try:
|
||||||
|
proceed = filter(proceed)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(filter)
|
||||||
|
raise
|
||||||
|
return proceed
|
||||||
|
|
||||||
|
|
||||||
|
schema_will_change_filter = _SchemaWillChangeFilter()
|
||||||
|
|
||||||
|
|
||||||
|
class _SearchTermsDidPrepareHook:
|
||||||
|
_hooks: List[Callable[[Dict[str, Callable]], None]] = []
|
||||||
|
|
||||||
|
def append(self, cb: Callable[[Dict[str, Callable]], None]) -> None:
|
||||||
|
"""(searches: Dict[str, Callable])"""
|
||||||
|
self._hooks.append(cb)
|
||||||
|
|
||||||
|
def remove(self, cb: Callable[[Dict[str, Callable]], None]) -> None:
|
||||||
|
if cb in self._hooks:
|
||||||
|
self._hooks.remove(cb)
|
||||||
|
|
||||||
|
def __call__(self, searches: Dict[str, Callable]) -> None:
|
||||||
|
for hook in self._hooks:
|
||||||
|
try:
|
||||||
|
hook(searches)
|
||||||
|
except:
|
||||||
|
# if the hook fails, remove it
|
||||||
|
self._hooks.remove(hook)
|
||||||
|
raise
|
||||||
|
# legacy support
|
||||||
|
runHook("search", searches)
|
||||||
|
|
||||||
|
|
||||||
|
search_terms_did_prepare_hook = _SearchTermsDidPrepareHook()
|
||||||
|
|
||||||
|
|
||||||
|
class _SyncProgressDidChangeHook:
|
||||||
_hooks: List[Callable[[str], None]] = []
|
_hooks: List[Callable[[str], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[str], None]) -> None:
|
def append(self, cb: Callable[[str], None]) -> None:
|
||||||
|
@ -493,10 +493,10 @@ class _SyncProgressMessageHook:
|
||||||
runHook("syncMsg", msg)
|
runHook("syncMsg", msg)
|
||||||
|
|
||||||
|
|
||||||
sync_progress_message_hook = _SyncProgressMessageHook()
|
sync_progress_did_change_hook = _SyncProgressDidChangeHook()
|
||||||
|
|
||||||
|
|
||||||
class _SyncStageHook:
|
class _SyncStageDidChangeHook:
|
||||||
_hooks: List[Callable[[str], None]] = []
|
_hooks: List[Callable[[str], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[str], None]) -> None:
|
def append(self, cb: Callable[[str], None]) -> None:
|
||||||
|
@ -519,10 +519,10 @@ class _SyncStageHook:
|
||||||
runHook("sync", stage)
|
runHook("sync", stage)
|
||||||
|
|
||||||
|
|
||||||
sync_stage_hook = _SyncStageHook()
|
sync_stage_did_change_hook = _SyncStageDidChangeHook()
|
||||||
|
|
||||||
|
|
||||||
class _TagCreatedHook:
|
class _TagDidCreateHook:
|
||||||
_hooks: List[Callable[[str], None]] = []
|
_hooks: List[Callable[[str], None]] = []
|
||||||
|
|
||||||
def append(self, cb: Callable[[str], None]) -> None:
|
def append(self, cb: Callable[[str], None]) -> None:
|
||||||
|
@ -545,7 +545,7 @@ class _TagCreatedHook:
|
||||||
runHook("newTag")
|
runHook("newTag")
|
||||||
|
|
||||||
|
|
||||||
tag_created_hook = _TagCreatedHook()
|
tag_did_create_hook = _TagDidCreateHook()
|
||||||
# @@AUTOGEN@@
|
# @@AUTOGEN@@
|
||||||
|
|
||||||
# Legacy hook handling
|
# Legacy hook handling
|
||||||
|
|
|
@ -184,4 +184,4 @@ def _errMsg(type: str, texpath: str) -> Any:
|
||||||
|
|
||||||
|
|
||||||
# setup q/a filter - type ignored due to import cycle
|
# setup q/a filter - type ignored due to import cycle
|
||||||
hooks.rendered_card_template_filter.append(mungeQA) # type: ignore
|
hooks.card_template_did_render_filter.append(mungeQA) # type: ignore
|
||||||
|
|
|
@ -107,7 +107,7 @@ class ModelManager:
|
||||||
if templates:
|
if templates:
|
||||||
self._syncTemplates(m)
|
self._syncTemplates(m)
|
||||||
self.changed = True
|
self.changed = True
|
||||||
hooks.note_type_created_hook(m)
|
hooks.note_type_did_create_hook(m)
|
||||||
|
|
||||||
def flush(self) -> None:
|
def flush(self) -> None:
|
||||||
"Flush the registry if any models were changed."
|
"Flush the registry if any models were changed."
|
||||||
|
|
|
@ -1150,7 +1150,7 @@ did = ?, queue = %s, due = ?, usn = ? where id = ?"""
|
||||||
card.odue = card.odid = 0
|
card.odue = card.odid = 0
|
||||||
card.queue = -1
|
card.queue = -1
|
||||||
# notify UI
|
# notify UI
|
||||||
hooks.leech_hook(card)
|
hooks.card_did_leech_hook(card)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Tools
|
# Tools
|
||||||
|
|
|
@ -1270,7 +1270,7 @@ where id = ?
|
||||||
if a == 0:
|
if a == 0:
|
||||||
card.queue = -1
|
card.queue = -1
|
||||||
# notify UI
|
# notify UI
|
||||||
hooks.leech_hook(card)
|
hooks.card_did_leech_hook(card)
|
||||||
return True
|
return True
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ class Syncer:
|
||||||
self.col.save()
|
self.col.save()
|
||||||
|
|
||||||
# step 1: login & metadata
|
# step 1: login & metadata
|
||||||
hooks.sync_stage_hook("login")
|
hooks.sync_stage_did_change_hook("login")
|
||||||
meta = self.server.meta()
|
meta = self.server.meta()
|
||||||
self.col.log("rmeta", meta)
|
self.col.log("rmeta", meta)
|
||||||
if not meta:
|
if not meta:
|
||||||
|
@ -95,7 +95,7 @@ class Syncer:
|
||||||
self.col.log("basic check")
|
self.col.log("basic check")
|
||||||
return "basicCheckFailed"
|
return "basicCheckFailed"
|
||||||
# step 2: startup and deletions
|
# step 2: startup and deletions
|
||||||
hooks.sync_stage_hook("meta")
|
hooks.sync_stage_did_change_hook("meta")
|
||||||
rrem = self.server.start(
|
rrem = self.server.start(
|
||||||
minUsn=self.minUsn, lnewer=self.lnewer, offset=self.col.localOffset()
|
minUsn=self.minUsn, lnewer=self.lnewer, offset=self.col.localOffset()
|
||||||
)
|
)
|
||||||
|
@ -118,31 +118,31 @@ class Syncer:
|
||||||
self.server.abort()
|
self.server.abort()
|
||||||
return self._forceFullSync()
|
return self._forceFullSync()
|
||||||
# step 3: stream large tables from server
|
# step 3: stream large tables from server
|
||||||
hooks.sync_stage_hook("server")
|
hooks.sync_stage_did_change_hook("server")
|
||||||
while 1:
|
while 1:
|
||||||
hooks.sync_stage_hook("stream")
|
hooks.sync_stage_did_change_hook("stream")
|
||||||
chunk = self.server.chunk()
|
chunk = self.server.chunk()
|
||||||
self.col.log("server chunk", chunk)
|
self.col.log("server chunk", chunk)
|
||||||
self.applyChunk(chunk=chunk)
|
self.applyChunk(chunk=chunk)
|
||||||
if chunk["done"]:
|
if chunk["done"]:
|
||||||
break
|
break
|
||||||
# step 4: stream to server
|
# step 4: stream to server
|
||||||
hooks.sync_stage_hook("client")
|
hooks.sync_stage_did_change_hook("client")
|
||||||
while 1:
|
while 1:
|
||||||
hooks.sync_stage_hook("stream")
|
hooks.sync_stage_did_change_hook("stream")
|
||||||
chunk = self.chunk()
|
chunk = self.chunk()
|
||||||
self.col.log("client chunk", chunk)
|
self.col.log("client chunk", chunk)
|
||||||
self.server.applyChunk(chunk=chunk)
|
self.server.applyChunk(chunk=chunk)
|
||||||
if chunk["done"]:
|
if chunk["done"]:
|
||||||
break
|
break
|
||||||
# step 5: sanity check
|
# step 5: sanity check
|
||||||
hooks.sync_stage_hook("sanity")
|
hooks.sync_stage_did_change_hook("sanity")
|
||||||
c = self.sanityCheck()
|
c = self.sanityCheck()
|
||||||
ret = self.server.sanityCheck2(client=c)
|
ret = self.server.sanityCheck2(client=c)
|
||||||
if ret["status"] != "ok":
|
if ret["status"] != "ok":
|
||||||
return self._forceFullSync()
|
return self._forceFullSync()
|
||||||
# finalize
|
# finalize
|
||||||
hooks.sync_stage_hook("finalize")
|
hooks.sync_stage_did_change_hook("finalize")
|
||||||
mod = self.server.finish()
|
mod = self.server.finish()
|
||||||
self.finish(mod)
|
self.finish(mod)
|
||||||
return "success"
|
return "success"
|
||||||
|
@ -501,7 +501,7 @@ class AnkiRequestsClient:
|
||||||
|
|
||||||
buf = io.BytesIO()
|
buf = io.BytesIO()
|
||||||
for chunk in resp.iter_content(chunk_size=HTTP_BUF_SIZE):
|
for chunk in resp.iter_content(chunk_size=HTTP_BUF_SIZE):
|
||||||
hooks.http_data_received_hook(len(chunk))
|
hooks.http_data_did_receive_hook(len(chunk))
|
||||||
buf.write(chunk)
|
buf.write(chunk)
|
||||||
return buf.getvalue()
|
return buf.getvalue()
|
||||||
|
|
||||||
|
@ -523,7 +523,7 @@ if os.environ.get("ANKI_NOVERIFYSSL"):
|
||||||
class _MonitoringFile(io.BufferedReader):
|
class _MonitoringFile(io.BufferedReader):
|
||||||
def read(self, size=-1) -> bytes:
|
def read(self, size=-1) -> bytes:
|
||||||
data = io.BufferedReader.read(self, HTTP_BUF_SIZE)
|
data = io.BufferedReader.read(self, HTTP_BUF_SIZE)
|
||||||
hooks.http_data_sent_hook(len(data))
|
hooks.http_data_did_send_hook(len(data))
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@ -707,13 +707,13 @@ class FullSyncer(HttpSyncer):
|
||||||
self.col = col
|
self.col = col
|
||||||
|
|
||||||
def download(self) -> Optional[str]:
|
def download(self) -> Optional[str]:
|
||||||
hooks.sync_stage_hook("download")
|
hooks.sync_stage_did_change_hook("download")
|
||||||
localNotEmpty = self.col.db.scalar("select 1 from cards")
|
localNotEmpty = self.col.db.scalar("select 1 from cards")
|
||||||
self.col.close()
|
self.col.close()
|
||||||
cont = self.req("download")
|
cont = self.req("download")
|
||||||
tpath = self.col.path + ".tmp"
|
tpath = self.col.path + ".tmp"
|
||||||
if cont == "upgradeRequired":
|
if cont == "upgradeRequired":
|
||||||
hooks.sync_stage_hook("upgradeRequired")
|
hooks.sync_stage_did_change_hook("upgradeRequired")
|
||||||
return None
|
return None
|
||||||
open(tpath, "wb").write(cont)
|
open(tpath, "wb").write(cont)
|
||||||
# check the received file is ok
|
# check the received file is ok
|
||||||
|
@ -733,7 +733,7 @@ class FullSyncer(HttpSyncer):
|
||||||
|
|
||||||
def upload(self) -> bool:
|
def upload(self) -> bool:
|
||||||
"True if upload successful."
|
"True if upload successful."
|
||||||
hooks.sync_stage_hook("upload")
|
hooks.sync_stage_did_change_hook("upload")
|
||||||
# make sure it's ok before we try to upload
|
# make sure it's ok before we try to upload
|
||||||
if self.col.db.scalar("pragma integrity_check") != "ok":
|
if self.col.db.scalar("pragma integrity_check") != "ok":
|
||||||
return False
|
return False
|
||||||
|
@ -765,7 +765,7 @@ class MediaSyncer:
|
||||||
|
|
||||||
def sync(self) -> Any:
|
def sync(self) -> Any:
|
||||||
# check if there have been any changes
|
# check if there have been any changes
|
||||||
hooks.sync_stage_hook("findMedia")
|
hooks.sync_stage_did_change_hook("findMedia")
|
||||||
self.col.log("findChanges")
|
self.col.log("findChanges")
|
||||||
try:
|
try:
|
||||||
self.col.media.findChanges()
|
self.col.media.findChanges()
|
||||||
|
@ -835,7 +835,7 @@ class MediaSyncer:
|
||||||
if not fnames:
|
if not fnames:
|
||||||
break
|
break
|
||||||
|
|
||||||
hooks.sync_progress_message_hook(
|
hooks.sync_progress_did_change_hook(
|
||||||
ngettext(
|
ngettext(
|
||||||
"%d media change to upload", "%d media changes to upload", toSend
|
"%d media change to upload", "%d media changes to upload", toSend
|
||||||
)
|
)
|
||||||
|
@ -886,7 +886,7 @@ class MediaSyncer:
|
||||||
fnames = fnames[cnt:]
|
fnames = fnames[cnt:]
|
||||||
|
|
||||||
n = self.downloadCount
|
n = self.downloadCount
|
||||||
hooks.sync_progress_message_hook(
|
hooks.sync_progress_did_change_hook(
|
||||||
ngettext("%d media file downloaded", "%d media files downloaded", n)
|
ngettext("%d media file downloaded", "%d media files downloaded", n)
|
||||||
% n,
|
% n,
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,7 +50,7 @@ class TagManager:
|
||||||
self.tags[t] = self.col.usn() if usn is None else usn
|
self.tags[t] = self.col.usn() if usn is None else usn
|
||||||
self.changed = True
|
self.changed = True
|
||||||
if found:
|
if found:
|
||||||
hooks.tag_created_hook(t) # pylint: disable=undefined-loop-variable
|
hooks.tag_did_create_hook(t) # pylint: disable=undefined-loop-variable
|
||||||
|
|
||||||
def all(self) -> List:
|
def all(self) -> List:
|
||||||
return list(self.tags.keys())
|
return list(self.tags.keys())
|
||||||
|
|
|
@ -72,7 +72,7 @@ def apply_custom_filters(
|
||||||
|
|
||||||
field_text = node.current_text
|
field_text = node.current_text
|
||||||
for filter_name in node.filters:
|
for filter_name in node.filters:
|
||||||
field_text = hooks.field_replacement_filter(
|
field_text = hooks.card_template_filter_will_apply_filter(
|
||||||
field_text, node.field_name, filter_name, fields
|
field_text, node.field_name, filter_name, fields
|
||||||
)
|
)
|
||||||
# legacy hook - the second and fifth argument are no longer used
|
# legacy hook - the second and fifth argument are no longer used
|
||||||
|
|
|
@ -373,7 +373,7 @@ def test_reviews():
|
||||||
def onLeech(card):
|
def onLeech(card):
|
||||||
hooked.append(1)
|
hooked.append(1)
|
||||||
|
|
||||||
hooks.leech_hook.append(onLeech)
|
hooks.card_did_leech_hook.append(onLeech)
|
||||||
d.sched.answerCard(c, 1)
|
d.sched.answerCard(c, 1)
|
||||||
assert hooked
|
assert hooked
|
||||||
assert c.queue == -1
|
assert c.queue == -1
|
||||||
|
|
|
@ -395,7 +395,7 @@ def test_reviews():
|
||||||
def onLeech(card):
|
def onLeech(card):
|
||||||
hooked.append(1)
|
hooked.append(1)
|
||||||
|
|
||||||
hooks.leech_hook.append(onLeech)
|
hooks.card_did_leech_hook.append(onLeech)
|
||||||
d.sched.answerCard(c, 1)
|
d.sched.answerCard(c, 1)
|
||||||
assert hooked
|
assert hooked
|
||||||
assert c.queue == -1
|
assert c.queue == -1
|
||||||
|
|
|
@ -17,55 +17,60 @@ from hookslib import Hook, update_file
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
hooks = [
|
hooks = [
|
||||||
Hook(name="leech", args=["card: Card"], legacy_hook="leech"),
|
Hook(name="card_did_leech", args=["card: Card"], legacy_hook="leech"),
|
||||||
Hook(name="odue_invalid"),
|
Hook(name="card_odue_was_invalid"),
|
||||||
Hook(name="mod_schema", args=["proceed: bool"], return_type="bool"),
|
Hook(name="schema_will_change", args=["proceed: bool"], return_type="bool"),
|
||||||
Hook(
|
Hook(
|
||||||
name="remove_notes",
|
name="notes_will_delete",
|
||||||
args=["col: anki.storage._Collection", "ids: List[int]"],
|
args=["col: anki.storage._Collection", "ids: List[int]"],
|
||||||
legacy_hook="remNotes",
|
legacy_hook="remNotes",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="deck_created",
|
name="deck_did_create",
|
||||||
args=["deck: Dict[str, Any]"],
|
args=["deck: Dict[str, Any]"],
|
||||||
legacy_hook="newDeck",
|
legacy_hook="newDeck",
|
||||||
legacy_no_args=True,
|
legacy_no_args=True,
|
||||||
),
|
),
|
||||||
Hook(name="exported_media_files", args=["count: int"]),
|
Hook(name="media_files_did_export", args=["count: int"]),
|
||||||
Hook(
|
Hook(
|
||||||
name="create_exporters_list",
|
name="exporters_list_did_create",
|
||||||
args=["exporters: List[Tuple[str, Any]]"],
|
args=["exporters: List[Tuple[str, Any]]"],
|
||||||
legacy_hook="exportersList",
|
legacy_hook="exportersList",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="prepare_searches",
|
name="search_terms_did_prepare",
|
||||||
args=["searches: Dict[str, Callable]"],
|
args=["searches: Dict[str, Callable]"],
|
||||||
legacy_hook="search",
|
legacy_hook="search",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="note_type_created",
|
name="note_type_did_create",
|
||||||
args=["notetype: Dict[str, Any]"],
|
args=["notetype: Dict[str, Any]"],
|
||||||
legacy_hook="newModel",
|
legacy_hook="newModel",
|
||||||
legacy_no_args=True,
|
legacy_no_args=True,
|
||||||
),
|
),
|
||||||
Hook(name="sync_stage", args=["stage: str"], legacy_hook="sync"),
|
Hook(name="sync_stage_did_change", args=["stage: str"], legacy_hook="sync"),
|
||||||
Hook(name="sync_progress_message", args=["msg: str"], legacy_hook="syncMsg"),
|
Hook(name="sync_progress_did_change", args=["msg: str"], legacy_hook="syncMsg"),
|
||||||
Hook(name="http_data_sent", args=["bytes: int"]),
|
Hook(name="http_data_did_send", args=["bytes: int"]),
|
||||||
Hook(name="http_data_received", args=["bytes: int"]),
|
Hook(name="http_data_did_receive", args=["bytes: int"]),
|
||||||
Hook(
|
Hook(
|
||||||
name="tag_created", args=["tag: str"], legacy_hook="newTag", legacy_no_args=True
|
name="tag_did_create",
|
||||||
|
args=["tag: str"],
|
||||||
|
legacy_hook="newTag",
|
||||||
|
legacy_no_args=True,
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="modify_fields_for_rendering",
|
name="fields_will_render",
|
||||||
args=["fields: Dict[str, str]", "notetype: Dict[str, Any]", "data: QAData",],
|
args=["fields: Dict[str, str]", "notetype: Dict[str, Any]", "data: QAData",],
|
||||||
|
doc="Can modify the available fields prior to rendering.",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="original_card_template",
|
name="card_template_will_render",
|
||||||
args=["template: str", "question_side: bool"],
|
args=["template: str", "question_side: bool"],
|
||||||
return_type="str",
|
return_type="str",
|
||||||
|
doc="Can modify the the card template used for rendering.",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="rendered_card_template",
|
name="card_template_did_render",
|
||||||
args=[
|
args=[
|
||||||
"text: str",
|
"text: str",
|
||||||
"side: str",
|
"side: str",
|
||||||
|
@ -78,9 +83,10 @@ hooks = [
|
||||||
],
|
],
|
||||||
return_type="str",
|
return_type="str",
|
||||||
legacy_hook="mungeQA",
|
legacy_hook="mungeQA",
|
||||||
|
doc="Can modify the resulting text after rendering completes.",
|
||||||
),
|
),
|
||||||
Hook(
|
Hook(
|
||||||
name="field_replacement",
|
name="card_template_filter_will_apply",
|
||||||
args=[
|
args=[
|
||||||
"field_text: str",
|
"field_text: str",
|
||||||
"field_name: str",
|
"field_name: str",
|
||||||
|
|
|
@ -2025,9 +2025,9 @@ update cards set usn=?, mod=?, did=? where id in """
|
||||||
gui_hooks.editor_typing_timer_did_fire_hook.append(self.refreshCurrentCard)
|
gui_hooks.editor_typing_timer_did_fire_hook.append(self.refreshCurrentCard)
|
||||||
gui_hooks.editor_note_did_load_hook.append(self.onLoadNote)
|
gui_hooks.editor_note_did_load_hook.append(self.onLoadNote)
|
||||||
gui_hooks.editor_field_did_lose_focus_filter.append(self.refreshCurrentCard)
|
gui_hooks.editor_field_did_lose_focus_filter.append(self.refreshCurrentCard)
|
||||||
hooks.tag_created_hook.append(self.maybeRefreshSidebar)
|
hooks.tag_did_create_hook.append(self.maybeRefreshSidebar)
|
||||||
hooks.note_type_created_hook.append(self.maybeRefreshSidebar)
|
hooks.note_type_did_create_hook.append(self.maybeRefreshSidebar)
|
||||||
hooks.deck_created_hook.append(self.maybeRefreshSidebar)
|
hooks.deck_did_create_hook.append(self.maybeRefreshSidebar)
|
||||||
|
|
||||||
def teardownHooks(self):
|
def teardownHooks(self):
|
||||||
gui_hooks.undo_state_did_change_hook.remove(self.onUndoState)
|
gui_hooks.undo_state_did_change_hook.remove(self.onUndoState)
|
||||||
|
@ -2035,9 +2035,9 @@ update cards set usn=?, mod=?, did=? where id in """
|
||||||
gui_hooks.editor_typing_timer_did_fire_hook.remove(self.refreshCurrentCard)
|
gui_hooks.editor_typing_timer_did_fire_hook.remove(self.refreshCurrentCard)
|
||||||
gui_hooks.editor_note_did_load_hook.remove(self.onLoadNote)
|
gui_hooks.editor_note_did_load_hook.remove(self.onLoadNote)
|
||||||
gui_hooks.editor_field_did_lose_focus_filter.remove(self.refreshCurrentCard)
|
gui_hooks.editor_field_did_lose_focus_filter.remove(self.refreshCurrentCard)
|
||||||
hooks.tag_created_hook.remove(self.maybeRefreshSidebar)
|
hooks.tag_did_create_hook.remove(self.maybeRefreshSidebar)
|
||||||
hooks.note_type_created_hook.remove(self.maybeRefreshSidebar)
|
hooks.note_type_did_create_hook.remove(self.maybeRefreshSidebar)
|
||||||
hooks.deck_created_hook.remove(self.maybeRefreshSidebar)
|
hooks.deck_did_create_hook.remove(self.maybeRefreshSidebar)
|
||||||
|
|
||||||
def onUndoState(self, on):
|
def onUndoState(self, on):
|
||||||
self.form.actionUndo.setEnabled(on)
|
self.form.actionUndo.setEnabled(on)
|
||||||
|
|
|
@ -57,7 +57,7 @@ class Downloader(QThread):
|
||||||
self.recvTotal += bytes
|
self.recvTotal += bytes
|
||||||
self.recv.emit()
|
self.recv.emit()
|
||||||
|
|
||||||
hooks.http_data_received_hook.append(recvEvent)
|
hooks.http_data_did_receive_hook.append(recvEvent)
|
||||||
client = AnkiRequestsClient()
|
client = AnkiRequestsClient()
|
||||||
try:
|
try:
|
||||||
resp = client.get(aqt.appShared + "download/%s?v=2.1" % self.code)
|
resp = client.get(aqt.appShared + "download/%s?v=2.1" % self.code)
|
||||||
|
@ -75,7 +75,7 @@ class Downloader(QThread):
|
||||||
self.error = _("Please check your internet connection.") + "\n\n" + str(e)
|
self.error = _("Please check your internet connection.") + "\n\n" + str(e)
|
||||||
return
|
return
|
||||||
finally:
|
finally:
|
||||||
hooks.http_data_received_hook.remove(recvEvent)
|
hooks.http_data_did_receive_hook.remove(recvEvent)
|
||||||
|
|
||||||
self.fname = re.match(
|
self.fname = re.match(
|
||||||
"attachment; filename=(.+)", resp.headers["content-disposition"]
|
"attachment; filename=(.+)", resp.headers["content-disposition"]
|
||||||
|
|
|
@ -132,9 +132,9 @@ class ExportDialog(QDialog):
|
||||||
)
|
)
|
||||||
% cnt
|
% cnt
|
||||||
)
|
)
|
||||||
hooks.exported_media_files_hook.append(exportedMedia)
|
hooks.media_files_did_export_hook.append(exportedMedia)
|
||||||
self.exporter.exportInto(file)
|
self.exporter.exportInto(file)
|
||||||
hooks.exported_media_files_hook.remove(exportedMedia)
|
hooks.media_files_did_export_hook.remove(exportedMedia)
|
||||||
period = 3000
|
period = 3000
|
||||||
if self.isVerbatim:
|
if self.isVerbatim:
|
||||||
msg = _("Collection exported.")
|
msg = _("Collection exported.")
|
||||||
|
|
|
@ -1153,9 +1153,9 @@ Difference to correct time: %s."""
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
def setupHooks(self) -> None:
|
def setupHooks(self) -> None:
|
||||||
hooks.mod_schema_filter.append(self.onSchemaMod)
|
hooks.schema_will_change_filter.append(self.onSchemaMod)
|
||||||
hooks.remove_notes_hook.append(self.onRemNotes)
|
hooks.notes_will_delete_hook.append(self.onRemNotes)
|
||||||
hooks.odue_invalid_hook.append(self.onOdueInvalid)
|
hooks.card_odue_was_invalid_hook.append(self.onOdueInvalid)
|
||||||
|
|
||||||
gui_hooks.mpv_will_play_hook.append(self.on_mpv_will_play)
|
gui_hooks.mpv_will_play_hook.append(self.on_mpv_will_play)
|
||||||
gui_hooks.mpv_did_idle_hook.append(self.on_mpv_idle)
|
gui_hooks.mpv_did_idle_hook.append(self.on_mpv_idle)
|
||||||
|
|
|
@ -41,7 +41,7 @@ class Reviewer:
|
||||||
self.typeCorrect = None # web init happens before this is set
|
self.typeCorrect = None # web init happens before this is set
|
||||||
self.state = None
|
self.state = None
|
||||||
self.bottom = aqt.toolbar.BottomBar(mw, mw.bottomWeb)
|
self.bottom = aqt.toolbar.BottomBar(mw, mw.bottomWeb)
|
||||||
hooks.leech_hook.append(self.onLeech)
|
hooks.card_did_leech_hook.append(self.onLeech)
|
||||||
|
|
||||||
def show(self):
|
def show(self):
|
||||||
self.mw.col.reset()
|
self.mw.col.reset()
|
||||||
|
|
|
@ -406,10 +406,10 @@ class SyncThread(QThread):
|
||||||
self._abort = 2
|
self._abort = 2
|
||||||
raise Exception("sync cancelled")
|
raise Exception("sync cancelled")
|
||||||
|
|
||||||
hooks.sync_stage_hook.append(syncEvent)
|
hooks.sync_stage_did_change_hook.append(syncEvent)
|
||||||
hooks.sync_progress_message_hook.append(syncMsg)
|
hooks.sync_progress_did_change_hook.append(syncMsg)
|
||||||
hooks.http_data_sent_hook.append(sendEvent)
|
hooks.http_data_did_send_hook.append(sendEvent)
|
||||||
hooks.http_data_received_hook.append(recvEvent)
|
hooks.http_data_did_receive_hook.append(recvEvent)
|
||||||
# run sync and catch any errors
|
# run sync and catch any errors
|
||||||
try:
|
try:
|
||||||
self._sync()
|
self._sync()
|
||||||
|
@ -419,10 +419,10 @@ class SyncThread(QThread):
|
||||||
finally:
|
finally:
|
||||||
# don't bump mod time unless we explicitly save
|
# don't bump mod time unless we explicitly save
|
||||||
self.col.close(save=False)
|
self.col.close(save=False)
|
||||||
hooks.sync_stage_hook.remove(syncEvent)
|
hooks.sync_stage_did_change_hook.remove(syncEvent)
|
||||||
hooks.sync_progress_message_hook.remove(syncMsg)
|
hooks.sync_progress_did_change_hook.remove(syncMsg)
|
||||||
hooks.http_data_sent_hook.remove(sendEvent)
|
hooks.http_data_did_send_hook.remove(sendEvent)
|
||||||
hooks.http_data_received_hook.remove(recvEvent)
|
hooks.http_data_did_receive_hook.remove(recvEvent)
|
||||||
|
|
||||||
def _abortingSync(self):
|
def _abortingSync(self):
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in a new issue