summaryrefslogtreecommitdiff
path: root/rdiff-backup/rdiff_backup/rpath.py
diff options
context:
space:
mode:
authorbescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2005-12-16 20:25:58 +0000
committerbescoto <bescoto@2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109>2005-12-16 20:25:58 +0000
commitde66d93df7e024b160116409dedea240056818b5 (patch)
tree6f807c94a1f29dcc0878f4dd6d4f7e83b09ef7e7 /rdiff-backup/rdiff_backup/rpath.py
parent895779c70dd4f6dd4c8d13b286540a4d5896b97f (diff)
downloadrdiff-backup-de66d93df7e024b160116409dedea240056818b5.tar.gz
Don't gzip 0 length files
git-svn-id: http://svn.savannah.nongnu.org/svn/rdiff-backup/trunk@712 2b77aa54-bcbc-44c9-a7ec-4f6cf2b41109
Diffstat (limited to 'rdiff-backup/rdiff_backup/rpath.py')
-rw-r--r--rdiff-backup/rdiff_backup/rpath.py55
1 files changed, 53 insertions, 2 deletions
diff --git a/rdiff-backup/rdiff_backup/rpath.py b/rdiff-backup/rdiff_backup/rpath.py
index 1f10f1a..7fed29c 100644
--- a/rdiff-backup/rdiff_backup/rpath.py
+++ b/rdiff-backup/rdiff_backup/rpath.py
@@ -1168,9 +1168,9 @@ class RPath(RORPath):
self.fsync(fp)
if Globals.fsync_directories: self.get_parent_rp().fsync()
- def get_data(self):
+ def get_data(self, compressed = None):
"""Open file as a regular file, read data, close, return data"""
- fp = self.open("rb")
+ fp = self.open("rb", compressed)
s = fp.read()
assert not fp.close()
return s
@@ -1263,6 +1263,57 @@ class GzipFile(gzip.GzipFile):
"""
def __del__(self): pass
+ def __getattr__(self, name):
+ if name == 'fileno': return self.fileobj.fileno
+ else: raise AttributeError(name)
+
+
+class MaybeGzip:
+ """Represent a file object that may or may not be compressed
+
+ We don't want to compress 0 length files. This class lets us
+ delay the opening of the file until either the first write (so we
+ know it has data and should be compressed), or close (when there's
+ no data).
+
+ """
+ def __init__(self, base_rp, callback = None):
+ """Return file-like object with filename based on base_rp"""
+ assert not base_rp.lstat(), base_rp
+ self.base_rp = base_rp
+ # callback will be called with final write rp as only argument
+ self.callback = callback
+ self.fileobj = None # Will be None unless data gets written
+ self.closed = 0
+
+ def __getattr__(self, name):
+ if name == 'fileno': return self.fileobj.fileno
+ else: raise AttributeError(name)
+
+ def get_gzipped_rp(self):
+ """Return gzipped rp by adding .gz to base_rp"""
+ if self.base_rp.index:
+ newind = self.base_rp.index[:-1] + (self.base_rp.index[-1]+'.gz',)
+ return self.base_rp.new_index(newind)
+ else: return self.base_rp.append_path('.gz')
+
+ def write(self, buf):
+ """Write buf to fileobj"""
+ if self.fileobj: return self.fileobj.write(buf)
+ if not buf: return
+
+ new_rp = self.get_gzipped_rp()
+ if self.callback: self.callback(new_rp)
+ self.fileobj = new_rp.open("w", compress = 1)
+ return self.fileobj.write(buf)
+
+ def close(self):
+ """Close related fileobj, pass return value"""
+ if self.closed: return None
+ self.closed = 1
+ if self.fileobj: return self.fileobj.close()
+ if self.callback: self.callback(self.base_rp)
+ self.base_rp.touch()
def setdata_local(rpath):