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
26
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
33 import os, sys, stat, logging
34
35 _log = logging.getLogger('gm.hook')
36 _log.info(__version__)
37
38
39
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
77
78 global hook_module
79 if not reimport:
80 if hook_module is not None:
81 return True
82
83
84
85
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:
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
133
134
135 _log.info('hook script: %s', full_script)
136 return True
137
139
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227