Package Gnumed :: Package importers :: Module gmImportIncoming |
[frames] | no frames]

# Source Code for Module Gnumed.importers.gmImportIncoming

      1  #!/usr/bin/python
      2  # -*- coding: utf-8 -*-
      3
      4
      5
      6  __doc__ = """Incoming data importer."""
      7  __author__ = "K.Hilbert <Karsten.Hilbert@gmx.net>"
      8  __license__ = "GPL v2 or later"
      9  #============================================================
     10
     11  # stdlib
     12  import sys
     13  import os
     14
     15
     16  # do not run as root
     17  if os.name in ['posix'] and os.geteuid() == 0:
     18          print("""
     19  %s should not be run as root.
     20
     21  Running as <root> can potentially put all your
     22  medical data at risk. It is strongly advised
     23  against. Please run as a non-root user.
     24  """ % sys.argv[0])
     25          sys.exit(1)
     26
     27
     28  # when attempting to run from a tarball:
     29  if '--local-import' in sys.argv:
     30          sys.path.insert(0, '../../')
     31
     32
     33  # stdlib
     34  import logging
     35
     36  # GNUmed
     37  from Gnumed.pycommon import gmCfg2
     38  from Gnumed.pycommon import gmPG2
     39  from Gnumed.pycommon import gmTools
     40
     41  from Gnumed.business import gmIncomingData
     42
     43
     44  _log = logging.getLogger('importer')
     45
     46  # update man page and help text when changing options
     47  _known_short_options = 'h?'
     48  _known_long_options = [
     49          'help',
     50          'local-import',
     51          'data-type=',
     52          'file2import=',
     53          'user=',
     54          'host=',
     55          'port='
     56  ]
     57
     58  # update man page when changing options
     59  _help_text = """
     60  --------------------------------------------------------------------------------------
     61  Command line:
     62   %s
     63
     64  Usage synopsis:
     65   %s --local-import --file2import=DATA --data-type=TYPE --user=USER --host=HOST --port=PORT
     66
     67    --local-import: use when running from a tarball
     68
     69    DATA: full path of data file to import
     70    TYPE: short description of file to be shown in GNUmed (say, "fax")
     71    USER: PostgreSQL user in database [%s]
     72    HOST: host name of machine running PostgreSQL, if needed
     73    PORT: port at which PostgreSQL listens on HOST, if needed, typically 5432
     74
     75  See the man page for more details.
     76
     77  Log file:
     78   %s
     79  --------------------------------------------------------------------------------------"""
     80
     81  #============================================================
     82 -def import_file(data_type, filename):
     83
     84          _log.info('[%s]: %s', data_type, filename)
     85
     86          inc = gmIncomingData.create_incoming_data(data_type, filename)
     87          if inc is None:
     88                  _log.error('import failed')
     89          else:
     90                  _log.info('success')
     91                  target_filename = filename + '.imported'
     92                  _log.debug('[%s] -> [%s]', filename, target_filename)
     93                  try:
     94                          os.rename(filename, target_filename)
     95                  except OSError:
     96                          _log.exception('cannot rename [%s] to [%s]', filename, target_filename)
     97          return inc
     98
     99  #       u'request_id',                                          # request ID as found in <data>
    100  #       u'firstnames',
    101  #       u'lastnames',
    102  #       u'dob',
    103  #       u'postcode',
    104  ##      u'other_info',                                          # other identifying info in .data
    105  #       u'gender',
    106  #       u'requestor',                                           # Requestor of data (e.g. who ordered test results) if available in source data.
    107  #       u'external_data_id',                            # ID of content of .data in external system (e.g. importer) where appropriate
    108  #       u'comment',                                                     # a free text comment on this row, eg. why is it here, error logs etc
    109
    110  #============================================================
    111 -def process_options():
    112
    113          if _cfg.get(option = '-h', source_order = [('cli', 'return')]):
    114                  show_usage()
    115                  sys.exit(0)
    116
    117          if _cfg.get(option = '-?', source_order = [('cli', 'return')]):
    118                  show_usage()
    119                  sys.exit(0)
    120
    121          if _cfg.get(option = '--help', source_order = [('cli', 'return')]):
    122                  show_usage()
    123                  sys.exit(0)
    124
    125          file2import = _cfg.get(option = '--file2import', source_order = [('cli', 'return')])
    126          if file2import is None:
    127                  exit_with_message('ERROR: option --file2import missing')
    128          if file2import is True:
    129                  exit_with_message('ERROR: data file missing in option --file2import=')
    130          try:
    131                  open(file2import).close()
    132          except IOError:
    133                  _log.exception('cannot open data file')
    134                  exit_with_message('ERROR: cannot open data file in option --file2import=%s' % file2import)
    135
    136          datatype = _cfg.get(option = '--data-type', source_order = [('cli', 'return')])
    137          if datatype is None:
    138                  exit_with_message('ERROR: option --data-type missing')
    139          if datatype is True:
    140                  exit_with_message('ERROR: data type missing in option --data-type=')
    141          if datatype.strip() == '':
    142                  exit_with_message('ERROR: invalid data type in option --data-type=>>>%s<<<' % datatype)
    143
    144          db_user = _cfg.get(option = '--user', source_order = [('cli', 'return')])
    145          if db_user is None:
    146                  exit_with_message('ERROR: option --user missing')
    147          if db_user is True:
    148                  exit_with_message('ERROR: user name missing in option --user=')
    149          if db_user.strip() == '':
    150                  exit_with_message('ERROR: invalid user name in option --user=>>>%s<<<' % db_user)
    151
    152          db_host = _cfg.get(option = '--host', source_order = [('cli', 'return')])
    153          if db_host is None:
    154                  _log.debug('option --host not set, using <UNIX domain socket> on <localhost>')
    155          elif db_host is True:
    156                  exit_with_message('ERROR: host name missing in option --host=')
    157          elif db_host.strip() == '':
    158                  _log.debug('option --host set to "", using <UNIX domain socket> on <localhost>')
    159                  db_host = None
    160
    161          db_port = _cfg.get(option = '--port', source_order = [('cli', 'return')])
    162          if db_port is None:
    163                  _log.debug('option --port not set, using <UNIX domain socket> on <localhost>')
    164          elif db_port is True:
    165                  exit_with_message('ERROR: port value missing in option --port=')
    166          elif db_port.strip() == '':
    167                  _log.debug('option --port set to "", using <UNIX domain socket> on <localhost>')
    168                  db_port = None
    169          else:
    170                  converted, db_port = gmTools.input2int(initial = db_port, minval = 1024, maxval = 65535)
    171                  if not converted:
    172                          exit_with_message('ERROR: invalid port in option --port=%s (must be 1024...65535)' % db_port)
    173
    174          gmPG2.log_auth_environment()
    175          dsn = gmPG2.make_psycopg2_dsn (
    176                  database = gmPG2.default_database,
    177                  host = db_host,
    178                  port = db_port,
    179                  user = db_user,
    180                  password = None                 # None = force not-required (TRUST/IDENT/PEER) or use-.pgpass-or-$PGPASSFILE
    181          )
    182          gmPG2._default_dsn = dsn
    183
    184          return datatype, file2import
    185
    186  #       val = _cfg.get(option = '--debug', source_order = [('cli', 'return')])
    187  #       _cfg.set_option (
    188  #               option = u'debug',
    189  #               value = val
    190  #       )
    191
    192  #============================================================
    193 -def exit_with_message(message=None):
    194          if message is not None:
    195                  _log.error(message)
    196                  print('')
    197                  print(message)
    198          show_usage()
    199          sys.exit(1)
    200
    201  #============================================================
    202 -def show_usage():
    203          from Gnumed.pycommon import gmLog2
    204          print(_help_text % (
    205                  ' '.join(sys.argv),
    206                  sys.argv[0],
    207                  gmPG2.default_database,
    208                  gmLog2._logfile_name
    209          ))
    210
    211  #============================================================
    212  if __name__ == '__main__':
    213
    214          _cfg = gmCfg2.gmCfgData()
    215          _cfg.add_cli (
    216                  short_options = _known_short_options,
    217                  long_options = _known_long_options
    218          )
    219          datatype, file2import = process_options()
    220          inc = import_file(datatype, file2import)
    221          sys.exit(0)
    222
    223  #       print('Log file:')
    224  #       from Gnumed.pycommon import gmLog2
    225  #       print(' %s' % gmLog2._logfile_name)
    226