~ed.so/duplicity/reuse-passphrase-for-signing-fix

« back to all changes in this revision

Viewing changes to duplicity/file_naming.py

  • Committer: bescoto
  • Date: 2002-10-29 01:49:46 UTC
  • Revision ID: vcs-imports@canonical.com-20021029014946-3m4rmm5plom7pl6q
Initial checkin

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2002 Ben Escoto
 
2
#
 
3
# This file is part of duplicity.
 
4
#
 
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.
 
10
 
 
11
"""Produce and parse the names of duplicity's backup files"""
 
12
 
 
13
import re
 
14
import dup_time
 
15
 
 
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)
 
18
 
 
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)
 
21
 
 
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)
 
24
 
 
25
def get(type, volume_number = None, manifest = None,
 
26
                encrypted = None, gzipped = None):
 
27
        """Return duplicity filename of specified type
 
28
 
 
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.
 
32
 
 
33
        """
 
34
        assert dup_time.curtimestr
 
35
        assert not (encrypted and gzipped)
 
36
        if encrypted: suffix = ".gpg"
 
37
        elif gzipped: suffix = ".gz"
 
38
        else: suffix = ""
 
39
 
 
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)
 
48
        else:
 
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"
 
53
                if type == "full":
 
54
                        return "duplicity-full.%s.%s%s" % \
 
55
                                   (dup_time.curtimestr, vol_string, suffix)
 
56
                elif type == "inc":
 
57
                        return "duplicity-inc.%s.to.%s.%s%s" % \
 
58
                          (dup_time.prevtimestr, dup_time.curtimestr, vol_string, suffix)
 
59
                else: assert 0
 
60
 
 
61
 
 
62
def parse(filename):
 
63
        """Parse duplicity filename, return None or ParseResults object"""
 
64
        def check_full():
 
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)
 
68
                if m1 or m2:
 
69
                        t = dup_time.stringtotime((m1 or m2).group("time"))
 
70
                        if t:
 
71
                                if m1: return ParseResults("full", time = t,
 
72
                                                                                volume_number = int(m1.group("num")))
 
73
                                else: return ParseResults("full", time = t, manifest = 1)
 
74
                return None
 
75
 
 
76
        def check_inc():
 
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)
 
80
                if m1 or m2:
 
81
                        t1 = dup_time.stringtotime((m1 or m2).group("start_time"))
 
82
                        t2 = dup_time.stringtotime((m1 or m2).group("end_time"))
 
83
                        if t1 and t2:
 
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)
 
88
                return None
 
89
 
 
90
        def check_sig():
 
91
                """Return ParseResults if file is a signature, None otherwise"""
 
92
                m = full_sig_re.search(filename)
 
93
                if m:
 
94
                        t = dup_time.stringtotime(m.group("time"))
 
95
                        if t: return ParseResults("full-sig", time = t)
 
96
                        else: return None
 
97
 
 
98
                m = new_sig_re.search(filename)
 
99
                if m:
 
100
                        t1 = dup_time.stringtotime(m.group("start_time"))
 
101
                        t2 = dup_time.stringtotime(m.group("end_time"))
 
102
                        if t1 and t2:
 
103
                                return ParseResults("new-sig", start_time = t1, end_time = t2)
 
104
                return None
 
105
 
 
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
 
110
 
 
111
                if filename.endswith('.gpg'): pr.encrypted = 1
 
112
                else: pr.encrypted = None
 
113
 
 
114
        pr = check_full()
 
115
        if not pr:
 
116
                pr = check_inc()
 
117
                if not pr:
 
118
                        pr = check_sig()
 
119
                        if not pr:
 
120
                                return None
 
121
        set_encryption_or_compression(pr)
 
122
        return pr
 
123
 
 
124
 
 
125
class ParseResults:
 
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")
 
132
                self.type = type
 
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
 
135
                else: assert time
 
136
 
 
137
                self.manifest = manifest
 
138
                self.volume_number = volume_number
 
139
                self.time = time
 
140
                self.start_time, self.end_time = start_time, end_time
 
141
 
 
142
                self.compressed = compressed # true if gzip compressed
 
143
                self.encrypted = encrypted # true if gpg encrypted