From b2ef0032077fbec4ff339469d8604a5572bcf816 Mon Sep 17 00:00:00 2001 From: Arthur Milchior Date: Tue, 11 Feb 2020 16:16:38 -0800 Subject: [PATCH] hook note_is_being_flushed I created multiple add-ons which want to transform a note before it is being saved. For example, one add-on trim it, and remove useless line break which arrived by accident. Another add-on want to compile LaTeX as soon as the note is done, and warn the user if LaTeX can't be compiled. Having a hook in pre-flush would be useful here --- pylib/anki/hooks.py | 27 +++++++++++++++++++++++++++ pylib/anki/notes.py | 2 ++ pylib/tools/genhooks.py | 5 +++++ 3 files changed, 34 insertions(+) diff --git a/pylib/anki/hooks.py b/pylib/anki/hooks.py index 5ab0f341a..1c1627401 100644 --- a/pylib/anki/hooks.py +++ b/pylib/anki/hooks.py @@ -18,6 +18,7 @@ import decorator import anki from anki.cards import Card +from anki.notes import Note # New hook/filter handling ############################################################################## @@ -277,6 +278,32 @@ class _NoteTypeAddedHook: note_type_added = _NoteTypeAddedHook() +class _NoteWillFlushHook: + """Allow to change a note before it is added/updated in the database.""" + + _hooks: List[Callable[[Note], None]] = [] + + def append(self, cb: Callable[[Note], None]) -> None: + """(note: Note)""" + self._hooks.append(cb) + + def remove(self, cb: Callable[[Note], None]) -> None: + if cb in self._hooks: + self._hooks.remove(cb) + + def __call__(self, note: Note) -> None: + for hook in self._hooks: + try: + hook(note) + except: + # if the hook fails, remove it + self._hooks.remove(hook) + raise + + +note_will_flush = _NoteWillFlushHook() + + class _NotesWillBeDeletedHook: _hooks: List[Callable[["anki.storage._Collection", List[int]], None]] = [] diff --git a/pylib/anki/notes.py b/pylib/anki/notes.py index 266733d64..6d6cf4174 100644 --- a/pylib/anki/notes.py +++ b/pylib/anki/notes.py @@ -6,6 +6,7 @@ from __future__ import annotations from typing import Any, Dict, List, Optional, Tuple import anki # pylint: disable=unused-import +from anki import hooks from anki.models import Field, NoteType from anki.utils import ( fieldChecksum, @@ -202,6 +203,7 @@ insert or replace into notes values (?,?,?,?,?,?,?,?,?,?,?)""", ################################################## def _preFlush(self) -> None: + hooks.note_will_flush(self) # have we been added yet? self.newlyAdded = not self.col.db.scalar( "select 1 from cards where nid = ?", self.id diff --git a/pylib/tools/genhooks.py b/pylib/tools/genhooks.py index df83e73fa..0923dba6b 100644 --- a/pylib/tools/genhooks.py +++ b/pylib/tools/genhooks.py @@ -67,6 +67,11 @@ hooks = [ Your add-on can check filter_name to decide whether it should modify field_text or not before returning it.""", ), + Hook( + name="note_will_flush", + args=["note: Note"], + doc="Allow to change a note before it is added/updated in the database.", + ), Hook( name="card_did_render", args=[