]> git.decadent.org.uk Git - dak.git/blob - scripts/debian/expire_dumps
Now it works :)
[dak.git] / scripts / debian / expire_dumps
1 #!/usr/bin/python
2
3 # Copyright (C) 2007 Florian Reitmeir <florian@reitmeir.org>
4 # Copyright (C) 2008 Joerg Jaspert <joerg@debian.org>
5
6 # Permission is hereby granted, free of charge, to any person obtaining
7 # a copy of this software and associated documentation files (the
8 # "Software"), to deal in the Software without restriction, including
9 # without limitation the rights to use, copy, modify, merge, publish,
10 # distribute, sublicense, and/or sell copies of the Software, and to
11 # permit persons to whom the Software is furnished to do so, subject to
12 # the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be
15 # included in all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
25 # requires: python-dateutil
26
27 import glob, os, sys
28 import time, datetime
29 import re
30 from datetime import datetime
31 from datetime import timedelta
32 from optparse import OptionParser
33
34 RULES = [
35     {'days':14,   'interval':0},
36     {'days':31,   'interval':7},
37     {'days':365,  'interval':31},
38     {'days':3650, 'interval':365},
39
40     # keep 14 days, all each day
41     # keep 31 days, 1 each 7th day
42     # keep 365 days, 1 each 31th day
43     # keep 3650 days, 1 each 365th day
44 ]
45
46 TODAY = datetime.today()
47 VERBOSE = False
48 NOACTION = False
49 PRINT = False
50 PREFIX = ''
51 PATH = ''
52
53 def all_files(pattern, search_path, pathsep=os.pathsep):
54     """ Given a search path, yield all files matching the pattern. """
55     for path in search_path.split(pathsep):
56         for match in glob.glob(os.path.join(path, pattern)):
57             yield match
58
59 def parse_file_dates(list):
60     out = []
61     # dump_2006.05.02-11:52:01.bz2
62     p = re.compile('^\./dump_([0-9]{4})\.([0-9]{2})\.([0-9]{2})-([0-9]{2}):([0-9]{2}):([0-9]{2})(.bz2)?$')
63     for file in list:
64         m = p.search(file)
65         if m:
66             d = datetime(int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4)), int(m.group(5)), int(m.group(6)))
67             out.append({'name': file, 'date': d})
68     return out
69
70 def prepare_rules(rules):
71     out = []
72     for rule in rules:
73         out.append(
74             {
75             'days':timedelta(days=rule['days']),
76             'interval':timedelta(days=rule['interval'])}
77             )
78     return out
79
80 def expire(rules, list):
81     t_rules=prepare_rules(rules)
82     rule = t_rules.pop(0)
83     last = list.pop(0)
84
85     for file in list:
86         if VERBOSE:
87             print "current file to expire: " + file['name']
88             print file['date']
89
90         # check if rule applies
91         if (file['date'] < (TODAY-rule['days'])):
92             if VERBOSE:
93                 print "move to next rule"
94             if t_rules:
95                 rule = t_rules.pop(0)
96
97         if (last['date'] - file['date']) < rule['interval']:
98             if VERBOSE:
99                 print "unlink file:" + file['name']
100             if PRINT:
101                 print file['name']
102             if not NOACTION:
103                 os.unlink(file['name'])
104         else:
105             last = file
106             if VERBOSE:
107                 print "kept file:" + file['name']
108
109
110 parser = OptionParser()
111 parser.add_option("-d", "--directory", dest="directory",
112                   help="directory name", metavar="Name")
113 parser.add_option("-f", "--pattern", dest="pattern",
114                   help="Pattern maybe some glob", metavar="*.backup")
115 parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
116                   help="verbose")
117 parser.add_option("-n", "--no-action", action="store_true", dest="noaction", default=False,
118                   help="just prints what would be done, this implies verbose")
119 parser.add_option("-p", "--print", action="store_true", dest="printfiles", default=False,
120                   help="just print the filenames that should be deleted, this forbids verbose")
121
122 (options, args) = parser.parse_args()
123
124 if (not options.directory):
125     parser.error("no directory to check given")
126
127 if options.noaction:
128     VERBOSE=True
129     NOACTION=True
130
131 if options.verbose:
132     VERBOSE=True
133
134 if options.printfiles:
135     VERBOSE=False
136     PRINT=True
137
138 files = sorted( list(all_files(options.pattern,options.directory)), reverse=True );
139
140 if not files:
141     sys.exit(0)
142
143 files_dates =  parse_file_dates(files);
144 expire(RULES, files_dates)