diff options
Diffstat (limited to 'Master/texmf-dist/scripts/webquiz/webquiz_util.py')
-rwxr-xr-x | Master/texmf-dist/scripts/webquiz/webquiz_util.py | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/Master/texmf-dist/scripts/webquiz/webquiz_util.py b/Master/texmf-dist/scripts/webquiz/webquiz_util.py new file mode 100755 index 00000000000..7a06108e1b0 --- /dev/null +++ b/Master/texmf-dist/scripts/webquiz/webquiz_util.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +r''' +------------------------------------------------------------------------------ + webquiz_util | utilty functions +------------------------------------------------------------------------------ + Copyright (C) Andrew Mathas, University of Sydney + + Distributed under the terms of the GNU General Public License (GPL) + http://www.gnu.org/licenses/ + + This file is part of the WebQuiz system. + + <Andrew.Mathas@sydney.edu.au> +------------------------------------------------------------------------------ +''' + +import os +import subprocess +import shutil +import stat +import sys +import traceback + +# --------------------------------------------------------------------------------------- +# Return the full path for a file in the webquiz directory +webquiz_file = lambda file: os.path.join(os.path.dirname(os.path.realpath(__file__)), file) + +def shell_command(cmd): + r''' + Short-cut for shell commands + ''' + return subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True).decode('ascii').strip() + +def kpsewhich(search): + r''' + Short-cut to access kpsewhich output. usage: kpsewhich('-var-value=TEXMFLOCAL') + ''' + return subprocess.check_output('kpsewhich ' + search, stderr=subprocess.STDOUT, shell=True).decode('ascii').strip() + +# --------------------------------------------------------------------------------------- +class MetaData(dict): + r""" + A dummy class for reading, accessing and storing key-value pairs from + a file. Any internal spaces in the key name are replaced with underscores + and lines without a key-value pair are ignored. + + The key-value pairs are available as both attributes and items + + Usage: MetaData(filename) or MetaData(filename, key-value pairs) + """ + + def __init__(self, filename, **args): + dict.__init__(self) + # add attributes from **args + for key in args: + setattr(self, key, args[key]) + with open(filename, 'r') as meta: + for line in meta: + if '=' in line: + key, val = line.strip().split('=') + if key.strip() != '': + self.__setitem__(key.strip().lower().replace(' ', '_'), + val.strip()) + setattr(self, + key.strip().lower().replace(' ', '_'), + val.strip()) + + +################################################################################# +def webquiz_debug(debugging, *arg): + if debugging: + sys.stderr.write(' '.join('{}'.format(a) for a in arg)+'\n') + + +################################################################################# +def webquiz_error(debugging, msg, err=None): + r''' + Consistent handling of errors in magthquiz: print the message `msg` and + exist with error code `err.errno` if it is available.abs + ''' + print('{dash}WebQuiz error:\n {msg}\n{dash}'.format( + msg=msg, dash='-'*40+'\n') + ) + + if err is not None: + trace = traceback.extract_tb(sys.exc_info()[2]) + filename, lineno, fn, text = trace[-1] + print('File: {}, line number: {}\nError {} in {}: {}'.format( + filename, lineno, err, fn, text)) + + if debugging and err is not None: + raise + + if hasattr(err, 'errno'): + sys.exit(err.errno) + + sys.exit(1) + + +############################################################################### +def copytree(src, dst, symlinks=False, ignore=None): + r''' Recursively copy directory tree, fixing shutil.copytree + from https://stackoverflow.com/questions/1868714 + ''' + if not os.path.exists(dst): + os.makedirs(dst) + shutil.copystat(src, dst) + lst = os.listdir(src) + if ignore: + excl = ignore(src, lst) + lst = [x for x in lst if x not in excl] + for item in lst: + s = os.path.join(src, item) + d = os.path.join(dst, item) + if symlinks and os.path.islink(s): + if os.path.lexists(d): + os.remove(d) + os.symlink(os.readlink(s), d) + try: + st = os.lstat(s) + mode = stat.S_IMODE(st.st_mode) + os.lchmod(d, mode) + except OSError: + pass # lchmod not available + elif os.path.isdir(s): + copytree(s, d, symlinks, ignore) + else: + shutil.copy2(s, d) |