Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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)))
Esempio n. 4
0
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
Esempio n. 5
0
 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)
Esempio n. 6
0
 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)