mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Fix various file access bugs.
This commit is contained in:
parent
ba7f030a88
commit
2e52d6dfe3
@ -241,8 +241,6 @@ class HTMLConverter(object):
|
|||||||
self.link_level += 1
|
self.link_level += 1
|
||||||
paths = [link['path'] for link in self.links]
|
paths = [link['path'] for link in self.links]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def is_baen(self, soup):
|
def is_baen(self, soup):
|
||||||
return bool(soup.find('meta', attrs={'name':'Publisher',
|
return bool(soup.find('meta', attrs={'name':'Publisher',
|
||||||
'content':re.compile('Baen', re.IGNORECASE)}))
|
'content':re.compile('Baen', re.IGNORECASE)}))
|
||||||
@ -791,7 +789,7 @@ class HTMLConverter(object):
|
|||||||
if fmt == 'JPG':
|
if fmt == 'JPG':
|
||||||
fmt = 'JPEG'
|
fmt = 'JPEG'
|
||||||
return fmt
|
return fmt
|
||||||
|
|
||||||
original_path = path
|
original_path = path
|
||||||
if self.rotated_images.has_key(path):
|
if self.rotated_images.has_key(path):
|
||||||
path = self.rotated_images[path].name
|
path = self.rotated_images[path].name
|
||||||
@ -807,7 +805,7 @@ class HTMLConverter(object):
|
|||||||
|
|
||||||
if width == None or height == None:
|
if width == None or height == None:
|
||||||
width, height = im.size
|
width, height = im.size
|
||||||
|
|
||||||
factor = 720./self.profile.dpi
|
factor = 720./self.profile.dpi
|
||||||
|
|
||||||
def scale_image(width, height):
|
def scale_image(width, height):
|
||||||
@ -846,7 +844,7 @@ class HTMLConverter(object):
|
|||||||
dc.append(Plot(im, xsize=ceil(width*factor), ysize=ceil(height*factor)))
|
dc.append(Plot(im, xsize=ceil(width*factor), ysize=ceil(height*factor)))
|
||||||
self.current_para.append(dc)
|
self.current_para.append(dc)
|
||||||
return
|
return
|
||||||
|
|
||||||
if not self.disable_autorotation and width > pwidth and width > height:
|
if not self.disable_autorotation and width > pwidth and width > height:
|
||||||
pt = PersistentTemporaryFile(suffix='.'+encoding.lower())
|
pt = PersistentTemporaryFile(suffix='.'+encoding.lower())
|
||||||
try:
|
try:
|
||||||
@ -1248,7 +1246,7 @@ class HTMLConverter(object):
|
|||||||
path = munge_paths(self.target_prefix, tag['href'])[0]
|
path = munge_paths(self.target_prefix, tag['href'])[0]
|
||||||
ext = os.path.splitext(path)[1]
|
ext = os.path.splitext(path)[1]
|
||||||
if ext: ext = ext[1:].lower()
|
if ext: ext = ext[1:].lower()
|
||||||
if os.access(path, os.R_OK):
|
if os.access(path, os.R_OK) and os.path.isfile(path):
|
||||||
if ext in ['png', 'jpg', 'bmp', 'jpeg']:
|
if ext in ['png', 'jpg', 'bmp', 'jpeg']:
|
||||||
self.process_image(path, tag_css)
|
self.process_image(path, tag_css)
|
||||||
else:
|
else:
|
||||||
@ -1260,14 +1258,14 @@ class HTMLConverter(object):
|
|||||||
if tag.has_key('id') or tag.has_key('name'):
|
if tag.has_key('id') or tag.has_key('name'):
|
||||||
key = 'name' if tag.has_key('name') else 'id'
|
key = 'name' if tag.has_key('name') else 'id'
|
||||||
self.targets[self.target_prefix+tag[key]] = self.current_block
|
self.targets[self.target_prefix+tag[key]] = self.current_block
|
||||||
else:
|
elif not urlparse(tag['href'])[0]:
|
||||||
self.logger.warn('Could not follow link to '+tag['href'])
|
self.logger.warn('Could not follow link to '+tag['href'])
|
||||||
elif tag.has_key('name') or tag.has_key('id'):
|
elif tag.has_key('name') or tag.has_key('id'):
|
||||||
self.process_anchor(tag, tag_css, tag_pseudo_css)
|
self.process_anchor(tag, tag_css, tag_pseudo_css)
|
||||||
elif tagname == 'img':
|
elif tagname == 'img':
|
||||||
if tag.has_key('src'):
|
if tag.has_key('src'):
|
||||||
path = munge_paths(self.target_prefix, tag['src'])[0]
|
path = munge_paths(self.target_prefix, tag['src'])[0]
|
||||||
if os.access(path, os.R_OK):
|
if os.access(path, os.R_OK) and os.path.isfile(path):
|
||||||
width, height = None, None
|
width, height = None, None
|
||||||
try:
|
try:
|
||||||
width = int(tag['width'])
|
width = int(tag['width'])
|
||||||
@ -1276,7 +1274,7 @@ class HTMLConverter(object):
|
|||||||
pass
|
pass
|
||||||
dropcaps = tag.has_key('class') and tag['class'] == 'libprs500_dropcaps'
|
dropcaps = tag.has_key('class') and tag['class'] == 'libprs500_dropcaps'
|
||||||
self.process_image(path, tag_css, width, height, dropcaps=dropcaps)
|
self.process_image(path, tag_css, width, height, dropcaps=dropcaps)
|
||||||
else:
|
elif not urlparse(tag['src'])[0]:
|
||||||
self.logger.warn('Could not find image: '+tag['src'])
|
self.logger.warn('Could not find image: '+tag['src'])
|
||||||
else:
|
else:
|
||||||
self.logger.debug("Failed to process: %s", str(tag))
|
self.logger.debug("Failed to process: %s", str(tag))
|
||||||
@ -1532,109 +1530,105 @@ def process_file(path, options, logger=None):
|
|||||||
level = logging.DEBUG if options.verbose else logging.INFO
|
level = logging.DEBUG if options.verbose else logging.INFO
|
||||||
logger = logging.getLogger('html2lrf')
|
logger = logging.getLogger('html2lrf')
|
||||||
setup_cli_handlers(logger, level)
|
setup_cli_handlers(logger, level)
|
||||||
cwd = os.getcwd()
|
path = os.path.normpath(os.path.abspath(path))
|
||||||
default_title = filename_to_utf8(os.path.splitext(os.path.basename(path))[0])
|
default_title = filename_to_utf8(os.path.splitext(os.path.basename(path))[0])
|
||||||
dirpath = os.path.dirname(path)
|
dirpath = os.path.dirname(path)
|
||||||
try:
|
|
||||||
cpath, tpath = '', ''
|
tpath = ''
|
||||||
try_opf(path, options, logger)
|
try_opf(path, options, logger)
|
||||||
if options.cover:
|
if options.cover:
|
||||||
cpath = os.path.join(dirpath, os.path.basename(options.cover))
|
options.cover = os.path.expanduser(options.cover)
|
||||||
if not os.path.exists(cpath):
|
if not os.path.isabs(options.cover):
|
||||||
cpath = os.path.abspath(os.path.expanduser(options.cover))
|
options.cover = os.path.join(dirpath, options.cover)
|
||||||
options.cover = cpath
|
if os.access(options.cover, os.R_OK):
|
||||||
if os.access(options.cover, os.R_OK):
|
th = Device.THUMBNAIL_HEIGHT
|
||||||
th = Device.THUMBNAIL_HEIGHT
|
im = PILImage.open(options.cover)
|
||||||
im = PILImage.open(os.path.join(cwd, cpath))
|
cim = im.resize((options.profile.screen_width,
|
||||||
cim = im.resize((options.profile.screen_width,
|
options.profile.screen_height - options.profile.fudge),
|
||||||
options.profile.screen_height - options.profile.fudge),
|
PILImage.BICUBIC).convert('RGB')
|
||||||
PILImage.BICUBIC).convert('RGB')
|
cf = PersistentTemporaryFile(prefix=__appname__+"_", suffix=".jpg")
|
||||||
cf = PersistentTemporaryFile(prefix=__appname__+"_", suffix=".jpg")
|
cf.close()
|
||||||
cf.close()
|
cim.save(cf.name)
|
||||||
cim.save(cf.name)
|
|
||||||
cpath = cf.name
|
tim = im.resize((int(0.75*th), th), PILImage.ANTIALIAS).convert('RGB')
|
||||||
|
tf = PersistentTemporaryFile(prefix="html2lrf_", suffix=".jpg")
|
||||||
|
tf.close()
|
||||||
|
tim.save(tf.name)
|
||||||
|
tpath = tf.name
|
||||||
|
else:
|
||||||
|
raise ConversionError, 'Cannot read from: %s'% (options.cover,)
|
||||||
|
|
||||||
|
|
||||||
tim = im.resize((int(0.75*th), th), PILImage.ANTIALIAS).convert('RGB')
|
if not options.title:
|
||||||
tf = PersistentTemporaryFile(prefix="html2lrf_", suffix=".jpg")
|
options.title = default_title
|
||||||
tf.close()
|
|
||||||
tim.save(tf.name)
|
for prop in ('author', 'author_sort', 'title', 'title_sort', 'publisher', 'freetext'):
|
||||||
tpath = tf.name
|
val = getattr(options, prop)
|
||||||
else:
|
if val and not isinstance(val, unicode):
|
||||||
raise ConversionError, 'Cannot read from: %s'% (options.cover,)
|
soup = BeautifulSoup(val)
|
||||||
|
setattr(options, prop, unicode(soup))
|
||||||
|
|
||||||
if not options.title:
|
title = (options.title, options.title_sort)
|
||||||
options.title = default_title
|
author = (options.author, options.author_sort)
|
||||||
|
|
||||||
for prop in ('author', 'author_sort', 'title', 'title_sort', 'publisher', 'freetext'):
|
args = dict(font_delta=options.font_delta, title=title, \
|
||||||
val = getattr(options, prop)
|
author=author, sourceencoding='utf8',\
|
||||||
if val and not isinstance(val, unicode):
|
freetext=options.freetext, category=options.category,
|
||||||
soup = BeautifulSoup(val)
|
publisher=options.publisher,
|
||||||
setattr(options, prop, unicode(soup))
|
booksetting=BookSetting(dpi=10*options.profile.dpi,
|
||||||
|
screenheight=options.profile.screen_height,
|
||||||
title = (options.title, options.title_sort)
|
screenwidth=options.profile.screen_width))
|
||||||
author = (options.author, options.author_sort)
|
if tpath:
|
||||||
|
args['thumbnail'] = tpath
|
||||||
args = dict(font_delta=options.font_delta, title=title, \
|
header = None
|
||||||
author=author, sourceencoding='utf8',\
|
if options.header:
|
||||||
freetext=options.freetext, category=options.category,
|
header = Paragraph()
|
||||||
publisher=options.publisher,
|
fheader = options.headerformat
|
||||||
booksetting=BookSetting(dpi=10*options.profile.dpi,
|
fheader = re.sub(r'([^%]|^)%t', r'\1' + options.title, fheader)
|
||||||
screenheight=options.profile.screen_height,
|
fheader = re.sub(r'([^%]|^)%a', r'\1' + options.author, fheader)
|
||||||
screenwidth=options.profile.screen_width))
|
fheader = re.sub(r'%%a','%a',fheader)
|
||||||
if tpath:
|
fheader = re.sub(r'%%t','%t',fheader)
|
||||||
args['thumbnail'] = tpath
|
header.append(fheader + " ")
|
||||||
header = None
|
book, fonts = Book(options, logger, header=header, **args)
|
||||||
if options.header:
|
le = re.compile(options.link_exclude) if options.link_exclude else \
|
||||||
header = Paragraph()
|
re.compile('$')
|
||||||
fheader = options.headerformat
|
pb = re.compile(options.page_break, re.IGNORECASE) if options.page_break else \
|
||||||
fheader = re.sub(r'([^%]|^)%t', r'\1' + options.title, fheader)
|
re.compile('$')
|
||||||
fheader = re.sub(r'([^%]|^)%a', r'\1' + options.author, fheader)
|
fpb = re.compile(options.force_page_break, re.IGNORECASE) if options.force_page_break else \
|
||||||
fheader = re.sub(r'%%a','%a',fheader)
|
re.compile('$')
|
||||||
fheader = re.sub(r'%%t','%t',fheader)
|
options.force_page_break = fpb
|
||||||
header.append(fheader + " ")
|
options.link_exclude = le
|
||||||
book, fonts = Book(options, logger, header=header, **args)
|
options.page_break = pb
|
||||||
le = re.compile(options.link_exclude) if options.link_exclude else \
|
options.chapter_regex = re.compile(options.chapter_regex, re.IGNORECASE)
|
||||||
re.compile('$')
|
fpba = options.force_page_break_attr.split(',')
|
||||||
pb = re.compile(options.page_break, re.IGNORECASE) if options.page_break else \
|
if len(fpba) != 3:
|
||||||
re.compile('$')
|
fpba = ['$', '', '$']
|
||||||
fpb = re.compile(options.force_page_break, re.IGNORECASE) if options.force_page_break else \
|
options.force_page_break_attr = [re.compile(fpba[0], re.IGNORECASE), fpba[1],
|
||||||
re.compile('$')
|
re.compile(fpba[2], re.IGNORECASE)]
|
||||||
options.cover = cpath
|
if not hasattr(options, 'anchor_ids'):
|
||||||
options.force_page_break = fpb
|
options.anchor_ids = True
|
||||||
options.link_exclude = le
|
files = options.spine if options.use_spine else [path]
|
||||||
options.page_break = pb
|
conv = HTMLConverter(book, fonts, options, logger, files)
|
||||||
options.chapter_regex = re.compile(options.chapter_regex, re.IGNORECASE)
|
if options.use_spine:
|
||||||
fpba = options.force_page_break_attr.split(',')
|
conv.create_toc(options.toc)
|
||||||
if len(fpba) != 3:
|
oname = options.output
|
||||||
fpba = ['$', '', '$']
|
if not oname:
|
||||||
options.force_page_break_attr = [re.compile(fpba[0], re.IGNORECASE), fpba[1],
|
suffix = '.lrs' if options.lrs else '.lrf'
|
||||||
re.compile(fpba[2], re.IGNORECASE)]
|
name = os.path.splitext(os.path.basename(path))[0] + suffix
|
||||||
if not hasattr(options, 'anchor_ids'):
|
oname = os.path.join(os.getcwd(), name)
|
||||||
options.anchor_ids = True
|
oname = os.path.abspath(os.path.expanduser(oname))
|
||||||
files = options.spine if options.use_spine else [path]
|
conv.writeto(oname, lrs=options.lrs)
|
||||||
conv = HTMLConverter(book, fonts, options, logger, files)
|
logger.info('Output written to %s', oname)
|
||||||
if options.use_spine:
|
conv.cleanup()
|
||||||
conv.create_toc(options.toc)
|
return oname
|
||||||
oname = options.output
|
|
||||||
if not oname:
|
|
||||||
suffix = '.lrs' if options.lrs else '.lrf'
|
|
||||||
name = os.path.splitext(os.path.basename(path))[0] + suffix
|
|
||||||
oname = os.path.join(cwd,name)
|
|
||||||
oname = os.path.abspath(os.path.expanduser(oname))
|
|
||||||
conv.writeto(oname, lrs=options.lrs)
|
|
||||||
logger.info('Output written to %s', oname)
|
|
||||||
conv.cleanup()
|
|
||||||
return oname
|
|
||||||
finally:
|
|
||||||
os.chdir(cwd)
|
|
||||||
|
|
||||||
def try_opf(path, options, logger):
|
def try_opf(path, options, logger):
|
||||||
try:
|
try:
|
||||||
opf = glob.glob(os.path.join(os.path.dirname(path),'*.opf'))[0]
|
opf = glob.glob(os.path.join(os.path.dirname(path),'*.opf'))[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return
|
return
|
||||||
opf = OPFReader(open(opf, 'rb'), os.path.dirname(os.path.abspath(opf)))
|
dirpath = os.path.dirname(os.path.abspath(opf))
|
||||||
|
opf = OPFReader(open(opf, 'rb'), dirpath)
|
||||||
try:
|
try:
|
||||||
title = opf.title
|
title = opf.title
|
||||||
if title and not options.title:
|
if title and not options.title:
|
||||||
@ -1655,7 +1649,8 @@ def try_opf(path, options, logger):
|
|||||||
if not options.cover:
|
if not options.cover:
|
||||||
cover = opf.cover
|
cover = opf.cover
|
||||||
if cover:
|
if cover:
|
||||||
cover = os.path.join(os.path.dirname(path), cover)
|
if not os.path.isabs(cover):
|
||||||
|
cover = os.path.join(dirpath, cover)
|
||||||
if os.access(cover, os.R_OK):
|
if os.access(cover, os.R_OK):
|
||||||
try:
|
try:
|
||||||
PILImage.open(cover)
|
PILImage.open(cover)
|
||||||
@ -1674,7 +1669,7 @@ def try_opf(path, options, logger):
|
|||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
options.spine = [i.href for i in opf.spine.items()]
|
options.spine = [i.href for i in opf.spine.items()]
|
||||||
options.toc = opf.toc
|
options.toc = opf.toc
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.exception('Failed to process opf file')
|
logger.exception('Failed to process opf file')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user