When reading the cover from comic files, ignore any image files inside __MACOSX/ directories. Fixes #1539414 [Calibre can't extract cbz/cbr cover with __macosx folder](https://bugs.launchpad.net/calibre/+bug/1539414)

This commit is contained in:
Kovid Goyal 2016-01-29 17:44:36 +05:30
parent 9de7e68c1a
commit 77904f0859
3 changed files with 21 additions and 7 deletions

View File

@ -3,7 +3,7 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import os, glob, functools, re
import os, glob, re
from calibre import guess_type
from calibre.customize import (FileTypePlugin, MetadataReaderPlugin,
MetadataWriterPlugin, PreferencesPlugin, InterfaceActionBase, StoreBase)
@ -143,14 +143,11 @@ class ComicMetadataReader(MetadataReaderPlugin):
elif id_.startswith(b'PK'):
ftype = 'cbz'
if ftype == 'cbr':
from calibre.utils.unrar import extract_first_alphabetically as extract_first
extract_first
from calibre.utils.unrar import extract_cover_image
else:
from calibre.libunzip import extract_member
extract_first = functools.partial(extract_member,
sort_alphabetically=True)
from calibre.libunzip import extract_cover_image
from calibre.ebooks.metadata import MetaInformation
ret = extract_first(stream)
ret = extract_cover_image(stream)
mi = MetaInformation(None, None)
stream.seek(0)
if ftype in {'cbr', 'cbz'}:

View File

@ -58,3 +58,14 @@ def extract_member(filename, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I)
for name in names:
if match.search(name):
return name, zf.read(name)
comic_exts = {'png', 'jpg', 'jpeg', 'gif', 'webp'}
def name_ok(name):
return bool(name and not name.startswith('__MACOSX/') and name.rpartition('.')[-1].lower() in comic_exts)
def extract_cover_image(filename):
with zipfile.ZipFile(filename) as zf:
for name in sorted(zf.namelist(), key=sort_key):
if name_ok(name):
return name, zf.read(name)

View File

@ -190,6 +190,12 @@ def extract_first_alphabetically(stream):
{'png', 'jpg', 'jpeg', 'gif', 'webp'}], key=sort_key)
return extract_member(stream, name=names_[0], match=None)
def extract_cover_image(stream):
from calibre.libunzip import sort_key, name_ok
for name in sorted(names(stream), key=sort_key):
if name_ok(name):
return extract_member(stream, name=name, match=None)
# Test normal RAR file {{{
def test_basic():