Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate ebook-converter (calibre binaries) #28

Closed
Technosoft2000 opened this issue Apr 22, 2018 · 31 comments
Closed

Integrate ebook-converter (calibre binaries) #28

Technosoft2000 opened this issue Apr 22, 2018 · 31 comments
Assignees

Comments

@Technosoft2000
Copy link
Owner

Merge the changes from https://github.com/jim3ma/docker-calibre-web
so that the ebook-converter from the original calibre application is included and can be used by calibre-web.

see also at janeczku/calibre-web#411

@Technosoft2000
Copy link
Owner Author

integrated the changes via commit 3675716

@bodybybuddha
Copy link

NICE!!! Redid my images/containers with the latest build. Kindlegen works, however having an issue with ebook-convert. Only 1% completed in the conversion after 10 min!

The only thing I did in the configuration was select the ebook-convert and put in the path to the tool. I did not put any additional settings. Was I suppose to?

Thanks for this build!

@Technosoft2000
Copy link
Owner Author

Hi @bodybybuddha,

thanks for testing. Didn't tried to convert an ebook via ebook-convert yet. I've to test a little bit and check if it's necessary to set specific options. I'll connect into the container too to execute it directly on command line to see if an error happens.

@adocampo
Copy link

Same here, with your docker and calibres' one as well. Calibre web stucks at 1% ad eternum, while the command line aslo stucks...
I've tried the ebook-convert without luck

/books/Joe Abercrombie/Tierras rojas (14677) # ls
'Tierras rojas - Joe Abercrombie.epub'   cover.jpg   metadata.opf
/books/Joe Abercrombie/Tierras rojas (14677) # ebook-convert Tierras\ rojas\ -\ 
Joe\ Abercrombie.epub Tierras\ rojas\ -\ Joe\ Abercrombie.mobi
1% Eingabe wird in HTML konvertiert …
InputFormatPlugin: EPUB Input running
on /books/Joe Abercrombie/Tierras rojas (14677)/Tierras rojas - Joe Abercrombie.epub
Found HTML cover OEBPS/Text/cubierta.xhtml
Parsing all content...
34% Umwandlungen am eBook werden ausgeführt …
Merging user specified metadata...
Detecting structure...
Flattening CSS and remapping font sizes...
Source base font size is 12.00000pt
Removing fake margins...
Removing level div_1 left margin of: 1.5em
Removing level div_1 right margin of: 1.5em
Cleaning up manifest...
Trimming unused files from manifest...
Trimming u'OEBPS/Text/cubierta.xhtml' from manifest
Creating MOBI Output...
67% MOBI Output-Erweiterung wird ausgeführt

I've tried both copying the epub to /tmp (to discard docker volume issues) and renaming to test.epub (to avoid spaces and so on the name). No luck. The same epub on a normal linux desktop converts just fine, this is the output:

$ ebook-convert test.epub test.mobi
1% Convirtiendo entrada a HTML...
InputFormatPlugin: EPUB Input running
on /tmp/test.epub
Found HTML cover OEBPS/Text/cubierta.xhtml
Parsing all content...
34% Aplicando transformaciones al libro electrónico...
Merging user specified metadata...
Detecting structure...
Flattening CSS and remapping font sizes...
Source base font size is 12.00000pt
Removing fake margins...
Removing level div_1 left margin of: 1.5em
Removing level div_1 right margin of: 1.5em
Cleaning up manifest...
Trimming unused files from manifest...
Trimming u'OEBPS/Text/cubierta.xhtml' from manifest
Creating MOBI Output...
67% Ejecutando el complemento MOBI Output
Serializing resources...
Creating MOBI 6 output
Generating in-line TOC...
Applying case-transforming CSS...
Rasterizing SVG images...
Converting XHTML to Mobipocket markup...
Serializing markup content...
  Compressing markup content...
Generating MOBI index for a book
MOBI output written to /tmp/test.mobi

@Technosoft2000
Copy link
Owner Author

Today I've digged into the issue and found the following:

bash-4.4# export LD_DEBUG=libs
bash-4.4# ebook-convert test.epub test.mobi -v
...
Conversion options changed from defaults:
  verbose: 1
