def make_numbered_dir(cls, prefix='session-', rootdir=None, keep=3, |
lock_timeout = 172800): |
""" return unique directory with a number greater than the current |
maximum one. The number is assumed to start directly after prefix. |
if keep is true directories with a number less than (maxnum-keep) |
will be removed. |
""" |
if rootdir is None: |
rootdir = cls.get_temproot() |
|
def parse_num(path): |
""" parse the number out of a path (if it matches the prefix) """ |
bn = path.basename |
if bn.startswith(prefix): |
try: |
return int(bn[len(prefix):]) |
except ValueError: |
pass |
|
|
|
lastmax = None |
while True: |
maxnum = -1 |
for path in rootdir.listdir(): |
num = parse_num(path) |
if num is not None: |
maxnum = max(maxnum, num) |
|
|
try: |
udir = rootdir.mkdir(prefix + str(maxnum+1)) |
except py.error.EEXIST: |
|
|
if lastmax == maxnum: |
raise |
lastmax = maxnum |
continue |
break |
|
|
|
lockfile = udir.join('.lock') |
mypid = os.getpid() |
if hasattr(lockfile, 'mksymlinkto'): |
lockfile.mksymlinkto(str(mypid)) |
else: |
lockfile.write(str(mypid)) |
def try_remove_lockfile(): |
|
|
|
|
|
if os.getpid() != mypid: |
return |
try: |
lockfile.remove() |
except py.error.Error: |
pass |
atexit.register(try_remove_lockfile) |
|
|
if keep: |
for path in rootdir.listdir(): |
num = parse_num(path) |
if num is not None and num <= (maxnum - keep): |
lf = path.join('.lock') |
try: |
t1 = lf.lstat().mtime |
-> t2 = lockfile.lstat().mtime |
if abs(t2-t1) < lock_timeout: |
continue |
except py.error.Error: |
pass |
try: |
path.remove(rec=1) |
except py.error.Error: |
pass |
|
|
try: |
username = os.environ['USER'] |
except KeyError: |
try: |
username = os.environ['USERNAME'] |
except KeyError: |
username = 'current' |
|
src = str(udir) |
dest = src[:src.rfind('-')] + '-' + username |
try: |
os.unlink(dest) |
except OSError: |
pass |
try: |
os.symlink(src, dest) |
except (OSError, AttributeError): |
pass |
|
return udir |