Extend FileTypePlugin with postconvert() and postdelete() methods

This commit is contained in:
Steffen Siebert 2023-02-16 21:23:22 +01:00
parent 839f977566
commit a26ba63e1f
4 changed files with 77 additions and 3 deletions

View File

@ -334,6 +334,16 @@ class FileTypePlugin(Plugin): # {{{
#: methods of the plugin are called. #: methods of the plugin are called.
on_postimport = False on_postimport = False
#: If True, this plugin is run after a book file is added
#: to the database. In this case the postconvert method of
#: the plugin is called.
on_postconvert = False
#: If True, this plugin is run after a book file is deleted
#: from the database. In this case the postdelete method of
#: the plugin is called.
on_postdelete = False
#: If True, this plugin is run just before a conversion #: If True, this plugin is run just before a conversion
on_preprocess = False on_preprocess = False
@ -378,6 +388,28 @@ class FileTypePlugin(Plugin): # {{{
''' '''
pass # Default implementation does nothing pass # Default implementation does nothing
def postconvert(self, book_id, book_format, db):
'''
Called post conversion, i.e., after the book file has been added to the database. It is
useful for modifying the book record based on the contents of the newly added file.
:param book_id: Database id of the added book.
:param book_format: The file type of the book that was added.
:param db: Library database.
'''
pass # Default implementation does nothing
def postdelete(self, book_id, book_format, db):
'''
Called post deletion, i.e., after the book file has been deleted from the database. It is
useful for modifying the book record based on the format of the deleted file.
:param book_id: Database id of the added book.
:param book_format: The file type of the book that was added.
:param db: Library database.
'''
pass # Default implementation does nothing
def postadd(self, book_id, fmt_map, db): def postadd(self, book_id, fmt_map, db):
''' '''
Called post add, i.e. after a book has been added to the db. Note that Called post add, i.e. after a book has been added to the db. Note that

View File

@ -122,15 +122,19 @@ def is_disabled(plugin):
_on_import = {} _on_import = {}
_on_postimport = {} _on_postimport = {}
_on_postconvert = {}
_on_postdelete = {}
_on_preprocess = {} _on_preprocess = {}
_on_postprocess = {} _on_postprocess = {}
_on_postadd = [] _on_postadd = []
def reread_filetype_plugins(): def reread_filetype_plugins():
global _on_import, _on_postimport, _on_preprocess, _on_postprocess, _on_postadd global _on_import, _on_postimport, _on_postconvert, _on_postdelete, _on_preprocess, _on_postprocess, _on_postadd
_on_import = defaultdict(list) _on_import = defaultdict(list)
_on_postimport = defaultdict(list) _on_postimport = defaultdict(list)
_on_postconvert = defaultdict(list)
_on_postdelete = defaultdict(list)
_on_preprocess = defaultdict(list) _on_preprocess = defaultdict(list)
_on_postprocess = defaultdict(list) _on_postprocess = defaultdict(list)
_on_postadd = [] _on_postadd = []
@ -146,6 +150,10 @@ def reread_filetype_plugins():
if plugin.on_postimport: if plugin.on_postimport:
_on_postimport[ft].append(plugin) _on_postimport[ft].append(plugin)
_on_postadd.append(plugin) _on_postadd.append(plugin)
if plugin.on_postconvert:
_on_postconvert[ft].append(plugin)
if plugin.on_postdelete:
_on_postdelete[ft].append(plugin)
if plugin.on_preprocess: if plugin.on_preprocess:
_on_preprocess[ft].append(plugin) _on_preprocess[ft].append(plugin)
if plugin.on_postprocess: if plugin.on_postprocess:
@ -155,6 +163,7 @@ def reread_filetype_plugins():
def plugins_for_ft(ft, occasion): def plugins_for_ft(ft, occasion):
op = { op = {
'import':_on_import, 'preprocess':_on_preprocess, 'postprocess':_on_postprocess, 'postimport':_on_postimport, 'import':_on_import, 'preprocess':_on_preprocess, 'postprocess':_on_postprocess, 'postimport':_on_postimport,
'postconvert':_on_postconvert, 'postdelete':_on_postdelete,
}[occasion] }[occasion]
for p in chain(op.get(ft, ()), op.get('*', ())): for p in chain(op.get(ft, ()), op.get('*', ())):
if not is_disabled(p): if not is_disabled(p):
@ -207,6 +216,34 @@ def run_plugins_on_postimport(db, book_id, fmt):
traceback.print_exc() traceback.print_exc()
def run_plugins_on_postconvert(db, book_id, fmt):
customization = config['plugin_customization']
fmt = fmt.lower()
for plugin in plugins_for_ft(fmt, 'postconvert'):
plugin.site_customization = customization.get(plugin.name, '')
with plugin:
try:
plugin.postconvert(book_id, fmt, db)
except:
print('Running file type plugin %s failed with traceback:'%
plugin.name)
traceback.print_exc()
def run_plugins_on_postdelete(db, book_id, fmt):
customization = config['plugin_customization']
fmt = fmt.lower()
for plugin in plugins_for_ft(fmt, 'postdelete'):
plugin.site_customization = customization.get(plugin.name, '')
with plugin:
try:
plugin.postdelete(book_id, fmt, db)
except:
print('Running file type plugin %s failed with traceback:'%
plugin.name)
traceback.print_exc()
def run_plugins_on_postadd(db, book_id, fmt_map): def run_plugins_on_postadd(db, book_id, fmt_map):
customization = config['plugin_customization'] customization = config['plugin_customization']
for plugin in _on_postadd: for plugin in _on_postadd:

