![]() |
#316 | |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
Also, doing something "temporarily" probably means it is permanent. ![]() |
|
![]() |
![]() |
![]() |
#317 | |
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
|
Quote:
The problem with the Find Duplicates is that the changing and restoring happened in two different (interactive) steps, which left a wide window for things to go wrong. The problem — as you yourself discovered — was that the restore step was not carried out if the user closed calibre without clearing the duplicates results first. Last edited by capink; 02-13-2021 at 08:20 AM. |
|
![]() |
![]() |
![]() |
#318 |
Interested in the matter
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 421
Karma: 426094
Join Date: Dec 2011
Location: Spain, south coast
Device: Pocketbook InkPad 3
|
|
![]() |
![]() |
![]() |
#319 | |
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
|
Quote:
|
|
![]() |
![]() |
![]() |
#320 |
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 10,993
Karma: 75337983
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
Question: Is there any known way to deliberately mark a book, rather than toggle mark? With the latter, already-marked books will become unmarked.
|
![]() |
![]() |
![]() |
#321 |
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
|
Yes. By using mark functionality provided by the plugin instead of calibre. Single Field Action > choose marked field. As usual you have to choice of runtime and predefined.
|
![]() |
![]() |
![]() |
#322 |
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 10,993
Karma: 75337983
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
I never noticed that. Thank you!
|
![]() |
![]() |
![]() |
#323 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Regarding marked books: I added a template function is_marked() that returns the list of comma-separated mark names if it exists, "true" if the book is marked with a non-named mark, or the empty string if the book isn't marked. The new function is in calibre source now.
|
![]() |
![]() |
![]() |
#324 |
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
|
Should be useful for conditionally changing the mark values, among other things.
![]() |
![]() |
![]() |
![]() |
#325 |
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
@capink: I have been thinking about something I would find useful, but a) I am not sure anyone else would, and b) whether the idea fits inside your plans/ideas for action chains.
The idea: sometimes I want to compute some value for a set of books. Some easy examples are the sum of some column, how many series does an author write, names of series for an author, etc. These can all be computed using a template if
The "run on selection" could be done with a new built-in action that runs the provided template on each selected book. The information could be displayed by providing a built-in action that shows the values in the globals dict in a dialog. If really fancy it could take a set of pairs ('global_var_name': 'display_name'). The action would display the listed globals using the display_name. Alternatively, computing and displaying might be done by changing the "formula" action to (optionally?) run over the selection, and to display some values from the globals dict. With these changes I could create an action that sets up variables (if needed), runs a template that computes what is needed and saves the result to globals, then runs an action that displays the answer. To continue the example, a template that counts the number of series in a selection could be: Code:
program: s = field('series'); globals(series_seen='', series_count=0); series_seen = list_union(series_seen, s, ','); series_count = count(series_seen, ','); # the new function to change the globals dict set_globals(series_seen, series_count) |
![]() |
![]() |
![]() |
#326 |
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
|
The idea of template modifying values that are remembered between invocations is interesting.
I think the action and the display should be separated. We run the action that iterates over selected books, and modify the global dict. After that the display can be handled by the formulas action, which already has access to the global dict. This way, any other action that uses templates, can be preceded by this new action (now that the display is optional and separate), and access whatever values it writes to the global dict. All this action would need to do is loop over all selected books, and run the template for each one. Here is what I think can be a preliminary implementation for this action: Code:
# python3 compatibility from six import text_type as unicode from calibre import prints from calibre.constants import DEBUG from calibre.gui2 import error_dialog from calibre.ebooks.metadata.book.formatter import SafeFormat from calibre_plugins.action_chains.actions.base import ChainAction from calibre_plugins.action_chains.templates import TemplateBox, check_template, get_metadata_object, TEMPLATE_ERROR class TemplateIteratorDialog(TemplateBox): def __init__(self, parent, plugin_action, action, name, title): self.plugin_action = plugin_action self.action = action self.gui = plugin_action.gui self.db = self.gui.current_db mi = get_metadata_object(self.gui) TemplateBox.__init__( self, parent, plugin_action, template_text='', placeholder_text=_('Enter a template here. It will be iterated over all selected books'), mi=mi ) self.setWindowTitle(title) def load_settings(self, settings): if settings: template = settings['template'] self.textbox.insertPlainText(template) def save_settings(self): settings = {} settings['template'] = unicode(self.textbox.toPlainText()).rstrip() return settings def accept(self): self.settings = self.save_settings() # validate settings is_valid = self.action.validate(self.settings) if is_valid is not True: msg, details = is_valid error_dialog( self, msg, details, show=True ) return TemplateBox.accept(self) class TemplateIteratorAction(ChainAction): name = 'Template Iterator' def run_template_for_book(self, db, template, book_id, chain_loop): mi = db.new_api.get_proxy_metadata(book_id) template_functions = self.plugin_action.template_functions template_output = SafeFormat().safe_format(template, mi, TEMPLATE_ERROR, mi, global_vars=chain_loop.chain_vars, template_functions=template_functions) return template_output def run(self, gui, settings, chain_loop): db = gui.current_db rows = gui.current_view().selectionModel().selectedRows() book_ids = [ gui.library_view.model().db.id(row.row()) for row in rows ] template = settings['template'] for book_id in book_ids: template_output = self.run_template_for_book(db, template, book_id, chain_loop) def config_widget(self): return TemplateIteratorDialog I still have to ponder on this for sometime, before jumping into final implementation, to get it right first. I am also struggling with name of this new action. Changing it later would break compatibility. Maybe someone can help. Edit: Maybe make the display part of the same action, and make it optional instead. Not yet sure about this. Last edited by capink; 02-18-2021 at 10:19 AM. |
![]() |
![]() |
![]() |
#327 | ||||
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,447
Karma: 8012886
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Quote:
Quote:
Quote:
Quote:
![]() Last edited by chaley; 02-18-2021 at 11:19 AM. Reason: The changes were accepted. |
||||
![]() |
![]() |
![]() |
#328 | |
Custom User Title
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 10,993
Karma: 75337983
Join Date: Oct 2018
Location: Canada
Device: Kobo Libra H2O, formerly Aura HD
|
Quote:
|
|
![]() |
![]() |
![]() |
#329 |
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
|
While testing the new action, I discovered the formulas action in the current version does not have access to the chain vars (strange that I overlooked this). Should be easy to correct. Will post a new version tomorrow, as it is time to go to bed now.
|
![]() |
![]() |
![]() |
#330 |
Wizard
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 1,196
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
|
New version now attached to first post with modifications to the formulas to give access to the chain_vars. Also functions defined by the formulas action can be used from other actions as well.
I tested the new action with the set_globals and it is working fine so far. |
![]() |
![]() |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
[Editor Plugin] Editor Chains | capink | Plugins | 106 | 06-17-2025 05:36 PM |
Action Chains Resources | capink | Plugins | 77 | 06-16-2025 12:45 PM |
[GUI Plugin] Noosfere_util, a companion plugin to noosfere DB | lrpirlet | Plugins | 2 | 08-18-2022 03:15 PM |
[GUI Plugin] Save Virtual Libraries To Column (GUI) | chaley | Plugins | 14 | 04-04-2021 05:25 AM |