1
# Copyright 2002 Ben Escoto
3
# This file is part of duplicity.
5
# duplicity is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA
8
# 02139, USA; either version 2 of the License, or (at your option) any
9
# later version; incorporated herein by reference.
11
"""Produce and parse the names of duplicity's backup files"""
16
full_vol_re = re.compile("^duplicity-full\\.(?P<time>.*?)\\.vol(?P<num>[0-9]+)\\.difftar($|\\.)", re.I)
17
full_manifest_re = re.compile("^duplicity-full\\.(?P<time>.*?)\\.manifest($|\\.)", re.I)
19
inc_vol_re = re.compile("^duplicity-inc\\.(?P<start_time>.*?)\\.to\\.(?P<end_time>.*?)\\.vol(?P<num>[0-9]+)\\.difftar($|\\.)", re.I)
20
inc_manifest_re = re.compile("^duplicity-inc\\.(?P<start_time>.*?)\\.to\\.(?P<end_time>.*?)\\.manifest(\\.|$)", re.I)
22
full_sig_re = re.compile("^duplicity-full-signatures\\.(?P<time>.*?)\\.sigtar(\\.|$)", re.I)
23
new_sig_re = re.compile("^duplicity-new-signatures\\.(?P<start_time>.*?)\\.to\\.(?P<end_time>.*?)\\.sigtar(\\.|$)", re.I)
25
def get(type, volume_number = None, manifest = None,
26
encrypted = None, gzipped = None):
27
"""Return duplicity filename of specified type
29
type can be "full", "inc", "full-sig", or "new-sig". volume_number
30
can be given with the full and inc types. If manifest is true the
31
filename is of a full or inc manifest file.
34
assert dup_time.curtimestr
35
assert not (encrypted and gzipped)
36
if encrypted: suffix = ".gpg"
37
elif gzipped: suffix = ".gz"
40
if type == "full-sig" or type == "new-sig":
41
assert not volume_number and not manifest
42
if type == "full-sig":
43
return "duplicity-full-signatures.%s.sigtar%s" % \
44
(dup_time.curtimestr, suffix)
45
elif type == "new-sig":
46
return "duplicity-new-signatures.%s.to.%s.sigtar%s" % \
47
(dup_time.prevtimestr, dup_time.curtimestr, suffix)
49
assert volume_number or manifest
50
assert not (volume_number and manifest)
51
if volume_number: vol_string = "vol%d.difftar" % volume_number
52
else: vol_string = "manifest"
54
return "duplicity-full.%s.%s%s" % \
55
(dup_time.curtimestr, vol_string, suffix)
57
return "duplicity-inc.%s.to.%s.%s%s" % \
58
(dup_time.prevtimestr, dup_time.curtimestr, vol_string, suffix)
63
"""Parse duplicity filename, return None or ParseResults object"""
65
"""Return ParseResults if file is from full backup, None otherwise"""
66
m1 = full_vol_re.search(filename)
67
m2 = full_manifest_re.search(filename)
69
t = dup_time.stringtotime((m1 or m2).group("time"))
71
if m1: return ParseResults("full", time = t,
72
volume_number = int(m1.group("num")))
73
else: return ParseResults("full", time = t, manifest = 1)
77
"""Return ParseResults if file is from inc backup, None otherwise"""
78
m1 = inc_vol_re.search(filename)
79
m2 = inc_manifest_re.search(filename)
81
t1 = dup_time.stringtotime((m1 or m2).group("start_time"))
82
t2 = dup_time.stringtotime((m1 or m2).group("end_time"))
84
if m1: return ParseResults("inc", start_time = t1,
85
end_time = t2, volume_number = int(m1.group("num")))
86
else: return ParseResults("inc", start_time = t1,
87
end_time = t2, manifest = 1)
91
"""Return ParseResults if file is a signature, None otherwise"""
92
m = full_sig_re.search(filename)
94
t = dup_time.stringtotime(m.group("time"))
95
if t: return ParseResults("full-sig", time = t)
98
m = new_sig_re.search(filename)
100
t1 = dup_time.stringtotime(m.group("start_time"))
101
t2 = dup_time.stringtotime(m.group("end_time"))
103
return ParseResults("new-sig", start_time = t1, end_time = t2)
106
def set_encryption_or_compression(pr):
107
"""Set encryption and compression flags in ParseResults pr"""
108
if filename.endswith('.gz'): pr.compressed = 1
109
else: pr.compressed = None
111
if filename.endswith('.gpg'): pr.encrypted = 1
112
else: pr.encrypted = None
121
set_encryption_or_compression(pr)
126
"""Hold information taken from a duplicity filename"""
127
def __init__(self, type, manifest = None, volume_number = None,
128
time = None, start_time = None, end_time = None,
129
encrypted = None, compressed = None):
130
assert (type == "full-sig" or type == "new-sig" or
131
type == "inc" or type == "full")
133
if type == "inc" or type == "full": assert manifest or volume_number
134
if type == "inc" or type == "new-sig": assert start_time and end_time
137
self.manifest = manifest
138
self.volume_number = volume_number
140
self.start_time, self.end_time = start_time, end_time
142
self.compressed = compressed # true if gzip compressed
143
self.encrypted = encrypted # true if gpg encrypted