View Single Post
Old 05-17-2025, 05:43 PM   #1495
bluefish2020
Junior Member
bluefish2020 began at the beginning.
 
bluefish2020's Avatar
 
Posts: 1
Karma: 10
Join Date: Mar 2025
Device: kindle oasis
Duplicate Book module

Quote:
Originally Posted by Nicolas.Laurent View Post
Is there a way to duplicate a book with an Action chain module? My level of Python knowledge is clearly insufficient, and all my attempts have failed..
I looked at what the add_empty builtin does and this seems to work well:

Code:
import os

from calibre_plugins.action_chains.actions.base import ChainAction

class DuplicateBookAction(ChainAction):
    name = 'Duplicate Book'
    support_scopes = True

    # code adapted from calibre/gui2/actions/add.py:add_empty()
    def run(self, gui, settings, chain):
        db = gui.current_db
        selected_books = chain.scope().get_book_ids()
        
        ids, orig_fmts = [], []
        for book_id in selected_books:
            metadata = db.get_metadata(book_id, index_is_id=True, get_cover=True, cover_as_data=True)
            orig_fmts = tuple(db.new_api.format(book_id, fmt, as_path=True) for fmt in db.new_api.formats(book_id))
            new_book_id = db.import_book(metadata, orig_fmts)
            ids.append(new_book_id)
            
        self.refresh_gui(gui, len(selected_books))
        # entirely optional: select and mark the copies
        if ids:
            ids.reverse()
            gui.library_view.select_rows(ids)
            db.set_marked_ids({id: 'duplicate' for id in ids})
        # clean up temp files created by new_api.format()
        for path in orig_fmts:
            os.remove(path)                        

    def refresh_gui(self, gui, num):
        gui.library_view.model().books_added(num)
        gui.refresh_cover_browser()
        gui.tags_view.recount()
bluefish2020 is offline   Reply With Quote