@BetterRed
Here is another method of achieving what you want, you need to add the following custom event (Manage modules > add module > copy paste the code below):
Code:
from functools import partial
# python 3 compatibility
from six import text_type as unicode
from PyQt5.Qt import (QApplication, Qt, QTimer, QWidget, QVBoxLayout, QCheckBox, pyqtSignal)
from calibre import prints
from calibre.constants import DEBUG
from calibre.db.listeners import EventType
from calibre.utils.date import now
from calibre_plugins.action_chains.events.base import ChainEvent
import calibre_plugins.action_chains.config as cfg
class ConfigWidget(QWidget):
def __init__(self, plugin_action):
QWidget.__init__(self)
self.plugin_action = plugin_action
self.gui = plugin_action.gui
self.db = self.gui.current_db
self._init_controls()
def _init_controls(self):
l = self.l = QVBoxLayout()
self.setLayout(l)
self.select_chk = QCheckBox(_('Select newly added books'))
self.select_chk.setChecked(True)
l.addWidget(self.select_chk)
l.addStretch(1)
self.setMinimumSize(300,300)
def load_settings(self, settings):
if settings:
self.select_chk.setChecked(settings['select_books'])
def save_settings(self):
settings = {}
settings['select_books'] = self.select_chk.isChecked()
return settings
class BooksAddedEvent(ChainEvent):
name = 'Books Added'
books_added = pyqtSignal(object)
timer_interval = 30
def __init__(self, plugin_action):
ChainEvent.__init__(self, plugin_action)
self.db = plugin_action.gui.current_db
self.gui.add_db_listener(self.process_event_in_db)
self.book_created_cache = set()
self.book_created_cache_last_updated = None
QTimer.singleShot(self.timer_interval * 1000, self._on_timeout)
def process_event_in_db(self, db, event_type, event_data):
if not db.library_id == self.gui.current_db.library_id:
return
if event_type == EventType.book_created:
book_id = event_data[0]
self.add_to_book_created_cache(book_id, now())
elif event_type == EventType.books_removed:
removed_book_ids = event_data[0]
self.book_created_cache = self.book_created_cache.difference(set(removed_book_ids))
def _on_timeout(self):
# Make sure no modal widget dialog is present (e.g. add books duplicate dialog). Otherwise, postpone
if QApplication.instance().activeModalWidget():
pass
# postpone event if another action chains is running
elif self.plugin_action.chainStack:
pass
else:
utime = self.book_created_cache_last_updated
if utime:
elapsed = now() - utime
if elapsed.seconds > 20:
QTimer.singleShot(0, partial(self.books_added.emit, self.book_created_cache))
QTimer.singleShot(0, self.clean_book_created_cache)
# keep the timer runnig
QTimer.singleShot(self.timer_interval * 1000, self._on_timeout)
def add_to_book_created_cache(self, book_id, timestamp):
self.book_created_cache.add(book_id)
self.book_created_cache_last_updated = timestamp
def clean_book_created_cache(self):
self.book_created_cache = set()
self.book_created_cache_last_updated = None
def get_event_signal(self):
return self.books_added
def config_widget(self):
return ConfigWidget
def pre_chains_event_actions(self, event_args, event_opts):
if event_opts.get('select_books', False):
book_ids = event_args[0]
self.gui.library_view.select_rows(book_ids)
if DEBUG:
prints('Action Chains: Books Added Event: Selecting newly added book_ids: {}')
After adding this you should have an event called "Books Added" in the dropdown list of the Event Manager. You can attach whatever chains you want to that event.
Notes:- The event will automatically select all added books, so that any chains attached to the event can act on them. If whatever reason you don't want this, you can turn it off (Event Manager > Books Added > Event optinos)
- There is a lag of several seconds before the event is activated. This is done to ensure calibre's adder (and auto-adder) has added all the books.
- You can attach one or more chain(s) to the event: Event Manager > Add Event > Books Added > click settings button next to the event.
- Whenever you change the name of a chain attached to an event, you will need to open the Event Manager to re-attach it.
Edit: The solution above is updated to work with auto-add. The File Type plugin solution could work, but it will need a separate plugin, also it will invoke the chain once after each book is added instead of waiting for all books before running the chain.
Edit2: The solution above is updated to be more cleaner:
- It no longer monkeypatches calibre code.
- It waits for all books to be added, and then releases one event for all added books, instead of a separate event per book.
- This will only work with Action Chains version >= 1.11.1