Package Gnumed :: Module gnumed
[frames] | no frames]

Source Code for Module Gnumed.gnumed

  1  #!/usr/bin/env python 
  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  --tool=<TOOL> 
 21   Run TOOL instead of the main GUI. 
 22  --text-domain=<text domain> 
 23   Set this to change the name of the language file to be loaded. 
 24   Note, this does not change the directory the file is searched in, 
 25   only the name of the file where messages are loaded from. The 
 26   standard textdomain is, of course, "gnumed.mo". 
 27  --log-file=<file> 
 28   Use this to change the name of the log file. 
 29   See gmLog2.py to find out where the standard log file would 
 30   end up. 
 31  --conf-file=<file> 
 32   Use configuration file <file> instead of searching for it in 
 33   standard locations. 
 34  --lang-gettext=<language> 
 35   Explicitly set the language to use in gettext translation. The very 
 36   same effect can be achieved by setting the environment variable $LANG 
 37   from a launcher script. 
 38  --override-schema-check 
 39   Continue loading the client even if the database schema version 
 40   and the client software version cannot be verified to be compatible. 
 41  --skip-update-check 
 42   Skip checking for client updates. This is useful during development 
 43   and when the update check URL is unavailable (down). 
 44  --local-import 
 45   Adjust the PYTHONPATH such that GNUmed can be run from a local source tree. 
 46  --ui=<ui type> 
 47   Start an alternative UI. Defaults to wxPython if not specified. 
 48   Currently "wxp" (wxPython) only. 
 49  --wxp=<version> 
 50   Explicitely request a wxPython version. Can be set to either "2" or "3". 
 51   Defaults to "try 3, then 2" if not set. 
 52  --version, -V 
 53   Show version information. 
 54  --help, -h, or -? 
 55   Show this help. 
 56  """ 
 57  #========================================================== 
 58  __author__ = "H. Herb <hherb@gnumed.net>, K. Hilbert <Karsten.Hilbert@gmx.net>, I. Haywood <i.haywood@ugrad.unimelb.edu.au>" 
 59  __license__ = "GPL v2 or later (details at http://www.gnu.org)" 
 60   
 61   
 62  # standard library 
 63  import sys 
 64  import os 
 65  import platform 
 66  import faulthandler 
 67  import random 
 68  import logging 
 69  import signal 
 70  import os.path 
 71  import shutil 
 72  import stat 
 73  import io 
 74   
 75   
 76  # do not run as module 
 77  if __name__ != "__main__": 
 78          print("GNUmed startup: This is not intended to be imported as a module !") 
 79          print("-----------------------------------------------------------------") 
 80          print(__doc__) 
 81          sys.exit(1) 
 82   
 83   
 84  # do not run as root 
 85  if os.name in ['posix'] and os.geteuid() == 0: 
 86          print(""" 
 87  GNUmed startup: GNUmed should not be run as root. 
 88  ------------------------------------------------- 
 89   
 90  Running GNUmed as <root> can potentially put all 
 91  your medical data at risk. It is strongly advised 
 92  against. Please run GNUmed as a non-root user. 
 93  """) 
 94          sys.exit(1) 
 95   
 96  #---------------------------------------------------------- 
 97  current_client_version = '1.8.rc1' 
 98  current_client_branch = '1.8' 
 99   
100  _log = None 
101  _pre_log_buffer = [] 
102  _cfg = None 
103  _old_sig_term = None 
104  _known_short_options = 'h?V' 
105  _known_long_options = [ 
106          'debug', 
107          'slave', 
108          'skip-update-check', 
109          'profile=', 
110          'text-domain=', 
111          'log-file=', 
112          'conf-file=', 
113          'lang-gettext=', 
114          'ui=', 
115          'override-schema-check', 
116          'local-import', 
117          'help', 
118          'version', 
119          'hipaa', 
120          'wxp=', 
121          'tool=' 
122  ] 
123   
124  _known_ui_types = [ 
125          'web', 
126          'wxp', 
127          'chweb' 
128  ] 
129   
130  _known_tools = [ 
131          'check_enc_epi_xref', 
132          'export_pat_emr_structure' 
133  ] 
134   
135   
136  import_error_sermon = """ 
137  GNUmed startup: Cannot load GNUmed Python modules ! 
138  --------------------------------------------------- 
139  CRITICAL ERROR: Program halted. 
140   
141  Please make sure you have: 
142   
143   1) the required third-party Python modules installed 
144   2) the GNUmed Python modules linked or installed into site-packages/ 
145      (if you do not run from a CVS tree the installer should have taken care of that) 
146   3) your PYTHONPATH environment variable set up correctly 
147   
148  <sys.path> is currently set to: 
149   
150   %s 
151   
152  If you are running from a copy of the CVS tree make sure you 
153  did run gnumed/check-prerequisites.sh with good results. 
154   
155  If you still encounter errors after checking the above 
156  requirements please ask on the mailing list. 
157  """ 
158   
159   
160  missing_cli_config_file = """ 
161  GNUmed startup: Missing configuration file. 
162  ------------------------------------------- 
163   
164  You explicitly specified a configuration file 
165  on the command line: 
166   
167          --conf-file=%s 
168   
169  The file does not exist, however. 
170  """ 
171   
172   
173  no_config_files = """ 
174  GNUmed startup: Missing configuration files. 
175  -------------------------------------------- 
176   
177  None of the below candidate configuration 
178  files could be found: 
179   
180   %s 
181   
182  Cannot run GNUmed without any of them. 
183  """ 
184   
185  #========================================================== 
186  # convenience functions 
187  #---------------------------------------------------------- 
201   
202  #========================================================== 
203  # startup helpers 
204  #---------------------------------------------------------- 
205 -def setup_fault_handler(target=None):
206 if target is None: 207 faulthandler.enable() 208 _pre_log_buffer.append('<faulthandler> enabled, target = [console]: %s' % faulthandler) 209 return 210 _pre_log_buffer.append('<faulthandler> enabled, target = [%s]: %s' % (target, faulthandler)) 211 faulthandler.enable(file = target)
212 213 #==========================================================
214 -def setup_console_encoding():
215 print_lines = [] 216 try: 217 sys.stdout.reconfigure(errors = 'surrogateescape') 218 sys.stderr.reconfigure(errors = 'surrogateescape') 219 _pre_log_buffer.append('stdout/stderr reconfigured to use <surrogateescape> for encoding errors') 220 return 221 except AttributeError: 222 line = 'cannot reconfigure sys.stdout/stderr to use <errors="surrogateescape"> (needs Python 3.7+)' 223 _pre_log_buffer.append(line) 224 print_lines.append(line) 225 try: 226 _pre_log_buffer.append('sys.stdout/stderr default to "${PYTHONIOENCODING}=%s"' % os.environ['PYTHONIOENCODING']) 227 return 228 except KeyError: 229 lines = [ 230 '${PYTHONIOENCODING} is not set up, use <PYTHONIOENCODING=utf-8:surrogateescape> in the shell (for Python < 3.7)', 231 'console encoding errors may occur' 232 ] 233 for line in lines: 234 print_lines.append(line) 235 _pre_log_buffer.append(line) 236 for line in print_lines: 237 print('GNUmed startup:', line)
238 239 #==========================================================
240 -def setup_python_path():
241 242 if not '--local-import' in sys.argv: 243 _pre_log_buffer.append('running against systemwide install') 244 return 245 246 local_python_import_dir = os.path.dirname ( 247 os.path.abspath(os.path.join(sys.argv[0], '..')) 248 ) 249 print("Running from local source tree (%s) ..." % local_python_import_dir) 250 _pre_log_buffer.append("running from local source tree: %s" % local_python_import_dir) 251 252 # does the path exist at all, physically ? 253 # (*broken* links are reported as False) 254 link_name = os.path.join(local_python_import_dir, 'Gnumed') 255 if os.path.exists(link_name): 256 _pre_log_buffer.append('local module import dir symlink exists: %s' % link_name) 257 else: 258 real_dir = os.path.join(local_python_import_dir, 'client') 259 print('Creating local module import symlink ...') 260 print(' real dir:', real_dir) 261 print(' link:', link_name) 262 try: 263 os.symlink(real_dir, link_name) 264 except AttributeError: 265 _pre_log_buffer.append('Windows does not have os.symlink(), resorting to ctypes') 266 result = _symlink_windows(real_dir, link_name) 267 _pre_log_buffer.append('ctypes.windll.kernel32.CreateSymbolicLinkW() exit code: %s', result) 268 _pre_log_buffer.append('created local module import dir symlink: link [%s] => dir [%s]' % (link_name, real_dir)) 269 270 sys.path.insert(0, local_python_import_dir) 271 _pre_log_buffer.append('sys.path with local module import base dir prepended: %s' % sys.path)
272 273 #==========================================================
274 -def setup_local_repo_path():
275 276 local_repo_path = os.path.expanduser(os.path.join ( 277 '~', 278 '.gnumed', 279 'local_code', 280 str(current_client_branch) 281 )) 282 local_wxGladeWidgets_path = os.path.join(local_repo_path, 'Gnumed', 'wxGladeWidgets') 283 284 if not os.path.exists(local_wxGladeWidgets_path): 285 _log.debug('[%s] not found', local_wxGladeWidgets_path) 286 _log.info('local wxGlade widgets repository not available') 287 return 288 289 _log.info('local wxGlade widgets repository found:') 290 _log.info(local_wxGladeWidgets_path) 291 292 if not os.access(local_wxGladeWidgets_path, os.R_OK): 293 _log.error('invalid repo: no read access') 294 return 295 296 all_entries = os.listdir(os.path.join(local_repo_path, 'Gnumed')) 297 _log.debug('repo base contains: %s', all_entries) 298 all_entries.remove('wxGladeWidgets') 299 try: 300 all_entries.remove('__init__.py') 301 except ValueError: 302 _log.error('invalid repo: lacking __init__.py') 303 return 304 try: 305 all_entries.remove('__init__.pyc') 306 except ValueError: 307 pass 308 309 if len(all_entries) > 0: 310 _log.error('insecure repo: additional files or directories found') 311 return 312 313 # repo must be 0700 (rwx------) 314 stat_val = os.stat(local_wxGladeWidgets_path) 315 _log.debug('repo stat(): %s', stat_val) 316 perms = stat.S_IMODE(stat_val.st_mode) 317 _log.debug('repo permissions: %s (octal: %s)', perms, oct(perms)) 318 if perms != 448: # octal 0700 319 if os.name in ['nt']: 320 _log.warning('this platform does not support os.stat() permission checking') 321 else: 322 _log.error('insecure repo: permissions not 0600') 323 return 324 325 print("Activating local wxGlade widgets repository (%s) ..." % local_wxGladeWidgets_path) 326 sys.path.insert(0, local_repo_path) 327 _log.debug('sys.path with repo:') 328 _log.debug(sys.path)
329 330 #==========================================================
331 -def setup_logging():
332 try: 333 from Gnumed.pycommon import gmLog2 as _gmLog2 334 except ImportError: 335 print(import_error_sermon % '\n '.join(sys.path)) 336 sys.exit(1) 337 338 print("Log file:", _gmLog2._logfile.name) 339 setup_fault_handler(target = _gmLog2._logfile) 340 341 global gmLog2 342 gmLog2 = _gmLog2 343 344 global _log 345 _log = logging.getLogger('gm.launcher')
346 347 #==========================================================
348 -def log_startup_info():
349 global _pre_log_buffer 350 if len(_pre_log_buffer) > 0: 351 _log.info('early startup log buffer:') 352 for line in _pre_log_buffer: 353 _log.info(' ' + line) 354 del _pre_log_buffer 355 _log.info('GNUmed client version [%s] on branch [%s]', current_client_version, current_client_branch) 356 _log.info('Platform: %s', platform.uname()) 357 _log.info(('Python %s on %s (%s)' % (sys.version, sys.platform, os.name)).replace('\n', '<\\n>')) 358 try: 359 import lsb_release 360 _log.info('lsb_release: %s', lsb_release.get_distro_information()) 361 except ImportError: 362 pass 363 _log.info('os.getcwd(): [%s]', os.getcwd()) 364 _log.info('process environment:') 365 for key, val in os.environ.items(): 366 _log.info(' %s: %s' % (('${%s}' % key).rjust(30), val))
367 368 #==========================================================
369 -def setup_console_exception_handler():
370 from Gnumed.pycommon.gmTools import handle_uncaught_exception_console 371 372 sys.excepthook = handle_uncaught_exception_console
373 374 #==========================================================
375 -def setup_cli():
376 from Gnumed.pycommon import gmCfg2 377 378 global _cfg 379 _cfg = gmCfg2.gmCfgData() 380 _cfg.add_cli ( 381 short_options = _known_short_options, 382 long_options = _known_long_options 383 ) 384 385 val = _cfg.get(option = '--debug', source_order = [('cli', 'return')]) 386 if val is None: 387 val = False 388 _cfg.set_option ( 389 option = 'debug', 390 value = val 391 ) 392 393 val = _cfg.get(option = '--slave', source_order = [('cli', 'return')]) 394 if val is None: 395 val = False 396 _cfg.set_option ( 397 option = 'slave', 398 value = val 399 ) 400 401 val = _cfg.get(option = '--skip-update-check', source_order = [('cli', 'return')]) 402 if val is None: 403 val = False 404 _cfg.set_option ( 405 option = 'skip-update-check', 406 value = val 407 ) 408 409 val = _cfg.get(option = '--hipaa', source_order = [('cli', 'return')]) 410 if val is None: 411 val = False 412 _cfg.set_option ( 413 option = 'hipaa', 414 value = val 415 ) 416 417 val = _cfg.get(option = '--local-import', source_order = [('cli', 'return')]) 418 if val is None: 419 val = False 420 _cfg.set_option ( 421 option = 'local-import', 422 value = val 423 ) 424 425 _cfg.set_option ( 426 option = 'client_version', 427 value = current_client_version 428 ) 429 430 _cfg.set_option ( 431 option = 'client_branch', 432 value = current_client_branch 433 )
434 435 #==========================================================
436 -def handle_sig_term(signum, frame):
437 _log.critical('SIGTERM (SIG%s) received, shutting down ...' % signum) 438 gmLog2.flush() 439 print('GNUmed: SIGTERM (SIG%s) received, shutting down ...' % signum) 440 if frame is not None: 441 print('%s::%s@%s' % (frame.f_code.co_filename, frame.f_code.co_name, frame.f_lineno)) 442 443 # FIXME: need to do something useful here 444 445 if _old_sig_term in [None, signal.SIG_IGN]: 446 sys.exit(1) 447 else: 448 _old_sig_term(signum, frame)
449 450 #----------------------------------------------------------
451 -def setup_signal_handlers():
452 global _old_sig_term 453 old_sig_term = signal.signal(signal.SIGTERM, handle_sig_term)
454 455 #==========================================================
456 -def setup_locale():
457 gmI18N.activate_locale() 458 459 td = _cfg.get(option = '--text-domain', source_order = [('cli', 'return')]) 460 l = _cfg.get(option = '--lang-gettext', source_order = [('cli', 'return')]) 461 gmI18N.install_domain(domain = td, language = l, prefer_local_catalog = _cfg.get(option = 'local-import'))
462 463 # # make sure we re-get the default encoding 464 # # in case it changed 465 # gmLog2.set_string_encoding() 466 467 #==========================================================
468 -def handle_help_request():
469 src = [('cli', 'return')] 470 471 help_requested = ( 472 _cfg.get(option = '--help', source_order = src) or 473 _cfg.get(option = '-h', source_order = src) or 474 _cfg.get(option = '-?', source_order = src) 475 ) 476 477 if help_requested: 478 print(_( 479 'Help requested\n' 480 '--------------' 481 )) 482 print(__doc__) 483 sys.exit(0)
484 485 #==========================================================
486 -def handle_version_request():
487 src = [('cli', 'return')] 488 489 version_requested = ( 490 _cfg.get(option = '--version', source_order = src) or 491 _cfg.get(option = '-V', source_order = src) 492 ) 493 494 if version_requested: 495 496 from Gnumed.pycommon.gmPG2 import map_client_branch2required_db_version, known_schema_hashes 497 498 print('GNUmed version information') 499 print('--------------------------') 500 print('client : %s on branch [%s]' % (current_client_version, current_client_branch)) 501 print('database : %s' % map_client_branch2required_db_version[current_client_branch]) 502 print('schema hash: %s' % known_schema_hashes[map_client_branch2required_db_version[current_client_branch]]) 503 sys.exit(0)
504 505 #==========================================================
506 -def setup_paths_and_files():
507 """Create needed paths in user home directory.""" 508 509 gnumed_DIR_README_TEXT = """GNUmed Electronic Medical Record 510 511 %s/ 512 513 This directory should only ever contain files which the 514 user will come into direct contact with while using the 515 application (say, by selecting a file from the file system, 516 as when selecting document parts from files). You can create 517 subdirectories here as you see fit for the purpose. 518 519 This directory will also serve as the default directory when 520 GNUmed asks the user to select a directory for storing a 521 file. 522 523 Any files which are NOT intended for direct user interaction 524 but must be configured to live at a known location (say, 525 inter-application data exchange files) should be put under 526 the hidden directory "%s/".""" % ( 527 os.path.expanduser(os.path.join('~', 'gnumed')), 528 os.path.expanduser(os.path.join('~', '.gnumed')) 529 ) 530 531 gmTools.mkdir(os.path.expanduser(os.path.join('~', '.gnumed', 'scripts'))) 532 gmTools.mkdir(os.path.expanduser(os.path.join('~', '.gnumed', 'spellcheck'))) 533 gmTools.mkdir(os.path.expanduser(os.path.join('~', '.gnumed', 'error_logs'))) 534 gmTools.mkdir(os.path.expanduser(os.path.join('~', 'gnumed'))) 535 536 README = io.open(os.path.expanduser(os.path.join('~', 'gnumed', '00_README')), mode = 'wt', encoding = 'utf8') 537 README.write(gnumed_DIR_README_TEXT) 538 README.close() 539 540 # wxPython not available yet 541 paths = gmTools.gmPaths(app_name = 'gnumed') 542 print("Temp dir:", paths.tmp_dir) 543 544 # ensure there's a user-level config file 545 io.open(os.path.expanduser(os.path.join('~', '.gnumed', 'gnumed.conf')), mode = 'a+t').close() 546 547 # symlink log file into temporary directory for easier debugging (everything in one place) 548 logfile_link = os.path.join(paths.tmp_dir, 'zzz-gnumed.log') 549 gmTools.mklink (gmLog2._logfile.name, logfile_link, overwrite = False)
550 551 #==========================================================
552 -def setup_date_time():
553 gmDateTime.init()
554 555 #==========================================================
556 -def setup_cfg():
557 """Detect and setup access to GNUmed config file. 558 559 Parts of this will have limited value due to 560 wxPython not yet being available. 561 """ 562 563 enc = gmI18N.get_encoding() 564 paths = gmTools.gmPaths(app_name = 'gnumed') 565 566 candidates = [ 567 # the current working dir 568 ['workbase', os.path.join(paths.working_dir, 'gnumed.conf')], 569 # /etc/gnumed/ 570 ['system', os.path.join(paths.system_config_dir, 'gnumed-client.conf')], 571 # ~/.gnumed/ 572 ['user', os.path.join(paths.user_config_dir, 'gnumed.conf')], 573 # CVS/tgz tree .../gnumed/client/ (IOW a local installation) 574 ['local', os.path.join(paths.local_base_dir, 'gnumed.conf')] 575 ] 576 # --conf-file= 577 explicit_fname = _cfg.get(option = '--conf-file', source_order = [('cli', 'return')]) 578 if explicit_fname is None: 579 candidates.append(['explicit', None]) 580 else: 581 candidates.append(['explicit', explicit_fname]) 582 583 for candidate in candidates: 584 _cfg.add_file_source ( 585 source = candidate[0], 586 file = candidate[1], 587 encoding = enc 588 ) 589 590 # --conf-file given but does not actually exist ? 591 if explicit_fname is not None: 592 if _cfg.source_files['explicit'] is None: 593 _log.error('--conf-file argument does not exist') 594 print(missing_cli_config_file % explicit_fname) 595 sys.exit(1) 596 597 # any config file found at all ? 598 found_any_file = False 599 for f in _cfg.source_files.values(): 600 if f is not None: 601 found_any_file = True 602 break 603 if not found_any_file: 604 _log.error('no config file found at all') 605 print(no_config_files % '\n '.join(candidates)) 606 sys.exit(1) 607 608 # mime type handling sources 609 fname = 'mime_type2file_extension.conf' 610 _cfg.add_file_source ( 611 source = 'user-mime', 612 file = os.path.join(paths.user_config_dir, fname), 613 encoding = enc 614 ) 615 _cfg.add_file_source ( 616 source = 'system-mime', 617 file = os.path.join(paths.system_config_dir, fname), 618 encoding = enc 619 )
620 621 #==========================================================
622 -def setup_ui_type():
623 global ui_type 624 ui_type = _cfg.get(option = '--ui', source_order = [('cli', 'return')]) 625 if ui_type in [True, False, None]: 626 ui_type = 'wxp' 627 ui_type = ui_type.strip() 628 if ui_type not in _known_ui_types: 629 _log.error('unknown UI type requested: %s', ui_type) 630 _log.debug('known UI types are: %s', str(_known_ui_types)) 631 print("GNUmed startup: Unknown UI type (%s). Defaulting to wxPython client." % ui_type) 632 ui_type = 'wxp' 633 _log.debug('UI type: %s', ui_type)
634 635 #==========================================================
636 -def setup_backend_environment():
637 638 db_version = gmPG2.map_client_branch2required_db_version[current_client_branch] 639 _log.info('client expects database version [%s]', db_version) 640 _cfg.set_option ( 641 option = 'database_version', 642 value = db_version 643 ) 644 645 # set up database connection timezone 646 timezone = _cfg.get ( 647 group = 'backend', 648 option = 'client timezone', 649 source_order = [ 650 ('explicit', 'return'), 651 ('workbase', 'return'), 652 ('local', 'return'), 653 ('user', 'return'), 654 ('system', 'return') 655 ] 656 ) 657 if timezone is not None: 658 gmPG2.set_default_client_timezone(timezone)
659 660 #==========================================================
661 -def run_gui():
662 gmHooks.run_hook_script(hook = 'startup-before-GUI') 663 664 if ui_type == 'wxp': 665 from Gnumed.wxpython import gmGuiMain 666 profile_file = _cfg.get(option = '--profile', source_order = [('cli', 'return')]) 667 if profile_file is not None: 668 _log.info('writing profiling data into %s', profile_file) 669 import profile 670 profile.run('gmGuiMain.main()', profile_file) 671 else: 672 gmGuiMain.main() 673 #elif ui_type == u'web': 674 # from Gnumed.proxiedpyjamas import gmWebGuiServer 675 # gmWebGuiServer.main() 676 #elif ui_type == u'chweb': 677 # from Gnumed.CherryPy import gmGuiWeb 678 # gmGuiWeb.main() 679 680 gmHooks.run_hook_script(hook = 'shutdown-post-GUI') 681 682 return 0
683 684 #==========================================================
685 -def run_tool():
686 tool = _cfg.get(option = '--tool', source_order = [('cli', 'return')]) 687 if tool is None: 688 # not running a tool 689 return None 690 691 if tool not in _known_tools: 692 _log.error('unknown tool requested: %s', tool) 693 print('GNUmed startup: Unknown tool [%s] requested.' % tool) 694 print('GNUmed startup: Known tools: %s' % _known_tools) 695 return -1 696 697 print('') 698 print('==============================================') 699 print('Running tool: %s' % tool) 700 print('----------------------------------------------') 701 print('') 702 703 if tool == 'check_enc_epi_xref': 704 from Gnumed.business import gmEMRStructItems 705 return gmEMRStructItems.check_fk_encounter_fk_episode_x_ref() 706 707 if tool == 'export_pat_emr_structure': 708 # setup praxis 709 from Gnumed.business import gmPraxis 710 praxis = gmPraxis.gmCurrentPraxisBranch(branch = gmPraxis.get_praxis_branches()[0]) 711 # get patient 712 from Gnumed.business import gmPersonSearch 713 pat = gmPersonSearch.ask_for_patient() 714 # setup exporters 715 from Gnumed.business import gmEMRStructItems 716 from Gnumed.exporters import gmTimelineExporter 717 from Gnumed.exporters import gmPatientExporter 718 while pat is not None: 719 print('patient:', pat['description_gender']) 720 # as EMR structure 721 fname = os.path.expanduser('~/gnumed/gm-emr_structure-%s.txt' % pat.subdir_name) 722 print('EMR structure:', gmEMRStructItems.export_emr_structure(patient = pat, filename = fname)) 723 # as timeline 724 fname = os.path.expanduser('~/gnumed/gm-emr-%s.timeline' % pat.subdir_name) 725 try: 726 print('EMR timeline:', gmTimelineExporter.create_timeline_file ( 727 patient = pat, 728 filename = fname, 729 include_documents = True, 730 include_vaccinations = True, 731 include_encounters = True 732 )) 733 finally: 734 pass 735 # as journal by encounter 736 exporter = gmPatientExporter.cEMRJournalExporter() 737 fname = os.path.expanduser('~/gnumed/gm-emr-journal_by_encounter-%s.txt' % pat.subdir_name) 738 print('EMR journal (by encounter):', exporter.save_to_file_by_encounter(patient = pat, filename = fname)) 739 # as journal by mod time 740 fname = os.path.expanduser('~/gnumed/gm-emr-journal_by_mod_time-%s.txt' % pat.subdir_name) 741 print('EMR journal (by mod time):', exporter.save_to_file_by_mod_time(patient = pat, filename = fname)) 742 # as statistical summary 743 fname = os.path.expanduser('~/gnumed/gm-emr-statistics-%s.txt' % pat.subdir_name) 744 output_file = io.open(fname, mode = 'wt', encoding = 'utf8', errors = 'replace') 745 emr = pat.emr 746 output_file.write(emr.format_statistics()) 747 output_file.close() 748 print('EMR statistics:', fname) 749 # as text file 750 exporter = gmPatientExporter.cEmrExport(patient = pat) 751 fname = os.path.expanduser('~/gnumed/gm-emr-text_export-%s.txt' % pat.subdir_name) 752 output_file = io.open(fname, mode = 'wt', encoding = 'utf8', errors = 'replace') 753 exporter.set_output_file(output_file) 754 exporter.dump_constraints() 755 exporter.dump_demographic_record(True) 756 exporter.dump_clinical_record() 757 exporter.dump_med_docs() 758 output_file.close() 759 print('EMR text file:', fname) 760 # another patient ? 761 pat = gmPersonSearch.ask_for_patient() 762 763 return 0 764 765 # tool export_patient_as (vcf, gdt, ...) 766 #if tool == 'export_pat_demographics': 767 768 # should not happen (because checked against _known_tools) 769 return -1
770 771 #========================================================== 772 # shutdown helpers 773 #----------------------------------------------------------
774 -def shutdown_backend():
775 gmPG2.shutdown()
776 777 #==========================================================
778 -def shutdown_logging():
779 780 # if _cfg.get(option = u'debug'): 781 # import types 782 783 # def get_refcounts(): 784 # refcount = {} 785 # # collect all classes 786 # for module in sys.modules.values(): 787 # for sym in dir(module): 788 # obj = getattr(module, sym) 789 # if type(obj) is types.ClassType: 790 # refcount[obj] = sys.getrefcount(obj) 791 # # sort by refcount 792 # pairs = map(lambda x: (x[1],x[0]), refcount.items()) 793 # pairs.sort() 794 # pairs.reverse() 795 # return pairs 796 797 # rcfile = io.open('./gm-refcount.lst', 'wt', encoding = 'utf8') 798 # for refcount, class_ in get_refcounts(): 799 # if not class_.__name__.startswith('wx'): 800 # rcfile.write(u'%10d %s\n' % (refcount, class_.__name__)) 801 # rcfile.close() 802 803 # do not choke on Windows 804 logging.raiseExceptions = False
805 806 #==========================================================
807 -def shutdown_tmp_dir():
808 809 tmp_dir = gmTools.gmPaths().tmp_dir 810 811 if _cfg.get(option = 'debug'): 812 _log.debug('not removing tmp dir (--debug mode): %s', tmp_dir) 813 return 814 815 _log.warning('removing tmp dir: %s', tmp_dir) 816 shutil.rmtree(tmp_dir, True)
817 818 #========================================================== 819 # main - launch the GNUmed wxPython GUI client 820 #---------------------------------------------------------- 821 822 random.seed() 823 824 # setup 825 setup_fault_handler(target = None) 826 setup_console_encoding() 827 setup_python_path() 828 setup_logging() 829 log_startup_info() 830 setup_console_exception_handler() 831 setup_cli() 832 setup_signal_handlers() 833 setup_local_repo_path() 834 835 from Gnumed.pycommon import gmI18N 836 from Gnumed.pycommon import gmTools 837 from Gnumed.pycommon import gmDateTime 838 839 setup_locale() 840 handle_help_request() 841 handle_version_request() 842 setup_paths_and_files() 843 setup_date_time() 844 setup_cfg() 845 setup_ui_type() 846 847 from Gnumed.pycommon import gmPG2 848 if ui_type in ['web']: 849 gmPG2.auto_request_login_params = False 850 setup_backend_environment() 851 852 # main 853 exit_code = run_tool() 854 if exit_code is None: 855 from Gnumed.pycommon import gmHooks 856 exit_code = run_gui() 857 858 # shutdown 859 shutdown_backend() 860 shutdown_tmp_dir() 861 _log.info('Normally shutting down as main module.') 862 shutdown_logging() 863 864 sys.exit(exit_code) 865 866 #========================================================== 867