|
|
|
import logging
|
|
|
|
import time
|
|
|
|
import os
|
|
|
|
|
|
|
|
from shutil import copyfile
|
|
|
|
|
|
|
|
from contextlib import contextmanager
|
|
|
|
|
|
|
|
logger = logging.getLogger('soil')
|
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
|
|
|
|
|
|
|
|
@contextmanager
|
|
|
|
def timer(name='task', pre="", function=logger.info, to_object=None):
|
|
|
|
start = time.time()
|
|
|
|
function('{}Starting {} at {}.'.format(pre, name,
|
|
|
|
time.strftime("%X", time.gmtime(start))))
|
|
|
|
yield start
|
|
|
|
end = time.time()
|
|
|
|
function('{}Finished {} at {} in {} seconds'.format(pre, name,
|
|
|
|
time.strftime("%X", time.gmtime(end)),
|
|
|
|
str(end-start)))
|
|
|
|
if to_object:
|
|
|
|
to_object.start = start
|
|
|
|
to_object.end = end
|
|
|
|
|
|
|
|
|
|
|
|
def safe_open(path, mode='r', backup=True, **kwargs):
|
|
|
|
outdir = os.path.dirname(path)
|
|
|
|
if outdir and not os.path.exists(outdir):
|
|
|
|
os.makedirs(outdir)
|
|
|
|
if backup and 'w' in mode and os.path.exists(path):
|
|
|
|
creation = os.path.getctime(path)
|
|
|
|
stamp = time.strftime('%Y-%m-%d_%H:%M', time.localtime(creation))
|
|
|
|
|
|
|
|
backup_dir = os.path.join(outdir, stamp)
|
|
|
|
if not os.path.exists(backup_dir):
|
|
|
|
os.makedirs(backup_dir)
|
|
|
|
newpath = os.path.join(backup_dir, os.path.basename(path))
|
|
|
|
if os.path.exists(newpath):
|
|
|
|
newpath = '{}@{}'.format(newpath, time.time())
|
|
|
|
copyfile(path, newpath)
|
|
|
|
return open(path, mode=mode, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
def open_or_reuse(f, *args, **kwargs):
|
|
|
|
try:
|
|
|
|
return safe_open(f, *args, **kwargs)
|
|
|
|
except (AttributeError, TypeError):
|
|
|
|
return f
|