aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/sabre/dav/bin/naturalselection.py
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/sabre/dav/bin/naturalselection.py')
-rwxr-xr-xvendor/sabre/dav/bin/naturalselection.py140
1 files changed, 140 insertions, 0 deletions
diff --git a/vendor/sabre/dav/bin/naturalselection.py b/vendor/sabre/dav/bin/naturalselection.py
new file mode 100755
index 000000000..aa5554dd0
--- /dev/null
+++ b/vendor/sabre/dav/bin/naturalselection.py
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+
+#
+# Copyright (c) 2009-2010 Evert Pot
+# All rights reserved.
+# http://www.rooftopsolutions.nl/
+#
+# This utility is distributed along with SabreDAV
+# license: http://code.google.com/p/sabredav/wiki/License Modified BSD License
+
+import os
+from optparse import OptionParser
+import time
+
+def getfreespace(path):
+ stat = os.statvfs(path)
+ return stat.f_frsize * stat.f_bavail
+
+def getbytesleft(path,treshold):
+ return getfreespace(path)-treshold
+
+def run(cacheDir, treshold, sleep=5, simulate=False, min_erase = 0):
+
+ bytes = getbytesleft(cacheDir,treshold)
+ if (bytes>0):
+ print "Bytes to go before we hit treshhold:", bytes
+ else:
+ print "Treshold exceeded with:", -bytes, "bytes"
+ dir = os.listdir(cacheDir)
+ dir2 = []
+ for file in dir:
+ path = cacheDir + '/' + file
+ dir2.append({
+ "path" : path,
+ "atime": os.stat(path).st_atime,
+ "size" : os.stat(path).st_size
+ })
+
+ dir2.sort(lambda x,y: int(x["atime"]-y["atime"]))
+
+ filesunlinked = 0
+ gainedspace = 0
+
+ # Left is the amount of bytes that need to be freed up
+ # The default is the 'min_erase setting'
+ left = min_erase
+
+ # If the min_erase setting is lower than the amount of bytes over
+ # the treshold, we use that number instead.
+ if left < -bytes :
+ left = -bytes
+
+ print "Need to delete at least:", left;
+
+ for file in dir2:
+
+ # Only deleting files if we're not simulating
+ if not simulate: os.unlink(file["path"])
+ left = int(left - file["size"])
+ gainedspace = gainedspace + file["size"]
+ filesunlinked = filesunlinked + 1
+
+ if(left<0):
+ break
+
+ print "%d files deleted (%d bytes)" % (filesunlinked, gainedspace)
+
+
+ time.sleep(sleep)
+
+
+
+def main():
+ parser = OptionParser(
+ version="naturalselecton v0.3",
+ description="Cache directory manager. Deletes cache entries based on accesstime and free space tresholds.\n" +
+ "This utility is distributed alongside SabreDAV.",
+ usage="usage: %prog [options] cacheDirectory",
+ )
+ parser.add_option(
+ '-s',
+ dest="simulate",
+ action="store_true",
+ help="Don't actually make changes, but just simulate the behaviour",
+ )
+ parser.add_option(
+ '-r','--runs',
+ help="How many times to check before exiting. -1 is infinite, which is the default",
+ type="int",
+ dest="runs",
+ default=-1
+ )
+ parser.add_option(
+ '-n','--interval',
+ help="Sleep time in seconds (default = 5)",
+ type="int",
+ dest="sleep",
+ default=5
+ )
+ parser.add_option(
+ '-l','--treshold',
+ help="Treshhold in bytes (default = 10737418240, which is 10GB)",
+ type="int",
+ dest="treshold",
+ default=10737418240
+ )
+ parser.add_option(
+ '-m', '--min-erase',
+ help="Minimum number of bytes to erase when the treshold is reached. " +
+ "Setting this option higher will reduce the amount of times the cache directory will need to be scanned. " +
+ "(the default is 1073741824, which is 1GB.)",
+ type="int",
+ dest="min_erase",
+ default=1073741824
+ )
+
+ options,args = parser.parse_args()
+ if len(args)<1:
+ parser.error("This utility requires at least 1 argument")
+ cacheDir = args[0]
+
+ print "Natural Selection"
+ print "Cache directory:", cacheDir
+ free = getfreespace(cacheDir);
+ print "Current free disk space:", free
+
+ runs = options.runs;
+ while runs!=0 :
+ run(
+ cacheDir,
+ sleep=options.sleep,
+ simulate=options.simulate,
+ treshold=options.treshold,
+ min_erase=options.min_erase
+ )
+ if runs>0:
+ runs = runs - 1
+
+if __name__ == '__main__' :
+ main()