def configure_string_option(parent=None, message=None, option=None, bias='user', default_value='', validator=None): dbcfg = gmCfg.cCfgSQL() current_value = dbcfg.get2 ( option = option, workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = bias, default = default_value ) if current_value is not None: current_value = '%s' % current_value if parent is None: parent = wx.GetApp().GetTopWindow() if validator is None: validator = lambda in_val: (True, in_val) while True: dlg = wx.TextEntryDialog ( parent, message, caption = _('Configuration'), value = gmTools.coalesce(current_value, ''), style = wx.OK | wx.CANCEL | wx.CENTRE ) result = dlg.ShowModal() if result == wx.ID_CANCEL: dlg.DestroyLater() return None user_val = dlg.GetValue().strip() dlg.DestroyLater() if user_val == current_value: return user_val validated, user_val = validator(user_val) if validated: break gmDispatcher.send ( signal = 'statustext', msg = _('Value [%s] not valid for option <%s>.') % (user_val, option), beep = True ) dbcfg = gmCfg.cCfgSQL() dbcfg.set ( workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, option = option, value = user_val ) return user_val
def configure_string_from_list_option(parent=None, message=None, option=None, bias='user', default_value='', choices=None, columns=None, data=None, caption=None): dbcfg = gmCfg.cCfgSQL() current_value = dbcfg.get2( option=option, workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias=bias, default=default_value) if parent is None: parent = wx.GetApp().GetTopWindow() if caption is None: caption = _('Configuration') selections = None if current_value is not None: try: selections = [choices.index(current_value)] except ValueError: pass choice = gmListWidgets.get_choices_from_list(parent=parent, msg=message, caption=caption, choices=choices, columns=columns, data=data, selections=selections, single_selection=True, can_return_empty=False) # aborted if choice is None: return # same value selected again if choice == current_value: return dbcfg = gmCfg.cCfgSQL() dbcfg.set(workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, option=option, value=choice) return
def configure_string_option(parent=None, message=None, option=None, bias='user', default_value='', validator=None): dbcfg = gmCfg.cCfgSQL() current_value = dbcfg.get2 ( option = option, workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = bias, default = default_value ) if current_value is not None: current_value = '%s' % current_value if parent is None: parent = wx.GetApp().GetTopWindow() while True: dlg = wx.TextEntryDialog ( parent, message, caption = _('Configuration'), value = gmTools.coalesce(current_value, ''), style = wx.OK | wx.CANCEL | wx.CENTRE ) result = dlg.ShowModal() if result == wx.ID_CANCEL: dlg.DestroyLater() return None user_val = dlg.GetValue().strip() dlg.DestroyLater() if user_val == current_value: return user_val validated, user_val = validator(user_val) if validated: break gmDispatcher.send ( signal = 'statustext', msg = _('Value [%s] not valid for option <%s>.') % (user_val, option), beep = True ) dbcfg = gmCfg.cCfgSQL() dbcfg.set ( workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, option = option, value = user_val ) return user_val
def configure_string_from_list_option(parent=None, message=None, option=None, bias='user', default_value='', choices=None, columns=None, data=None, caption=None): dbcfg = gmCfg.cCfgSQL() current_value = dbcfg.get2 ( option = option, workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = bias, default = default_value ) if parent is None: parent = wx.GetApp().GetTopWindow() if caption is None: caption = _('Configuration') selections = None if current_value is not None: try: selections = [choices.index(current_value)] except ValueError: pass choice = gmListWidgets.get_choices_from_list ( parent = parent, msg = message, caption = caption, choices = choices, columns = columns, data = data, selections = selections, single_selection = True, can_return_empty = False ) # aborted if choice is None: return # same value selected again if choice == current_value: return dbcfg = gmCfg.cCfgSQL() dbcfg.set ( workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, option = option, value = choice ) return
def clone(workplace=None): if workplace is None: return False new_name = wx.GetTextFromUser ( message = _('Enter a name for the new workplace !'), caption = _('Cloning workplace'), default_value = '%s-2' % workplace, parent = parent ).strip() if new_name == '': return False dbcfg = gmCfg.cCfgSQL() opt = 'horstspace.notebook.plugin_load_order' plugins = dbcfg.get2 ( option = opt, workplace = workplace, bias = 'workplace' ) dbcfg.set ( option = opt, value = plugins, workplace = new_name ) # FIXME: clone cfg, too return True
def _check_birthday(patient=None): if patient['dob'] is None: return dbcfg = gmCfg.cCfgSQL() dob_distance = dbcfg.get2 ( option = 'patient_search.dob_warn_interval', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = '1 week' ) if not patient.dob_in_range(dob_distance, dob_distance): return now = gmDateTime.pydt_now_here() enc = gmI18N.get_encoding() msg = _('%(pat)s turns %(age)s on %(month)s %(day)s ! (today is %(month_now)s %(day_now)s)') % { 'pat': patient.get_description_gender(), 'age': patient.get_medical_age().strip('y'), 'month': patient.get_formatted_dob(format = '%B'), 'day': patient.get_formatted_dob(format = '%d'), 'month_now': gmDateTime.pydt_strftime(now, '%B', gmDateTime.acc_months), 'day_now': gmDateTime.pydt_strftime(now, '%d', gmDateTime.acc_days) } gmDispatcher.send(signal = 'statustext', msg = msg)
def __on_add_unassociated(self, evt): """Add new editor for as-yet unassociated progress note. Clinical logic as per discussion with Jim Busser: - if patient has no episodes: - new patient - always allow several NEWs - if patient has episodes: - allow several NEWs per configuration """ emr = self.__pat.emr epis = emr.get_episodes() if len(epis) == 0: value = True else: dbcfg = gmCfg.cCfgSQL() value = bool(dbcfg.get2 ( option = 'horstspace.soap_editor.allow_same_episode_multiple_times', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = False )) self.__soap_notebook.add_editor(allow_same_problem = value)
def delete(item): delete_it = gmGuiHelpers.gm_show_question ( aTitle = _('Deleting option'), aMessage = '%s\n\n%s %s (#%s) %s\n\n%s\n\n%s' % ( tooltip(item), gmTools.u_box_horiz_single * 3, item['option'], item['pk_cfg_item'], gmTools.u_box_horiz_single * 3, _('Do you really want to delete this option ?'), _('(GNUmed will re-create options as needed.)') ) ) if not delete_it: return False from Gnumed.wxpython.gmAuthWidgets import get_dbowner_connection conn = get_dbowner_connection(procedure = _('Deleting option')) if conn is None: gmDispatcher.send(signal = 'statustext', msg = _('Cannot connect as database owner. Unable to delete option.')) return False cfg = gmCfg.cCfgSQL() cfg.delete(conn = conn, pk_option = item['pk_cfg_item']) return True
def check_for_updates(): dbcfg = gmCfg.cCfgSQL() url = dbcfg.get2 ( option = u'horstspace.update.url', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'workplace', default = u'http://www.gnumed.de/downloads/gnumed-versions.txt' ) consider_latest_branch = bool(dbcfg.get2 ( option = u'horstspace.update.consider_latest_branch', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'workplace', default = True )) _cfg = gmCfg2.gmCfgData() found, msg = gmNetworkTools.check_for_update ( url = url, current_branch = _cfg.get(option = 'client_branch'), current_version = _cfg.get(option = 'client_version'), consider_latest_branch = consider_latest_branch ) if found is False: gmDispatcher.send(signal = 'statustext', msg = _('Your client (%s) is up to date.') % _cfg.get(option = 'client_version')) return gmGuiHelpers.gm_show_info ( msg, _('Checking for client updates') )
def _on_problem_activated(self, event): """Open progress note editor for this problem. """ problem = self._LCTRL_active_problems.get_selected_item_data(only_one = True) if problem is None: return True dbcfg = gmCfg.cCfgSQL() allow_duplicate_editors = bool(dbcfg.get2 ( option = 'horstspace.soap_editor.allow_same_episode_multiple_times', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = False )) if self._PNL_editors.add_editor(problem = problem, allow_same_problem = allow_duplicate_editors): return True gmGuiHelpers.gm_show_error ( aMessage = _( 'Cannot open progress note editor for\n\n' '[%s].\n\n' ) % problem['problem'], aTitle = _('opening progress note editor') ) return False
def __on_add_unassociated(self, evt): """Add new editor for as-yet unassociated progress note. Clinical logic as per discussion with Jim Busser: - if patient has no episodes: - new patient - always allow several NEWs - if patient has episodes: - allow several NEWs per configuration """ emr = self.__pat.emr epis = emr.get_episodes() if len(epis) == 0: value = True else: dbcfg = gmCfg.cCfgSQL() value = bool( dbcfg.get2( option= 'horstspace.soap_editor.allow_same_episode_multiple_times', workplace=gmPraxis.gmCurrentPraxisBranch( ).active_workplace, bias='user', default=False)) self.__soap_notebook.add_editor(allow_same_problem=value)
def __get_lab_panel(self): # get panel to use dbcfg = gmCfg.cCfgSQL() pk_panel = dbcfg.get2( option=u'horstspace.top_panel.lab_panel', workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias='user') if pk_panel is None: return None try: panel = gmPathLab.cTestPanel(aPK_obj=pk_panel) except gmExceptions.ConstructorError: _log.exception('cannot load configured test panel') panel = None if panel is not None: return panel _log.error( 'Cannot load test panel [#%s] configured for patient pane (horstspace.top_panel.lab_panel).', pk_panel) gmGuiHelpers.gm_show_error( title=_('GNUmed startup'), error=_('Cannot load test panel [#%s] configured\n' 'for the top pane with option\n' '\n' ' <horstspace.top_panel.lab_panel>\n' '\n' 'Please reconfigure.') % pk_panel) return None
def _check_birthday(patient=None): if patient['dob'] is None: return dbcfg = gmCfg.cCfgSQL() dob_distance = dbcfg.get2 ( option = 'patient_search.dob_warn_interval', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = '1 week' ) if not patient.dob_in_range(dob_distance, dob_distance): return now = gmDateTime.pydt_now_here() msg = _('%(pat)s turns %(age)s on %(month)s %(day)s ! (today is %(month_now)s %(day_now)s)') % { 'pat': patient.get_description_gender(), 'age': patient.get_medical_age(at_date = patient.birthday_this_year).strip('y'), 'month': patient.get_formatted_dob(format = '%B'), 'day': patient.get_formatted_dob(format = '%d'), 'month_now': gmDateTime.pydt_strftime(now, '%B', gmDateTime.acc_months), 'day_now': gmDateTime.pydt_strftime(now, '%d', gmDateTime.acc_days) } gmDispatcher.send(signal = 'statustext', msg = msg)
def __init__ (self, *args, **kwargs): cPersonSearchCtrl.__init__(self, *args, **kwargs) # get configuration cfg = gmCfg.cCfgSQL() self.__always_dismiss_on_search = bool ( cfg.get2 ( option = 'patient_search.always_dismiss_previous_patient', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = 0 ) ) self.__always_reload_after_search = bool ( cfg.get2 ( option = 'patient_search.always_reload_new_patient', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = 0 ) ) self.__register_events()
def clone(workplace=None): if workplace is None: return False new_name = wx.GetTextFromUser ( message = _('Enter a name for the new workplace !'), caption = _('Cloning workplace'), default_value = u'%s-2' % workplace, parent = parent ).strip() if new_name == u'': return False dbcfg = gmCfg.cCfgSQL() opt = u'horstspace.notebook.plugin_load_order' plugins = dbcfg.get2 ( option = opt, workplace = workplace, bias = 'workplace' ) dbcfg.set ( option = opt, value = plugins, workplace = new_name ) # FIXME: clone cfg, too return True
def __init__(self, *args, **kwargs): try: self.problem = kwargs['problem'] del kwargs['problem'] except KeyError: self.problem = None wxgProgressNotesEAPnl.wxgProgressNotesEAPnl.__init__(self, *args, **kwargs) dbcfg = gmCfg.cCfgSQL() self.__use_soap_fields = bool(dbcfg.get2 ( option = 'horstspace.soap_editor.use_one_field_per_soap_category', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = True )) self.__soap_fields = [ self._TCTRL_Soap, self._TCTRL_sOap, self._TCTRL_soAp, self._TCTRL_soaP ] self.__init_ui() self.__register_interests() return
def __init_ui(self): cfg = gmCfg2.gmCfgData() if cfg.get(option='slave'): self._TCTRL_patient_selector.SetEditable(0) self._TCTRL_patient_selector.SetToolTip(None) if sys.platform == 'darwin': _log.debug('adjusting font size on Mac for top panel parts') for ctrl in [ self._TCTRL_patient_selector, self._LBL_age, self._LBL_allergies, self._TCTRL_allergies ]: curr_font = ctrl.GetFont() mac_font = wx.Font(curr_font.GetNativeFontInfo()) mac_font.SetPointSize(pointSize=int(curr_font.GetPointSize() / 0.8)) ctrl.SetFont(mac_font) # get panel to use dbcfg = gmCfg.cCfgSQL() pk_panel = dbcfg.get2( option='horstspace.top_panel.lab_panel', workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias='user') if pk_panel is None: self.__lab_panel = None else: self.__lab_panel = gmPathLab.cTestPanel(aPK_obj=pk_panel)
def __init_ui(self): cfg = gmCfg2.gmCfgData() if cfg.get(option = 'slave'): self._TCTRL_patient_selector.SetEditable(0) self._TCTRL_patient_selector.SetToolTip(None) if sys.platform == u'darwin': _log.debug('adjusting font size on Mac for top panel parts') for ctrl in [self._TCTRL_patient_selector, self._LBL_age, self._LBL_allergies, self._TCTRL_allergies]: curr_font = ctrl.GetFont() mac_font = wx.FontFromNativeInfo(curr_font.NativeFontInfo) mac_font.SetPointSize(pointSize = int(curr_font.GetPointSize() / 0.8)) ctrl.SetFont(mac_font) # get panel to use dbcfg = gmCfg.cCfgSQL() pk_panel = dbcfg.get2 ( option = u'horstspace.top_panel.lab_panel', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user' ) if pk_panel is None: self.__lab_panel = None else: self.__lab_panel = gmPathLab.cTestPanel(aPK_obj = pk_panel)
def _get_update_status(): dbcfg = gmCfg.cCfgSQL() url = dbcfg.get2 ( option = 'horstspace.update.url', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'workplace', default = 'http://www.gnumed.de/downloads/gnumed-versions.txt' ) consider_latest_branch = bool(dbcfg.get2 ( option = 'horstspace.update.consider_latest_branch', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'workplace', default = True )) _cfg = gmCfg2.gmCfgData() update_found, msg = gmNetworkTools.check_for_update ( url = url, current_branch = _cfg.get(option = 'client_branch'), current_version = _cfg.get(option = 'client_version'), consider_latest_branch = consider_latest_branch ) return update_found, msg
def _on_post_patient_selection(self, **kwargs): db_cfg = gmCfg.cCfgSQL() default_plugin = db_cfg.get2( option='patient_search.plugin_to_raise_after_search', workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias='user', default='gmPatientOverviewPlugin') gmDispatcher.send(signal='display_widget', name=default_plugin)
def edit_old(workplace=None): available_plugins = gmPlugin.get_installed_plugins(plugin_dir='gui') dbcfg = gmCfg.cCfgSQL() if workplace is None: dlg = wx.TextEntryDialog( parent=parent, message=_('Enter a descriptive name for the new workplace:'), caption=_('Configuring GNUmed workplaces ...'), defaultValue=u'', style=wx.OK | wx.CENTRE) dlg.ShowModal() workplace = dlg.GetValue().strip() if workplace == u'': gmGuiHelpers.gm_show_error( _('Cannot save a new workplace without a name.'), _('Configuring GNUmed workplaces ...')) return False curr_plugins = [] choices = available_plugins else: curr_plugins = gmTools.coalesce( dbcfg.get2(option=u'horstspace.notebook.plugin_load_order', workplace=workplace, bias='workplace'), []) choices = curr_plugins[:] for p in available_plugins: if p not in choices: choices.append(p) sels = range(len(curr_plugins)) new_plugins = gmListWidgets.get_choices_from_list( parent=parent, msg=_('\n' 'Select the plugin(s) to be loaded the next time\n' 'the client is restarted under the workplace:\n' '\n' ' [%s]' '\n') % workplace, caption=_('Configuring GNUmed workplaces ...'), choices=choices, selections=sels, columns=[_('Plugins')], single_selection=False) if new_plugins == curr_plugins: return True if new_plugins is None: return True dbcfg.set(option=u'horstspace.notebook.plugin_load_order', value=new_plugins, workplace=workplace) return True
def create_new_person(parent=None, activate=False): if parent is None: parent = wx.GetApp().GetTopWindow() if activate: # meaning we will switch away from the current patient if any msg = _('Before creating a new person review the encounter details\n' 'of the patient you just worked on:\n') gmEncounterWidgets.sanity_check_encounter_of_active_patient( parent=parent, msg=msg) msg = _( 'Edit the current encounter of the patient you are ABOUT TO LEAVE:' ) dbcfg = gmCfg.cCfgSQL() def_region = dbcfg.get2( option='person.create.default_region', workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias='user') def_country = None if def_region is None: def_country = dbcfg.get2( option='person.create.default_country', workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias='user') else: countries = gmDemographicRecord.get_country_for_region( region=def_region) if len(countries) == 1: def_country = countries[0]['code_country'] ea = cNewPatientEAPnl(parent, -1, country=def_country, region=def_region) dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area=ea, single_entry=True) dlg.SetTitle(_('Adding new person')) ea._PRW_lastname.SetFocus() result = dlg.ShowModal() pat = ea.data dlg.Destroy() if result != wx.ID_OK: return False _log.debug('created new person [%s]', pat.ID) if activate: from Gnumed.wxpython import gmPatSearchWidgets gmPatSearchWidgets.set_active_patient(patient=pat) gmDispatcher.send(signal='display_widget', name='gmNotebookedPatientEditionPlugin') return True
def _on_post_patient_selection(self, **kwargs): db_cfg = gmCfg.cCfgSQL() default_plugin = db_cfg.get2 ( option = u'patient_search.plugin_to_raise_after_search', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = u'user', default = u'gmPatientOverviewPlugin' ) gmDispatcher.send(signal = 'display_widget', name = default_plugin)
def _on_char(self, evt): """True: patient was selected. False: no patient was selected. """ keycode = evt.GetKeyCode() # list of previously active patients if keycode == wx.WXK_DOWN: evt.Skip() if len(self.__prev_idents) == 0: return False dlg = cSelectPersonFromListDlg(wx.GetTopLevelParent(self), -1) dlg.set_persons(persons = self.__prev_idents) result = dlg.ShowModal() if result == wx.ID_OK: wx.BeginBusyCursor() self.person = dlg.get_selected_person() dlg.DestroyLater() wx.EndBusyCursor() return True dlg.DestroyLater() return False # recall previous search fragment if keycode == wx.WXK_UP: evt.Skip() # FIXME: cycling through previous fragments if self._prev_search_term is not None: self.SetValue(self._prev_search_term) return False # invoke external patient sources if keycode == wx.WXK_F2: evt.Skip() dbcfg = gmCfg.cCfgSQL() search_immediately = bool(dbcfg.get2 ( option = 'patient_search.external_sources.immediately_search_if_single_source', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = 0 )) p = get_person_from_external_sources ( parent = wx.GetTopLevelParent(self), search_immediately = search_immediately ) if p is not None: self.person = p return True return False # FIXME: invoke add new person # FIXME: add popup menu apart from system one evt.Skip()
def __init__(self, aUser=None, aWorkplace='xxxDEFAULTxxx'): """ Init DB connection""" ConfigData.__init__(self, "DB") # connect to config database if ConfigDataDB._dbcfg is None: ConfigDataDB._dbcfg = gmCfg.cCfgSQL() self.mUser = aUser self.mWorkplace = aWorkplace
def __init__(self, aUser = None, aWorkplace = 'xxxDEFAULTxxx'): """ Init DB connection""" ConfigData.__init__(self,"DB") # connect to config database if ConfigDataDB._dbcfg is None: ConfigDataDB._dbcfg = gmCfg.cCfgSQL() self.mUser = aUser self.mWorkplace = aWorkplace
def browse2schedules(vaccination=None): dbcfg = gmCfg.cCfgSQL() url = dbcfg.get2 ( option = 'external.urls.vaccination_plans', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = gmVaccination.URL_vaccination_plan ) gmNetworkTools.open_url_in_browser(url = url) return False
def browse2schedules(vaccination=None): dbcfg = gmCfg.cCfgSQL() url = dbcfg.get2 ( option = 'external.urls.vaccination_plans', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = u'http://www.bundesaerztekammer.de/downloads/STIKOEmpf2011.pdf' ) gmNetworkTools.open_url_in_browser(url = url) return False
def create_new_person(parent=None, activate=False): if parent is None: parent = wx.GetApp().GetTopWindow() if activate: # meaning we will switch away from the current patient if any msg = _( 'Before creating a new person review the encounter details\n' 'of the patient you just worked on:\n' ) gmEncounterWidgets.sanity_check_encounter_of_active_patient(parent = parent, msg = msg) msg = _('Edit the current encounter of the patient you are ABOUT TO LEAVE:') dbcfg = gmCfg.cCfgSQL() def_region = dbcfg.get2 ( option = 'person.create.default_region', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user' ) def_country = None if def_region is None: def_country = dbcfg.get2 ( option = 'person.create.default_country', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user' ) else: countries = gmDemographicRecord.get_country_for_region(region = def_region) if len(countries) == 1: def_country = countries[0]['code_country'] ea = cNewPatientEAPnl(parent, -1, country = def_country, region = def_region) dlg = gmEditArea.cGenericEditAreaDlg2(parent, -1, edit_area = ea, single_entry = True) dlg.SetTitle(_('Adding new person')) ea._PRW_lastname.SetFocus() result = dlg.ShowModal() pat = ea.data dlg.DestroyLater() if result != wx.ID_OK: return False _log.debug('created new person [%s]', pat.ID) if activate: from Gnumed.wxpython import gmPatSearchWidgets gmPatSearchWidgets.set_active_patient(patient = pat) gmDispatcher.send(signal = 'display_widget', name = 'gmNotebookedPatientEditionPlugin') return True
def edit(workplace=None): dbcfg = gmCfg.cCfgSQL() if workplace is None: dlg = wx.TextEntryDialog( parent=parent, message=_('Enter a descriptive name for the new workplace:'), caption=_('Configuring GNUmed workplaces ...'), defaultValue=u'', style=wx.OK | wx.CENTRE) dlg.ShowModal() workplace = dlg.GetValue().strip() if workplace == u'': gmGuiHelpers.gm_show_error( _('Cannot save a new workplace without a name.'), _('Configuring GNUmed workplaces ...')) return False curr_plugins = [] else: curr_plugins = gmTools.coalesce( dbcfg.get2(option=u'horstspace.notebook.plugin_load_order', workplace=workplace, bias='workplace'), []) msg = _( 'Pick the plugin(s) to be loaded the next time the client is restarted under the workplace:\n' '\n' ' [%s]\n') % workplace picker = gmListWidgets.cItemPickerDlg( parent, -1, title=_('Configuring workplace plugins ...'), msg=msg) picker.set_columns(['Available plugins'], ['Active plugins']) available_plugins = gmPlugin.get_installed_plugins(plugin_dir='gui') picker.set_choices(available_plugins) picker.set_picks(picks=curr_plugins[:]) btn_pressed = picker.ShowModal() if btn_pressed != wx.ID_OK: picker.Destroy() return False new_plugins = picker.get_picks() picker.Destroy() if new_plugins == curr_plugins: return True if new_plugins is None: return True dbcfg.set(option=u'horstspace.notebook.plugin_load_order', value=new_plugins, workplace=workplace) return True
def _on_report_button_pressed(self, event): event.Skip() dbcfg = gmCfg.cCfgSQL() url = dbcfg.get2 ( option = 'external.urls.report_vaccine_ADR', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user' ) if url.strip() == '': url = dbcfg.get2 ( option = 'external.urls.report_ADR', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user' ) gmNetworkTools.open_url_in_browser(url = url)
def __init__(self, parent, id): """Set up our specialised grid. """ # get connection self.__backend = gmPG.ConnectionPool() self.__defconn = self.__backend.GetConnection('blobs') if self.__defconn is None: _log.Log(gmLog.lErr, "Cannot retrieve lab data without database connection !") raise gmExceptions.ConstructorError, "cLabDataGrid.__init__(): need db conn" # connect to config database self.__dbcfg = gmCfg.cCfgSQL( aConn = self.__backend.GetConnection('default'), aDBAPI = gmPG.dbapi ) wx.Grid.__init__( self, parent, id, pos = wx.DefaultPosition, size = wx.DefaultSize, style= wx.WANTS_CHARS ) self.__pat = gmPerson.gmCurrentPatient() #wx.EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick) # create new grid self.__grid_unreviewed_results = self.CreateGrid(0, 0, wx.Grid.wx.GridSelectCells ) self.SetDefaultCellAlignment(wx.ALIGN_RIGHT,wx.ALIGN_CENTRE) #renderer = apply(wxGridCellStringRenderer, ()) renderer = apply(cLabDataGridCellRenderer, ()) self.SetDefaultRenderer(renderer) # There is a bug in wxGTK for this method... self.AutoSizeColumns(True) self.AutoSizeRows(True) # attribute objects let you keep a set of formatting values # in one spot, and reuse them if needed font = self.GetFont() #font.SetWeight(wx.BOLD) attr = wx.GridCellAttr() attr.SetFont(font) #attr.SetBackgroundColour(wx.LIGHT_GREY) attr.SetReadOnly(True)
def new(): cfg_db = gmCfg.cCfgSQL() enc_type = cfg_db.get2 ( option = u'encounter.default_type', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = u'user' ) if enc_type is None: enc_type = gmEMRStructItems.get_most_commonly_used_encounter_type() if enc_type is None: enc_type = u'in surgery' enc = gmEMRStructItems.create_encounter(fk_patient = patient.ID, enc_type = enc_type) saved = edit_encounter(parent = parent, encounter = enc) if saved: return True gmEMRStructItems.delete_encounter(pk_encounter = enc['pk_encounter']) return False
def GetPluginLoadList(option, plugin_dir = '', defaults = None, workplace=None): """Get a list of plugins to load. 1) from database if option is not None 2) from list of defaults 3) if 2 is None, from source directory (then stored in database) FIXME: NOT from files in directories (important for py2exe) """ if workplace == 'System Fallback': return ['gmProviderInboxPlugin', 'gmDataMiningPlugin'] if workplace is None: workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace p_list = None if option is not None: dbcfg = gmCfg.cCfgSQL() p_list = dbcfg.get2 ( option = option, workplace = workplace, bias = 'workplace', default = defaults ) if p_list is not None: return p_list if defaults is None: p_list = get_installed_plugins(plugin_dir = plugin_dir) if (len(p_list) == 0): _log.error('cannot find plugins by scanning plugin directory ?!?') return defaults else: p_list = defaults # store for current user/current workplace dbcfg.set ( option = option, value = p_list, workplace = workplace ) _log.debug("plugin load list stored: %s" % str(p_list)) return p_list
def _on_report_button_pressed(self, event): event.Skip() dbcfg = gmCfg.cCfgSQL() url = dbcfg.get2 ( option = u'external.urls.report_vaccine_ADR', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = u'user', default = u'http://www.pei.de/cln_042/SharedDocs/Downloads/fachkreise/uaw/meldeboegen/b-ifsg-meldebogen,templateId=raw,property=publicationFile.pdf/b-ifsg-meldebogen.pdf' ) if url.strip() == u'': url = dbcfg.get2 ( option = u'external.urls.report_ADR', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = u'user' ) gmNetworkTools.open_url_in_browser(url = url)
def load_persons_from_kvks(): dbcfg = gmCfg.cCfgSQL() kvk_dir = os.path.abspath(os.path.expanduser(dbcfg.get2 ( option = 'DE.KVK.spool_dir', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'workplace', default = '/var/spool/kvkd/' #default = u'/home/ncq/gnumed/' ))) dtos = [] for dto in gmKVK.get_available_kvks_as_dtos(spool_dir = kvk_dir): dtos.append({'dto': dto, 'source': 'KVK'}) # for dto in gmKVK.get_available_CCRdr_files_as_dtos(spool_dir = kvk_dir): # dtos.append({'dto': dto, 'source': dto.source}) return dtos
def configure_list_from_list_option(parent=None, message=None, option=None, bias='user', default_value=None, choices=None, columns=None, data=None, caption=None, picks=None): if default_value is None: default_value = [] dbcfg = gmCfg.cCfgSQL() current_value = dbcfg.get2( option=option, workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias=bias, default=default_value) if parent is None: parent = wx.GetApp().GetTopWindow() if caption is None: caption = _('Configuration') # setup item picker picker = gmListWidgets.cItemPickerDlg(parent, -1, msg=message) picker.set_columns(columns) picker.set_choices(choices) picker.set_picks(picks) result = picker.ShowModal() if result == wx.ID_CANCEL: picker.DestroyLater() return picks = picker.get_picks() picker.DestroyLater() dbcfg.set(workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, option=option, value=picks) return
def new(): cfg_db = gmCfg.cCfgSQL() enc_type = cfg_db.get2( option=u'encounter.default_type', workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias=u'user') if enc_type is None: enc_type = gmEMRStructItems.get_most_commonly_used_encounter_type() if enc_type is None: enc_type = u'in surgery' enc = gmEMRStructItems.create_encounter(fk_patient=patient.ID, enc_type=enc_type) saved = edit_encounter(parent=parent, encounter=enc) if saved: return True gmEMRStructItems.delete_encounter(pk_encounter=enc['pk_encounter']) return False
def configure_boolean_option(parent=None, question=None, option=None, button_tooltips=None): if parent is None: parent = wx.GetApp().GetTopWindow() tooltips = [ _('Set "%s" to <True>.') % option, _('Set "%s" to <False>.') % option, _('Abort the dialog and do not change the current setting.') ] if button_tooltips is not None: for idx in range(len(button_tooltips)): tooltips[idx] = button_tooltips[idx] dlg = gmGuiHelpers.c3ButtonQuestionDlg(parent, -1, caption=_('Configuration'), question=question, button_defs=[{ 'label': _('Yes'), 'tooltip': tooltips[0] }, { 'label': _('No'), 'tooltip': tooltips[1] }, { 'label': _('Cancel'), 'tooltip': tooltips[2], 'default': True }]) decision = dlg.ShowModal() dbcfg = gmCfg.cCfgSQL() if decision == wx.ID_YES: dbcfg.set(workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, option=option, value=True) elif decision == wx.ID_NO: dbcfg.set(workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, option=option, value=False) return
def configure_boolean_option(parent=None, question=None, option=None, button_tooltips=None): if parent is None: parent = wx.GetApp().GetTopWindow() tooltips = [ _('Set "%s" to <True>.') % option, _('Set "%s" to <False>.') % option, _('Abort the dialog and do not change the current setting.') ] if button_tooltips is not None: for idx in range(len(button_tooltips)): tooltips[idx] = button_tooltips[idx] dlg = gmGuiHelpers.c3ButtonQuestionDlg ( parent, -1, caption = _('Configuration'), question = question, button_defs = [ {'label': _('Yes'), 'tooltip': tooltips[0]}, {'label': _('No'), 'tooltip': tooltips[1]}, {'label': _('Cancel'), 'tooltip': tooltips[2], 'default': True} ] ) decision = dlg.ShowModal() dbcfg = gmCfg.cCfgSQL() if decision == wx.ID_YES: dbcfg.set ( workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, option = option, value = True ) elif decision == wx.ID_NO: dbcfg.set ( workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, option = option, value = False ) return
def GetPluginLoadList(option, plugin_dir='', defaults=None, workplace=None): """Get a list of plugins to load. 1) from database if option is not None 2) from list of defaults 3) if 2 is None, from source directory (then stored in database) FIXME: NOT from files in directories (important for py2exe) """ if workplace == 'System Fallback': return ['gmProviderInboxPlugin', 'gmDataMiningPlugin'] if workplace is None: workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace p_list = None if option is not None: dbcfg = gmCfg.cCfgSQL() p_list = dbcfg.get2(option=option, workplace=workplace, bias='workplace', default=defaults) if p_list is not None: return p_list if defaults is None: p_list = get_installed_plugins(plugin_dir=plugin_dir) if (len(p_list) == 0): _log.error('cannot find plugins by scanning plugin directory ?!?') return defaults else: p_list = defaults # store for current user/current workplace dbcfg.set(option=option, value=p_list, workplace=workplace) _log.debug("plugin load list stored: %s" % str(p_list)) return p_list
def configure_list_from_list_option(parent=None, message=None, option=None, bias='user', default_value=None, choices=None, columns=None, data=None, caption=None, picks=None): if default_value is None: default_value = [] dbcfg = gmCfg.cCfgSQL() current_value = dbcfg.get2 ( option = option, workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = bias, default = default_value ) if parent is None: parent = wx.GetApp().GetTopWindow() if caption is None: caption = _('Configuration') # setup item picker picker = gmListWidgets.cItemPickerDlg(parent, -1, msg = message) picker.set_columns(columns) picker.set_choices(choices) picker.set_picks(picks) result = picker.ShowModal() if result == wx.ID_CANCEL: picker.DestroyLater() return picks = picker.get_picks() picker.DestroyLater() dbcfg.set ( workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, option = option, value = picks ) return
def _get_very_recent_encounter(pk_identity): cfg_db = gmCfg.cCfgSQL() min_ttl = cfg_db.get2 ( option = u'encounter.minimum_ttl', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = u'user', default = u'1 hour 30 minutes' ) cmd = u""" SELECT pk_encounter FROM clin.v_most_recent_encounters WHERE pk_patient = %s and last_affirmed > (now() - %s::interval) ORDER BY last_affirmed DESC""" rows, idx = gmPG2.run_ro_queries(queries = [{'cmd': cmd, 'args': [pk_identity, min_ttl]}]) if len(rows) == 0: _log.debug('no <very recent> encounter (younger than [%s]) found' % min_ttl) return None _log.debug('"very recent" encounter [%s] found and re-activated', rows[0][0]) return gmEMRStructItems.cEncounter(aPK_obj = rows[0][0])
def _decide_on_active_encounter(pk_identity): enc = _get_very_recent_encounter(pk_identity) if enc is not None: return enc _here = gmPraxis.gmCurrentPraxisBranch() cfg_db = gmCfg.cCfgSQL() enc_type = cfg_db.get2 ( option = u'encounter.default_type', workplace = _here.active_workplace, bias = u'user' ) if enc_type is None: enc_type = gmEMRStructItems.get_most_commonly_used_encounter_type() if enc_type is None: enc_type = u'in surgery' enc = gmEMRStructItems.create_encounter(fk_patient = pk_identity, enc_type = enc_type) enc['pk_org_unit'] = _here['pk_org_unit'] enc.save() _log.debug('new encounter [%s] initiated' % enc['pk_encounter']) return enc
def __refresh_soap_notebook(self): self.__reset_soap_notebook() if self.__pat is None: return dbcfg = gmCfg.cCfgSQL() auto_open_recent_problems = bool(dbcfg.get2 ( option = 'horstspace.soap_editor.auto_open_latest_episodes', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = True )) emr = self.__pat.emr recent_epis = emr.active_encounter.get_episodes() prev_enc = emr.get_last_but_one_encounter() if prev_enc is not None: recent_epis.extend(prev_enc.get_episodes()) for epi in recent_epis: if not epi['episode_open']: continue self._NB_soap_editors.add_editor(problem = epi)
def load_data_packs_list(): dbcfg = gmCfg.cCfgSQL() dpl_url = dbcfg.get2( option=dpl_url_option, workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias='workplace', default=default_dpl_url) items = [] data = [] dpl_fname = gmNetworkTools.download_data_packs_list(dpl_url) if dpl_fname is None: return (items, data) try: _cfg.add_file_source(source='data-packs', file=dpl_fname) except (UnicodeDecodeError): _log.exception("cannot read data pack list from [%s]", dpl_fname) return (items, data) packs = _cfg.get('data packs', 'data packs', source_order=[('data-packs', 'return')]) if packs is None: _log.info('no data packs listed in data packs list file') _cfg.remove_source('data-packs') return (items, data) for pack in packs: _log.debug('reading pack [%s] metadata', pack) pack_group = u'pack %s' % pack name = _cfg.get(pack_group, u'name', source_order=[('data-packs', 'return')]) pack_url = _cfg.get(pack_group, u'URL', source_order=[('data-packs', 'return')]) md5_url = pack_url + u'.md5' db_min = _cfg.get(pack_group, u'minimum database version', source_order=[('data-packs', 'return')]) converted, db_min = gmTools.input2int( db_min, # here we introduced data packs: #16, 0, # no use looking at data packs requiring a database > the current database: _cfg.get(option='database_version')) if not converted: _log.error('cannot convert minimum database version [%s]', db_min) continue db_max = _cfg.get(pack_group, u'maximum database version', source_order=[('data-packs', 'return')]) if db_max is None: db_max = sys.maxint converted, db_max = gmTools.input2int( db_max, db_min # max version must be at least db_min ) if not converted: _log.error('cannot convert maximum database version [%s]', db_max) continue if _cfg.get(option='database_version') < db_min: _log.error( 'ignoring data pack: current database version (%s) < minimum required database version (%s)', _cfg.get(option='database_version'), db_min) continue if _cfg.get(option='database_version') > db_max: _log.error( 'ignoring data pack: current database version (%s) > maximum allowable database version (%s)', _cfg.get(option='database_version'), db_max) continue items.append([name, u'v%s' % db_min, u'v%s' % db_max, pack_url]) data.append({ 'name': name, 'pack_url': pack_url, 'md5_url': md5_url, 'db_min': db_min, 'db_max': db_max }) _cfg.remove_source('data-packs') return (items, data)
def move_episode_to_issue(episode=None, target_issue=None, save_to_backend=False): """Prepare changing health issue for an episode. Checks for two-open-episodes conflict. When this function succeeds, the pk_health_issue has been set on the episode instance and the episode should - for all practical purposes - be ready for save_payload(). """ # episode is closed: should always work if not episode['episode_open']: episode['pk_health_issue'] = target_issue['pk_health_issue'] if save_to_backend: episode.save_payload() return True # un-associate: should always work, too if target_issue is None: episode['pk_health_issue'] = None if save_to_backend: episode.save_payload() return True # try closing possibly expired episode on target issue if any db_cfg = gmCfg.cCfgSQL() epi_ttl = int(db_cfg.get2 ( option = 'episode.ttl', workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'user', default = 60 # 2 months )) if target_issue.close_expired_episode(ttl=epi_ttl) is True: gmDispatcher.send(signal='statustext', msg=_('Closed episodes older than %s days on health issue [%s]') % (epi_ttl, target_issue['description'])) existing_epi = target_issue.get_open_episode() # no more open episode on target issue: should work now if existing_epi is None: episode['pk_health_issue'] = target_issue['pk_health_issue'] if save_to_backend: episode.save_payload() return True # don't conflict on SELF ;-) if existing_epi['pk_episode'] == episode['pk_episode']: episode['pk_health_issue'] = target_issue['pk_health_issue'] if save_to_backend: episode.save_payload() return True # we got two open episodes at once, ask user move_range = (episode.best_guess_clinical_start_date, episode.best_guess_clinical_end_date) if move_range[1] is None: move_range_end = '?' else: move_range_end = move_range[1].strftime('%m/%y') exist_range = (existing_epi.best_guess_clinical_start_date, existing_epi.best_guess_clinical_end_date) if exist_range[1] is None: exist_range_end = '?' else: exist_range_end = exist_range[1].strftime('%m/%y') question = _( 'You want to associate the running episode:\n\n' ' "%(new_epi_name)s" (%(new_epi_start)s - %(new_epi_end)s)\n\n' 'with the health issue:\n\n' ' "%(issue_name)s"\n\n' 'There already is another episode running\n' 'for this health issue:\n\n' ' "%(old_epi_name)s" (%(old_epi_start)s - %(old_epi_end)s)\n\n' 'However, there can only be one running\n' 'episode per health issue.\n\n' 'Which episode do you want to close ?' ) % { 'new_epi_name': episode['description'], 'new_epi_start': move_range[0].strftime('%m/%y'), 'new_epi_end': move_range_end, 'issue_name': target_issue['description'], 'old_epi_name': existing_epi['description'], 'old_epi_start': exist_range[0].strftime('%m/%y'), 'old_epi_end': exist_range_end } dlg = gmGuiHelpers.c3ButtonQuestionDlg ( parent = None, id = -1, caption = _('Resolving two-running-episodes conflict'), question = question, button_defs = [ {'label': _('old episode'), 'default': True, 'tooltip': _('close existing episode "%s"') % existing_epi['description']}, {'label': _('new episode'), 'default': False, 'tooltip': _('close moving (new) episode "%s"') % episode['description']} ] ) decision = dlg.ShowModal() if decision == wx.ID_CANCEL: # button 3: move cancelled by user return False elif decision == wx.ID_YES: # button 1: close old episode existing_epi['episode_open'] = False existing_epi.save_payload() elif decision == wx.ID_NO: # button 2: close new episode episode['episode_open'] = False else: raise ValueError('invalid result from c3ButtonQuestionDlg: [%s]' % decision) episode['pk_health_issue'] = target_issue['pk_health_issue'] if save_to_backend: episode.save_payload() return True
def edit_visual_progress_note(filename=None, episode=None, discard_unmodified=False, doc_part=None, health_issue=None): """This assumes <filename> contains an image which can be handled by the configured image editor.""" if doc_part is not None: filename = doc_part.export_to_file() if filename is None: gmDispatcher.send( signal=u'statustext', msg=_('Cannot export visual progress note to file.')) return None dbcfg = gmCfg.cCfgSQL() cmd = dbcfg.get2( option=u'external.tools.visual_soap_editor_cmd', workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace, bias='user') if cmd is None: gmDispatcher.send( signal=u'statustext', msg=_('Editor for visual progress note not configured.'), beep=False) cmd = configure_visual_progress_note_editor() if cmd is None: gmDispatcher.send( signal=u'statustext', msg=_('Editor for visual progress note not configured.'), beep=True) return None if u'%(img)s' in cmd: cmd = cmd % {u'img': filename} else: cmd = u'%s %s' % (cmd, filename) if discard_unmodified: original_stat = os.stat(filename) original_md5 = gmTools.file2md5(filename) success = gmShellAPI.run_command_in_shell(cmd, blocking=True) if not success: gmGuiHelpers.gm_show_error( _('There was a problem with running the editor\n' 'for visual progress notes.\n' '\n' ' [%s]\n' '\n') % cmd, _('Editing visual progress note')) return None try: open(filename, 'r').close() except Exception: _log.exception('problem accessing visual progress note file [%s]', filename) gmGuiHelpers.gm_show_error( _('There was a problem reading the visual\n' 'progress note from the file:\n' '\n' ' [%s]\n' '\n') % filename, _('Saving visual progress note')) return None if discard_unmodified: modified_stat = os.stat(filename) # same size ? if original_stat.st_size == modified_stat.st_size: modified_md5 = gmTools.file2md5(filename) # same hash ? if original_md5 == modified_md5: _log.debug('visual progress note (template) not modified') # ask user to decide msg = _( u'You either created a visual progress note from a template\n' u'in the database (rather than from a file on disk) or you\n' u'edited an existing visual progress note.\n' u'\n' u'The template/original was not modified at all, however.\n' u'\n' u'Do you still want to save the unmodified image as a\n' u'visual progress note into the EMR of the patient ?\n') save_unmodified = gmGuiHelpers.gm_show_question( msg, _('Saving visual progress note')) if not save_unmodified: _log.debug('user discarded unmodified note') return if doc_part is not None: _log.debug('updating visual progress note') doc_part.update_data_from_file(fname=filename) doc_part.set_reviewed(technically_abnormal=False, clinically_relevant=True) return None if not isinstance(episode, gmEMRStructItems.cEpisode): if episode is None: episode = _('visual progress notes') pat = gmPerson.gmCurrentPatient() emr = pat.emr episode = emr.add_episode(episode_name=episode.strip(), pk_health_issue=health_issue, is_open=False) doc = gmDocumentWidgets.save_file_as_new_document( filename=filename, document_type=gmDocuments.DOCUMENT_TYPE_VISUAL_PROGRESS_NOTE, episode=episode, unlock_patient=False, pk_org_unit=gmPraxis.gmCurrentPraxisBranch()['pk_org_unit']) doc.set_reviewed(technically_abnormal=False, clinically_relevant=True) return doc
def load_data_packs_list(): dbcfg = gmCfg.cCfgSQL() dpl_url = dbcfg.get2 ( option = dpl_url_option, workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace, bias = 'workplace', default = default_dpl_url ) items = [] data = [] dpl_fname = gmNetworkTools.download_data_packs_list(dpl_url) if dpl_fname is None: return (items, data) try: _cfg.add_file_source(source = 'data-packs', file = dpl_fname) except (UnicodeDecodeError): _log.exception("cannot read data pack list from [%s]", dpl_fname) return (items, data) packs = _cfg.get('data packs', 'data packs', source_order = [('data-packs', 'return')]) if packs is None: _log.info('no data packs listed in data packs list file') _cfg.remove_source('data-packs') return (items, data) for pack in packs: _log.debug('reading pack [%s] metadata', pack) pack_group = u'pack %s' % pack name = _cfg.get(pack_group, u'name', source_order = [('data-packs', 'return')]) pack_url = _cfg.get(pack_group, u'URL', source_order = [('data-packs', 'return')]) md5_url = pack_url + u'.md5' db_min = _cfg.get(pack_group, u'minimum database version', source_order = [('data-packs', 'return')]) converted, db_min = gmTools.input2int ( db_min, # here we introduced data packs: #16, 0, # no use looking at data packs requiring a database > the current database: _cfg.get(option = 'database_version') ) if not converted: _log.error('cannot convert minimum database version [%s]', db_min) continue db_max = _cfg.get(pack_group, u'maximum database version', source_order = [('data-packs', 'return')]) if db_max is None: db_max = sys.maxint converted, db_max = gmTools.input2int ( db_max, db_min # max version must be at least db_min ) if not converted: _log.error('cannot convert maximum database version [%s]', db_max) continue if _cfg.get(option = 'database_version') < db_min: _log.error('ignoring data pack: current database version (%s) < minimum required database version (%s)', _cfg.get(option = 'database_version'), db_min) continue if _cfg.get(option = 'database_version') > db_max: _log.error('ignoring data pack: current database version (%s) > maximum allowable database version (%s)', _cfg.get(option = 'database_version'), db_max) continue items.append([name, u'v%s' % db_min, u'v%s' % db_max, pack_url]) data.append ({ 'name': name, 'pack_url': pack_url, 'md5_url': md5_url, 'db_min': db_min, 'db_max': db_max }) _cfg.remove_source('data-packs') return (items, data)