1% Eingabe wird in HTML konvertiert …
InputFormatPlugin: EPUB Input running
on /tmp/test.epub
Found HTML cover OEBPS/cover.xhtml
Parsing all content...
Parsing OEBPS/chapter_18.xhtml ...
Parsing OEBPS/chapter_20.xhtml ...
Parsing OEBPS/cover.xhtml ...
Parsing OEBPS/chapter_17.xhtml ...
Parsing OEBPS/chapter_12.xhtml ...
Parsing OEBPS/css/stylesheet.css ...
Parsing OEBPS/chapter_9.xhtml ...
Parsing OEBPS/toc.xhtml ...
Parsing OEBPS/chapter_4.xhtml ...
Parsing OEBPS/cover_title.xhtml ...
Parsing OEBPS/chapter_21.xhtml ...
Parsing OEBPS/chapter_7.xhtml ...
Parsing OEBPS/chapter_15.xhtml ...
Parsing OEBPS/chapter_2.xhtml ...
Parsing OEBPS/chapter_10.xhtml ...
Parsing OEBPS/chapter_3.xhtml ...
Parsing OEBPS/chapter_13.xhtml ...
Parsing OEBPS/css/images.css ...
Parsing OEBPS/impressum.xhtml ...
Parsing OEBPS/chapter_1.xhtml ...
Parsing OEBPS/chapter_16.xhtml ...
Parsing OEBPS/chapter_8.xhtml ...
Parsing OEBPS/chapter_5.xhtml ...
Parsing OEBPS/chapter_22.xhtml ...
Parsing OEBPS/chapter_11.xhtml ...
Parsing OEBPS/chapter_19.xhtml ...
Parsing OEBPS/chapter_6.xhtml ...
Parsing OEBPS/chapter_14.xhtml ...
Reading TOC from NCX...
34% Umwandlungen am eBook werden ausgeführt …
Merging user specified metadata...
Detecting structure...
        79:     
        79:     calling init: /opt/calibre/lib/python2.7/lib-dynload/unicodedata.so
        79:     
        79:     
        79:     calling init: /opt/calibre/lib/python2.7/site-packages/calibre/plugins/tokenizer.so
        79:     
Flattening CSS and remapping font sizes...
Source base font size is 10.80000pt
Removing fake margins...
Found 3341 items of level: p_1
p_1  left margin stats: Counter({u'0': 3341})
p_1  right margin stats: Counter({u'0': 3341})
Cleaning up manifest...
Trimming unused files from manifest...
Trimming u'OEBPS/cover.xhtml' from manifest
Trimming u'OEBPS/fonts/Bitstream-Copyright.txt' from manifest
Creating MOBI Output...
67% MOBI Output-Erweiterung wird ausgeführt
        79:     find library=libQt5Core.so.5 [0]; searching
        79:      search path=/sw/sw/qt/lib/tls/x86_64/x86_64:/sw/sw/qt/lib/tls/x86_64:/sw/sw/qt/lib/tls/x86_64:/sw/sw/qt/lib/tls:/sw/sw/qt/lib/x86_64/x86_64:/sw/sw/qt/lib/x86_64:/sw/sw/qt/lib/x86_64:/sw/sw/qt/lib
