mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Pull from trunk
This commit is contained in:
commit
4b2f39aa85
@ -67,10 +67,17 @@ def load_plugin(path_to_zip_file): # {{{
|
||||
if name.lower().endswith('plugin.py'):
|
||||
locals = {}
|
||||
raw = zf.read(name)
|
||||
match = re.search(r'coding[:=]\s*([-\w.]+)', raw[:300])
|
||||
encoding = 'utf-8'
|
||||
lines, encoding = raw.splitlines(), 'utf-8'
|
||||
cr = re.compile(r'coding[:=]\s*([-\w.]+)')
|
||||
raw = []
|
||||
for l in lines[:2]:
|
||||
match = cr.search(l)
|
||||
if match is not None:
|
||||
encoding = match.group(1)
|
||||
else:
|
||||
raw.append(l)
|
||||
raw += lines[2:]
|
||||
raw = '\n'.join(raw)
|
||||
raw = raw.decode(encoding)
|
||||
raw = re.sub('\r\n', '\n', raw)
|
||||
exec raw in locals
|
||||
|
@ -15,7 +15,7 @@ from calibre.customize.ui import available_input_formats
|
||||
from calibre.ebooks.metadata.opf2 import OPF
|
||||
from calibre.ptempfile import TemporaryDirectory
|
||||
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.logging import Log
|
||||
from calibre import guess_type, prints
|
||||
@ -294,12 +294,8 @@ class EbookIterator(object):
|
||||
zf = open(self.pathtoebook, 'r+b')
|
||||
except IOError:
|
||||
return
|
||||
zipf = ZipFile(zf, mode='a')
|
||||
for name in zipf.namelist():
|
||||
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)
|
||||
safe_replace(zf, 'META-INF/calibre_bookmarks.txt', StringIO(dat),
|
||||
add_missing=True)
|
||||
else:
|
||||
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
@ -281,7 +281,7 @@ class ZipInfo (object):
|
||||
'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
|
||||
|
||||
# Terminate the file name at the first null byte. Null bytes in file
|
||||
@ -1362,30 +1362,42 @@ class ZipFile:
|
||||
self.fp.close()
|
||||
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
|
||||
and re-creating the zipfile. This is necessary because :method:`ZipFile.replace`
|
||||
sometimes created corrupted zip files.
|
||||
|
||||
|
||||
:param zipstream: Stream from a zip file
|
||||
:param name: The name of the file to replace
|
||||
:param datastream: The data to replace the file with.
|
||||
:param extra_replacements: Extra replacements. Mapping of name to file-like
|
||||
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')
|
||||
replacements = {name:datastream}
|
||||
replacements.update(extra_replacements)
|
||||
names = frozenset(replacements.keys())
|
||||
found = set([])
|
||||
with SpooledTemporaryFile(max_size=100*1024*1024) as temp:
|
||||
ztemp = ZipFile(temp, 'w')
|
||||
for obj in z.infolist():
|
||||
if isinstance(obj.filename, unicode):
|
||||
obj.flag_bits |= 0x16 # Set isUTF-8 bit
|
||||
if obj.filename in names:
|
||||
ztemp.writestr(obj, replacements[obj.filename].read())
|
||||
found.add(obj.filename)
|
||||
else:
|
||||
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()
|
||||
z.close()
|
||||
temp.seek(0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user