janeczku / calibre-web

:books: Web app for browsing, reading and downloading eBooks stored in a Calibre database
GNU General Public License v3.0
13.01k stars 1.39k forks source link

Conversion to kepub issue #2577

Open psyciknz opened 2 years ago

psyciknz commented 2 years ago

Describe the bug/problem A clear and concise description of what the bug is. If you are asking for support, please check our Wiki if your question is already answered there.

To Reproduce Steps to reproduce the behavior:

  1. Go to Book
  2. Click on Edit Metadata
  3. Set book input format (eg epub)
  4. Set output format to kepub
  5. Check failed task.
  6. View logs and see the following error message in the log
  7. When looking at the disk system a file [F05]_Keys to the Demon Prison - Brandon Mull_converted.kepub.epub is created

Logfile

[2022-10-19 17:21:46,631] DEBUG {cps.tasks.convert:208} Kepubify v4.0.4
[2022-10-19 17:21:46,638] DEBUG {cps.tasks.convert:208} [  1/  1] Converting /books/Brandon Mull/[F05]_Keys to the Demon Prison (756)/[F05]_Keys to the Demon Prison - Brandon Mull.epub
[2022-10-19 17:21:46,638] DEBUG {cps.tasks.convert:208} 1 total: 1 converted, 0 copied, 0 skipped, 0 errored
[2022-10-19 17:21:46,661]  INFO {cps.tasks.convert:188} ebook converter failed with error while converting book
[2022-10-19 17:21:46,661] ERROR {cps.tasks.convert:192} Converted file not found or more than one file in folder /books/Brandon Mull/[F05]_Keys to the Demon Prison (756)

Expected behavior No error and a [F05]_Keys to the Demon Prison - Brandon Mull.kepub file created. It always seems to be [F05]_Keys to the Demon Prison - Brandon Mull_converted.kepub.epub and the error appears in the log. And it doesn't show up as an available format.

Screenshots n/a

Environment (please complete the following information):

Additional context Using reverse proxy, not sure relevant

ja-m commented 5 months ago

I have the same problem here. Version 0.6.21 (Docker) If I shorten the title and convert the book again, everything works fine. I have the .kepub file. But with a different file name. It is shorter (1 character) because the file extension is one character longer (epub -> kepub) I think there is a problem with the length of the path and file name in the conversion process.

Local on a Mac I use the kepubify parameter "--calibre --inplace" and the file name remains correct.

ja-m commented 5 months ago

I found a solution. I modify the file convert.py:

    def _convert_kepubify(self, file_path, format_old_ext, format_new_ext):
        quotes = [1, 3]
## add the parameter --calibre
        command = [config.config_kepubifypath, (file_path + format_old_ext), '-o', os.path.dirname(file_path), '-i', '--calibre']
        try:
            p = process_open(command, quotes)
        except OSError as e:
            return 1, N_("Kepubify-converter failed: %(error)s", error=e)
        self.progress = 0.01
        while True:
            nextline = p.stdout.readlines()
            nextline = [x.strip('\n') for x in nextline if x != '\n']
            for line in nextline:
                log.debug(line)
            if p.poll() is not None:
                break

        # ToD Handle
        # process returncode
        check = p.returncode

        # move file
        if check == 0:
            converted_file = glob(os.path.join(os.path.dirname(file_path), "*.kepub.epub"))
            if len(converted_file) == 1:
                copyfile(converted_file[0], (file_path + format_new_ext))
                os.unlink(converted_file[0])
            else:
# disable error handling
                return check, None
                #return 1, N_("Converted file not found or more than one file in folder %(folder)s",
                #            folder=os.path.dirname(file_path))
        return check, None

I add the parameter "--calibre" the the kepubify command and disable the error handling.

ja-m commented 2 months ago

"glob" has the problem with '[' in the filename because it is a wildcard.

With the kepubify parameter "--calibre" we don't need the file convert. So I modify the code again:

    def _convert_kepubify(self, file_path, format_old_ext, format_new_ext):
        if config.config_embed_metadata and config.config_binariesdir:
            tmp_dir, temp_file_name = helper.do_calibre_export(self.book_id, format_old_ext[1:])
            filename = os.path.join(tmp_dir, temp_file_name + format_old_ext)
            temp_file_path = tmp_dir
        else:
            filename = file_path + format_old_ext
            temp_file_path = os.path.dirname(file_path)
        quotes = [1, 3]
## add the parameter --calibre        
        command = [config.config_kepubifypath, filename, '-o', temp_file_path, '-i', '--calibre']
        try:
            p = process_open(command, quotes)
        except OSError as e:
            return 1, N_("Kepubify-converter failed: %(error)s", error=e)
        self.progress = 0.01
        while True:
            nextline = p.stdout.readlines()
            nextline = [x.strip('\n') for x in nextline if x != '\n']
            for line in nextline:
                log.debug(line)
            if p.poll() is not None:
                break

        # process returncode
        check = p.returncode

        # move file
        # add simple error handling
        if check == 0:
            log.info("ebook convert ok")
#            converted_file = glob(os.path.splitext(filename)[0] + "*.kepub.epub")
#            if len(converted_file) == 1:
#               copyfile(converted_file[0], (file_path + format_new_ext))
#                os.unlink(converted_file[0])
#            else:
#                return 1, N_("Converted file not found or more than one file in folder %(folder)s",
#                             folder=os.path.dirname(file_path))
        return check, None
ja-m commented 1 week ago

Since I modified the file, I had no more problems with the conversion. @OzzieIsaacs Can you change this in the master branch? Or can you correct the handling of the wildcard? My correction may not the best :-)

OzzieIsaacs commented 1 week ago

changing the line: converted_file = glob(os.path.splitext(filename)[0] + "*.kepub.epub") to converted_file = glob(glob.escape(os.path.splitext(filename)[0] + "*.kepub.epub"))

should do the job, I'll check that

OzzieIsaacs commented 1 week ago

Please check the newest nightly version, it should work now as expected

ja-m commented 6 days ago

Yes! I checked it on my demo instance. Epubs with "[" in the file name will now be correct converted to kepub.

Thank you for the fix.