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  # $Source: /cvsroot/gnumed/gnumed/gnumed/client/pycommon/gmHooks.py,v $ 
 26  # $Id: gmHooks.py,v 1.18 2008/12/09 23:25:43 ncq Exp $ 
 27  __version__ = "$Revision: 1.18 $" 
 28  __author__  = "K. Hilbert <Karsten.Hilbert@gmx.net>" 
 29  __license__ = "GPL (details at http://www.gnu.org)" 
 30   
 31   
 32  # stdlib 
 33  import os, sys, stat, logging 
 34   
 35  _log = logging.getLogger('gm.hook') 
 36  _log.info(__version__) 
 37   
 38   
 39  # GNUmed libs 
 40  if __name__ == '__main__': 
 41          sys.path.insert(0, '../../') 
 42  from Gnumed.pycommon import gmDispatcher, gmTools 
 43   
 44  # ======================================================================== 
 45  known_hooks = [ 
 46          u'post_patient_activation', 
 47   
 48          u'shutdown-post-GUI', 
 49          u'startup-after-GUI-init', 
 50          u'startup-before-GUI', 
 51   
 52          u'request_user_attention', 
 53          u'app_activated_startup', 
 54          u'app_activated', 
 55          u'app_deactivated', 
 56   
 57          u'after_new_doc_created', 
 58          u'before_print_doc', 
 59          u'before_fax_doc', 
 60          u'before_mail_doc', 
 61          u'before_print_doc_part', 
 62          u'before_fax_doc_part', 
 63          u'before_mail_doc_part', 
 64          u'before_external_doc_access', 
 65   
 66          u'db_maintenance_warning' 
 67  ] 
 68   
 69  _log.debug('known hooks:') 
 70  for hook in known_hooks: 
 71          _log.debug(hook) 
 72   
 73  # ======================================================================== 
 74  hook_module = None 
 75   
76 -def import_hook_module(reimport=False):
77 78 global hook_module 79 if not reimport: 80 if hook_module is not None: 81 return True 82 83 # hardcoding path and script name allows us to 84 # not need configuration for it, the environment 85 # can always be detected at runtime (workplace etc) 86 script_name = 'hook_script.py' 87 script_path = os.path.expanduser(os.path.join('~', '.gnumed', 'scripts')) 88 full_script = os.path.join(script_path, script_name) 89 90 if not os.access(full_script, os.F_OK): 91 _log.warning('creating default hook script') 92 f = open(full_script, 'w') 93 f.write(""" 94 # known hooks: 95 # %s 96 97 def run_script(hook=None): 98 pass 99 """ % '# '.join(known_hooks)) 100 f.close() 101 os.chmod(full_script, 384) 102 103 if os.path.islink(full_script): 104 gmDispatcher.send ( 105 signal = 'statustext', 106 msg = _('Script must not be a link: [%s].') % full_script 107 ) 108 return False 109 110 if not os.access(full_script, os.R_OK): 111 gmDispatcher.send ( 112 signal = 'statustext', 113 msg = _('Script must be readable by the calling user: [%s].') % full_script 114 ) 115 return False 116 117 script_mode = stat.S_IMODE(os.stat(full_script).st_mode) 118 if script_mode != 384: # octal 0600 119 gmDispatcher.send ( 120 signal = 'statustext', 121 msg = _('Script must be readable by the calling user only (permissions "0600"): [%s].') % full_script 122 ) 123 return False 124 125 try: 126 tmp = gmTools.import_module_from_directory(script_path, script_name) 127 except StandardError: 128 _log.exception('cannot import hook script') 129 return False 130 131 hook_module = tmp 132 # if reimport: 133 # reload(tmp) # this has well-known shortcomings ! 134 135 _log.info('hook script: %s', full_script) 136 return True
137 # ========================================================================
138 -def run_hook_script(hook=None):
139 # NOTE: this just *might* be a huge security hole 140 141 if hook not in known_hooks: 142 raise ValueError('run_hook_script(): unknown hook [%s]' % hook) 143 144 if not import_hook_module(reimport = False): 145 return False 146 147 try: 148 hook_module.run_script(hook = hook) 149 except StandardError: 150 _log.exception('error running hook script for [%s]', hook) 151 gmDispatcher.send ( 152 signal = u'statustext', 153 msg = _('Error running hook [%s] script.') % hook, 154 beep = True 155 ) 156 return False 157 158 return True
159 # ======================================================================== 160 if __name__ == '__main__': 161 162 run_hook_script(hook = 'shutdown-post-GUI') 163 run_hook_script(hook = 'invalid hook') 164 165 # ======================================================================== 166 # $Log: gmHooks.py,v $ 167 # Revision 1.18 2008/12/09 23:25:43 ncq 168 # - prepare hook script reload infrastructure 169 # 170 # Revision 1.17 2008/11/23 12:44:00 ncq 171 # - add hook after_new_doc_created 172 # - since a hook value of None is not in known_hooks do not run an extra check for it 173 # 174 # Revision 1.16 2008/09/09 22:03:01 ncq 175 # - fix typo 176 # 177 # Revision 1.15 2008/09/09 20:17:45 ncq 178 # - add some logging 179 # - don't crash on hook script errors 180 # 181 # Revision 1.14 2008/05/31 16:32:04 ncq 182 # - add before external doc access hook 183 # 184 # Revision 1.13 2008/05/19 15:45:39 ncq 185 # - slightly better wording 186 # 187 # Revision 1.12 2008/04/28 13:32:07 ncq 188 # - run hook on database maintenance notification - so maybe 189 # user can be paged to his desk to close GNUmed clients 190 # 191 # Revision 1.11 2008/04/12 19:17:35 ncq 192 # - doc part hooks 193 # 194 # Revision 1.10 2008/04/11 23:11:52 ncq 195 # - add fax/mail/print hooks 196 # - list known hooks when creating hook script 197 # 198 # Revision 1.9 2008/01/27 21:10:34 ncq 199 # - fix stat()ing of the hook script 200 # 201 # Revision 1.8 2008/01/22 22:03:25 ncq 202 # - import hook script once only 203 # 204 # Revision 1.7 2007/11/03 17:54:04 ncq 205 # - added hooks 206 # 207 # Revision 1.6 2007/08/12 00:06:07 ncq 208 # - no more gmSignals.py 209 # 210 # Revision 1.5 2007/07/10 20:51:20 ncq 211 # - hooks_registry -> known_hooks 212 # 213 # Revision 1.4 2007/04/20 08:21:42 ncq 214 # - improved docs 215 # 216 # Revision 1.3 2007/04/01 15:29:22 ncq 217 # - create hook script on first use if not existant 218 # - improve test 219 # 220 # Revision 1.2 2007/03/26 14:42:27 ncq 221 # - register startup-after-GUI-init 222 # 223 # Revision 1.1 2007/03/18 13:19:13 ncq 224 # - factor out hooks framework 225 # 226 # 227