Package Gnumed :: Package pycommon :: Module gmHooks
[frames] | no frames]

Source Code for Module Gnumed.pycommon.gmHooks

  1  """GNUmed hooks framework. 
  2   
  3  This module provides convenience functions and definitions 
  4  for accessing the GNUmed hooks framework. 
  5   
  6  This framework calls the script 
  7   
  8          ~/.gnumed/scripts/hook_script.py 
  9   
 10  at various times during client execution. The script must 
 11  contain a function 
 12   
 13  def run_script(hook=None): 
 14          pass 
 15   
 16  which accepts a single argument <hook>. That argument will 
 17  contain the hook that is being activated. 
 18   
 19  This source code is protected by the GPL licensing scheme. 
 20  Details regarding the GPL are available at http://www.gnu.org 
 21  You may use and share it as long as you don't deny this right 
 22  to anybody else. 
 23  """ 
 24  # ======================================================================== 
 25  __version__ = "$Revision: 1.18 $" 
 26  __author__  = "K. Hilbert <Karsten.Hilbert@gmx.net>" 
 27  __license__ = "GPL (details at http://www.gnu.org)" 
 28   
 29   
 30  # stdlib 
 31  import os, sys, stat, logging 
 32   
 33  _log = logging.getLogger('gm.hook') 
 34  _log.info(__version__) 
 35   
 36   
 37  # GNUmed libs 
 38  if __name__ == '__main__': 
 39          sys.path.insert(0, '../../') 
 40  from Gnumed.pycommon import gmDispatcher, gmTools 
 41   
 42  # ======================================================================== 
 43  known_hooks = [ 
 44          u'post_patient_activation', 
 45   
 46          u'shutdown-post-GUI', 
 47          u'startup-after-GUI-init', 
 48          u'startup-before-GUI', 
 49   
 50          u'request_user_attention', 
 51          u'app_activated_startup', 
 52          u'app_activated', 
 53          u'app_deactivated', 
 54   
 55          u'after_substance_intake_modified', 
 56          u'after_test_result_modified', 
 57          u'after_soap_modified', 
 58   
 59          u'after_new_doc_created', 
 60          u'before_print_doc', 
 61          u'before_fax_doc', 
 62          u'before_mail_doc', 
 63          u'before_print_doc_part', 
 64          u'before_fax_doc_part', 
 65          u'before_mail_doc_part', 
 66          u'before_external_doc_access', 
 67   
 68          u'db_maintenance_warning' 
 69  ] 
 70   
 71  _log.debug('known hooks:') 
 72  for hook in known_hooks: 
 73          _log.debug(hook) 
 74   
 75  # ======================================================================== 
 76  hook_module = None 
 77   
78 -def import_hook_module(reimport=False):
79 80 global hook_module 81 if not reimport: 82 if hook_module is not None: 83 return True 84 85 # hardcoding path and script name allows us to 86 # not need configuration for it, the environment 87 # can always be detected at runtime (workplace etc) 88 script_name = 'hook_script.py' 89 script_path = os.path.expanduser(os.path.join('~', '.gnumed', 'scripts')) 90 full_script = os.path.join(script_path, script_name) 91 92 if not os.access(full_script, os.F_OK): 93 _log.warning('creating default hook script') 94 f = open(full_script, 'w') 95 f.write(""" 96 # known hooks: 97 # %s 98 99 def run_script(hook=None): 100 pass 101 """ % '# '.join(known_hooks)) 102 f.close() 103 os.chmod(full_script, 384) 104 105 if os.path.islink(full_script): 106 gmDispatcher.send ( 107 signal = 'statustext', 108 msg = _('Script must not be a link: [%s].') % full_script 109 ) 110 return False 111 112 if not os.access(full_script, os.R_OK): 113 gmDispatcher.send ( 114 signal = 'statustext', 115 msg = _('Script must be readable by the calling user: [%s].') % full_script 116 ) 117 return False 118 119 script_mode = stat.S_IMODE(os.stat(full_script).st_mode) 120 if script_mode != 384: # octal 0600 121 gmDispatcher.send ( 122 signal = 'statustext', 123 msg = _('Script must be readable by the calling user only (permissions "0600"): [%s].') % full_script 124 ) 125 return False 126 127 try: 128 tmp = gmTools.import_module_from_directory(script_path, script_name) 129 except StandardError: 130 _log.exception('cannot import hook script') 131 return False 132 133 hook_module = tmp 134 # if reimport: 135 # reload(tmp) # this has well-known shortcomings ! 136 137 _log.info('hook script: %s', full_script) 138 return True
139 # ========================================================================
140 -def run_hook_script(hook=None):
141 # NOTE: this just *might* be a huge security hole 142 143 if hook not in known_hooks: 144 raise ValueError('run_hook_script(): unknown hook [%s]' % hook) 145 146 if not import_hook_module(reimport = False): 147 return False 148 149 try: 150 hook_module.run_script(hook = hook) 151 except StandardError: 152 _log.exception('error running hook script for [%s]', hook) 153 gmDispatcher.send ( 154 signal = u'statustext', 155 msg = _('Error running hook [%s] script.') % hook, 156 beep = True 157 ) 158 return False 159 160 return True
161 # ======================================================================== 162 if __name__ == '__main__': 163 164 run_hook_script(hook = 'shutdown-post-GUI') 165 run_hook_script(hook = 'invalid hook') 166 167 # ======================================================================== 168