Module Gnumed.pycommon.gmHooks
GNUmed hooks framework.
This module provides convenience functions and definitions for accessing the GNUmed hooks framework.
This framework calls the script
~/.config/gnumed/scripts/hook_script.py
at various times during client execution. The script must contain a function
def run_script(hook=None): pass
which accepts a single argument
Functions
def import_hook_module(reimport=False)
-
Expand source code
def import_hook_module(reimport=False): global hook_module if not reimport: if hook_module is not None: return True if not os.access(HOOK_SCRIPT_FULL_NAME, os.F_OK): _log.warning('creating default hook script') f = open(HOOK_SCRIPT_FULL_NAME, mode = 'wt', encoding = 'utf8') f.write(""" # known hooks: # %s def run_script(hook=None): pass """ % '\n#\t'.join(known_hooks)) f.close() os.chmod(HOOK_SCRIPT_FULL_NAME, 384) if os.path.islink(HOOK_SCRIPT_FULL_NAME): gmDispatcher.send ( signal = 'statustext', msg = _('Script must not be a link: [%s].') % HOOK_SCRIPT_FULL_NAME ) return False if not os.access(HOOK_SCRIPT_FULL_NAME, os.R_OK): gmDispatcher.send ( signal = 'statustext', msg = _('Script must be readable by the calling user: [%s].') % HOOK_SCRIPT_FULL_NAME ) return False script_stat_val = os.stat(HOOK_SCRIPT_FULL_NAME) _log.debug('hook script stat(): %s', script_stat_val) script_perms = stat.S_IMODE(script_stat_val.st_mode) _log.debug('hook script mode: %s (oktal: %s)', script_perms, oct(script_perms)) if script_perms != 384: # octal 0600 if os.name in ['nt']: _log.warning('this platform does not support os.stat() file permission checking') else: gmDispatcher.send ( signal = 'statustext', msg = _('Script must be readable by the calling user only (permissions "0600"): [%s].') % HOOK_SCRIPT_FULL_NAME ) return False try: tmp = gmTools.import_module_from_directory(HOOK_SCRIPT_DIR, HOOK_SCRIPT_NAME) except Exception: _log.exception('cannot import hook script') return False hook_module = tmp # if reimport: # imp.reload(tmp) # this has well-known shortcomings ! _log.info('hook script: %s', HOOK_SCRIPT_FULL_NAME) return True
def run_hook_script(hook=None)
-
Expand source code
def run_hook_script(hook=None): # NOTE: this just *might* be a huge security hole _log.info('told to pull hook [%s]', hook) if hook not in known_hooks: raise ValueError('run_hook_script(): unknown hook [%s]' % hook) if not import_hook_module(reimport = False): _log.debug('cannot import hook module, not pulling hook') return False if hook in __current_hook_stack: _log.error('hook-code cycle detected, aborting') _log.error('current hook stack: %s', __current_hook_stack) return False __current_hook_stack.append(hook) try: hook_module.run_script(hook = hook) except Exception: _log.exception('error running hook script for [%s]', hook) gmDispatcher.send ( signal = 'statustext', msg = _('Error running hook [%s] script.') % hook, beep = True ) if __current_hook_stack[-1] != hook: _log.error('hook nesting error detected') _log.error('latest hook: expected [%s], found [%s]', hook, __current_hook_stack[-1]) _log.error('current hook stack: %s', __current_hook_stack) else: __current_hook_stack.pop() return False if __current_hook_stack[-1] != hook: _log.error('hook nesting error detected') _log.error('latest hook: expected [%s], found [%s]', hook, __current_hook_stack[-1]) _log.error('current hook stack: %s', __current_hook_stack) else: __current_hook_stack.pop() return True
def setup_hook_dir()
-
Expand source code
def setup_hook_dir(): _old_path = os.path.join(gmTools.gmPaths().home_dir, '.gnumed', 'scripts') if os.path.isdir(_old_path): print('obsolete: [%s], use [%s]' %(_old_path, HOOK_SCRIPT_DIR)) _log.debug('obsolete: %s', _old_path) _log.debug('known hooks:') for hook in known_hooks: _log.debug(hook) gmTools.mkdir(HOOK_SCRIPT_DIR) gmTools.create_directory_description_file(directory = HOOK_SCRIPT_DIR, readme = README_hook_dir) # create hook script example/template example_name = os.path.join(HOOK_SCRIPT_DIR, HOOK_SCRIPT_NAME + '.example') example = open(example_name, mode = 'wt', encoding = 'utf8') example.write(HOOK_SCRIPT_EXAMPLE) example.close() os.chmod(example_name, 384)