Package Gnumed :: Package wxpython :: Module gmDataPackWidgets |
[frames] | no frames]

# Source Code for Module Gnumed.wxpython.gmDataPackWidgets

      1  """GNUmed data pack related widgets."""
      2  #================================================================
      3  __author__ = 'karsten.hilbert@gmx.net'
      4  __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
      5
      6  # stdlib
      7  import logging
      8  import sys
      9  import urllib2 as wget
     10
     11  # 3rd party
     12  import wx
     13
     14
     15  # GNUmed
     16  if __name__ == '__main__':
     17          sys.path.insert(0, '../../')
     18
     19  from Gnumed.pycommon import gmCfg2
     20  from Gnumed.pycommon import gmCfg
     21  from Gnumed.pycommon import gmTools
     22  from Gnumed.pycommon import gmNetworkTools
     23  from Gnumed.pycommon import gmPG2
     24  from Gnumed.business import gmSurgery
     25  from Gnumed.wxpython import gmListWidgets
     26  from Gnumed.wxpython import gmGuiHelpers
     27  from Gnumed.wxpython import gmAuthWidgets
     28  from Gnumed.wxpython import gmCfgWidgets
     29
     30
     31  _log = logging.getLogger('gm.ui')
     32  _cfg = gmCfg2.gmCfgData()
     33
     34
     35  default_dpl_url = u'http://www.gnumed.de/downloads/data/data-packs.conf'
     36  dpl_url_option = u'horstspace.data_packs.url'
     37  #================================================================
     38 -def install_data_pack(data_pack=None):
     39
     40          if data_pack is None:
     41                  return False
     42
     43          _log.info('attempting installation of data pack: %s', data_pack['name'])
     44
     45          msg = _(
     46                  'Note that GNUmed data packs are provided\n'
     47                  '\n'
     48                  'WITHOUT ANY GUARANTEE WHATSOEVER\n'
     49                  '\n'
     50                  'regarding their content.\n'
     51                  '\n'
     52                  'Despite data packs having been prepared with the\n'
     53                  'utmost care you must still vigilantly apply caution,\n'
     54                  'common sense, and due diligence to make sure you\n'
     55                  'render appropriate care to your patients.\n'
     56                  '\n'
     57                  'Press [Yes] to declare agreement with this precaution.\n'
     58                  '\n'
     59                  'Press [No] to abort installation of the data pack.\n'
     60          )
     61          go_ahead = gmGuiHelpers.gm_show_question(msg, _('Terms of Data Pack Use'))
     62          if not go_ahead:
     63                  _log.info('user did not agree to terms of data pack use')
     64                  return True
     65
     66          gm_dbo_conn = gmAuthWidgets.get_dbowner_connection(procedure = _('installing data pack'))
     67          if gm_dbo_conn is None:
     68                  msg = _('Lacking permissions to install data pack.')
     69                  gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
     70                  return False
     71
     72          wx.BeginBusyCursor()
     73          verified, data = gmNetworkTools.download_data_pack (
     74                  data_pack['pack_url'],
     75                  md5_url = data_pack['md5_url']
     76          )
     77          wx.EndBusyCursor()
     78          if not verified:
     79                  _log.error('cannot download and verify data pack: %s', data_pack['name'])
     80                  md5_expected, md5_calculated = data
     81                  msg = _(
     82                          'Cannot validate data pack.\n'
     83                          '\n'
     84                          '  name: %s\n'
     85                          '  URL: %s\n'
     86                          '\n'
     87                          '  MD5\n'
     88                          '   calculated: %s\n'
     89                          '   expected: %s\n'
     90                          '   source: %s\n'
     91                          '\n'
     92                          'You may want to try downloading again or you\n'
     93                          'may need to contact your administrator.'
     94                  ) % (
     95                          data_pack['name'],
     96                          data_pack['pack_url'],
     97                          md5_calculated,
     98                          md5_expected,
     99                          data_pack['md5_url']
    100                  )
    101                  gmGuiHelpers.gm_show_error(msg, _('Verifying data pack'))
    102                  return False
    103
    104          data_pack['local_archive'] = data
    105
    106          wx.BeginBusyCursor()
    107          unzip_dir = gmNetworkTools.unzip_data_pack(filename = data)
    108          wx.EndBusyCursor()
    109          if unzip_dir is None:
    110                  msg = _(
    111                          'Cannot unpack data pack.\n'
    112                          '\n'
    113                          '  name: %s\n'
    114                          '  URL: %s\n'
    115                          '  local: %s\n'
    116                          '\n'
    117                          'You may want to try downloading again or you\n'
    118                          'may need to contact your administrator.'
    119                  ) % (
    120                          data_pack['name'],
    121                          data_pack['pack_url'],
    122                          data_pack['local_archive']
    123                  )
    124                  gmGuiHelpers.gm_show_error(msg, _('Unpacking data pack'))
    125                  return False
    126
    127          data_pack['unzip_dir'] = unzip_dir
    128
    129          wx.BeginBusyCursor()
    130          try:
    131                  installed = gmNetworkTools.install_data_pack(data_pack, gm_dbo_conn)
    132          finally:
    133                  wx.EndBusyCursor()
    134
    135          # check schema hash
    136          db_version = gmPG2.map_client_branch2required_db_version[_cfg.get(option = 'client_branch')]
    137          if not gmPG2.database_schema_compatible(version = db_version):
    138                  if db_version != 0:
    139                          msg = _(
    140                                  'Installation of data pack failed because\n'
    141                                  'it attempted to modify the database layout.\n'
    142                                  '\n'
    143                                  '  name: %s\n'
    144                                  '  URL: %s\n'
    145                                  '  local: %s\n'
    146                                  '\n'
    147                                  'You will need to contact your administrator.'
    148                          ) % (
    149                                  data_pack['name'],
    150                                  data_pack['pack_url'],
    151                                  data_pack['local_archive']
    152                          )
    153                          gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
    154                          return False
    155
    156          if not installed:
    157                  msg = _(
    158                          'Installation of data pack failed.\n'
    159                          '\n'
    160                          '  name: %s\n'
    161                          '  URL: %s\n'
    162                          '  local: %s\n'
    163                          '\n'
    164                          'You may want to try downloading again or you\n'
    165                          'may need to contact your administrator.'
    166                  ) % (
    167                          data_pack['name'],
    168                          data_pack['pack_url'],
    169                          data_pack['local_archive']
    170                  )
    171                  gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
    172                  return False
    173
    174          msg = _(
    175                  'Successfully installed data pack.\n'
    176                  '\n'
    177                  '  name: %s\n'
    178                  '  URL: %s\n'
    179          ) % (
    180                  data_pack['name'],
    181                  data_pack['pack_url']
    182          )
    183          gmGuiHelpers.gm_show_info(msg, _('Installing data pack'))
    184
    185          return True
    186  #----------------------------------------------------------------
    187 -def load_data_packs_list():
    188
    189          dbcfg = gmCfg.cCfgSQL()
    190          dpl_url = dbcfg.get2 (
    191                  option = dpl_url_option,
    192                  workplace = gmSurgery.gmCurrentPractice().active_workplace,
    193                  bias = 'workplace',
    194                  default = default_dpl_url
    195          )
    196
    197          items = []
    198          data = []
    199
    200          dpl_fname = gmNetworkTools.download_data_packs_list(dpl_url)
    201          if dpl_fname is None:
    202                  return (items, data)
    203          try:
    204                  _cfg.add_file_source(source = 'data-packs', file = dpl_fname)
    205          except (UnicodeDecodeError):
    206                  _log.exception("cannot read data pack list from [%s]", dpl_fname)
    207                  return (items, data)
    208
    209          packs = _cfg.get('data packs', 'data packs', source_order = [('data-packs', 'return')])
    210          if packs is None:
    211                  _log.info('no data packs listed in data packs list file')
    212                  _cfg.remove_source('data-packs')
    213                  return (items, data)
    214
    215          for pack in packs:
    216                  _log.debug('reading pack [%s] metadata', pack)
    217                  pack_group = u'pack %s' % pack
    218                  name = _cfg.get(pack_group, u'name', source_order = [('data-packs', 'return')])
    219                  pack_url = _cfg.get(pack_group, u'URL', source_order = [('data-packs', 'return')])
    220                  md5_url = pack_url + u'.md5'
    221                  db_min = _cfg.get(pack_group, u'minimum database version', source_order = [('data-packs', 'return')])
    222                  converted, db_min = gmTools.input2int (
    223                          db_min,
    224                          # here we introduced data packs:
    225                          #16,
    226                          0,
    227                          # no use looking at data packs requiring a database > the current database:
    228                          _cfg.get(option = 'database_version')
    229                  )
    230                  if not converted:
    231                          _log.error('cannot convert minimum database version [%s]', db_min)
    232                          continue
    233
    234                  db_max = _cfg.get(pack_group, u'maximum database version', source_order = [('data-packs', 'return')])
    235                  if db_max is None:
    236                          db_max = sys.maxint
    237                  converted, db_max = gmTools.input2int (
    238                          db_max,
    239                          db_min          # max version must be at least db_min
    240                  )
    241                  if not converted:
    242                          _log.error('cannot convert maximum database version [%s]', db_max)
    243                          continue
    244
    245                  if _cfg.get(option = 'database_version') < db_min:
    246                          _log.error('ignoring data pack: current database version (%s) < minimum required database version (%s)', _cfg.get(option = 'database_version'), db_min)
    247                          continue
    248
    249                  if _cfg.get(option = 'database_version') > db_max:
    250                          _log.error('ignoring data pack: current database version (%s) > maximum allowable database version (%s)', _cfg.get(option = 'database_version'), db_max)
    251                          continue
    252
    253                  items.append([name, u'v%s' % db_min, u'v%s' % db_max, pack_url])
    254                  data.append ({
    255                          'name': name,
    256                          'pack_url': pack_url,
    257                          'md5_url': md5_url,
    258                          'db_min': db_min,
    259                          'db_max': db_max
    260                  })
    261
    262          _cfg.remove_source('data-packs')
    263          return (items, data)
    264  #----------------------------------------------------------------
    265 -def manage_data_packs(parent=None):
    266
    267          if parent is None:
    268                  parent = wx.GetApp().GetTopWindow()
    269
    270          #--------------------------------------------
    271          def validate_url(url):
    272                  return True, url
    273          #--------------------------------------------
    274          def configure_dpl_url(item):
    275                  gmCfgWidgets.configure_string_option (
    276                          parent = parent,
    277                          message = _(
    278                                  'Please enter the URL under which to load\n'
    279                                  'the list of available data packs.\n'
    280                                  '\n'
    281                                  'The default URL is:\n'
    282                                  '\n'
    283                                  ' [%s]\n'
    284                          ) % default_dpl_url,
    285                          option = dpl_url_option,
    286                          bias = u'workplace',
    287                          default_value = default_dpl_url,
    288                          validator = validate_url
    289                  )
    290                  return True
    291          #--------------------------------------------
    292          def refresh(lctrl):
    293                  items, data = load_data_packs_list()
    294                  lctrl.set_string_items(items)
    295                  lctrl.set_data(data)
    296          #--------------------------------------------
    297          lb_tt = _(
    298                  'Install the selected data pack.\n'
    299                  '\n'
    300                  'This can take quite a while depending on\n'
    301                  'the amount of data to be installed.\n'
    302                  '\n'
    303                  'GNUmed will block until installation is\n'
    304                  'complete and eventually inform you of\n'
    305                  'success or failure.'
    306          )
    307          gmListWidgets.get_choices_from_list (
    308                  parent = parent,
    309                  msg = _(
    310                          'Data packs available for installation into this v%s database.\n'
    311                  ) % (
    312                          _cfg.get(option = 'database_version')
    313                  ),
    314                  caption = _('Showing data packs.'),
    315                  columns = [ _('Data pack'), _('min DB'), _('max DB'), _('Source') ],
    316                  single_selection = True,
    317                  can_return_empty = False,
    318                  ignore_OK_button = True,
    319                  refresh_callback = refresh,
    320                  left_extra_button = (
    321                          _('&Install'),
    322                          lb_tt,
    323                          install_data_pack
    324                  ),
    325  #               middle_extra_button=None,
    326                  right_extra_button = (
    327                          _('&Configure'),
    328                          _('Configure the data packs list source'),
    329                          configure_dpl_url
    330                  )
    331          )
    332
    333  #================================================================
    334  # main
    335  #----------------------------------------------------------------
    336  if __name__ == '__main__':
    337
    338          if len(sys.argv) < 2:
    339                  sys.exit()
    340
    341          if sys.argv[1] != 'test':
    342                  sys.exit()
    343
    344          from Gnumed.pycommon import gmI18N
    345          gmI18N.activate_locale()
    346          gmI18N.install_domain()
    347  #       from Gnumed.pycommon import gmPG2
    348
    349          #--------------------------------------------------------
    350  #       def test_generic_codes_prw():
    351  #               gmPG2.get_connection()
    352  #               app = wx.PyWidgetTester(size = (500, 40))
    353  #               pw = cGenericCodesPhraseWheel(app.frame, -1)
    354  #               #pw.set_context(context = u'zip', val = u'04318')
    355  #               app.frame.Show(True)
    356  #               app.MainLoop()
    357  #       #--------------------------------------------------------
    358  #       test_generic_codes_prw()
    359
    360  #================================================================
    361