Make reading MOBI metadata a little more robust

This commit is contained in:
Kovid Goyal 2010-02-20 14:08:11 -07:00
parent 3edb183c25
commit 466fb8f4f6
2 changed files with 26 additions and 10 deletions

View File

@ -795,10 +795,12 @@ class MobiReader(object):
def get_metadata(stream):
from calibre.utils.logging import Log
log = Log(level=Log.DEBUG)
log = Log()
mi = MetaInformation(os.path.basename(stream.name), [_('Unknown')])
try:
mh = MetadataHeader(stream, log)
if mh.title and mh.title != _('Unknown'):
mi.title = mh.title
if mh.exth is not None:
if mh.exth.mi is not None:
@ -817,10 +819,15 @@ def get_metadata(stream):
else:
data = mh.section_data(mh.first_image_index)
buf = cStringIO.StringIO(data)
try:
im = PILImage.open(buf)
except:
log.exception('Failed to read MOBI cover')
else:
obuf = cStringIO.StringIO()
im.convert('RGBA').save(obuf, format='JPEG')
im.convert('RGB').save(obuf, format='JPEG')
mi.cover_data = ('jpg', obuf.getvalue())
except:
log.filter_level = Log.DEBUG
log.exception('Failed to read MOBI metadata')
return mi

View File

@ -224,6 +224,11 @@ def extract_member(path, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I), na
f.write(data)
f.flush()
path = f.name
def is_match(fname):
return (name is not None and fname == name) or \
(match is not None and match.search(fname))
with TemporaryDirectory('_libunrar') as dir:
with CurrentDir(dir):
open_archive_data = RAROpenArchiveDataEx(ArcName=path, OpenMode=RAR_OM_EXTRACT, CmtBuf=None)
@ -235,14 +240,18 @@ def extract_member(path, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I), na
while True:
if _libunrar.RARReadHeaderEx(arc_data, byref(header_data)) != 0:
raise UnRARException('%s has no files'%path)
file_name = header_data.FileNameW
if is_match(file_name):
PFCode = _libunrar.RARProcessFileW(arc_data, RAR_EXTRACT, None, None)
if PFCode != 0:
raise UnRARException(_interpret_process_file_error(PFCode))
file_name = header_data.FileNameW
if (name is not None and file_name == name) or \
(match is not None and match.search(file_name)):
return header_data.FileNameW.replace('/', os.sep), \
open(os.path.join(dir, *header_data.FileNameW.split('/')), 'rb').read()
else:
PFCode = _libunrar.RARProcessFileW(arc_data, RAR_SKIP, None, None)
if PFCode != 0:
raise UnRARException(_interpret_process_file_error(PFCode))
finally:
_libunrar.RARCloseArchive(arc_data)