def html2pdf(html_filename, output_filename=None, **options): """ Convert a HTML file to PDF using FOP""" if not output_filename: output_filename = newTempfile(suffix='.pdf') if not prince_available: raise RuntimeError("The external PrinceXML converter isn't available") cmd_options = list() for k, v in options.items(): if v is None: cmd_options.append('--%s ' % k) else: cmd_options.append('--%s="%s" ' % (k, v)) if sys.platform == 'win32': raise NotImplementedError( 'No support for PrinceXML on Windows available') else: cmd = '%s "prince" "%s" %s -o "%s"' % \ (execution_shell, html_filename, ' '.join(cmd_options), output_filename) status, output = runcmd(cmd) if status != 0: raise ConversionError('Error executing: %s' % cmd, output) return dict(output_filename=output_filename, status=status, output=output)
class Record(object): __metaclass__ = RecordMeta def __new__(self, line): # fast return self.type(*(line[s] if convert is None else convert(line[s]) for s, convert in self.fields)) @classmethod def explain(cls, line): # safe and verbose, but slow problems = {} elements = [] for name, field in zip(cls.type._fields, cls.fields): s, convert = field raw = line[s] try: value = (convert or str)(line[s]) except Exception, e: problems[name] = Problem(raw, convert, e) else: elements.append(value) if problems: return ConversionError(problems, line) return cls.type(*elements)
def resize_image(self, image_path, image_width, image_height, transparency): """Resize image. :param image_path: Path to the source icon. :param image_width: Width of the icon. :param image_height: Height of the icon. :param image_format: Format of the icon. :param target_format: Target icon format. :param transparency: Whether to add transparency or not. :returns: Path to the resized image. """ resized_file = tempfile.NamedTemporaryFile( prefix='resized_', suffix='.' + os.path.splitext(image_path)[1][1:], delete=False) resized_path = resized_file.name # Adding transparency to make a square image if transparency: args_string = "%s %s -gravity center -background transparent " \ "-extent %dx%d %s" % (self.converttool, image_path, image_width, image_height, resized_path) # Resizing square image to the closest supported size else: args_string = "%s %s -resize %dx%d %s" % ( self.converttool, image_path, image_width, image_height, resized_path) args = args_string.split() logging.debug('Conversion call arguments: %r' % (args)) try: subprocess.check_output(args, stderr = subprocess.STDOUT) except subprocess.CalledProcessError, e: raise ConversionError('Failed to resize image %s' % (e.output))
def html2pdf(html_filename, output_filename=None, **options): """ Convert a HTML file to PDF using FOP""" if not output_filename: output_filename = newTempfile(suffix='.pdf') if not pdfreactor_available: raise RuntimeError("The external 'pdfreactor' converter isn't available") cmd = '%s "pdfreactor" "%s" "%s"' % \ (execution_shell, html_filename, output_filename) status, output = runcmd(cmd) if status != 0: raise ConversionError('Error executing: %s' % cmd, output) return dict(output_filename=output_filename, status=status, output=output)
def convert(self, image_list, target_format, target_path): """Convert a list of image files to an ico/icns file. :param image_list: List of image files to convert (either local paths or URLs). :param target_format: Target format. Must be one of ``FORMAT_ICO`` and ``FORMAT_ICNS``. :param target_path: Target path of the conversion. """ # Validate the input arguments. if target_format not in Converter.SUPPORTED_TARGET_FORMATS: raise ConversionError('invalid target format identifier: %s' % ( target_format)) if len(image_list) == 0: raise ValueError('image input list cannot be empty') # Make sure that all input files are stored locally and as PNGs. # image_list can contain either a local path or an http url local_image_list = [] for image_location in image_list: if ((image_location.startswith("http:")) or (image_location.startswith("https:"))): # Skip invalid/corrupt URLs try: image_location = self.fetch_image(image_location) except requests.exceptions.HTTPError, e: err = 'Could not retrieve image: %s' % str(e) self.notices.append(err) logging.debug(err) continue except ImageError, e: err = 'Could not save image: %s' % str(e) self.notices.append(err) logging.debug(err) continue
def fo2pdf(fo_filename, output_filename=None): """ Convert a FO file to PDF using XINC """ if not output_filename: output_filename = newTempfile(suffix='.pdf') if not xinc_available: raise RuntimeError("The external XINC converter isn't available") if sys.platform == 'win32': cmd = '%s\\bin\\windows\\xinc.exe -fo "%s" -pdf "%s"' % ( xinc_home, fo_filename, output_filename) else: cmd = '"%s/bin/unix/xinc" -fo "%s" -pdf "%s"' % ( xinc_home, fo_filename, output_filename) status, output = runcmd(cmd) if status != 0: raise ConversionError('Error executing: %s' % cmd, output) return dict(output_filename=output_filename, status=status, output=output)
def fo2pdf(fo_filename, output_filename=None): """ Convert a FO file to PDF using FOP""" if not output_filename: output_filename = newTempfile(suffix='.pdf') if not fop_available: raise RuntimeError("The external FOP converter isn't available") if sys.platform == 'win32': cmd = '%s\\fop.bat -fo "%s" -pdf "%s"' % (fop_home, fo_filename, output_filename) else: cmd = '%s "%s/fop" -fo "%s" -pdf "%s"' % \ (execution_shell, fop_home, fo_filename, output_filename) status, output = runcmd(cmd) if status != 0: raise ConversionError('Error executing: %s' % cmd, output) return dict(output_filename=output_filename, status=status, output=output)
def convert_to_png32(self, source_path, target_path): """Convert a source image to a 32 bit PNG image. :param source_path: Path of the source image. :param target_path: Path of the target image. :raises ConversionError: if conversion fails. """ logging.debug('Converting input image to 32-bit PNG: %s -> %s' % ( source_path, target_path)) # Perform the conversion. try: subprocess.check_output([ self.converttool, source_path, 'png32:%s' % (target_path) ], stderr = subprocess.STDOUT) except subprocess.CalledProcessError, e: raise ConversionError('Failed to convert input file to 32-bit PNG: %s' % ( e.output))
def html2calibre(html_filename, output_filename=None, cmdopts='', **calibre_options): """ Convert a HTML file using calibre """ if not html_filename.endswith('.html'): shutil.copy(html_filename, html_filename + '.html') html_filename += '.html' if not output_filename: output_filename = newTempfile(suffix='.epub') if not calibre_available: raise RuntimeError("The external calibre converter isn't available") options = list() for k, v in calibre_options.items(): if v is None: options.append('--%s ' % k) else: options.append('--%s="%s" ' % (k, v)) if sys.platform == 'win32': raise NotImplementedError( 'No support for using Calibre on Windows available') else: options = ' '.join(options) options = options + ' ' + cmdopts cmd = '"ebook-convert" "%s" "%s" %s' % (html_filename, output_filename, options) status, output = runcmd(cmd) if status != 0: raise ConversionError('Error executing: %s' % cmd, output) return dict(output_filename=output_filename, status=status, output=output)
if fixed_image_tuple: (resized_path, resized_width, resized_height) = fixed_image_tuple if not (resized_width, resized_height) in resized_images: resized_images[(resized_width, resized_height)] = resized_path image_list.append(resized_path) else: image_list.append(image_path) # Execute conversion command. logging.debug('Target path: %r' % (target_path)) logging.debug('Image list: %r' % (image_list)) if target_format == FORMAT_ICNS: args = [self.png2icns, target_path] + image_list elif target_format == FORMAT_ICO: args = [self.converttool] + image_list + [target_path] logging.debug('Conversion call arguments: %r' % (args)) logging.debug('Conversion call: %s' % ( ' '.join(['"%s"' % (a) if ' ' in a else a for a in args]))) # Verify libicns' bogus errors try: subprocess.check_output(args, stderr = subprocess.STDOUT) except subprocess.CalledProcessError, e: if not self.verify_generated_icon(target_format, target_path): raise ConversionError('Failed to create container icon: %s: %s' % ( target_format, e.output))
def convert(self, filename, encoding='utf-8', tidy=True, output_filename=None, **kw): """ Convert a HTML file stored as 'filename' to FO using CSS2XSLFO. """ if tidy: filename = tidyhtml(filename, encoding, strip_base=kw.get('strip_base', False)) if output_filename: fo_filename = output_filename else: fo_filename = newTempfile(suffix='.fo') csstoxslfo = os.path.abspath( os.path.join(dirname, 'lib', 'csstoxslfo', 'css2xslfo.jar')) if not os.path.exists(csstoxslfo): raise IOError('%s does not exist' % csstoxslfo) cmd = '"%s"' % java + \ ' -Duser.language=en -Xms256m -Xmx256m -jar "%(csstoxslfo)s" "%(filename)s" -fo "%(fo_filename)s"' % vars() for k in kw: cmd += ' %s="%s"' % (k, kw[k]) status, output = runcmd(cmd) if status != 0: raise ConversionError('Error executing: %s' % cmd, output) # remove tidy-ed file if tidy: os.unlink(filename) # remove some stuff from the generated FO file causing # some conversion trouble either with XINC or XFC E = parse(fo_filename) ids_seen = list() for node in E.getiterator(): get = node.attrib.get # ensure that ID attributes are unique node_id = get('id') if node_id is not None: if node_id in ids_seen: del node.attrib['id'] ids_seen.append(node_id) for k, v in (('footnote', 'reset'), ('unicode-bidi', 'embed'), ('writing-mode', 'lr-tb'), ('font-selection-strategy', 'character-by-character'), ('line-height-shift-adjustment', 'disregard-shifts'), ('page-break-after', 'avoid'), ('page-break-before', 'avoid'), ('page-break-inside', 'avoid')): value = get(k) if value == v: del node.attrib[k] for attr in ('margin-left', 'margin-right', 'margin-top', 'margin-bottom', 'padding-left', 'padding-right', 'padding-top', 'padding-bottom'): value = get(attr) if value == '0': node.attrib[attr] = '0em' if get('page-break-after') == 'always': del node.attrib['page-break-after'] node.attrib['break-after'] = 'page' if get('text-transform'): del node.attrib['text-transform'] value = get('white-space') if value == 'pre': del node.attrib['white-space'] node.text = '\n' + node.text.lstrip() for k, v in { 'white-space-treatment': 'preserve', 'white-space-collapse': 'false', 'wrap-option': 'no-wrap', 'linefeed-treatment': 'preserve' }.items(): node.attrib[k] = v fo_text = tostring(E.getroot()) fo_text = fo_text.replace( '<ns0:block ', '<ns0:block margin-top="0" margin-bottom="0" ' ) # avoid a linebreak through <li><p> (XFC) # fo_text = fo_text.replace('<ns0:block/>', '') # causes a crash with XINC fo_text = fo_text.replace( '<ns0:block margin-top="0" margin-bottom="0" />', '') file(fo_filename, 'wb').write(fo_text) return fo_filename