(RPATH from file /opt/calibre/lib/python2.7/site-packages/PyQt5/QtCore.so)
        79:       trying file=/sw/sw/qt/lib/tls/x86_64/x86_64/libQt5Core.so.5
        79:       trying file=/sw/sw/qt/lib/tls/x86_64/libQt5Core.so.5
        79:       trying file=/sw/sw/qt/lib/tls/x86_64/libQt5Core.so.5
        79:       trying file=/sw/sw/qt/lib/tls/libQt5Core.so.5
        79:       trying file=/sw/sw/qt/lib/x86_64/x86_64/libQt5Core.so.5
        79:       trying file=/sw/sw/qt/lib/x86_64/libQt5Core.so.5
        79:       trying file=/sw/sw/qt/lib/x86_64/libQt5Core.so.5
        79:       trying file=/sw/sw/qt/lib/libQt5Core.so.5
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libQt5Core.so.5
        79:     
        79:     find library=libicui18n.so.60 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libicui18n.so.60
        79:     
        79:     find library=libicuuc.so.60 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libicuuc.so.60
        79:     
        79:     find library=libpcre2-16.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libpcre2-16.so.0
        79:     
        79:     find library=libglib-2.0.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libglib-2.0.so.0
        79:     
        79:     find library=libicudata.so.60 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libicudata.so.60
        79:     
        79:     find library=libpcre.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libpcre.so.1
        79:     
        79:     find library=libintl.so.8 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libintl.so.8
        79:     
        79:     
        79:     calling init: /usr/lib/libintl.so.8
        79:     
        79:     
        79:     calling init: /usr/lib/libpcre.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libglib-2.0.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libpcre2-16.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libicuuc.so.60
        79:     
        79:     
        79:     calling init: /usr/lib/libicui18n.so.60
        79:     
        79:     
        79:     calling init: /usr/lib/libQt5Core.so.5
        79:     
        79:     
        79:     calling init: /opt/calibre/lib/python2.7/site-packages/PyQt5/QtCore.so
        79:     
        79:     
        79:     calling init: /opt/calibre/lib/python2.7/site-packages/sip.so
        79:     
        79:     find library=libQt5Gui.so.5 [0]; searching
        79:      search path=           (RPATH from file /opt/calibre/lib/python2.7/site-packages/PyQt5/QtCore.so)
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libQt5Gui.so.5
        79:     
        79:     find library=libGL.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libGL.so.1
        79:     
        79:     find library=libpng16.so.16 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libpng16.so.16
        79:     
        79:     find library=libharfbuzz.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libharfbuzz.so.0
        79:     
        79:     find library=libexpat.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libexpat.so.1
        79:     
        79:     find library=libxcb-dri3.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libxcb-dri3.so.0
        79:     
        79:     find library=libxcb-present.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libxcb-present.so.0
        79:     
        79:     find library=libxcb-sync.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libxcb-sync.so.1
        79:     
        79:     find library=libxshmfence.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libxshmfence.so.1
        79:     
        79:     find library=libglapi.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libglapi.so.0
        79:     
        79:     find library=libXext.so.6 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libXext.so.6
        79:     
        79:     find library=libXdamage.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libXdamage.so.1
        79:     
        79:     find library=libXfixes.so.3 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libXfixes.so.3
        79:     
        79:     find library=libX11-xcb.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libX11-xcb.so.1
        79:     
        79:     find library=libX11.so.6 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libX11.so.6
        79:     
        79:     find library=libxcb.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libxcb.so.1
        79:     
        79:     find library=libxcb-glx.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libxcb-glx.so.0
        79:     
        79:     find library=libxcb-dri2.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libxcb-dri2.so.0
        79:     
        79:     find library=libXxf86vm.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libXxf86vm.so.1
        79:     
        79:     find library=libdrm.so.2 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libdrm.so.2
        79:     
        79:     find library=libfreetype.so.6 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libfreetype.so.6
        79:     
        79:     find library=libgraphite2.so.3 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libgraphite2.so.3
        79:     
        79:     find library=libXau.so.6 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libXau.so.6
        79:     
        79:     find library=libXdmcp.so.6 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libXdmcp.so.6
        79:     
        79:     find library=libbz2.so.1 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libbz2.so.1
        79:     
        79:     find library=libbsd.so.0 [0]; searching
        79:      search path=/usr/lib:/opt/calibre/lib          (LD_LIBRARY_PATH)
        79:       trying file=/usr/lib/libbsd.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libbsd.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libbz2.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libXdmcp.so.6
        79:     
        79:     
        79:     calling init: /usr/lib/libXau.so.6
        79:     
        79:     
        79:     calling init: /usr/lib/libgraphite2.so.3
        79:     
        79:     
        79:     calling init: /usr/lib/libpng16.so.16
        79:     
        79:     
        79:     calling init: /usr/lib/libfreetype.so.6
        79:     
        79:     
        79:     calling init: /usr/lib/libdrm.so.2
        79:     
        79:     
        79:     calling init: /usr/lib/libxcb.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libX11.so.6
        79:     
        79:     
        79:     calling init: /usr/lib/libXext.so.6
        79:     
        79:     
        79:     calling init: /usr/lib/libXxf86vm.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libxcb-dri2.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libxcb-glx.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libX11-xcb.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libXfixes.so.3
        79:     
        79:     
        79:     calling init: /usr/lib/libXdamage.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libglapi.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libxshmfence.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libxcb-sync.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libxcb-present.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libxcb-dri3.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libexpat.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libharfbuzz.so.0
        79:     
        79:     
        79:     calling init: /usr/lib/libGL.so.1
        79:     
        79:     
        79:     calling init: /usr/lib/libQt5Gui.so.5
        79:     

So ebook-convert stucks then in a function at the library libQt5Gui.so.

To get more detailed information I've changed then the level of LD_DEBUG to all and checked the output:

