Fix #7488 (Cover extraction from cbr/cbz does not always extract correct file)

This commit is contained in:
Kovid Goyal 2010-11-12 11:50:45 -07:00
parent 815b3c65c5
commit 5f709bdb37
3 changed files with 23 additions and 7 deletions

View File

@ -2,9 +2,7 @@ import os.path
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import textwrap
import os
import glob
import textwrap, os, glob, functools
from calibre.customize import FileTypePlugin, MetadataReaderPlugin, \
MetadataWriterPlugin, PreferencesPlugin, InterfaceActionBase
from calibre.constants import numeric_version
@ -95,10 +93,12 @@ class ComicMetadataReader(MetadataReaderPlugin):
def get_metadata(self, stream, ftype):
if ftype == 'cbr':
from calibre.libunrar import extract_member as extract_first
from calibre.libunrar import extract_first_alphabetically as extract_first
extract_first
else:
from calibre.libunzip import extract_member as extract_first
from calibre.libunzip import extract_member
extract_first = functools.partial(extract_member,
sort_alphabetically=True)
from calibre.ebooks.metadata import MetaInformation
ret = extract_first(stream)
mi = MetaInformation(None, None)

View File

@ -269,3 +269,16 @@ def extract_member(path, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I),
path = _extract_member(path, match, name)
return path, open(path, 'rb').read()
def extract_first_alphabetically(path):
if hasattr(path, 'read'):
data = path.read()
f = NamedTemporaryFile(suffix='.rar')
f.write(data)
f.flush()
path = f.name
names_ = [x for x in names(path) if os.path.splitext(x)[1][1:].lower() in
('png', 'jpg', 'jpeg', 'gif')]
names_.sort()
return extract_member(path, name=names_[0], match=None)

View File

@ -43,9 +43,12 @@ def extract(filename, dir):
zf = zipfile.ZipFile( filename )
zf.extractall(dir)
def extract_member(filename, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I)):
def extract_member(filename, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$',
re.I), sort_alphabetically=False):
zf = zipfile.ZipFile(filename)
names = zf.namelist()
names = list(zf.namelist())
if sort_alphabetically:
names.sort()
for name in names:
if match.search(name):
return name, zf.read(name)