def patch_seq2ropath( patch_seq ): """Apply the patches in patch_seq, return single ropath""" first = patch_seq[0] assert first.difftype != "diff", patch_seq if not first.isreg(): # No need to bother with data if not regular file assert len( patch_seq ) == 1, 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 needs true file tempfp = os.tmpfile() misc.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 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 librsyncPatchFile(oldfile, deltafile, newfile): logger.debug( u"Librsync patch: old file {!r}, delta file {!r}, new file {!r}", oldfile, deltafile, newfile) oldfile = forceFilename(oldfile) newfile = forceFilename(newfile) deltafile = forceFilename(deltafile) if oldfile == newfile: raise ValueError(u"Oldfile and newfile are the same file") if deltafile == newfile: raise ValueError(u"deltafile and newfile are the same file") if deltafile == oldfile: raise ValueError(u"oldfile and deltafile are the same file") bufsize = 1024 * 1024 try: with open(oldfile, "rb") as of: with open(deltafile, "rb") as df: with open(newfile, "wb") as nf: with closing(librsync.PatchedFile(of, df)) as pf: data = True while data: data = pf.read(bufsize) nf.write(data) except Exception as patchError: logger.debug("Patching {!r} with delta {!r} into {!r} failed: {}", oldfile, deltafile, newfile, patchError) raise RuntimeError(u"Failed to patch file %s: %s" % (oldfile, forceUnicode(patchError)))
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. """ tempfp = tempfile.TemporaryFile(dir=tempdir.default().dir()) misc.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 patch_with_attribs(self, diff_ropath): """Patch self with diff and then copy attributes over""" assert self.isreg() and diff_ropath.isreg() temp_path = self.get_temp_in_same_dir() patch_fileobj = librsync.PatchedFile(self.open("rb"), diff_ropath.open("rb")) temp_path.writefileobj(patch_fileobj) diff_ropath.copy_attribs(temp_path) temp_path.rename(self)
def patch_with_attribs(self, diff_ropath): u"""Patch self with diff and then copy attributes over""" assert self.isreg() and diff_ropath.isreg() temp_path = self.get_temp_in_same_dir() fbase = self.open(u"rb") fdiff = diff_ropath.open(u"rb") patch_fileobj = librsync.PatchedFile(fbase, fdiff) temp_path.writefileobj(patch_fileobj) assert not fbase.close() assert not fdiff.close() diff_ropath.copy_attribs(temp_path) temp_path.rename(self)