Pull from trunk

This commit is contained in:
Kovid Goyal 2010-09-24 13:47:40 -06:00
commit 4b2f39aa85
28 changed files with 31489 additions and 24727 deletions

View File

@ -67,10 +67,17 @@ def load_plugin(path_to_zip_file): # {{{
if name.lower().endswith('plugin.py'): if name.lower().endswith('plugin.py'):
locals = {} locals = {}
raw = zf.read(name) raw = zf.read(name)
match = re.search(r'coding[:=]\s*([-\w.]+)', raw[:300]) lines, encoding = raw.splitlines(), 'utf-8'
encoding = 'utf-8' cr = re.compile(r'coding[:=]\s*([-\w.]+)')
raw = []
for l in lines[:2]:
match = cr.search(l)
if match is not None: if match is not None:
encoding = match.group(1) encoding = match.group(1)
else:
raw.append(l)
raw += lines[2:]
raw = '\n'.join(raw)
raw = raw.decode(encoding) raw = raw.decode(encoding)
raw = re.sub('\r\n', '\n', raw) raw = re.sub('\r\n', '\n', raw)
exec raw in locals exec raw in locals

View File

@ -15,7 +15,7 @@ from calibre.customize.ui import available_input_formats
from calibre.ebooks.metadata.opf2 import OPF from calibre.ebooks.metadata.opf2 import OPF
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre.ebooks.chardet import xml_to_unicode from calibre.ebooks.chardet import xml_to_unicode
from calibre.utils.zipfile import safe_replace, ZipFile from calibre.utils.zipfile import safe_replace
from calibre.utils.config import DynamicConfig from calibre.utils.config import DynamicConfig
from calibre.utils.logging import Log from calibre.utils.logging import Log
from calibre import guess_type, prints from calibre import guess_type, prints
@ -294,12 +294,8 @@ class EbookIterator(object):
zf = open(self.pathtoebook, 'r+b') zf = open(self.pathtoebook, 'r+b')
except IOError: except IOError:
return return
zipf = ZipFile(zf, mode='a') safe_replace(zf, 'META-INF/calibre_bookmarks.txt', StringIO(dat),
for name in zipf.namelist(): add_missing=True)
if name == 'META-INF/calibre_bookmarks.txt':
safe_replace(zf, 'META-INF/calibre_bookmarks.txt', StringIO(dat))
return
zipf.writestr('META-INF/calibre_bookmarks.txt', dat)
else: else:
self.config['bookmarks_'+self.pathtoebook] = dat self.config['bookmarks_'+self.pathtoebook] = dat

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -281,7 +281,7 @@ class ZipInfo (object):
'file_offset', 'file_offset',
) )
def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): def __init__(self, filename=u"NoName", date_time=(1980,1,1,0,0,0)):
self.orig_filename = filename # Original file name in archive self.orig_filename = filename # Original file name in archive
# Terminate the file name at the first null byte. Null bytes in file # Terminate the file name at the first null byte. Null bytes in file
@ -1362,30 +1362,42 @@ class ZipFile:
self.fp.close() self.fp.close()
self.fp = None self.fp = None
def safe_replace(zipstream, name, datastream, extra_replacements={}): def safe_replace(zipstream, name, datastream, extra_replacements={},
add_missing=False):
''' '''
Replace a file in a zip file in a safe manner. This proceeds by extracting Replace a file in a zip file in a safe manner. This proceeds by extracting
and re-creating the zipfile. This is necessary because :method:`ZipFile.replace` and re-creating the zipfile. This is necessary because :method:`ZipFile.replace`
sometimes created corrupted zip files. sometimes created corrupted zip files.
:param zipstream: Stream from a zip file :param zipstream: Stream from a zip file
:param name: The name of the file to replace :param name: The name of the file to replace
:param datastream: The data to replace the file with. :param datastream: The data to replace the file with.
:param extra_replacements: Extra replacements. Mapping of name to file-like :param extra_replacements: Extra replacements. Mapping of name to file-like
objects objects
:param add_missing: If a replacement does not exist in the zip file, it is
added. Use with care as currently parent directories
are not created.
''' '''
z = ZipFile(zipstream, 'r') z = ZipFile(zipstream, 'r')
replacements = {name:datastream} replacements = {name:datastream}
replacements.update(extra_replacements) replacements.update(extra_replacements)
names = frozenset(replacements.keys()) names = frozenset(replacements.keys())
found = set([])
with SpooledTemporaryFile(max_size=100*1024*1024) as temp: with SpooledTemporaryFile(max_size=100*1024*1024) as temp:
ztemp = ZipFile(temp, 'w') ztemp = ZipFile(temp, 'w')
for obj in z.infolist(): for obj in z.infolist():
if isinstance(obj.filename, unicode):
obj.flag_bits |= 0x16 # Set isUTF-8 bit
if obj.filename in names: if obj.filename in names:
ztemp.writestr(obj, replacements[obj.filename].read()) ztemp.writestr(obj, replacements[obj.filename].read())
found.add(obj.filename)
else: else:
ztemp.writestr(obj, z.read_raw(obj), raw_bytes=True) ztemp.writestr(obj, z.read_raw(obj), raw_bytes=True)
if add_missing:
for name in names - found:
ztemp.writestr(name, replacements[name].read())
ztemp.close() ztemp.close()
z.close() z.close()
temp.seek(0) temp.seek(0)