from optparse import OptionParser
+now=datetime.now()
+counter=0
+
class FileIgnored (Exception): pass
# in days
return parsing_failed
# one entry like this per file, managed in the Kind class
-now=datetime.now()
-
class File:
def __init__ (self, dir, filename, datetime, options):
self.group = self._group_string()
def __repr__ (self):
- return "%s (%s) -- weekday %s"%(self.filename,self.datetime,self.datetime.weekday())
+ return "%s (%s) -- weekday %s"%(self.path(),self.datetime,self.datetime.weekday())
+
+ def path (self):
+ return os.path.normpath(os.path.join(self.dir,self.filename))
def age_days (self):
return self.age.days
weeks += 1
return "week%02d"%weeks
+ def cleanup (self, preserved):
+ global counter
+ counter+=1
+ if self.options.dry_run:
+ print "Would cleanup %s"%(self.path())
+ print " (keeping %s)"%preserved.path()
+ else:
+ if self.options.verbose: print "unlink",self.path()
+ os.unlink (self.path())
+
# all files in a given timeslot (either month or week)
class Group:
def __init__ (self, groupname):
self.files.append(file)
def epilogue (self):
self.files.sort (File.sort_relevance)
-# print 20*'*','after sort'
-# for file in self.files:
-# print "%s"%file
+ def keep_one (self):
+ for file in self.files[1:]:
+ file.cleanup(self.files[0])
# all files with the same (prefix, suffix)
class Kind:
def sort_size (k1, k2):
return len(k1.list)-len(k2.list)
+ def cleanup (self):
+ groupnames=self.groups.keys()
+ groupnames.sort()
+ for groupname in groupnames:
+ if self.options.extra_verbose: print 'GROUP',groupname
+ self.groups[groupname].keep_one()
+
# keeps an index of all files found, index by (prefix, suffix), then sorted by time
class Index:
def __init__ (self,options):
continue
self.insert (dir, filename, p, s, d)
-def handle_arg (index, dir, pattern):
+ def cleanup (self):
+ for kind in self.index.values(): kind.cleanup()
+
+def handle_dir_pattern (index, dir, pattern):
try:
os.chdir(dir)
except:
index.insert_many (dir, filenames)
def main ():
- parser=OptionParser()
+ usage="Usage: %prog [options] dir_or_files"
+ parser=OptionParser(usage=usage)
parser.add_option ("-v","--verbose",dest='verbose',action='store_true',default=False,
help="run in verbose mode")
parser.add_option ("-x","--extra-verbose",dest='extra_verbose',action='store_true',default=False,
(options, args) = parser.parse_args()
if options.extra_verbose: options.verbose=True
try:
- #options.offset=int(options.offset)
- print 'offset=%d'%options.offset
if options.offset !=0:
global now
now += timedelta(days=options.offset)
print "Offset not understood %s - expect an int. number of days"%options.offset
sys.exit(1)
+ if len(args) ==0:
+ parser.print_help()
+ sys.exit(1)
+
# args can be directories, or patterns, like
# main /db-backup /db-backup-f8/*bz2
# in any case we handle each arg completely separately
- index = Index (options)
+ dir_patterns=[]
for arg in args:
if os.path.isdir (arg):
- handle_arg (index, arg, "*")
+ if arg=='.': arg=os.getcwd()
+ dir_patterns.append ( (arg, '*',) )
else:
(dir,pattern)=os.path.split(arg)
- if not dir: dir='.'
- handle_arg (index, dir, pattern)
+ if not dir: dir=os.getcwd()
+ dir_patterns.append ( (dir, pattern,) )
+
+ index = Index (options)
+ for (dir, pattern) in dir_patterns: handle_dir_pattern (index, dir, pattern)
index.epilogue()
index.show()
+ index.cleanup()
+ print 'Found %d entries to unlink'%counter
if __name__ == '__main__':
main()