python-tldp/tldp/utils.py

161 lines
4.8 KiB
Python
Raw Normal View History

2016-02-11 03:22:23 +00:00
#! /usr/bin/python
from __future__ import absolute_import, division, print_function
2016-02-12 18:31:50 +00:00
import os
2016-02-12 21:24:09 +00:00
import io
2016-02-11 03:22:23 +00:00
import sys
import errno
import operator
2016-02-15 22:03:56 +00:00
import subprocess
import functools
2016-02-15 22:03:56 +00:00
from tempfile import mkstemp
2016-02-11 03:22:23 +00:00
import logging
logdir = 'tldp-document-build-logs'
2016-02-11 03:22:23 +00:00
2016-02-18 03:38:27 +00:00
2016-02-11 03:22:23 +00:00
def getLogger(**opts):
level = opts.get('level', logging.INFO)
2016-02-11 03:22:23 +00:00
logging.basicConfig(stream=sys.stderr, level=level)
logger = logging.getLogger()
return logger
logger = getLogger()
2016-02-15 22:03:56 +00:00
def execute(cmd, stdin=None, stdout=None, stderr=None,
logdir=None, env=os.environ):
prefix = os.path.basename(cmd[0]) + '.' + str(os.getpid()) + '-'
if logdir is None:
raise Exception("Missing required parameter: logdir.")
if not os.path.isdir(logdir):
raise IOError(errno.ENOENT, os.strerror(errno.ENOENT), logdir)
2016-02-15 22:03:56 +00:00
# -- not remapping STDIN, because that doesn't make sense here
if stdout is None:
stdout, stdoutname = mkstemp(prefix=prefix, suffix='.stdout',
dir=logdir)
if stderr is None:
stderr, stderrname = mkstemp(prefix=prefix, suffix='.stderr',
dir=logdir)
logger.debug("About to execute: %r", cmd)
proc = subprocess.Popen(cmd, shell=False, close_fds=True,
stdin=stdin, stdout=stdout, stderr=stderr,
env=env, preexec_fn=os.setsid)
result = proc.wait()
if result != 0:
logger.warning("Return code (%s) for process: %r", result, cmd)
logger.warning("Find STDOUT/STDERR in %s/%s", logdir, prefix)
return result
2016-02-12 18:31:50 +00:00
def is_executable(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
def which(program):
'''return None or the full path to an executable (respecting $PATH)
http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python/377028#377028
'''
fpath, fname = os.path.split(program)
if fpath and is_executable(program):
return program
else:
for path in os.environ["PATH"].split(os.pathsep):
path = path.strip('"')
sut = os.path.join(path, program)
if is_executable(sut):
return sut
return None
def makefh(thing):
2016-02-12 21:24:09 +00:00
if isinstance(thing, io.IOBase):
2016-02-12 18:31:50 +00:00
f = thing
elif isinstance(thing, str) and os.path.isfile(thing):
f = open(thing)
else:
raise TypeError("Cannot make file from %s of %r" %
2016-02-12 18:31:50 +00:00
(type(thing), thing,))
return f
def statfile(name):
try:
st = os.stat(name)
except OSError as e:
if e.errno != errno.ENOENT:
raise e
if os.path.islink(name):
st = os.lstat(name)
else:
st = None
return st
def statfiles(name, relative=None):
statinfo = dict()
if not os.path.exists(name):
return statinfo
if not os.path.isdir(name):
if relative:
relpath = os.path.relpath(name, start=relative)
else:
relpath = name
statinfo[relpath] = statfile(name)
if statinfo[relpath] is None:
del statinfo[relpath]
else:
for root, dirs, files in os.walk(name):
for x in files:
foundpath = os.path.join(root, x)
if relative:
relpath = os.path.relpath(foundpath, start=relative)
else:
relpath = foundpath
statinfo[relpath] = statfile(foundpath)
if statinfo[relpath] is None:
del statinfo[relpath]
return statinfo
def att_statinfo(statinfo, attr='st_mtime', func=max):
if statinfo:
return func([getattr(v, attr) for v in statinfo.values()])
else:
return 0
max_size = functools.partial(att_statinfo, attr='st_size', func=max)
min_size = functools.partial(att_statinfo, attr='st_size', func=min)
max_mtime = functools.partial(att_statinfo, attr='st_mtime', func=max)
min_mtime = functools.partial(att_statinfo, attr='st_mtime', func=min)
max_ctime = functools.partial(att_statinfo, attr='st_ctime', func=max)
min_ctime = functools.partial(att_statinfo, attr='st_ctime', func=min)
max_atime = functools.partial(att_statinfo, attr='st_atime', func=max)
min_atime = functools.partial(att_statinfo, attr='st_atime', func=min)
def sieve(operand, statinfo, attr='st_mtime', func=operator.gt):
result = set()
for fname, stbuf in statinfo.items():
if func(getattr(stbuf, attr), operand):
result.add(fname)
return result
mtime_gt = functools.partial(sieve, attr='st_mtime', func=operator.gt)
mtime_lt = functools.partial(sieve, attr='st_mtime', func=operator.lt)
size_gt = functools.partial(sieve, attr='st_size', func=operator.gt)
size_lt = functools.partial(sieve, attr='st_size', func=operator.lt)
2016-02-11 03:22:23 +00:00
#
# -- end of file