mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Enable support for WMF images in rtf2lrf on linux and windows.
This commit is contained in:
parent
3a7a5b37f3
commit
4d782cce87
12
setup.py
12
setup.py
@ -12,11 +12,11 @@
|
|||||||
## You should have received a copy of the GNU General Public License along
|
## You should have received a copy of the GNU General Public License along
|
||||||
## with this program; if not, write to the Free Software Foundation, Inc.,
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
#!/usr/bin/env python
|
|
||||||
import sys, re, os, shutil
|
import sys, re, os, shutil
|
||||||
sys.path.append('src')
|
sys.path.append('src')
|
||||||
from libprs500 import __version__ as VERSION
|
from libprs500 import __version__ as VERSION
|
||||||
from libprs500 import __appname__ as APPNAME
|
from libprs500 import __appname__ as APPNAME
|
||||||
|
from libprs500 import islinux
|
||||||
|
|
||||||
entry_points = {
|
entry_points = {
|
||||||
'console_scripts': [ \
|
'console_scripts': [ \
|
||||||
@ -33,10 +33,12 @@ entry_points = {
|
|||||||
'web2lrf = libprs500.ebooks.lrf.web.convert_from:main',
|
'web2lrf = libprs500.ebooks.lrf.web.convert_from:main',
|
||||||
'pdf2lrf = libprs500.ebooks.lrf.pdf.convert_from:main',
|
'pdf2lrf = libprs500.ebooks.lrf.pdf.convert_from:main',
|
||||||
'any2lrf = libprs500.ebooks.lrf.any.convert_from:main',
|
'any2lrf = libprs500.ebooks.lrf.any.convert_from:main',
|
||||||
'lrf2lrs = libprs500.ebooks.lrf.parser:main',
|
'lrf2lrs = libprs500.ebooks.lrf.parser:main',
|
||||||
'lrfviewer = libprs500.gui2.lrf_renderer.main:main',
|
|
||||||
],
|
],
|
||||||
'gui_scripts' : [ APPNAME+' = libprs500.gui2.main:main']
|
'gui_scripts' : [
|
||||||
|
APPNAME+' = libprs500.gui2.main:main',
|
||||||
|
'lrfviewer = libprs500.gui2.lrf_renderer.main:main',
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
def _ep_to_script(ep, base='src'):
|
def _ep_to_script(ep, base='src'):
|
||||||
@ -125,5 +127,5 @@ if __name__ == '__main__':
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
if 'develop' in ' '.join(sys.argv):
|
if 'develop' in ' '.join(sys.argv) and islinux:
|
||||||
subprocess.check_call('libprs500_postinstall', shell=True)
|
subprocess.check_call('libprs500_postinstall', shell=True)
|
@ -19,13 +19,11 @@ from libprs500.ebooks.metadata.meta import get_metadata
|
|||||||
from libprs500.ebooks.lrf.html.convert_from import process_file as html_process_file
|
from libprs500.ebooks.lrf.html.convert_from import process_file as html_process_file
|
||||||
from libprs500.ebooks import ConversionError
|
from libprs500.ebooks import ConversionError
|
||||||
from libprs500 import isosx, setup_cli_handlers, __appname__
|
from libprs500 import isosx, setup_cli_handlers, __appname__
|
||||||
|
from libprs500.libwand import convert, WandException
|
||||||
|
|
||||||
UNRTF = 'unrtf'
|
UNRTF = 'unrtf'
|
||||||
CONVERT = 'convert'
|
|
||||||
if isosx and hasattr(sys, 'frameworks_dir'):
|
if isosx and hasattr(sys, 'frameworks_dir'):
|
||||||
UNRTF = os.path.join(sys.frameworks_dir, UNRTF)
|
UNRTF = os.path.join(getattr(sys, 'frameworks_dir'), UNRTF)
|
||||||
CONVERT = os.path.join(sys.frameworks_dir, CONVERT)
|
|
||||||
|
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
return lrf_option_parser(
|
return lrf_option_parser(
|
||||||
@ -38,9 +36,9 @@ def convert_images(html, logger):
|
|||||||
for wmf in wmfs:
|
for wmf in wmfs:
|
||||||
target = os.path.join(os.path.dirname(wmf), os.path.splitext(os.path.basename(wmf))[0]+'.jpg')
|
target = os.path.join(os.path.dirname(wmf), os.path.splitext(os.path.basename(wmf))[0]+'.jpg')
|
||||||
try:
|
try:
|
||||||
subprocess.check_call(CONVERT + ' ' + wmf + ' ' + target, shell=True)
|
convert(wmf, target)
|
||||||
html = html.replace(os.path.basename(wmf), os.path.basename(target))
|
html = html.replace(os.path.basename(wmf), os.path.basename(target))
|
||||||
except Exception, err:
|
except WandException, err:
|
||||||
logger.warning(u'Unable to convert image %s with error: %s'%(wmf, unicode(err)))
|
logger.warning(u'Unable to convert image %s with error: %s'%(wmf, unicode(err)))
|
||||||
continue
|
continue
|
||||||
return html
|
return html
|
||||||
@ -57,15 +55,16 @@ def generate_html(rtfpath, logger):
|
|||||||
cmd = ' '.join([UNRTF, '"'+rtfpath+'"'])
|
cmd = ' '.join([UNRTF, '"'+rtfpath+'"'])
|
||||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
|
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE)
|
||||||
file.write(convert_images(p.stdout.read(), logger))
|
raw = p.stdout.read()
|
||||||
ret = p.wait()
|
ret = p.wait()
|
||||||
if ret != 0:
|
if ret != 0:
|
||||||
if isosx and ret == -11: #unrtf segfaults on OSX but seems to convert most of the file.
|
if len(raw) > 1000: #unrtf crashes occassionally on OSX and windows but still convert correctly
|
||||||
file.write('</body>\n</html>')
|
raw += '</body>\n</html>'
|
||||||
else:
|
else:
|
||||||
logger.critical(p.stderr.read())
|
logger.critical(p.stderr.read())
|
||||||
raise ConversionError, 'unrtf failed with error code: %d'%(ret,)
|
raise ConversionError, 'unrtf failed with error code: %d'%(ret,)
|
||||||
file.close()
|
file.write(convert_images(raw, logger))
|
||||||
|
file.close()
|
||||||
return path
|
return path
|
||||||
finally:
|
finally:
|
||||||
os.chdir(cwd)
|
os.chdir(cwd)
|
||||||
@ -86,18 +85,16 @@ def process_file(path, options, logger=None):
|
|||||||
ext = '.lrs' if options.lrs else '.lrf'
|
ext = '.lrs' if options.lrs else '.lrf'
|
||||||
options.output = os.path.abspath(os.path.basename(os.path.splitext(path)[0]) + ext)
|
options.output = os.path.abspath(os.path.basename(os.path.splitext(path)[0]) + ext)
|
||||||
options.output = os.path.abspath(os.path.expanduser(options.output))
|
options.output = os.path.abspath(os.path.expanduser(options.output))
|
||||||
if (not options.title or options.title == 'Unknown') and mi.title:
|
if not mi.title:
|
||||||
sys.argv.append('-t')
|
mi.title = os.path.splitext(os.path.basename(rtf))[0]
|
||||||
sys.argv.append('"'+mi.title+'"')
|
if (not options.title or options.title == 'Unknown'):
|
||||||
|
options.title = mi.title
|
||||||
if (not options.author or options.author == 'Unknown') and mi.author:
|
if (not options.author or options.author == 'Unknown') and mi.author:
|
||||||
sys.argv.append('-a')
|
options.author = mi.author
|
||||||
sys.argv.append('"'+mi.author+'"')
|
|
||||||
if (not options.category or options.category == 'Unknown') and mi.category:
|
if (not options.category or options.category == 'Unknown') and mi.category:
|
||||||
sys.argv.append('--category')
|
options.category = mi.category
|
||||||
sys.argv.append('"'+mi.category+'"')
|
|
||||||
if (not options.freetext or options.freetext == 'Unknown') and mi.comments:
|
if (not options.freetext or options.freetext == 'Unknown') and mi.comments:
|
||||||
sys.argv.append('--comment')
|
options.freetext = mi.comments
|
||||||
sys.argv.append('"'+mi.comments+'"')
|
|
||||||
html_process_file(html, options, logger)
|
html_process_file(html, options, logger)
|
||||||
finally:
|
finally:
|
||||||
shutil.rmtree(tdir)
|
shutil.rmtree(tdir)
|
||||||
|
67
src/libprs500/libwand.py
Normal file
67
src/libprs500/libwand.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
## Copyright (C) 2007 Kovid Goyal kovid@kovidgoyal.net
|
||||||
|
## This program is free software; you can redistribute it and/or modify
|
||||||
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
## the Free Software Foundation; either version 2 of the License, or
|
||||||
|
## (at your option) any later version.
|
||||||
|
##
|
||||||
|
## This program is distributed in the hope that it will be useful,
|
||||||
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
## GNU General Public License for more details.
|
||||||
|
##
|
||||||
|
## You should have received a copy of the GNU General Public License along
|
||||||
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
import ctypes, os, sys
|
||||||
|
|
||||||
|
from libprs500 import iswindows, isosx
|
||||||
|
|
||||||
|
class WandException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
_lib_name = 'CORE_RL_wand_.dll' if iswindows else 'libWand.dylib' if isosx else 'libWand.so'
|
||||||
|
if iswindows and hasattr(sys, 'frozen'):
|
||||||
|
im_dir = os.path.join(os.path.dirname(sys.executable), 'ImageMagick')
|
||||||
|
os.putenv('PATH', im_dir + ';' + os.environ['PATH'])
|
||||||
|
_libwand = None
|
||||||
|
try:
|
||||||
|
_libwand = ctypes.cdll.LoadLibrary(_lib_name)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Severity(ctypes.c_long):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class String(ctypes.c_char_p):
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
_libwand.MagickRelinquishMemory(self)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
if _libwand is not None:
|
||||||
|
_libwand.MagickGetException.argtypes = [ctypes.c_void_p, ctypes.POINTER(Severity)]
|
||||||
|
_libwand.MagickGetException.restype = String
|
||||||
|
|
||||||
|
def get_exception(wand):
|
||||||
|
severity = Severity()
|
||||||
|
desc = _libwand.MagickGetException(wand, ctypes.byref(severity))
|
||||||
|
return str(desc)
|
||||||
|
|
||||||
|
def convert(source, dest):
|
||||||
|
if _libwand is None:
|
||||||
|
raise WandException('Could not find ImageMagick library')
|
||||||
|
if not _libwand.MagickWandGenesis():
|
||||||
|
raise WandException('Unable to initialize Image Magick')
|
||||||
|
wand = _libwand.NewMagickWand()
|
||||||
|
if wand <= 0:
|
||||||
|
raise WandException('Unable to initialize Image Magick. Cannot create wand.')
|
||||||
|
if not _libwand.MagickReadImage(wand, source):
|
||||||
|
raise WandException('Cannot read image %s: %s'%(source, get_exception(wand)))
|
||||||
|
if not _libwand.MagickWriteImage(wand, dest):
|
||||||
|
raise WandException('Cannot write image to file %s: %s'%(source, get_exception(wand)))
|
||||||
|
_libwand.DestroyMagickWand(wand)
|
||||||
|
_libwand.MagickWandTerminus()
|
@ -59,6 +59,7 @@ Var MUI_TEMP
|
|||||||
!define CLIT "C:\clit\clit.exe"
|
!define CLIT "C:\clit\clit.exe"
|
||||||
!define UNRTF "C:\unrtf\unrtf.exe"
|
!define UNRTF "C:\unrtf\unrtf.exe"
|
||||||
!define PDFTOHTML "C:\pdftohtml\pdftohtml.exe"
|
!define PDFTOHTML "C:\pdftohtml\pdftohtml.exe"
|
||||||
|
!define IMAGEMAGICK "C:\ImageMagick"
|
||||||
|
|
||||||
;------------------------------------------------------------------------------------------------------
|
;------------------------------------------------------------------------------------------------------
|
||||||
;General
|
;General
|
||||||
@ -129,6 +130,10 @@ Section "Main" "secmain"
|
|||||||
File "${CLIT}"
|
File "${CLIT}"
|
||||||
File "${UNRTF}"
|
File "${UNRTF}"
|
||||||
File "${PDFTOHTML}"
|
File "${PDFTOHTML}"
|
||||||
|
|
||||||
|
SetOutPath "$INSTDIR\ImageMagick"
|
||||||
|
File /r "${IMAGEMAGICK}\*"
|
||||||
|
|
||||||
|
|
||||||
SetOutPath "$SYSDIR"
|
SetOutPath "$SYSDIR"
|
||||||
File "${LIBUNRAR_DIR}\unrar.dll"
|
File "${LIBUNRAR_DIR}\unrar.dll"
|
||||||
@ -151,6 +156,7 @@ Section "Main" "secmain"
|
|||||||
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${WEBSITE}"
|
WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${WEBSITE}"
|
||||||
CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
|
CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
|
||||||
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\libprs500.lnk" "$INSTDIR\${PRODUCT_NAME}.exe"
|
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\libprs500.lnk" "$INSTDIR\${PRODUCT_NAME}.exe"
|
||||||
|
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\lrfviewer.lnk" "$INSTDIR\lrfviewer.exe"
|
||||||
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
|
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
|
||||||
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
|
||||||
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\libprs500.exe"
|
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\libprs500.exe"
|
||||||
@ -424,17 +430,24 @@ console = [dict(dest_base=basenames['console'][i], script=scripts['console'][i])
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
cmdclass = {'py2exe': BuildEXE},
|
cmdclass = {'py2exe': BuildEXE},
|
||||||
windows = [{'script' : scripts['gui'][0],
|
windows = [
|
||||||
|
{'script' : scripts['gui'][0],
|
||||||
'dest_base' : APPNAME,
|
'dest_base' : APPNAME,
|
||||||
'icon_resources' : [(1, 'icons/library.ico')],
|
'icon_resources' : [(1, 'icons/library.ico')],
|
||||||
'other_resources' : [BuildEXE.manifest(APPNAME)],
|
'other_resources' : [BuildEXE.manifest(APPNAME)],
|
||||||
},],
|
},
|
||||||
|
{'script' : scripts['gui'][1],
|
||||||
|
'dest_base' : 'lrfviewer',
|
||||||
|
'icon_resources' : [(1, 'icons/viewer.ico')],
|
||||||
|
'other_resources' : [BuildEXE.manifest('lrfviewer')],
|
||||||
|
},
|
||||||
|
],
|
||||||
console = console,
|
console = console,
|
||||||
options = { 'py2exe' : {'compressed': 1,
|
options = { 'py2exe' : {'compressed': 1,
|
||||||
'optimize' : 2,
|
'optimize' : 2,
|
||||||
'dist_dir' : PY2EXE_DIR,
|
'dist_dir' : PY2EXE_DIR,
|
||||||
'includes' : ['sip', 'pkg_resources', 'PyQt4.QtSvg', 'mechanize', 'ClientForm'],
|
'includes' : ['sip', 'pkg_resources', 'PyQt4.QtSvg', 'mechanize', 'ClientForm'],
|
||||||
'packages' : ['PIL', 'WmfPlugin'],
|
'packages' : ['PIL'],
|
||||||
'excludes' : ["Tkconstants", "Tkinter", "tcl",
|
'excludes' : ["Tkconstants", "Tkinter", "tcl",
|
||||||
"_imagingtk", "ImageTk", "FixTk",
|
"_imagingtk", "ImageTk", "FixTk",
|
||||||
'pydoc'],
|
'pydoc'],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user