summaryrefslogtreecommitdiff
path: root/rdiff-backup/rdiff_backup/manage.py
blob: c0f4a8578d0bf6663a04be97bb1589634eb63ad3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
execfile("restore.py")

#######################################################################
#
# manage - list, delete, and otherwise manage increments
#

class ManageException(Exception): pass

class Manage:
	def get_incobjs(datadir):
		"""Return Increments objects given the rdiff-backup data directory"""
		return map(IncObj, Manage.find_incrps_with_base(datadir, "increments"))

	def find_incrps_with_base(dir_rp, basename):
		"""Return list of incfiles with given basename in dir_rp"""
		rps = map(dir_rp.append, dir_rp.listdir())
		incrps = filter(RPath.isincfile, rps)
		result = filter(lambda rp: rp.getincbase_str() == basename, incrps)
		Log("find_incrps_with_base: found %d incs" % len(result), 6)
		return result
	
	def describe_root_incs(datadir):
		"""Return a string describing all the the root increments"""
		result = []
		currentrps = Manage.find_incrps_with_base(datadir, "current_mirror")
		if not currentrps:
			Log("Warning: no current mirror marker found", 1)
		elif len(currentrps) > 1:
			Log("Warning: multiple mirror markers found", 1)
		for rp in currentrps:
			result.append("Found mirror marker %s" % rp.path)
			result.append("Indicating latest mirror taken at %s" %
						  Time.stringtopretty(rp.getinctime()))
		result.append("---------------------------------------------"
					  "-------------")

		# Sort so they are in reverse order by time
		time_w_incobjs = map(lambda io: (-io.time, io),
							 Manage.get_incobjs(datadir))
		time_w_incobjs.sort()
		incobjs = map(lambda x: x[1], time_w_incobjs)
		result.append("Found %d increments:" % len(incobjs))
		result.append("\n------------------------------------------\n".join(
			map(IncObj.full_description, incobjs)))
		return "\n".join(result)

	def delete_earlier_than(baserp, time):
		"""Deleting increments older than time in directory baserp

		time is in seconds.  It will then delete any empty directories
		in the tree.  To process the entire backup area, the
		rdiff-backup-data directory should be the root of the tree.

		"""
		def yield_files(rp):
			yield rp
			if rp.isdir():
				for filename in rp.listdir():
					for sub_rp in yield_files(rp.append(filename)):
						yield sub_rp

		for rp in yield_files(baserp):
			if ((rp.isincfile() and
				 Time.stringtotime(rp.getinctime()) < time) or
				(rp.isdir() and not rp.listdir())):
				Log("Deleting increment file %s" % rp.path, 5)
				rp.delete()

MakeStatic(Manage)


class IncObj:
	"""Increment object - represent a completed increment"""
	def __init__(self, incrp):
		"""IncObj initializer

		incrp is an RPath of a path like increments.TIMESTR.dir
		standing for the root of the increment.

		"""
		if not incrp.isincfile():
			raise ManageException("%s is not an inc file" % incrp.path)
		self.incrp = incrp
		self.time = Time.stringtotime(incrp.getinctime())

	def getbaserp(self):
		"""Return rp of the incrp without extensions"""
		return self.incrp.getincbase()

	def pretty_time(self):
		"""Return a formatted version of inc's time"""
		return Time.timetopretty(self.time)

	def full_description(self):
		"""Return string describing increment"""
		s = ["Increment file %s" % self.incrp.path,
			 "Date: %s" % self.pretty_time()]
		return "\n".join(s)