View File

@ -24,7 +24,7 @@ from time import monotonic, sleep, time
from calibre import as_unicode, detect_ncpus, isbytestring from calibre import as_unicode, detect_ncpus, isbytestring
from calibre.constants import iswindows, preferred_encoding from calibre.constants import iswindows, preferred_encoding
from calibre.customize.ui import ( from calibre.customize.ui import (
run_plugins_on_import, run_plugins_on_postadd, run_plugins_on_postimport, run_plugins_on_import, run_plugins_on_postadd, run_plugins_on_postimport, run_plugins_on_postdelete,
) )
from calibre.db import SPOOL_SIZE, _get_next_series_num_for_list from calibre.db import SPOOL_SIZE, _get_next_series_num_for_list
from calibre.db.annotations import merge_annotations from calibre.db.annotations import merge_annotations
@ -1865,6 +1865,10 @@ class Cache:
size_map = table.remove_formats(formats_map, self.backend) size_map = table.remove_formats(formats_map, self.backend)
self.fields['size'].table.update_sizes(size_map) self.fields['size'].table.update_sizes(size_map)
for book_id, fmts in iteritems(formats_map):
run_plugins_on_postdelete(self, book_id, fmt)
self._update_last_modified(tuple(formats_map)) self._update_last_modified(tuple(formats_map))
self.event_dispatcher(EventType.formats_removed, formats_map) self.event_dispatcher(EventType.formats_removed, formats_map)

View File

@ -9,7 +9,7 @@ import os
from functools import partial from functools import partial
from qt.core import QModelIndex, QTimer from qt.core import QModelIndex, QTimer
from calibre.customize.ui import plugin_for_input_format from calibre.customize.ui import plugin_for_input_format, run_plugins_on_postconvert
from calibre.gui2 import Dispatcher, error_dialog, gprefs from calibre.gui2 import Dispatcher, error_dialog, gprefs
from calibre.gui2.actions import InterfaceAction from calibre.gui2.actions import InterfaceAction
from calibre.gui2.tools import convert_bulk_ebook, convert_single_ebook from calibre.gui2.tools import convert_bulk_ebook, convert_single_ebook
@ -274,6 +274,7 @@ class ConvertAction(InterfaceAction):
with open(temp_files[-1].name, 'rb') as data: with open(temp_files[-1].name, 'rb') as data:
db.add_format(book_id, fmt, data, index_is_id=True) db.add_format(book_id, fmt, data, index_is_id=True)
run_plugins_on_postconvert(db, book_id, fmt)
self.gui.book_converted.emit(book_id, fmt) self.gui.book_converted.emit(book_id, fmt)
self.gui.status_bar.show_message(job.description + ' ' + self.gui.status_bar.show_message(job.description + ' ' +
_('completed'), 2000) _('completed'), 2000)