bash-4.4# export LD_DEBUG=all
bash-4.4# ebook-convert test.epub test.mobi -v
...
        97:     calling init: /usr/lib/libQt5Gui.so.5
        97:     
        97:     symbol=calloc;  lookup in file=ebook-convert [0]
        97:     symbol=calloc;  lookup in file=/opt/calibre/lib/libcalibre-launcher.so [0]
        97:     symbol=calloc;  lookup in file=/usr/glibc-compat/lib/libc.so.6 [0]
        97:     binding file /usr/glibc-compat/lib/libpthread.so.0 [0] to /usr/glibc-compat/lib/libc.so.6 [0]: normal symbol `calloc' [GLIBC_2.2.5]

Therefore the issue happens then at the GLIBC library from https://github.com/sgerrand/alpine-pkg-glibc.

I tried the following things today:

At the Calibre site the following info appears:
WARNING: calibre is a highly complex piece of software with lots of very finicky dependencies. If you install from source, you are on your own. Please do not open bug reports or expect any form of support. You have been warned.

So at the moment I've no idea how to fix the issue, but I'll stay tuned to find a solution.

@bodybybuddha
Copy link

Wow @Technosoft2000! That's a lot of testing. Thanks for doing that.

Here's a shot in the dark:

I've been running aptalca/docker-rdp-calibre docker image (Ubuntu base) for Calibre and I took a peek at its configuration. The only instance for that particular library, libQt5Core.so.5, is under /opt/calibre/lib.

As in the above log file, the /opt/calibre/lib directory was the first directory checked for the file - and then it went onto using the version in /user/lib. I'll assume that Calibre isn't using the library files supplied with its installation.

Also, at one time, I was running Calibre in 'headless' mode on my Ubuntu server via an X-server. So I checked out it's configuration and notice the same thing - the libQt5Core.so.5 file is only found in the /opt/calibre/lib directory and not the /user/lib.

Don't know if the above was helpful or not. If I can help test, let me know what scenarios you'd like for me to test and I'll see if I can give it a whirl.

Thanks!

@adocampo
Copy link

adocampo commented Aug 20, 2018

I want to post here my last try with this.

I realized is on my desktop (arch linux) my ebook-convert is a python script

$ file $(which ebook-convert)
/usr/bin/ebook-convert: Python script, ASCII text executable

While on the docker is

file $(which ebook-convert) 
/opt/calibre/bin/ebook-convert: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=9fce5f4bad05bffb06762ea119687b97280322ba, stripped

So as it's dynamically linked I saw /usr/lib/libQt5Gui.so.5 is a symlink to /usr/lib/libQt5Gui.so.5.10.1 so I tried to remove that link and create one to /opt/calibre/lib/libQt5Gui.so.5

It fails now with:

...
Trimming u'OEBPS/Text/cubierta.xhtml' from manifest
Creating MOBI Output...
67% MOBI Output-Erweiterung wird ausgeführt
Traceback (most recent call last):
  File "site.py", line 77, in main
  File "site-packages/calibre/ebooks/conversion/cli.py", line 391, in main
  File "site-packages/calibre/ebooks/conversion/plumber.py", line 1270, in run
  File "site-packages/calibre/ebooks/conversion/plugins/mobi_output.py", line 185, in convert
  File "site-packages/calibre/ebooks/mobi/writer2/resources.py", line 13, in <module>
  File "site-packages/calibre/ebooks/mobi/utils.py", line 14, in <module>
  File "site-packages/calibre/utils/img.py", line 18, in <module>
ImportError: /usr/lib/libQt5Gui.so.5: symbol _ZNK11QLocaleData13validateCharsERK7QStringNS_10NumberModeEP10QByteArrayib version Qt_5 not defined in file libQt5Core.so.5 with link time reference

I guess ebook-convert can be compiled to be a statically linked binary (but I think we can enter in a dark and deep hole, ignoring the warning developers advice to avoid). Perhaps we could create a wrapper (just like arch linux's calibre does). The content of ebook-convert python is:

#!/usr/bin/env python2
"""
This is the standard runscript for all of calibre's tools.
Do not modify it unless you know what you are doing.
"""

import sys, os

path = os.environ.get('CALIBRE_PYTHON_PATH', '/usr/lib/calibre')
if path not in sys.path:
    sys.path.insert(0, path)

sys.resources_location = os.environ.get('CALIBRE_RESOURCES_PATH', '/usr/share/calibre')
sys.extensions_location = os.environ.get('CALIBRE_EXTENSIONS_PATH', '/usr/lib/calibre/calibre/plugins')
sys.executables_location = os.environ.get('CALIBRE_EXECUTABLES_PATH', '/usr/bin')


from calibre.ebooks.conversion.cli import main
sys.exit(main())

What do you think?

@adocampo
Copy link

Just a quick update. I've just renamed the ebook-convert ELF binary and created a python wrapper instead with this content

#!/usr/bin/env python2

"""
This is the standard runscript for all of calibre's tools.
Do not modify it unless you know what you are doing.
"""

import sys, os

path = os.environ.get('CALIBRE_PYTHON_PATH', '/opt/calibre/lib/python2.7/site-packages')
if path not in sys.path:
    sys.path.insert(0, path)

sys.resources_location = os.environ.get('CALIBRE_RESOURCES_PATH', '/opt/calibre/resources')
sys.extensions_location = os.environ.get('CALIBRE_EXTENSIONS_PATH', '/opt/calibre/lib/python2.7/site-packages/calibre/plugins/')
sys.executables_location = os.environ.get('CALIBRE_EXECUTABLES_PATH', '/opt/calibre/bin')


from calibre.ebooks.conversion.cli import main
sys.exit(main())

It will fail. On my desktop, in CALIBRE_PYTHON_PATH there is the source code while in the docker there are only the objects (.pyo and .pyc) so we can't call it the same way we can do on Arch...

@bodybybuddha
Copy link

bodybybuddha commented Aug 20, 2018

I think I may have found the solution...

I simply changed the PATH for calibre binaries from: /opt/calibre/bin to: /opt/calibre

I ran the ebook-convert manually (with verbose on) on an ePub book to Mobi and it worked! However, the tool didn't update the calibre database with the new data. Not sure if I needed to include a parameter or if another command was used to add the book to the database. But the conversion worked.

Not exactly where to change the PATH for the image to do a full test. (EDIT: line 206 of the dockerfile seems to be the place.)

Can one of you see if this simple change resolve the conversion issue?

Thanks!

@adocampo
Copy link

Those are good news indeed!!

You cannot simply put an ebook on a directory and hope it shows in calibre :| I guess when we convert the book through the GUI, it usually updates de calibredb, so perhaps just recreating the docker image with the right PATH just works, did you tried it?

@bodybybuddha
Copy link

I was able to create a new image with a modified dockerfile. The manual ebook-convert work correctly.

However, I ran two tests with the GUI. One, with the converter tool command line setting set to /opt/calibre and in the second test, the command line setting was set to /opt/calibre/bin. Both got stuck at the 1% mark for over 5 minutes in both tests. -- I did do a manual convert of the same file and it took under 30 seconds to complete.

Here's the log of the working manual conversion:

bash-4.4# ebook-convert test.epub test.mobi -v
Conversion options changed from defaults:
  verbose: 1
1% Eingabe wird in HTML konvertiert …
InputFormatPlugin: EPUB Input running
on /root/test.epub
Found HTML cover OEBPS/Text/titlepage.xhtml
Parsing all content...
Parsing OEBPS/Text/part0007.xhtml ...
Parsing OEBPS/Text/part0014.xhtml ...
Parsing OEBPS/Text/part0025.xhtml ...
Parsing OEBPS/Text/part0011.xhtml ...
...
Parsing OEBPS/Text/part0032.xhtml ...
Parsing OEBPS/Text/part0024.xhtml ...
Parsing OEBPS/Text/part0006.xhtml ...
Reading TOC from NCX...
34% Umwandlungen am eBook werden ausgeführt …
Merging user specified metadata...
Detecting structure...
Flattening CSS and remapping font sizes...
Source base font size is 12.00000pt
Removing fake margins...
Found 103 items of level: div_2
Found 31 items of level: div_3
Found 36 items of level: p_3
Found 37 items of level: div_1
Found 3902 items of level: p_2
div_2  left margin stats: Counter({u'0': 1})
div_2  right margin stats: Counter({u'0': 1})
div_3  left margin stats: Counter({u'0': 25, u'18.5%': 2, u'7%': 1, u'14%': 1, u'30%': 1, u'17%': 1})
div_3  right margin stats: Counter({u'0': 25, u'18.5%': 2, u'7%': 1, u'14%': 1, u'30%': 1, u'17%': 1})
Negative text indent detected at level  p_3, ignoring this level
div_1  left margin stats: Counter({u'0': 27, u'0%': 1})
div_1  right margin stats: Counter({u'0': 28})
p_2  left margin stats: Counter({u'0': 3902})
p_2  right margin stats: Counter({u'0': 3902})
Cleaning up manifest...
Trimming unused files from manifest...
Trimming u'OEBPS/Text/titlepage.xhtml' from manifest
Creating MOBI Output...
67% MOBI Output-Erweiterung wird ausgeführt
Serializing resources...
Creating MOBI 6 output
Applying case-transforming CSS...
Parsing manglecase.css ...
Rasterizing SVG images...
Converting XHTML to Mobipocket markup...
Serializing markup content...
  Compressing markup content...
Generating MOBI index for a book
MOBI output written to /root/test.mobi
Ausgabe gespeichert in   /root/test.mobi

Now that manual conversion is working, I think the next steps is to take a look at how the feature is implemented in calibre-web. Just to rule out any 'basic' issues - before we go back into looking at libraries.

I did not do a pull-request of the change I made to @Technosoft2000's docker image. I was hoping to solve this issue before making the request.

@bodybybuddha
Copy link

Okay - I've learned a lot. Here's my update.

First, I found out the calibre-web has changed in the last few days, so I had to do an update. Now instead of being at 1% and never ending, it will fail the conversion immediately. This is with the modified PATH solution above.

This is better than before as now the system doesn't have a subprocess going forever. (Side note - it doesn't really go forever. If you look at the processes you'll see a new process started for the conversion. It'll have the cmd string as verbiage. After some time out the verbiage will change on the process to "[EBOOK-CONVERT]". So it doesn't look like the process is doing anything other just being there. I digress.)

Then, I wanted to make sure the calibre-web was sending the right command with parameters to convert the book properly. The conversion code is the worker.py. Line 236 handles the gathering of the appropriate command:

command = [web.ub.config.config_converterpath, '"' + file_path + u'.epub"',
                           '"'+file_path + u'.mobi"']

In my version I changed the file_path to be unicode:

command = [web.ub.config.config_converterpath, u'"' + file_path + u'.epub"',
                           '"'+file_path + u'.mobi"']

The real magic is line 246, where the subprocess is executed:
p = subprocess.Popen(command, stdout=subprocess.PIPE, universal_newlines=True)

To see what was in the command object, I put in a couple of debug lines just before line 246:

web.app.logger.debug('next line is command being executed with conversion')
web.app.logger.debug(command)

Then I used the website to convert a book and this is what the log came back with:

[2018-08-21 01:07:06,098] {/calibre-web/app/cps/web.py:170} INFO - Starting Calibre Web...
[2018-08-21 01:07:06,449] {/calibre-web/app/cps/server.py:52} INFO - Starting Gevent server
[2018-08-21 01:07:23,155] {/calibre-web/app/cps/worker.py:246} DEBUG - next line is command being executed with conversion
[2018-08-21 01:07:23,287] {/calibre-web/app/cps/worker.py:247} DEBUG - [u'/opt/calibre/ebook-convert', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.mobi"']
[2018-08-21 01:07:23,499] {/calibre-web/app/cps/worker.py:268} DEBUG - No write acces to /home/calibre/.config/calibre using a temporary dir instead
[2018-08-21 01:07:23,798] {/calibre-web/app/cps/worker.py:268} DEBUG - Cannot read from /calibre-web/app/"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"
[2018-08-21 01:07:23,817] {/calibre-web/app/cps/worker.py:268} DEBUG -
[2018-08-21 01:07:23,817] {/calibre-web/app/cps/worker.py:299} INFO - ebook converter failed with error while converting book
[2018-08-21 01:07:23,818] {/calibre-web/app/cps/worker.py:435} ERROR - Ebook converter failed with unknown error

The good news - the command object is done correctly. The first item in the sequence the executable, then a list of args you want the subprocess to execute:

[2018-08-21 01:07:23,287] {/calibre-web/app/cps/worker.py:247} DEBUG - [u'/opt/calibre/ebook-convert', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.mobi"']

So in the above, execute ebook-convert from the right directory, then the ePub you want converted, and where you want the mobi file to be. So far so good.

The interesting bit is the error message that is given when the job fails:

[2018-08-21 01:07:23,798] {/calibre-web/app/cps/worker.py:268} DEBUG - Cannot read from /calibre-web/app/"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"

Note that '/calibre-web/app/' was added to the beginning of the ePub file location. The ebook-convert program is getting this string from somewhere - not sure if it means its the current directory (b/c if you do open a bash session in the docker image, you are in the /calibre-web/app directory) or if it's pulling it from something else.

So I changed the subprocess.Popen command to this:

 p = subprocess.Popen(command, stdout=subprocess.PIPE, cwd='/', universal_newlines=True)

I changed the current working directory to /. This is the result of that test:

[2018-08-21 01:35:33,891] {/calibre-web/app/cps/worker.py:268} DEBUG - Cannot read from /"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"

Ahh.. so what if I change the current working directory to cwd='' - different result:

[2018-08-21 02:05:35,938] {/calibre-web/app/cps/worker.py:246} DEBUG - next line is command being executed with conversion
[2018-08-21 02:05:35,938] {/calibre-web/app/cps/worker.py:247} DEBUG - [u'/opt/calibre/bin/ebook-convert', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.mobi"']
[2018-08-21 02:05:36,243] {/calibre-web/app/cps/worker.py:435} ERROR - Ebook-converter failed: [Errno 2] No such file or directory: ''

We are executing the ebook-converter, but we aren't passing in the right parameters?

Oh yes - I also opened up a bash session to the container and from the default directory (/calibre-web/app) I executed what should be the correct command line for the conversion for the book I used in the tests above and it converted perfectly and in the right directory. This rules out any string issues with the path, etc.

So now I'm stuck. Any suggestions where to go from here?

Lastly, if one were to look into the code in the Worker.py file after the points mentioned above, one will see that on a successful conversion, the code will then add the new version of the book to the calibre database.

I'll start looking into the ebook-convert tool a little bit more to see why it would have the default directory added to the ePub portion of the string and more into the pOpen subprocess interface (although I suspect pOpen isn't the issue.)

@bodybybuddha
Copy link

Another quick update - I notice that any conversion to mobi may not have the requisite [PDOC] tag if you want to use WhispherSync, so I added a couple of extra parameters via the GUI screen. The new parameters did make it to the command object - but in the end I got the same failure.

[2018-08-21 02:22:49,298] {/calibre-web/app/cps/web.py:170} INFO - Starting Calibre Web...
[2018-08-21 02:22:49,612] {/calibre-web/app/cps/server.py:52} INFO - Starting Gevent server
[2018-08-21 02:24:41,357] {/calibre-web/app/cps/worker.py:246} DEBUG - next line is command being executed with conversion
[2018-08-21 02:24:41,358] {/calibre-web/app/cps/worker.py:247} DEBUG - [u'/opt/calibre/bin/ebook-convert', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.mobi"', u'--personal-doc --output-profile kindle']
[2018-08-21 02:24:41,400] {/calibre-web/app/cps/worker.py:268} DEBUG - No write acces to /home/calibre/.config/calibre using a temporary dir instead
[2018-08-21 02:24:41,710] {/calibre-web/app/cps/worker.py:268} DEBUG - Cannot read from /calibre-web/app/"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"
[2018-08-21 02:24:41,728] {/calibre-web/app/cps/worker.py:268} DEBUG -
[2018-08-21 02:24:41,728] {/calibre-web/app/cps/worker.py:299} INFO - ebook converter failed with error while converting book
[2018-08-21 02:24:41,729] {/calibre-web/app/cps/worker.py:435} ERROR - Ebook converter failed with unknown error

@bodybybuddha
Copy link

bodybybuddha commented Aug 21, 2018

Last update on this one for tonight :-)

I decided to write a small python script that used the same key lines from calibre-web to test it with the command object (array... whatever it is..):

# Import the module
import subprocess

command = ['/opt/calibre/ebook-convert', '"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub"', u'"/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.mobi"']

# Set up the echo command and direct the output to a pipe
p1 = subprocess.Popen(command, stdout=subprocess.PIPE)

# Run the command
output = p1.communicate()[0]

print output

After many different variations I FINALLY got it to work. The only way the above code work was to remove all the double quotes from the book paths:

command = ['/opt/calibre/ebook-convert', '/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.epub', u'/books/Timothy Zahn/Thrawn_ Alliances (Star Wars) (13333)/Thrawn_ Alliances (Star Wars) - Timothy Zahn.mobi']

So as it turns out, once we have the PATH corrected in @Technosoft2000's image - we will need to change calibre-web's worker.py to strip out the unneeded double quotes. However, after reading some of @OzzieIsaacs commits, there may have been some Window OS considerations. Thus the code may need to test for OS first before determining to strip out the double quotes.

I was wondering if the jim3ma/docker-calibre-web has the same issue?

Thoughts?

@Technosoft2000
Copy link
Owner Author

Hi all,

many thanks for additional testing and the new ideas and tests to get it work, awesome.

I'll check this after my work and try to include the fix into the docker image.

Thanks for the support :)

@OzzieIsaacs
Copy link

On windows I had the same issue you are also stuck with: for an unknown reason something was added to the path, and therefore it didn't work. Another issue on window was, that without the double quotes it could not handle path with spaces in it. I'll doublecheck if it is working on "normal linux" without the qoutes, I can remove tham, and only add them for the windows version (which has a special processing anyway)

@Technosoft2000
Copy link
Owner Author

I'll doublecheck if it is working on "normal linux" without the qoutes, I can remove tham, and only add them for the windows version (which has a special processing anyway)

That would be great, because then I don't have to patch the file inside the docker image.

@bodybybuddha
Copy link

Thanks for the quick replies everyone!

@Technosoft2000 - Just verifying as I'm already setup to do the tests: I ran a test of the working test script against your original image and it worked. So if @OzzieIsaacs can verify that removing the double quotes is the solution and finds time to do so - I think we are good to go!

Thank you both for all your efforts!

@adocampo - thanks for your contributions to this as well!

Technosoft2000 added a commit that referenced this issue Aug 21, 2018
…worked correct,

   therefore changed the internal Calibre path from `/opt/calibre/bin` to `/opt/calibre`;
   thanks to @bodybybuddha and @adocampo for testing and finding a solution for this issue;
   see for details at issue #28
@OzzieIsaacs
Copy link

I changed calibre-web to excecute the command without qoutes on linux. But to make it work I had to add an .encode(sys.getfilesystemencoding()) to the command. So please check if it is working, now. Otherwise, we/I have to include a detection of the docker-container, or the alpine?-linux you guys are using.

@bodybybuddha
Copy link

Thanks @OzzieIsaacs! I'll test a little later today.

@bodybybuddha
Copy link

Perfect! It worked! I updated my 'production' container to the latest calibre-web release and was able to send an ePub to my Kindle after a mobi conversion. Woot!!

image

image

image

Thank you @OzzieIsaacs!

@adocampo
Copy link

Just tried. Works flawlessly!
Good job guys! 👍

@astrodad
Copy link

Do I need to so something other than restart the docker to pick up the latest version of calibre-web? For me, it still shows not installed for Calibre converter.

@bodybybuddha
Copy link

@astrodad - Stop your container, then do a docker pull of the image, start container. That will get you the latest version of calibre-web that was configured in the image.

To get updates of calibre-web that occur after the image refresh - go into the admin page of calibre-web and you'll see a Check for Updates button. Click it and it'll change to Update if a new version exists. The update button will restart calibre-web for you.

FYI - to use the calibre ebook-converter tool, go to the admin page of calibre-web and click on Basic configuration. Then fill in the appropriate fields:
image

Hope that helps!

@astrodad
Copy link

I issued a docker pull, restarted and then also checked for updates. It found one and I applied. When re-booted it still shows Not Installed for the calibre converter tool. Log shows this:

[2018-08-25 23:07:13,825] {/calibre-web/app/cps/web.py:170} INFO - Starting Calibre Web...
[2018-08-25 23:07:13,911] {/calibre-web/app/cps/server.py:52} INFO - Starting Gevent server
[2018-08-25 23:13:13,175] {/calibre-web/app/cps/worker.py:274} DEBUG - WARNING: Failed to set default libc locale, using en_US.UTF-8
[2018-08-25 23:13:13,176] {/calibre-web/app/cps/worker.py:274} DEBUG -
[2018-08-25 23:13:13,176] {/calibre-web/app/cps/worker.py:305} INFO - ebook converter failed with error while converting book
[2018-08-25 23:13:13,176] {/calibre-web/app/cps/worker.py:441} ERROR - Ebook converter failed with unknown error

@bodybybuddha
Copy link

That's interesting. When you did the pull, did it pull any new layers?

I removed my container and the images for calibre-web and pull a new copy image:
image

I also did another pull to get the following image info:
image

When I did a check for an update on calibre-web, there was no further updates. Here's the date stamp of the latest commit:
image

So the version in the image should be the latest as of right now. The about page did list the ebook-convert program (I didn't change my configuration files in the steps above.) I was also able to successfully send an ePub book to my Kindle, with a conversion.

The only thing I can think of is maybe you have two images of the docker file? Can you do a "docker image ls" and double-check? I had this happen to me once - I had two images with the same repo name, but different tags; one with and the other with 'latest'. I got rid of the one and all was well.

@astrodad
Copy link

astrodad commented Aug 26, 2018

UPDATE: removing the image and the container fixed the problem. I never got the document but I didn’t get any errors. That’s a separate issue, but it looks like the conversion was good. Thanks for the help.

Thanks for your help on this.

I checked and didn't see any other images:

$ docker image ls | grep calibre
technosoft2000/calibre-web latest 3a1979b0c0e7 4 days ago 997MB

$ docker image pull technosoft2000/calibre-web
Using default tag: latest
latest: Pulling from technosoft2000/calibre-web
Digest: sha256:4410691dc0d3b2a405c34b6bd96e972b665e9bcf4886e9d703f2664520e7025e
Status: Image is up to date for technosoft2000/calibre-web:latest

Administration
Current commit timestamp: 8/22/18, 7:55 PM

I am going to drop the image, drop the container, and try again from scratch.

@Technosoft2000
Copy link
Owner Author

Hi @astrodad,

may be you have the same issue like here #34 ebook-convert : Error: unsupported locale setting
At the moment I try to fix the issue and I'll publish a new docker image.

@adocampo
Copy link

Hi @Technosoft2000, did you see the @astrodad UPDATE? He got it work by deleting the container and re-fetching it again.

I'm not very experimented with docker, but I always create the containers with persistent volumes and when there is an update, I remove the container, then the image, and then grab the latest version. I haven't had any problem this way.

@Technosoft2000
Copy link
Owner Author

@adocampo thanks for the hint, I've overlooked the UPDATE :-|

when there is an update, I remove the container, then the image, and then grab the latest version

I do it in the same way :)

@astrodad
Copy link

Thanks! I’ll use this routine from now on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants