Fix various file access bugs.

This commit is contained in:
Kovid Goyal 2007-10-13 17:30:45 +00:00
parent ba7f030a88
commit 2e52d6dfe3

View File

@ -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')