calibre-debug: Change the --explode-book action to only create the exploded directory and not rebuild the file. Add a new --implode-book action to rebuild the file, separately.

This commit is contained in:
Kovid Goyal 2017-07-21 12:13:59 +05:30
parent 51caa0ea04
commit 224921792e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 79 additions and 37 deletions

View File

@ -82,12 +82,17 @@ Everything after the -- is passed to the script.
help=_('Inspect the MOBI file(s) at the specified path(s)'))
parser.add_option('-t', '--edit-book', action='store_true',
help=_('Launch the calibre "Edit book" tool in debug mode.'))
parser.add_option('-x', '--explode-book', default=None,
help=_('Explode the book (exports the book as a collection of HTML '
parser.add_option('-x', '--explode-book', default=False, action='store_true',
help=_('Explode the book into the specified directory.\nUsage: '
'-x file.epub output_dir\n'
'Exports the book as a collection of HTML '
'files and metadata, which you can edit using standard HTML '
'editing tools, and then rebuilds the file from the edited HTML. '
'Makes no additional changes to the HTML, unlike a full calibre '
'conversion).'))
'editing tools. Works with EPUB, AZW3, HTMLZ and DOCX files.'))
parser.add_option('-i', '--implode-book', default=False, action='store_true', help=_(
'Implode a previously exploded book.\nUsage: -i output_dir file.epub\n'
'Imports the book from the files in output_dir which must have'
' been created by a previous call to --explode-book. Be sure to'
' specify the same file type as was used when exploding.'))
parser.add_option('--export-all-calibre-data', default=False, action='store_true',
help=_('Export all calibre data (books/settings/plugins)'))
parser.add_option('--import-calibre-data', default=False, action='store_true',
@ -277,9 +282,14 @@ def main(args=sys.argv):
elif opts.edit_book:
from calibre.gui_launch import ebook_edit
ebook_edit(['ebook-edit'] + args[1:])
elif opts.explode_book:
from calibre.ebooks.tweak import tweak
tweak(opts.explode_book)
elif opts.explode_book or opts.implode_book:
from calibre.ebooks.tweak import explode, implode
try:
a1, a2 = args[1:]
except Exception:
raise SystemExit('Must provide exactly two arguments')
f = explode if opts.explode_book else implode
f(a1, a2)
elif opts.test_build:
from calibre.test_build import test
test()

View File

@ -7,11 +7,11 @@ __license__ = 'GPL v3'
__copyright__ = '2012, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import sys, os, shlex, subprocess, shutil, unicodedata
import sys, os, unicodedata
from calibre import prints, as_unicode, walk
from calibre.constants import iswindows, __appname__
from calibre.ptempfile import TemporaryDirectory, TemporaryFile
from calibre.ptempfile import TemporaryDirectory
from calibre.libunzip import extract as zipextract
from calibre.utils.zipfile import ZipFile, ZIP_DEFLATED, ZIP_STORED
from calibre.utils.ipc.simple_worker import WorkerError
@ -102,6 +102,61 @@ def get_tools(fmt):
return ans
def explode(ebook_file, output_dir):
if not os.path.exists(output_dir):
os.makedirs(output_dir)
if not os.path.isdir(output_dir):
raise SystemExit('%s is not a directory' % output_dir)
output_dir = os.path.abspath(output_dir)
fmt = ebook_file.rpartition('.')[-1].lower()
exploder, rebuilder = get_tools(fmt)
if exploder is None:
raise SystemExit('Cannot tweak %s files. Supported formats are: EPUB, HTMLZ, AZW3, MOBI, DOCX' % fmt.upper())
try:
opf = exploder(ebook_file, output_dir, question=ask_cli_question)
except WorkerError as e:
prints('Failed to unpack', ebook_file)
prints(e.orig_tb)
raise SystemExit(1)
except Error as e:
prints(as_unicode(e), file=sys.stderr)
raise SystemExit(1)
if opf is None:
# The question was answered with No
return
h = '_' if iswindows else '.'
with lopen(os.path.join(output_dir, h + '__explode_fmt__'), 'wb') as f:
f.write(fmt)
prints('Book extracted to', output_dir)
prints('Make your changes and once you are done, use --implode-book to rebuild')
def implode(output_dir, ebook_file):
output_dir = os.path.abspath(output_dir)
fmt = ebook_file.rpartition('.')[-1].lower()
exploder, rebuilder = get_tools(fmt)
if rebuilder is None:
raise SystemExit('Cannot tweak %s files. Supported formats are: EPUB, HTMLZ, AZW3, MOBI, DOCX' % fmt.upper())
h = '_' if iswindows else '.'
efmt_path = os.path.join(output_dir, h + '__explode_fmt__')
try:
with lopen(efmt_path, 'rb') as f:
efmt = f.read()
except Exception:
raise SystemExit('The directory %s does not seem to have been created by --explode-book' % output_dir)
if efmt != fmt:
raise SystemExit('You must use the same format of file as was used when exploding the book')
os.remove(efmt_path)
try:
rebuilder(output_dir, ebook_file)
except WorkerError as e:
prints('Failed to rebuild', ebook_file)
prints(e.orig_tb)
raise SystemExit(1)
prints(ebook_file, 'successfully rebuilt')
def tweak(ebook_file):
''' Command line interface to the Tweak Book tool '''
fmt = ebook_file.rpartition('.')[-1].lower()
@ -127,33 +182,11 @@ def tweak(ebook_file):
# The question was answered with No
return
ed = os.environ.get('EDITOR', 'dummy')
cmd = shlex.split(ed)
isvim = bool([x for x in cmd[0].split('/') if x.endswith('vim')])
proceed = False
prints('Book extracted to', tdir)
if not isvim:
prints('Make your tweaks and once you are done,', __appname__,
'will rebuild', ebook_file, 'from', tdir)
print()
proceed = ask_cli_question('Rebuild ' + ebook_file + '?')
else:
base = os.path.basename(ebook_file)
with TemporaryFile(base+'.zip') as zipf:
with ZipFile(zipf, 'w') as zf:
zf.add_dir(tdir)
try:
subprocess.check_call(cmd + [zipf])
except:
prints(ed, 'failed, aborting...')
raise SystemExit(1)
with ZipFile(zipf, 'r') as zf:
shutil.rmtree(tdir)
os.mkdir(tdir)
zf.extractall(path=tdir)
proceed = True
prints('Make your tweaks and once you are done,', __appname__,
'will rebuild', ebook_file, 'from', tdir)
print()
proceed = ask_cli_question('Rebuild ' + ebook_file + '?')
if proceed:
prints('Rebuilding', ebook_file, 'please wait ...')
@ -164,4 +197,3 @@ def tweak(ebook_file):
prints(e.orig_tb)
raise SystemExit(1)
prints(ebook_file, 'successfully tweaked')