View Single Post
Old 12-25-2025, 08:02 AM   #120
capink
Wizard
capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.capink ought to be getting tired of karma fortunes by now.
 
Posts: 1,221
Karma: 1995558
Join Date: Aug 2015
Device: Kindle
Quote:
Originally Posted by nqk View Post
I have this python script to rename image.webp to image_width_height.webp, which runs fine on Windows
......
The "Run Command" action operates on the file contents without changing their names. It has an option to change file extension which is sueful when converting to different file format. Other than that it is supposed to work on the content and not the filenames.

The reason for that is that the structure for files in the container is different than the usual directory structure, so the usual code to work on these files like os.replace() is not going to work. Which is why your code does not work as expected.

To work around this, you can mimic the way the "Run Command" action works, by copying the content of the files into temporary files that exist in a classic directory, and run the commands on the temporary file, after which it replaces the corresponsing files in the container with the temporary files.

Here is how to adapt your code into a "Run Python Code" action using the same idea, but since your code does not change the content of the files, we will not need to replace the files, but only to rename them using calibre's rename_files()

Code:
from PIL import Image
import os

from calibre.ptempfile import better_mktemp
from calibre.ebooks.oeb.polish.replace import rename_files

supported_formats = ['epub']

def run(chain, settings):
    container = chain.current_container
    name_map = {}

    for name, media_type in container.mime_map.items():
        dirname = os.path.dirname(name)
        basename = os.path.basename(name)
        base, ext = os.path.splitext(basename)
        if media_type.startswith('image'):
            temp_file = better_mktemp(suffix=ext)
            with open(temp_file, 'wb') as f:
                f.write(container.raw_data(name, decode=False))
            im = Image.open(temp_file)
            w, h = im.size
            im.close()
            new_name = f"{base}_{w}_{h}{ext}"
            name_map[name] = os.path.join(dirname, new_name)
            os.remove(temp_file)

    rename_files(container, name_map)

Quote:
Originally Posted by nqk View Post
PS: Merry Christmas and Happy New Year
Thanks. Merry Christmas to you.

Edit: The above code will work on all image files in the book, if you want only the selected files run this:

Code:
from PIL import Image
import os

from calibre.ptempfile import better_mktemp
from calibre.ebooks.oeb.polish.replace import rename_files

supported_formats = ['epub']

def run(chain, settings):
    container = chain.current_container
    name_map = {}

    for name in chain.gui.file_list.file_list.selected_names:
        dirname = os.path.dirname(name)
        basename = os.path.basename(name)
        base, ext = os.path.splitext(basename)
        temp_file = better_mktemp(suffix=ext)
        with open(temp_file, 'wb') as f:
            f.write(container.raw_data(name, decode=False))
        im = Image.open(temp_file)
        w, h = im.size
        im.close()
        new_name = f"{base}_{w}_{h}{ext}"
        name_map[name] = os.path.join(dirname, new_name)
        os.remove(temp_file)

    rename_files(container, name_map)

Last edited by capink; 12-25-2025 at 08:15 AM.
capink is offline   Reply With Quote