]> git.decadent.org.uk Git - dak.git/blob - scripts/debian/expire_dumps
Merge commit 'ftpmaster/master' into web
[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 ]
44
45 TODAY = datetime.today()
46 VERBOSE = False
47 NOACTION = False
48 PRINT = False
49 PREFIX = ''
50 PATH = ''
51
52 def all_files(pattern, search_path, pathsep=os.pathsep):
53     """ Given a search path, yield all files matching the pattern. """
54     for path in search_path.split(pathsep):
55         for match in glob.glob(os.path.join(path, pattern)):
56             yield match
57
58 def parse_file_dates(list):
59     out = []
60     # dump_2006.05.02-11:52:01.bz2
61     p = re.compile('^\./dump_([0-9]{4})\.([0-9]{2})\.([0-9]{2})-([0-9]{2}):([0-9]{2}):([0-9]{2})(.bz2)?$')
62     for file in list:
63         m = p.search(file)
64         if m:
65             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)))
66             out.append({'name': file, 'date': d})
67     return out
68
69 def prepare_rules(rules):
70     out = []
71     for rule in rules:
72         out.append(
73             {
74             'days':timedelta(days=rule['days']),
75             'interval':timedelta(days=rule['interval'])}
76             )
77     return out
78
79 def expire(rules, list):
80     t_rules=prepare_rules(rules)
81     rule = t_rules.pop(0)
82     last = list.pop(0)
83
84     for file in list:
85         if VERBOSE:
86             print "current file to expire: " + file['name']
87             print file['date']
88
89         # check if rule applies
90         if (file['date'] < (TODAY-rule['days'])):
91             if VERBOSE:
92                 print "move to next rule"
93             if t_rules:
94                 rule = t_rules.pop(0)
95
96         if (last['date'] - file['date']) < rule['interval']:
97             if VERBOSE:
98                 print "unlink file:" + file['name']
99             if PRINT:
100                 print file['name']
101             if not NOACTION:
102                 os.unlink(file['name'])
103         else:
104             last = file
105             if VERBOSE:
106                 print "kept file:" + file['name']
107
108
109 parser = OptionParser()
110 parser.add_option("-d", "--directory", dest="directory",
111                   help="directory name", metavar="Name")
112 parser.add_option("-f", "--pattern", dest="pattern",
113                   help="Pattern maybe some glob", metavar="*.backup")
114 parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False,
115                   help="verbose")
116 parser.add_option("-n", "--no-action", action="store_true", dest="noaction", default=False,
117                   help="just prints what would be done, this implies verbose")
118 parser.add_option("-p", "--print", action="store_true", dest="printfiles", default=False,
119                   help="just print the filenames that should be deleted, this forbids verbose")
120
121 (options, args) = parser.parse_args()
122
123 if (not options.directory):
124     parser.error("no directory to check given")
125
126 if options.noaction:
127     VERBOSE=True
128     NOACTION=True
129
130 if options.verbose:
131     VERBOSE=True
132
133 if options.printfiles:
134     VERBOSE=False
135     PRINT=True
136
137 files = sorted( list(all_files(options.pattern,options.directory)), reverse=True );
138
139 if not files:
140     sys.exit(0)
141
142 files_dates =  parse_file_dates(files);
143 expire(RULES, files_dates)