Purge improvements: New options yearly and prefix

This commit is contained in:
Jonas Borgström 2011-08-07 14:04:14 +02:00
parent e0615df187
commit 9feef66d4e
3 changed files with 35 additions and 10 deletions

View File

@ -43,7 +43,9 @@ class Archive(object):
except self.store.DoesNotExist: except self.store.DoesNotExist:
raise self.DoesNotExist raise self.DoesNotExist
self.metadata = msgpack.unpackb(data) self.metadata = msgpack.unpackb(data)
assert self.metadata['version'] == 1 if self.metadata['version'] != 1:
raise Exception('Unknown archive metadata version')
self.name = self.metadata['name']
@property @property
def ts(self): def ts(self):

View File

@ -11,7 +11,7 @@ from .cache import Cache
from .key import Key from .key import Key
from .helpers import location_validator, format_file_size, format_time,\ from .helpers import location_validator, format_file_size, format_time,\
format_file_mode, IncludePattern, ExcludePattern, exclude_path, to_localtime, \ format_file_mode, IncludePattern, ExcludePattern, exclude_path, to_localtime, \
get_cache_dir get_cache_dir, day_of_year
from .remote import StoreServer, RemoteStore from .remote import StoreServer, RemoteStore
class Archiver(object): class Archiver(object):
@ -224,31 +224,39 @@ class Archiver(object):
num_daily = args.daily num_daily = args.daily
num_weekly = args.weekly num_weekly = args.weekly
num_monthly = args.monthly num_monthly = args.monthly
if args.daily + args.weekly + args.monthly == 0: num_yearly = args.yearly
self.print_error('At least one of the "daily", "weekly", "monthly" ' if args.daily + args.weekly + args.monthly + args.yearly == 0:
self.print_error('At least one of the "daily", "weekly", "monthly" or "yearly" '
'settings must be specified') 'settings must be specified')
return 1 return 1
t0 = date.today() + timedelta(days=1) # Tomorrow t0 = date.today() + timedelta(days=1) # Tomorrow
daily = weekly = monthly = 0 daily = weekly = monthly = yearly = 0
for archive in archives: for archive in archives:
if args.prefix and not archive.name.startswith(args.prefix):
continue
t = to_localtime(archive.ts).date() t = to_localtime(archive.ts).date()
if daily < args.daily and t < t0: if daily < args.daily and t < t0:
daily += 1 daily += 1
self.print_verbose('Archive "%s" is daily archive number %d', self.print_verbose('Archive "%s" is daily archive number %d',
archive.metadata['name'], daily) archive.name, daily)
t0 = t t0 = t
elif weekly < args.weekly and t < t0 and t.weekday() == 1: elif weekly < args.weekly and t < t0 and t.weekday() == 1:
weekly += 1 weekly += 1
self.print_verbose('Archive "%s" is weekly archive number %d', self.print_verbose('Archive "%s" is weekly archive number %d',
archive.metadata['name'], weekly) archive.name, weekly)
t0 = t t0 = t
elif monthly < args.monthly and t < t0 and t.day == 1: elif monthly < args.monthly and t < t0 and t.day == 1:
num_weekly += 1 monthly += 1
self.print_verbose('Archive "%s" is monthly archive number %d', self.print_verbose('Archive "%s" is monthly archive number %d',
archive.metadata['name'], monthly) archive.name, monthly)
t0 = t
elif yearly < args.yearly and t < t0 and day_of_year(t) == 1:
yearly += 1
self.print_verbose('Archive "%s" is yearly archive number %d',
archive.name, yearly)
t0 = t t0 = t
else: else:
self.print_verbose('Purging archive %s', archive.metadata['name']) self.print_verbose('Purging archive %s', archive.name)
if args.really: if args.really:
archive.delete(cache) archive.delete(cache)
else: else:
@ -346,6 +354,10 @@ class Archiver(object):
help='Number of daily archives to keep') help='Number of daily archives to keep')
subparser.add_argument('-m', '--monthly', dest='monthly', type=int, default=0, subparser.add_argument('-m', '--monthly', dest='monthly', type=int, default=0,
help='Number of monthly archives to keep') help='Number of monthly archives to keep')
subparser.add_argument('-y', '--yearly', dest='yearly', type=int, default=0,
help='Number of yearly archives to keep')
subparser.add_argument('-p', '--prefix', dest='prefix', type=str,
help='Only consider archive names starting with this prefix')
subparser.add_argument('-r', '--really', dest='really', subparser.add_argument('-r', '--really', dest='really',
action='store_true', default=False, action='store_true', default=False,
help='Actually delete archives') help='Actually delete archives')

View File

@ -12,6 +12,12 @@ import sys
import time import time
import urllib import urllib
def day_of_year(d):
"""Calculate the "day of year" from a date object"""
return int(d.strftime('%j'))
# OSX filenames are UTF-8 Only so any non-utf8 filenames are url encoded # OSX filenames are UTF-8 Only so any non-utf8 filenames are url encoded
if sys.platform == 'darwin': if sys.platform == 'darwin':
def encode_filename(name): def encode_filename(name):
@ -23,6 +29,7 @@ if sys.platform == 'darwin':
else: else:
encode_filename = str encode_filename = str
class Counter(object): class Counter(object):
__slots__ = ('v',) __slots__ = ('v',)
@ -48,6 +55,7 @@ def get_keys_dir():
return os.environ.get('DARC_KEYS_DIR', return os.environ.get('DARC_KEYS_DIR',
os.path.join(os.path.expanduser('~'), '.darc', 'keys')) os.path.join(os.path.expanduser('~'), '.darc', 'keys'))
def get_cache_dir(): def get_cache_dir():
"""Determine where to store keys and cache""" """Determine where to store keys and cache"""
return os.environ.get('DARC_CACHE_DIR', return os.environ.get('DARC_CACHE_DIR',
@ -69,14 +77,17 @@ def deferrable(f):
return f(*args, **kw) return f(*args, **kw)
return wrapper return wrapper
def error_callback(res, error, data): def error_callback(res, error, data):
if res: if res:
raise res raise res
def to_localtime(ts): def to_localtime(ts):
"""Convert datetime object from UTC to local time zone""" """Convert datetime object from UTC to local time zone"""
return ts - timedelta(seconds=time.altzone) return ts - timedelta(seconds=time.altzone)
def read_set(path): def read_set(path):
"""Read set from disk (as int32s) """Read set from disk (as int32s)
""" """