def patch_seq2ropath(patch_seq): """Apply the patches in patch_seq, return single ropath""" first = patch_seq[0] assert first.difftype != "diff", "First patch in sequence " \ "%s was a diff" % patch_seq if not first.isreg(): # No need to bother with data if not regular file assert len(patch_seq) == 1, "Patch sequence isn't regular, but " \ "has %d entries" % len(patch_seq) return first.get_ropath() current_file = first.open("rb") for delta_ropath in patch_seq[1:]: assert delta_ropath.difftype == "diff", delta_ropath.difftype if not isinstance(current_file, file): """ librsync insists on a real file object, which we create manually by using the duplicity.tempdir to tell us where. See https://bugs.launchpad.net/duplicity/+bug/670891 for discussion of os.tmpfile() vs tempfile.TemporaryFile() w.r.t. Windows / Posix, which is worked around in librsync.PatchedFile() now. """ tempfp = tempfile.TemporaryFile(dir=tempdir.default().dir()) util.copyfileobj(current_file, tempfp) assert not current_file.close() tempfp.seek(0) current_file = tempfp current_file = librsync.PatchedFile(current_file, delta_ropath.open("rb")) result = patch_seq[-1].get_ropath() result.setfileobj(current_file) return result
def top_off(bytes, file): """ Add bytes of incompressible data to to_gpg_fp In this case we take the incompressible data from the beginning of filename (it should contain enough because size >> largest block size). """ incompressible_fp = open(filename, "rb") assert util.copyfileobj(incompressible_fp, file.gpg_input, bytes) == bytes incompressible_fp.close()