From 79e1e261af6cf3fa2a00024d59ff71eb55b235a6 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 21 Jan 2009 21:32:34 -0800 Subject: [PATCH] Create mobi-meta command line tool and make cover extraction from MOBI files more efficient --- src/calibre/ebooks/metadata/mobi.py | 29 +++++++++++++++++++ src/calibre/ebooks/mobi/reader.py | 44 ++++++++++++----------------- src/calibre/linux.py | 3 +- 3 files changed, 49 insertions(+), 27 deletions(-) create mode 100644 src/calibre/ebooks/metadata/mobi.py diff --git a/src/calibre/ebooks/metadata/mobi.py b/src/calibre/ebooks/metadata/mobi.py new file mode 100644 index 0000000000..933cbbdaed --- /dev/null +++ b/src/calibre/ebooks/metadata/mobi.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +__license__ = 'GPL v3' +__copyright__ = '2009, Kovid Goyal kovid@kovidgoyal.net' +__docformat__ = 'restructuredtext en' + +''' +''' + +import sys, os + +from calibre.ebooks.mobi.reader import get_metadata + +def main(args=sys.argv): + if len(args) != 2: + print >>sys.stderr, 'Usage: %s file.mobi' % args[0] + return 1 + fname = args[1] + mi = get_metadata(open(fname, 'rb')) + print unicode(mi) + if mi.cover_data[1]: + cover = os.path.abspath( + '.'.join((os.path.splitext(os.path.basename(fname))[0], + mi.cover_data[0].lower()))) + open(cover, 'wb').write(mi.cover_data[1]) + print _('Cover saved to'), cover + return 0 + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file diff --git a/src/calibre/ebooks/mobi/reader.py b/src/calibre/ebooks/mobi/reader.py index 5d2edd3fe0..51e184a420 100644 --- a/src/calibre/ebooks/mobi/reader.py +++ b/src/calibre/ebooks/mobi/reader.py @@ -311,7 +311,7 @@ class MobiReader(object): opf.cover = 'images/%05d.jpg'%(self.book_header.exth.cover_offset+1) manifest = [(htmlfile, 'text/x-oeb1-document')] bp = os.path.dirname(htmlfile) - for i in self.image_names: + for i in getattr(self, 'image_names', []): manifest.append((os.path.join(bp, 'images/', i), 'image/jpg')) opf.create_manifest(manifest) @@ -451,7 +451,7 @@ class MobiReader(object): image_index += 1 try: im = PILImage.open(buf) - except IOError, e: + except IOError: continue path = os.path.join(output_dir, '%05d.jpg'%image_index) @@ -476,31 +476,23 @@ def get_metadata(stream): if mr.book_header.exth is None: mi = MetaInformation(mr.name, [_('Unknown')]) else: - tdir = tempfile.mkdtemp('_mobi_meta', __appname__+'_') - atexit.register(shutil.rmtree, tdir) - #print tdir - mr.extract_images([], tdir) mi = mr.create_opf('dummy.html') - if mi.cover: - cover = os.path.join(tdir, mi.cover) - if not os.access(cover, os.R_OK): - fname = os.path.basename(cover) - match = re.match(r'(\d+)(.+)', fname) - if match: - num, ext = int(match.group(1), 10), match.group(2) - while num > 0: - num -= 1 - candidate = os.path.join(os.path.dirname(cover), '%05d%s'%(num, ext)) - if os.access(candidate, os.R_OK): - cover = candidate - break - if os.access(cover, os.R_OK): - mi.cover_data = ('JPEG', open(os.path.join(tdir, cover), 'rb').read()) - else: - path = os.path.join(tdir, 'images', '00001.jpg') - if os.access(path, os.R_OK): - mi.cover_data = ('JPEG', open(path, 'rb').read()) - return mi + try: + if hasattr(mr.book_header.exth, 'cover_offset'): + cover_index = mr.book_header.first_image_index + mr.book_header.exth.cover_offset + data = mr.sections[cover_index][0] + else: + data = mr.sections[mr.book_header.first_image_index][0] + buf = cStringIO.StringIO(data) + im = PILImage.open(buf) + obuf = cStringIO.StringIO() + im.convert('RGBA').save(obuf, format='JPEG') + mi.cover_data = ('jpg', obuf.getvalue()) + except: + import traceback + traceback.print_exc() + return mi + def option_parser(): from calibre.utils.config import OptionParser diff --git a/src/calibre/linux.py b/src/calibre/linux.py index acd7e0b1bd..a05a7ea7a8 100644 --- a/src/calibre/linux.py +++ b/src/calibre/linux.py @@ -26,6 +26,7 @@ entry_points = { 'opf-meta = calibre.ebooks.metadata.opf2:main', 'odt-meta = calibre.ebooks.metadata.odt:main', 'epub-meta = calibre.ebooks.metadata.epub:main', + 'mobi-meta = calibre.ebooks.metadata.mobi:main', 'txt2lrf = calibre.ebooks.lrf.txt.convert_from:main', 'html2lrf = calibre.ebooks.lrf.html.convert_from:main', 'html2oeb = calibre.ebooks.html:main', @@ -423,7 +424,7 @@ def install_man_pages(fatal_errors): if prog in ('prs500', 'pdf-meta', 'epub-meta', 'lit-meta', 'markdown-calibre', 'calibre-debug', 'fb2-meta', 'calibre-fontconfig', 'calibre-parallel', 'odt-meta', - 'rb-meta', 'imp-meta'): + 'rb-meta', 'imp-meta', 'mobi-meta'): continue help2man = ('help2man', prog, '--name', 'part of %s'%__appname__,