1
2
3 __doc__ = """GNUmed client launcher.
4
5 This is the launcher for the GNUmed GUI client. It takes
6 care of all the pre- and post-GUI runtime environment setup.
7
8 --quiet
9 Be extra quiet and show only _real_ errors in the log.
10 --debug
11 Pre-set the [debug mode] checkbox in the login dialog to
12 increase verbosity in the log file. Useful for, well, debugging :-)
13 --slave
14 Pre-set the [enable remote control] checkbox in the login
15 dialog to enable the XML-RPC remote control feature.
16 --hipaa
17 Enable HIPAA functionality which has user impact.
18 --profile=<file>
19 Activate profiling and write profile data to <file>.
20 --text-domain=<text domain>
21 Set this to change the name of the language file to be loaded.
22 Note, this does not change the directory the file is searched in,
23 only the name of the file where messages are loaded from. The
24 standard textdomain is, of course, "gnumed.mo".
25 --log-file=<file>
26 Use this to change the name of the log file.
27 See gmLog2.py to find out where the standard log file would
28 end up.
29 --conf-file=<file>
30 Use configuration file <file> instead of searching for it in
31 standard locations.
32 --lang-gettext=<language>
33 Explicitly set the language to use in gettext translation. The very
34 same effect can be achieved by setting the environment variable $LANG
35 from a launcher script.
36 --override-schema-check
37 Continue loading the client even if the database schema version
38 and the client software version cannot be verified to be compatible.
39 --skip-update-check
40 Skip checking for client updates. This is useful during development
41 and when the update check URL is unavailable (down).
42 --local-import
43 Adjust the PYTHONPATH such that GNUmed can be run from a local source tree.
44 --ui=<ui type>
45 Start an alternative UI. Defaults to wxPython if not specified.
46 Valid values: chweb (CherryPy), wxp (wxPython), web (ProxiedWeb)
47 --version, -V
48 Show version information.
49 --help, -h, or -?
50 Show this help.
51 """
52
53 __version__ = "$Revision: 1.169 $"
54 __author__ = "H. Herb <hherb@gnumed.net>, K. Hilbert <Karsten.Hilbert@gmx.net>, I. Haywood <i.haywood@ugrad.unimelb.edu.au>"
55 __license__ = "GPL (details at http://www.gnu.org)"
56
57
58 import sys, os, os.path, signal, logging, platform
59
60
61
62 if __name__ != "__main__":
63 print "GNUmed startup: This is not intended to be imported as a module !"
64 print "-----------------------------------------------------------------"
65 print __doc__
66 sys.exit(1)
67
68
69
70 if os.name in ['posix'] and os.geteuid() == 0:
71 print """
72 GNUmed startup: GNUmed should not be run as root.
73 -------------------------------------------------
74
75 Running GNUmed as <root> can potentially put all
76 your medical data at risk. It is strongly advised
77 against. Please run GNUmed as a non-root user.
78 """
79 sys.exit(1)
80
81
82
83 current_client_version = u'GIT HEAD'
84
85 current_client_branch = u'GIT tree'
86
87 _log = None
88 _cfg = None
89 _old_sig_term = None
90 _known_short_options = u'h?V'
91 _known_long_options = [
92 u'debug',
93 u'slave',
94 u'skip-update-check',
95 u'profile=',
96 u'text-domain=',
97 u'log-file=',
98 u'conf-file=',
99 u'lang-gettext=',
100 u'ui=',
101 u'override-schema-check',
102 u'local-import',
103 u'help',
104 u'version',
105 u'hipaa'
106 ]
107
108 _known_ui_types = [
109 u'web',
110 u'wxp',
111 u'chweb'
112 ]
113
114 import_error_sermon = """
115 GNUmed startup: Cannot load GNUmed Python modules !
116 ---------------------------------------------------
117 CRITICAL ERROR: Program halted.
118
119 Please make sure you have:
120
121 1) the required third-party Python modules installed
122 2) the GNUmed Python modules linked or installed into site-packages/
123 (if you do not run from a CVS tree the installer should have taken care of that)
124 3) your PYTHONPATH environment variable set up correctly
125
126 sys.path is currently set to:
127
128 %s
129
130 If you are running from a copy of the CVS tree make sure you
131 did run gnumed/check-prerequisites.sh with good results.
132
133 If you still encounter errors after checking the above
134 requirements please ask on the mailing list.
135 """
136
137
138 missing_cli_config_file = u"""
139 GNUmed startup: Missing configuration file.
140 -------------------------------------------
141
142 You explicitly specified a configuration file
143 on the command line:
144
145 --conf-file=%s
146
147 The file does not exist, however.
148 """
149
150
151 no_config_files = u"""
152 GNUmed startup: Missing configuration files.
153 --------------------------------------------
154
155 None of the below candidate configuration
156 files could be found:
157
158 %s
159
160 Cannot run GNUmed without any of them.
161 """
162
163
164
166
167 if not u'--local-import' in sys.argv:
168 return
169
170 print "GNUmed startup: Running from local source tree."
171 print "-----------------------------------------------"
172
173 local_python_base_dir = os.path.dirname (
174 os.path.abspath(os.path.join(sys.argv[0], '..'))
175 )
176
177
178
179 link_name = os.path.join(local_python_base_dir, 'Gnumed')
180 if not os.path.exists(link_name):
181 real_dir = os.path.join(local_python_base_dir, 'client')
182 print "Creating module import symlink ..."
183 print ' real dir:', real_dir
184 print ' link:', link_name
185 os.symlink(real_dir, link_name)
186
187 print "Adjusting PYTHONPATH ..."
188 sys.path.insert(0, local_python_base_dir)
189
201
212
217
219 from Gnumed.pycommon import gmCfg2
220
221 global _cfg
222 _cfg = gmCfg2.gmCfgData()
223 _cfg.add_cli (
224 short_options = _known_short_options,
225 long_options = _known_long_options
226 )
227
228 val = _cfg.get(option = '--debug', source_order = [('cli', 'return')])
229 if val is None:
230 val = False
231 _cfg.set_option (
232 option = u'debug',
233 value = val
234 )
235
236 val = _cfg.get(option = '--slave', source_order = [('cli', 'return')])
237 if val is None:
238 val = False
239 _cfg.set_option (
240 option = u'slave',
241 value = val
242 )
243
244 val = _cfg.get(option = '--skip-update-check', source_order = [('cli', 'return')])
245 if val is None:
246 val = False
247 _cfg.set_option (
248 option = u'skip-update-check',
249 value = val
250 )
251
252 val = _cfg.get(option = '--hipaa', source_order = [('cli', 'return')])
253 if val is None:
254 val = False
255 _cfg.set_option (
256 option = u'hipaa',
257 value = val
258 )
259
260 val = _cfg.get(option = '--local-import', source_order = [('cli', 'return')])
261 if val is None:
262 val = False
263 _cfg.set_option (
264 option = u'local-import',
265 value = val
266 )
267
268 _cfg.set_option (
269 option = u'client_version',
270 value = current_client_version
271 )
272
273 _cfg.set_option (
274 option = u'client_branch',
275 value = current_client_branch
276 )
277
278
280 _log.critical('SIGTERM (SIG%s) received, shutting down ...' % signum)
281 gmLog2.flush()
282 print 'GNUmed: SIGTERM (SIG%s) received, shutting down ...' % signum
283 if frame is not None:
284 print '%s::%s@%s' % (frame.f_code.co_filename, frame.f_code.co_name, frame.f_lineno)
285
286
287
288 if _old_sig_term in [None, signal.SIG_IGN]:
289 sys.exit(signal.SIGTERM)
290 else:
291 _old_sig_term(signum, frame)
292
296
307
309 src = [(u'cli', u'return')]
310
311 help_requested = (
312 _cfg.get(option = u'--help', source_order = src) or
313 _cfg.get(option = u'-h', source_order = src) or
314 _cfg.get(option = u'-?', source_order = src)
315 )
316
317 if help_requested:
318 print _(
319 'Help requested\n'
320 '--------------'
321 )
322 print __doc__
323 sys.exit(0)
324
343
344
346 """Create needed paths in user home directory."""
347
348 gmTools.mkdir(os.path.expanduser(os.path.join('~', '.gnumed', 'scripts')))
349 gmTools.mkdir(os.path.expanduser(os.path.join('~', '.gnumed', 'spellcheck')))
350 gmTools.mkdir(os.path.expanduser(os.path.join('~', '.gnumed', 'tmp')))
351 gmTools.mkdir(os.path.expanduser(os.path.join('~', 'gnumed', 'export', 'docs')))
352 gmTools.mkdir(os.path.expanduser(os.path.join('~', 'gnumed', 'export', 'xDT')))
353 gmTools.mkdir(os.path.expanduser(os.path.join('~', 'gnumed', 'export', 'EMR')))
354 gmTools.mkdir(os.path.expanduser(os.path.join('~', 'gnumed', 'xDT')))
355 gmTools.mkdir(os.path.expanduser(os.path.join('~', 'gnumed', 'logs')))
356
357 paths = gmTools.gmPaths(app_name = u'gnumed')
358
359 open(os.path.expanduser(os.path.join('~', '.gnumed', 'gnumed.conf')), 'a+').close()
360
363
365 """Detect and setup access to GNUmed config file.
366
367 Parts of this will have limited value due to
368 wxPython not yet being available.
369 """
370
371 enc = gmI18N.get_encoding()
372 paths = gmTools.gmPaths(app_name = u'gnumed')
373
374 candidates = [
375
376 [u'workbase', os.path.join(paths.working_dir, 'gnumed.conf')],
377
378 [u'system', os.path.join(paths.system_config_dir, 'gnumed-client.conf')],
379
380 [u'user', os.path.join(paths.user_config_dir, 'gnumed.conf')],
381
382 [u'local', os.path.join(paths.local_base_dir, 'gnumed.conf')]
383 ]
384
385 explicit_fname = _cfg.get(option = u'--conf-file', source_order = [(u'cli', u'return')])
386 if explicit_fname is None:
387 candidates.append([u'explicit', None])
388 else:
389 candidates.append([u'explicit', explicit_fname])
390
391 for candidate in candidates:
392 _cfg.add_file_source (
393 source = candidate[0],
394 file = candidate[1],
395 encoding = enc
396 )
397
398
399 if explicit_fname is not None:
400 if _cfg.source_files['explicit'] is None:
401 _log.error('--conf-file argument does not exist')
402 sys.exit(missing_cli_config_file % explicit_fname)
403
404
405 found_any_file = False
406 for f in _cfg.source_files.values():
407 if f is not None:
408 found_any_file = True
409 break
410 if not found_any_file:
411 _log.error('no config file found at all')
412 sys.exit(no_config_files % '\n '.join(candidates))
413
414
415 fname = u'mime_type2file_extension.conf'
416 _cfg.add_file_source (
417 source = u'user-mime',
418 file = os.path.join(paths.user_config_dir, fname),
419 encoding = enc
420 )
421 _cfg.add_file_source (
422 source = u'system-mime',
423 file = os.path.join(paths.system_config_dir, fname),
424 encoding = enc
425 )
426
428 global ui_type
429
430 ui_type = _cfg.get(option = u'--ui', source_order = [(u'cli', u'return')])
431
432 if ui_type in [True, False, None]:
433 ui_type = 'wxp'
434
435 ui_type = ui_type.strip()
436
437 if ui_type not in _known_ui_types:
438 _log.error('unknown UI type: %s', ui_type)
439 _log.debug('known UI types: %s', str(_known_ui_types))
440 print "GNUmed startup: Unknown UI type (%s). Defaulting to wxPython client." % ui_type
441 ui_type = 'wxp'
442
443 _log.debug('UI type: %s', ui_type)
444
446 _log.info('client expects database version [%s]', gmPG2.map_client_branch2required_db_version[current_client_branch])
447
448
449 timezone = _cfg.get (
450 group = u'backend',
451 option = 'client timezone',
452 source_order = [
453 ('explicit', 'return'),
454 ('workbase', 'return'),
455 ('local', 'return'),
456 ('user', 'return'),
457 ('system', 'return')
458 ]
459 )
460 if timezone is not None:
461 gmPG2.set_default_client_timezone(timezone)
462
465
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492 logging.raiseExceptions = False
493
494
495
496
497 setup_python_path()
498 setup_logging()
499 log_startup_info()
500 setup_console_exception_handler()
501 setup_cli()
502 setup_signal_handlers()
503
504 from Gnumed.pycommon import gmI18N, gmTools, gmDateTime, gmHooks
505 setup_locale()
506 handle_help_request()
507 handle_version_request()
508 setup_paths_and_files()
509 setup_date_time()
510 setup_cfg()
511 setup_ui_type()
512
513 from Gnumed.pycommon import gmPG2
514 if ui_type in [u'web']:
515 gmPG2.auto_request_login_params = False
516 setup_backend()
517
518
519 gmHooks.run_hook_script(hook = u'startup-before-GUI')
520
521 if ui_type == u'wxp':
522 from Gnumed.wxpython import gmGuiMain
523 profile_file = _cfg.get(option = u'--profile', source_order = [(u'cli', u'return')])
524 if profile_file is not None:
525 _log.info('writing profiling data into %s', profile_file)
526 import profile
527 profile.run('gmGuiMain.main()', profile_file)
528 else:
529 gmGuiMain.main()
530 elif ui_type == u'web':
531 from Gnumed.proxiedpyjamas import gmWebGuiServer
532 gmWebGuiServer.main()
533
534 elif ui_type == u'chweb':
535 from Gnumed.CherryPy import gmGuiWeb
536 gmGuiWeb.main()
537
538 gmHooks.run_hook_script(hook = u'shutdown-post-GUI')
539
540 shutdown_backend()
541 _log.info('Normally shutting down as main module.')
542 shutdown_logging()
543
544
545