def encode(self, command, source, dest, pretend=False): """Encode `source` to `dest` using command template `command`. Raises `subprocess.CalledProcessError` if the command exited with a non-zero status code. """ # The paths and arguments must be bytes. assert isinstance(command, bytes) assert isinstance(source, bytes) assert isinstance(dest, bytes) quiet = self.config['quiet'].get(bool) if not quiet and not pretend: self._log.info('Encoding {0}', util.displayable_path(source)) command = command.decode(arg_encoding(), 'surrogateescape') source = decode_commandline_path(source) dest = decode_commandline_path(dest) # Substitute $source and $dest in the argument list. args = shlex.split(command) encode_cmd = [] for i, arg in enumerate(args): args[i] = Template(arg).safe_substitute({ 'source': source, 'dest': dest, }) encode_cmd.append(args[i].encode(util.arg_encoding())) if pretend: self._log.info('{0}', ' '.join(ui.decargs(args))) return try: util.command_output(encode_cmd) except subprocess.CalledProcessError as exc: # Something went wrong (probably Ctrl+C), remove temporary files self._log.info('Encoding {0} failed. Cleaning up...', util.displayable_path(source)) self._log.debug('Command {0} exited with status {1}: {2}', args, exc.returncode, exc.output) util.remove(dest) util.prune_dirs(os.path.dirname(dest)) raise except OSError as exc: raise ui.UserError( "convert: couldn't invoke '{}': {}".format( ' '.join(ui.decargs(args)), exc ) ) if not quiet and not pretend: self._log.info('Finished encoding {0}', util.displayable_path(source))
def _checksum(self, item, prog): """Run external `prog` on file path associated with `item`, cache output as flexattr on a key that is the name of the program, and return the key, checksum tuple. """ args = [ p.format(file=decode_commandline_path(item.path)) for p in shlex.split(prog) ] key = args[0] checksum = getattr(item, key, False) if not checksum: self._log.debug( u'key {0} on item {1} not cached:' u'computing checksum', key, displayable_path(item.path)) try: checksum = command_output(args).stdout setattr(item, key, checksum) item.store() self._log.debug(u'computed checksum for {0} using {1}', item.title, key) except subprocess.CalledProcessError as e: self._log.debug(u'failed to checksum {0}: {1}', displayable_path(item.path), e) else: self._log.debug( u'key {0} on item {1} cached:' u'not computing checksum', key, displayable_path(item.path)) return key, checksum