Beispiel #1
0
    def valid(self):
        for bmp_version in AMTS_BMP_XSDs:
            xsd_filename = os.path.join(gmTools.gmPaths().system_app_data_dir,
                                        'resources', 'amts',
                                        AMTS_BMP_XSDs[bmp_version])
            try:
                self.__xml_schema = lxml_etree.XMLSchema(file=xsd_filename)
            except lxml_etree.XMLSchemaParseError:
                _log.exception('cannot find [%s], trying local base dir',
                               xsd_filename)
                # retry, maybe in dev tree
                xsd_filename = os.path.join(gmTools.gmPaths().local_base_dir,
                                            'resources', 'amts',
                                            AMTS_BMP_XSDs[bmp_version])
                self.__xml_schema = lxml_etree.XMLSchema(file=xsd_filename)

            with open(self.__filename, encoding='iso-8859-1') as bmp_file:
                try:
                    self.xml_doc = lxml_etree.parse(bmp_file)
                except lxml_etree.XMLSyntaxError:
                    _log.exception('[%s] does not parse as XML',
                                   self.__filename)
                    break
            validated = self.__xml_schema.validate(self.xml_doc)
            if validated:
                self.bmp_version = bmp_version
                _log.debug('[%s] validates as AMTS BMP v%s', self.__filename,
                           self.bmp_version)
                # check for second/third file !
                return True
            _log.debug('[%s] does not validate against [%s]', self.__filename,
                       xsd_filename)

        _log.debug('[%s] does not validate as AMTS BMP', self.__filename)
        return False
Beispiel #2
0
def _print_files_by_shellscript(filenames=None, jobtype=None):

	paths = gmTools.gmPaths()
	local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', 'gm-print_doc')

	#candidates = [u'gm-print_doc', u'gm-print_doc.bat', local_script, u'gm-print_doc.bat']
	candidates = [u'gm-print_doc', local_script, u'gm-print_doc.bat']
	found, binary = gmShellAPI.find_first_binary(binaries = candidates)
	if not found:
		binary = r'gm-print_doc.bat'

	cmd_line = [
		binary,
		jobtype
	]
	cmd_line.extend(filenames)
	_log.debug('printing with %s', cmd_line)
	try:
		gm_print_doc = subprocess.Popen(cmd_line)
	except OSError:
		_log.debug('cannot run <gm_print_doc(.bat)>')
		return False
	gm_print_doc.communicate()
	if gm_print_doc.returncode != 0:
		_log.error('<gm_print_doc> returned [%s], failed to print', gm_print_doc.returncode)
		return False

	return True
Beispiel #3
0
    def __init__(self, parent, frame):
        wx.Panel.__init__(self, parent, -1)
        self.frame = frame

        # get base directory for manuals from broker
        paths = gmTools.gmPaths(app_name='gnumed', wx=wx)
        candidates = [
            os.path.join(paths.local_base_dir, 'doc', 'user-manual'),
            '/usr/share/doc/gnumed/user-manual/',
            os.path.join(paths.system_app_data_dir, 'doc', 'user-manual')
        ]
        for self.docdir in candidates:
            if os.access(self.docdir, os.R_OK):
                _log.info('found Manual path [%s]', self.docdir)
                break

        self.box = wx.BoxSizer(wx.VERTICAL)

        infobox = wx.BoxSizer(wx.HORIZONTAL)
        n = wx.NewId()
        self.infoline = wx.TextCtrl(self, n, style=wx.TE_READONLY)
        self.infoline.SetBackgroundColour(wx.LIGHT_GREY)
        infobox.Add(self.infoline, 1, wx.GROW | wx.ALL)
        self.box.Add(infobox, 0, wx.GROW)

        self.html = ManualHtmlWindow(self, -1)
        self.html.SetRelatedFrame(frame, "")
        self.html.SetRelatedStatusBar(0)
        self.box.Add(self.html, 1, wx.GROW)

        self.SetSizer(self.box)
        self.SetAutoLayout(True)

        self.already_loaded = None
Beispiel #4
0
def download_data_pack_old(url, target_dir=None):

    if target_dir is None:
        target_dir = gmTools.get_unique_filename(prefix='gm-dl-')

    _log.debug('downloading [%s]', url)
    _log.debug('unpacking into [%s]', target_dir)

    gmTools.mkdir(directory=target_dir)

    # FIXME: rewrite to use urllib.urlretrieve() and

    paths = gmTools.gmPaths()
    local_script = os.path.join(paths.local_base_dir, '..', 'external-tools',
                                'gm-download_data')

    candidates = [
        u'gm-download_data', u'gm-download_data.bat', local_script,
        u'gm-download_data.bat'
    ]
    args = u' %s %s' % (url, target_dir)

    success = gmShellAPI.run_first_available_in_shell(binaries=candidates,
                                                      args=args,
                                                      blocking=True,
                                                      run_last_one_anyway=True)

    if success:
        return True, target_dir

    _log.error('download failed')
    return False, None
Beispiel #5
0
def update_atc_reference_data():

    dlg = wx.FileDialog(parent=None,
                        message=_('Choose an ATC import config file'),
                        defaultDir=gmTools.gmPaths().user_work_dir,
                        defaultFile='',
                        wildcard="%s (*.conf)|*.conf|%s (*)|*" %
                        (_('config files'), _('all files')),
                        style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)

    result = dlg.ShowModal()
    if result == wx.ID_CANCEL:
        return

    cfg_file = dlg.GetPath()
    dlg.DestroyLater()

    conn = gmAuthWidgets.get_dbowner_connection(
        procedure=_('importing ATC reference data'))
    if conn is None:
        return False

    wx.BeginBusyCursor()

    if gmATC.atc_import(cfg_fname=cfg_file, conn=conn):
        gmDispatcher.send(signal='statustext',
                          msg=_('Successfully imported ATC reference data.'))
    else:
        gmDispatcher.send(signal='statustext',
                          msg=_('Importing ATC reference data failed.'),
                          beep=True)

    wx.EndBusyCursor()
    return True
Beispiel #6
0
    def __init__(self):
        # while not strictly necessary it is good to fail early
        # this will tell us fairly safely whether XSane is properly installed
        self._stock_xsanerc = os.path.expanduser(
            os.path.join('~', '.sane', 'xsane', 'xsane.rc'))
        try:
            open(self._stock_xsanerc, 'r').close()
        except IOError:
            msg = ('XSane not properly installed for this user:\n\n'
                   ' [%s] not found\n\n'
                   'Start XSane once before using it with GNUmed.'
                   ) % self._stock_xsanerc
            raise ImportError(msg)

        # make sure we've got a custom xsanerc for
        # the user to modify manually (therefore, in user_config_dir)
        self._gm_custom_xsanerc = os.path.join(
            gmTools.gmPaths().user_config_dir, 'gm-xsanerc.conf')
        try:
            open(self._gm_custom_xsanerc, 'r+b').close()
        except IOError:
            _log.info('creating [%s] from [%s]', self._gm_custom_xsanerc,
                      self._stock_xsanerc)
            shutil.copyfile(self._stock_xsanerc, self._gm_custom_xsanerc)

        self.device_settings_file = None
        self.default_device = None
Beispiel #7
0
def load_person_from_vcard_file():

	wildcards = '|'.join ([
		'%s (*.vcf)|*.vcf' % _('vcf files'),
		'%s (*.VCF)|*.VCF' % _('VCF files'),
		'%s (*)|*' % _('all files'),
		'%s (*.*)|*.*' % _('all files (Windows)')
	])

	dlg = wx.FileDialog (
		parent = wx.GetApp().GetTopWindow(),
		message = _('Choose a vCard file:'),
		defaultDir = os.path.join(gmTools.gmPaths().home_dir, 'gnumed'),
		wildcard = wildcards,
		style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
	)
	result = dlg.ShowModal()
	fname = dlg.GetPath()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return

	from Gnumed.business import gmVCard
	dto = gmVCard.parse_vcard2dto(filename = fname)
	if dto is None:
		gmDispatcher.send(signal='statustext', msg=_('[%s] does not seem to contain a vCard.') % fname)
		return

	idents = dto.get_candidate_identities(can_create = True)
	if len(idents) == 1:
		ident = idents[0]
		if not set_active_patient(patient = ident):
			gmGuiHelpers.gm_show_info (_(
				'Cannot activate patient:\n\n'
				'%s %s (%s)\n'
				'%s'
				) % (
					dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
				),
				_('Activating external patient')
			)
		return

	dlg = cSelectPersonFromListDlg(wx.GetApp().GetTopWindow(), -1)
	dlg.set_persons(persons = idents)
	result = dlg.ShowModal()
	ident = dlg.get_selected_person()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return
	if not set_active_patient(patient = ident):
		gmGuiHelpers.gm_show_info (_(
			'Cannot activate patient:\n\n'
			'%s %s (%s)\n'
			'%s'
			) % (
				dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
			),
			_('Activating external patient')
		)
def load_person_from_vcard_file():

	wildcards = '|'.join ([
		'%s (*.vcf)|*.vcf' % _('vcf files'),
		'%s (*.VCF)|*.VCF' % _('VCF files'),
		'%s (*)|*' % _('all files'),
		'%s (*.*)|*.*' % _('all files (Windows)')
	])

	dlg = wx.FileDialog (
		parent = wx.GetApp().GetTopWindow(),
		message = _('Choose a vCard file:'),
		defaultDir = os.path.join(gmTools.gmPaths().home_dir, 'gnumed'),
		wildcard = wildcards,
		style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
	)
	result = dlg.ShowModal()
	fname = dlg.GetPath()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return

	from Gnumed.business import gmVCard
	dto = gmVCard.parse_vcard2dto(filename = fname)
	if dto is None:
		gmDispatcher.send(signal='statustext', msg=_('[%s] does not seem to contain a vCard.') % fname)
		return

	idents = dto.get_candidate_identities(can_create = True)
	if len(idents) == 1:
		ident = idents[0]
		if not set_active_patient(patient = ident):
			gmGuiHelpers.gm_show_info (_(
				'Cannot activate patient:\n\n'
				'%s %s (%s)\n'
				'%s'
				) % (
					dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
				),
				_('Activating external patient')
			)
		return

	dlg = cSelectPersonFromListDlg(wx.GetApp().GetTopWindow(), -1)
	dlg.set_persons(persons = idents)
	result = dlg.ShowModal()
	ident = dlg.get_selected_person()
	dlg.DestroyLater()
	if result == wx.ID_CANCEL:
		return
	if not set_active_patient(patient = ident):
		gmGuiHelpers.gm_show_info (_(
			'Cannot activate patient:\n\n'
			'%s %s (%s)\n'
			'%s'
			) % (
				dto.firstnames, dto.lastnames, dto.gender, gmDateTime.pydt_strftime(dto.dob, '%Y %b %d')
			),
			_('Activating external patient')
		)
Beispiel #9
0
def __run_file_describer(filename=None):
	base_name = 'gm-describe_file'
	paths = gmTools.gmPaths()
	local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', base_name)
	candidates = [ base_name, local_script ]		#, base_name + u'.bat'
	found, binary = gmShellAPI.find_first_binary(binaries = candidates)
	if not found:
		_log.error('cannot find <%s(.bat)>', base_name)
		return (False, _('<%s(.bat)> not found') % base_name)

	cmd_line = [binary, filename]
	_log.debug('describing: %s', cmd_line)
	try:
		proc_result = subprocess.run (
			args = cmd_line,
			stdin = subprocess.PIPE,
			stdout = subprocess.PIPE,
			stderr = subprocess.PIPE,
			#timeout = timeout,
			encoding = 'utf8'
		)
	except (subprocess.TimeoutExpired, FileNotFoundError):
		_log.exception('there was a problem running external process')
		return (False, _('problem with <%s>') % binary)

	_log.info('exit code [%s]', proc_result.returncode)
	if proc_result.returncode != 0:
		_log.error('[%s] failed', binary)
		_log.error('STDERR:\n%s', proc_result.stderr)
		_log.error('STDOUT:\n%s', proc_result.stdout)
		return (False, _('problem with <%s>') % binary)
	return (True, proc_result.stdout)
Beispiel #10
0
def _print_files_by_shellscript(filenames=None, jobtype=None, verbose=False):

    paths = gmTools.gmPaths()
    local_script = os.path.join(paths.local_base_dir, '..', 'external-tools',
                                'gm-print_doc')
    candidates = ['gm-print_doc', local_script, 'gm-print_doc.bat']
    found, binary = gmShellAPI.find_first_binary(binaries=candidates)
    if not found:
        binary = r'gm-print_doc.bat'
    cmd_line = [binary, jobtype]
    cmd_line.extend(filenames)
    success, returncode, stdout = gmShellAPI.run_process(cmd_line=cmd_line,
                                                         verbose=verbose)
    if not success:
        _log.debug(
            'gm-print_doc(.bat) arguments: "DOCUMENT_TYPE LIST-OF-FILES-TO-PRINT"'
        )
        _log.debug(
            'gm-print_doc(.bat): call printing app, perhaps based on DOCUMENT_TYPE, and pass in LIST-OF-FILES-TO-PRINT'
        )
        _log.debug('gm-print_doc(.bat): return 0 on success')
        _log.debug(
            'gm-print_doc(.bat): DOCUMENT_TYPE - can be used to decide which way to process a particular print job (Example: medication_list)'
        )
        _log.debug(
            'gm-print_doc(.bat): LIST-OF-FILES-TO-PRINT - can be of any mimetype so the script needs to be able to process them, typically PDF though'
        )
        return False

    return True
Beispiel #11
0
def __run_file_describer(filename=None):
    base_name = 'gm-describe_file'
    paths = gmTools.gmPaths()
    local_script = os.path.join(paths.local_base_dir, '..', 'external-tools',
                                base_name)
    candidates = [base_name, local_script]  #, base_name + '.bat'
    found, binary = gmShellAPI.find_first_binary(binaries=candidates)
    if not found:
        _log.error('cannot find <%s(.bat)>', base_name)
        return (False, _('<%s(.bat)> not found') % base_name)

    cmd_line = [binary, filename]
    _log.debug('describing: %s', cmd_line)
    try:
        proc_result = subprocess.run(
            args=cmd_line,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            #timeout = timeout,
            encoding='utf8',
            errors='backslashreplace')
    except (subprocess.TimeoutExpired, FileNotFoundError):
        _log.exception('there was a problem running external process')
        return (False, _('problem with <%s>') % binary)

    _log.info('exit code [%s]', proc_result.returncode)
    if proc_result.returncode != 0:
        _log.error('[%s] failed', binary)
        _log.error('STDERR:\n%s', proc_result.stderr)
        _log.error('STDOUT:\n%s', proc_result.stdout)
        return (False, _('problem with <%s>') % binary)
    return (True, proc_result.stdout)
Beispiel #12
0
	def _on_export_button_pressed(self, event):
		if self.data is None:
			return

		engine_abbrev = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]

		wildcards = []
		try:
			wildcards.append('%s (%s)|%s' % (
				gmForms.form_engine_names[engine_abbrev],
				gmForms.form_engine_template_wildcards[engine_abbrev],
				gmForms.form_engine_template_wildcards[engine_abbrev]
			))
		except KeyError:
			pass
		wildcards.append("%s (*)|*" % _('all files'))
		wildcards.append("%s (*.*)|*.*" % _('all files (Windows)'))

		dlg = wx.FileDialog (
			parent = self,
			message = _('Enter a filename to save the template to'),
			defaultDir = gmTools.gmPaths().user_work_dir,
			defaultFile = '',
			wildcard = '|'.join(wildcards),
			style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT
		)
		result = dlg.ShowModal()
		if result != wx.ID_CANCEL:
			fname = dlg.GetPath()
			self.data.save_to_file(filename = fname)
		dlg.DestroyLater()

		event.Skip()
Beispiel #13
0
	def _on_load_button_pressed(self, event):
		engine_abbrev = gmForms.form_engine_abbrevs[self._CH_engine.GetSelection()]

		wildcards = []
		try:
			wildcards.append('%s (%s)|%s' % (
				gmForms.form_engine_names[engine_abbrev],
				gmForms.form_engine_template_wildcards[engine_abbrev],
				gmForms.form_engine_template_wildcards[engine_abbrev]
			))
		except KeyError:
			pass
		wildcards.append("%s (*)|*" % _('all files'))
		wildcards.append("%s (*.*)|*.*" % _('all files (Windows)'))

		dlg = wx.FileDialog (
			parent = self,
			message = _('Choose a form template file'),
			defaultDir = gmTools.gmPaths().user_work_dir,
			defaultFile = '',
			wildcard = '|'.join(wildcards),
			style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
		)
		result = dlg.ShowModal()
		if result != wx.ID_CANCEL:
			self._TCTRL_filename.SetValue(dlg.GetPath())
		dlg.DestroyLater()

		event.Skip()
Beispiel #14
0
	def __init__(self, parent, frame):
		wx.Panel.__init__(self, parent, -1)
		self.frame = frame

		# get base directory for manuals from broker
		paths = gmTools.gmPaths(app_name = u'gnumed', wx = wx)
		candidates = [
			os.path.join(paths.local_base_dir, 'doc', 'user-manual'),
			'/usr/share/doc/gnumed/user-manual/',
			os.path.join(paths.system_app_data_dir, 'doc', 'user-manual')
		]
		for self.docdir in candidates:
			if os.access(self.docdir, os.R_OK):
				_log.info('found Manual path [%s]', self.docdir)
				break

		self.box = wx.BoxSizer(wx.VERTICAL)

		infobox = wx.BoxSizer(wx.HORIZONTAL)
		n = wx.NewId()
		self.infoline = wx.TextCtrl(self, n, style=wx.TE_READONLY)
		self.infoline.SetBackgroundColour(wx.LIGHT_GREY)
		infobox.Add(self.infoline, 1, wx.GROW|wx.ALL)
		self.box.Add(infobox, 0, wx.GROW)

		self.html = ManualHtmlWindow(self, -1)
		self.html.SetRelatedFrame(frame, "")
		self.html.SetRelatedStatusBar(0)
		self.box.Add(self.html, 1, wx.GROW)

		self.SetSizer(self.box)
		self.SetAutoLayout(True)

		self.already_loaded = None
Beispiel #15
0
def _print_files_by_shellscript(filenames=None, jobtype=None):

    paths = gmTools.gmPaths()
    local_script = os.path.join(paths.local_base_dir, '..', 'external-tools',
                                'gm-print_doc')

    #candidates = [u'gm-print_doc', u'gm-print_doc.bat', local_script, u'gm-print_doc.bat']
    candidates = ['gm-print_doc', local_script, 'gm-print_doc.bat']
    found, binary = gmShellAPI.find_first_binary(binaries=candidates)
    if not found:
        binary = r'gm-print_doc.bat'

    cmd_line = [binary, jobtype]
    cmd_line.extend(filenames)
    _log.debug('printing with %s', cmd_line)
    try:
        gm_print_doc = subprocess.Popen(cmd_line)
    except OSError:
        _log.debug('cannot run <gm_print_doc(.bat)>')
        return False
    gm_print_doc.communicate()
    if gm_print_doc.returncode != 0:
        _log.error('<gm_print_doc> returned [%s], failed to print',
                   gm_print_doc.returncode)
        return False

    return True
Beispiel #16
0
    def _on_save_results_button_pressed(self, event):
        event.Skip()

        user_query = self._TCTRL_query.GetValue().strip().strip(';')
        if user_query == '':
            return

        pat = None
        curr_pat = gmPerson.gmCurrentPatient()
        if curr_pat.connected:
            pat = curr_pat.ID
        success, hint, cols, rows = gmDataMining.run_report_query(
            query=user_query, limit=None, pk_identity=pat)

        if not success:
            return

        if len(rows) == 0:
            return

        dlg = wx.FileDialog(
            parent=self,
            message=_("Save SQL report query results as CSV in..."),
            defaultDir=gmTools.gmPaths().user_work_dir,
            defaultFile='gm-query_results.csv',
            wildcard='%s (*.csv)|*.csv|%s (*)|*' %
            (_("CSV files"), _("all files")),
            style=wx.FD_SAVE)
        choice = dlg.ShowModal()
        csv_name = dlg.GetPath()
        dlg.DestroyLater()
        if choice != wx.ID_OK:
            return

        csv_file = io.open(csv_name, mode='wt', encoding='utf8')
        csv_file.write(
            '#-------------------------------------------------------------------------------------\n'
        )
        csv_file.write('# GNUmed SQL report results\n')
        csv_file.write('#\n')
        csv_file.write('# Report: "%s"\n' %
                       self._PRW_report_name.GetValue().strip())
        csv_file.write('#\n')
        csv_file.write('# SQL:\n')
        for line in user_query.split('\n'):
            csv_file.write('# %s\n' % line)
        csv_file.write('#\n')
        csv_file.write('# ID of active patient: %s\n' % pat)
        csv_file.write('#\n')
        csv_file.write('# hits found: %s\n' % len(rows))
        csv_file.write(
            '#-------------------------------------------------------------------------------------\n'
        )

        csv_writer = csv.writer(csv_file)
        csv_writer.writerow(cols)
        for row in rows:
            csv_writer.writerow(row)

        csv_file.close()
Beispiel #17
0
def download_data_pack_old(url, target_dir=None):

	if target_dir is None:
		target_dir = gmTools.get_unique_filename(prefix = 'gm-dl-')

	_log.debug('downloading [%s]', url)
	_log.debug('unpacking into [%s]', target_dir)

	gmTools.mkdir(directory = target_dir)

	# FIXME: rewrite to use urllib.urlretrieve() and 

	paths = gmTools.gmPaths()
	local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', 'gm-download_data')

	candidates = [u'gm-download_data', u'gm-download_data.bat', local_script, u'gm-download_data.bat']
	args = u' %s %s' % (url, target_dir)

	success = gmShellAPI.run_first_available_in_shell (
		binaries = candidates,
		args = args,
		blocking = True,
		run_last_one_anyway = True
	)

	if success:
		return True, target_dir

	_log.error('download failed')
	return False, None
Beispiel #18
0
	def __init_ui(self):
		msg = ('\n' + _('Number of entries to save: %s') + '\n\n' + _('Patient: %s') + '\n') % (
			self.__item_count,
			self.__patient['description_gender']
		)
		self._LBL_header.Label = msg
		self._LBL_directory.Label = os.path.join(gmTools.gmPaths().home_dir, 'gnumed', self.__patient.subdir_name) + os.sep
		self.__update_ui_state()
Beispiel #19
0
    def _on_burn_items_button_pressed(self, event):
        event.Skip()

        found, external_cmd = gmShellAPI.detect_external_binary('gm-burn_doc')
        if not found:
            return False

        items = self._LCTRL_items.get_selected_item_data(only_one=False)
        if len(items) == 0:
            items = self._LCTRL_items.get_item_data()

        base_dir = None
        dlg = wx.DirDialog(
            self,
            message=_(
                'If you wish to include an existing directory select it here:'
            ),
            defaultPath=os.path.join(gmTools.gmPaths().home_dir, 'gnumed'),
            style=wx.DD_DEFAULT_STYLE | wx.DD_DIR_MUST_EXIST)
        choice = dlg.ShowModal()
        path2include = dlg.GetPath()
        if choice == wx.ID_OK:
            if not gmTools.dir_is_empty(path2include):
                base_dir = path2include

        export_dir = gmPerson.gmCurrentPatient().export_area.export(
            base_dir=base_dir, items=items, with_metadata=True)
        if export_dir is None:
            return False

        cmd = u'%s %s' % (external_cmd, export_dir)
        if os.name == 'nt':
            blocking = True
        else:
            blocking = False
        success = gmShellAPI.run_command_in_shell(command=cmd,
                                                  blocking=blocking)
        if not success:
            gmGuiHelpers.gm_show_error(
                aMessage=_('Error burning documents to CD/DVD.'),
                aTitle=_('Burning documents'))
            return False

        self.save_soap_note(soap=_('Burned onto CD/DVD:\n - %s') %
                            u'\n - '.join([i['description'] for i in items]))

        browse_index = gmGuiHelpers.gm_show_question(
            title=title,
            question=_('Browse patient data pack ?'),
            cancel_button=False)
        if browse_index:
            gmNetworkTools.open_url_in_browser(
                url=u'file://%s' % os.path.join(export_dir, u'index.html'))

        return True
Beispiel #20
0
	def __init__(self, *args, **kwargs):

		wx.StaticBitmap.__init__(self, *args, **kwargs)

		paths = gmTools.gmPaths(app_name = 'gnumed', wx = wx)
		self.__fallback_pic_name = os.path.join(paths.system_app_data_dir, 'bitmaps', 'empty-face-in-bust.png')
		self.__desired_width = 50
		self.__desired_height = 54
		self.__pat = gmPerson.gmCurrentPatient()

		self.__init_ui()
		self.__register_events()
Beispiel #21
0
	def __init__(self, *args, **kwargs):

		wx.StaticBitmap.__init__(self, *args, **kwargs)

		paths = gmTools.gmPaths(app_name = u'gnumed', wx = wx)
		self.__fallback_pic_name = os.path.join(paths.system_app_data_dir, 'bitmaps', 'empty-face-in-bust.png')
		self.__desired_width = 50
		self.__desired_height = 54
		self.__pat = gmPerson.gmCurrentPatient()

		self.__init_ui()
		self.__register_events()
Beispiel #22
0
    def _validate_timeline_file(self, tl_filename):
        xsd_name = 'timeline.xsd'
        xsd_paths = [
            os.path.join(gmTools.gmPaths().system_app_data_dir, 'resources',
                         'timeline', xsd_name),
            # maybe in dev tree
            os.path.join(gmTools.gmPaths().local_base_dir, 'resources',
                         'timeline', xsd_name)
        ]
        xml_schema = None
        for xsd_filename in xsd_paths:
            _log.debug('XSD: %s', xsd_filename)
            if not os.path.exists(xsd_filename):
                _log.warning('not found')
                continue
            try:
                xml_schema = lxml_etree.XMLSchema(file=xsd_filename)
                break
            except lxml_etree.XMLSchemaParseError:
                _log.exception('cannot parse')
        if xml_schema is None:
            _log.error('no XSD found')
            return False

        with open(tl_filename, encoding='utf-8') as tl_file:
            try:
                xml_doc = lxml_etree.parse(tl_file)
            except lxml_etree.XMLSyntaxError:
                _log.exception('[%s] does not parse as XML', tl_filename)
                return False

        if xml_schema.validate(xml_doc):
            _log.debug('[%s] seems valid', tl_filename)
            return True

        _log.warning('[%s] does not validate against [%s]', tl_filename,
                     xsd_filename)
        for entry in xml_schema.error_log:
            _log.debug(entry)
        return False
Beispiel #23
0
def convert_file(filename=None, target_mime=None, target_filename=None, target_extension=None, verbose=False):
	"""Convert file from one format into another.

		target_mime: a mime type
	"""
	assert (target_mime is not None), '<target_mime> must not be None'
	assert (filename is not None), '<filename> must not be None'
	assert (filename != target_filename), '<target_filename> must be different from <filename>'

	source_mime = guess_mimetype(filename = filename)
	if source_mime.lower() == target_mime.lower():
		_log.debug('source file [%s] already target mime type [%s]', filename, target_mime)
		if target_filename is None:
			return filename

		shutil.copyfile(filename, target_filename)
		return target_filename

	converted_ext = guess_ext_by_mimetype(target_mime)
	if converted_ext is None:
		if target_filename is not None:
			tmp, converted_ext = os.path.splitext(target_filename)
	if converted_ext is None:
		converted_ext = target_extension		# can still stay None
	converted_fname = gmTools.get_unique_filename(suffix = converted_ext)
	_log.debug('attempting conversion: [%s] -> [<%s>:%s]', filename, target_mime, gmTools.coalesce(target_filename, converted_fname))
	script_name = 'gm-convert_file'
	paths = gmTools.gmPaths()
	local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', script_name)
	candidates = [ script_name, local_script ]		#, script_name + u'.bat'
	found, binary = gmShellAPI.find_first_binary(binaries = candidates)
	if not found:
		# try anyway
		binary = script_name# + r'.bat'
	_log.debug('<%s> API: SOURCEFILE TARGET_MIMETYPE TARGET_EXTENSION TARGET_FILENAME' % binary)
	cmd_line = [
		binary,
		filename,
		target_mime,
		converted_ext.lstrip('.'),
		converted_fname
	]
	success, returncode, stdout = gmShellAPI.run_process(cmd_line = cmd_line, verbose = True)
	if not success:
		_log.error('conversion failed')
		return None

	if target_filename is None:
		return converted_fname

	shutil.copyfile(converted_fname, target_filename)
	return target_filename
Beispiel #24
0
def get_installed_plugins(plugin_dir=''):
	"""Looks for installed plugins in the filesystem.

	The first directory in sys.path which contains a wxpython/gui/
	is considered the one -- because that's where the import will
	get it from.
	"""
	_log.debug('searching installed plugins')
	search_path = None
	candidates = sys.path[:]
	candidates.append(gmTools.gmPaths().local_base_dir)
	for candidate in candidates:
		candidate = os.path.join(candidate, 'Gnumed', 'wxpython', plugin_dir)
		_log.debug(candidate)
		if os.path.exists(candidate):
			search_path = candidate
			break
		_log.debug('not found')

	if search_path is None:
		_log.error('unable to find any directory matching [%s]', os.path.join('${CANDIDATE}', 'Gnumed', 'wxpython', plugin_dir))
		_log.error('candidates: %s', str(candidates))
		# read from config file
		_log.info('trying to read list of installed plugins from config files')
		plugins = _cfg.get (
			group = 'client',
			option = 'installed plugins',
			source_order = [
				('system', 'extend'),
				('user', 'extend'),
				('workbase', 'extend'),
				('explicit', 'extend')
			]
		)
		if plugins is None:
			_log.debug('no plugins found in config files')
			return []
		_log.debug("plugins found: %s" % str(plugins))
		return plugins

	_log.info("scanning plugin directory [%s]" % search_path)

	files = glob.glob(os.path.join(search_path, 'gm*.py'))
	plugins = []
	for f in files:
		path, fname = os.path.split(f)
		mod_name, ext = os.path.splitext(fname)
		plugins.append(mod_name)

	_log.debug("plugins found: %s" % str(plugins))

	return plugins
Beispiel #25
0
	def get_useful_filename(self, patient=None, make_unique=False, directory=None, include_gnumed_tag=True, date_before_type=False, name_first=True):
		patient_part = ''
		if patient is not None:
			if name_first:
				patient_part = '%s-' % patient.subdir_name
			else:
				patient_part = '-%s' % patient.subdir_name

		# preserve original filename extension if available
		suffix = '.dat'
		if self._payload[self._idx['filename']] is not None:
			tmp, suffix = os.path.splitext (
				gmTools.fname_sanitize(self._payload[self._idx['filename']]).lower()
			)
			if suffix == '':
				suffix = '.dat'

		if include_gnumed_tag:
			fname_template = 'gm_doc-part_%s-%%s' % self._payload[self._idx['seq_idx']]
		else:
			fname_template = '%%s-part_%s' % self._payload[self._idx['seq_idx']]

		if date_before_type:
			date_type_part = '%s-%s' % (
				gmDateTime.pydt_strftime(self._payload[self._idx['date_generated']], '%Y-%m-%d', 'utf-8', gmDateTime.acc_days),
				self._payload[self._idx['l10n_type']].replace(' ', '_').replace('-', '_'),
			)
		else:
			date_type_part = '%s-%s' % (
				self._payload[self._idx['l10n_type']].replace(' ', '_').replace('-', '_'),
				gmDateTime.pydt_strftime(self._payload[self._idx['date_generated']], '%Y-%m-%d', 'utf-8', gmDateTime.acc_days)
			)

		if name_first:
			date_type_name_part = patient_part + date_type_part
		else:
			date_type_name_part = date_type_part + patient_part

		fname = fname_template % date_type_name_part

		if make_unique:
			fname = gmTools.get_unique_filename (
				prefix = '%s-' % gmTools.fname_sanitize(fname),
				suffix = suffix,
				tmp_dir = directory
			)
		else:
			fname = gmTools.fname_sanitize(os.path.join(gmTools.coalesce(directory, gmTools.gmPaths().tmp_dir), fname + suffix))

		return fname
Beispiel #26
0
	def get_useful_filename(self, patient=None, make_unique=False, directory=None, include_gnumed_tag=True, date_before_type=False, name_first=True):
		patient_part = ''
		if patient is not None:
			if name_first:
				patient_part = '%s-' % patient.subdir_name
			else:
				patient_part = '-%s' % patient.subdir_name

		# preserve original filename extension if available
		suffix = '.dat'
		if self._payload[self._idx['filename']] is not None:
			tmp, suffix = os.path.splitext (
				gmTools.fname_sanitize(self._payload[self._idx['filename']]).lower()
			)
			if suffix == '':
				suffix = '.dat'

		if include_gnumed_tag:
			fname_template = 'gm_doc-part_%s-%%s' % self._payload[self._idx['seq_idx']]
		else:
			fname_template = '%%s-part_%s' % self._payload[self._idx['seq_idx']]

		if date_before_type:
			date_type_part = '%s-%s' % (
				gmDateTime.pydt_strftime(self._payload[self._idx['date_generated']], '%Y-%m-%d', 'utf-8', gmDateTime.acc_days),
				self._payload[self._idx['l10n_type']].replace(' ', '_').replace('-', '_'),
			)
		else:
			date_type_part = '%s-%s' % (
				self._payload[self._idx['l10n_type']].replace(' ', '_').replace('-', '_'),
				gmDateTime.pydt_strftime(self._payload[self._idx['date_generated']], '%Y-%m-%d', 'utf-8', gmDateTime.acc_days)
			)

		if name_first:
			date_type_name_part = patient_part + date_type_part
		else:
			date_type_name_part = date_type_part + patient_part

		fname = fname_template % date_type_name_part

		if make_unique:
			fname = gmTools.get_unique_filename (
				prefix = '%s-' % gmTools.fname_sanitize(fname),
				suffix = suffix,
				tmp_dir = directory
			)
		else:
			fname = gmTools.fname_sanitize(os.path.join(gmTools.coalesce(directory, gmTools.gmPaths().tmp_dir), fname + suffix))

		return fname
Beispiel #27
0
def get_installed_plugins(plugin_dir=''):
    """Looks for installed plugins in the filesystem.

	The first directory in sys.path which contains a wxpython/gui/
	is considered the one -- because that's where the import will
	get it from.
	"""
    _log.debug('searching installed plugins')
    search_path = None
    candidates = sys.path[:]
    candidates.append(gmTools.gmPaths().local_base_dir)
    for candidate in candidates:
        candidate = os.path.join(candidate, 'Gnumed', 'wxpython', plugin_dir)
        _log.debug(candidate)
        if os.path.exists(candidate):
            search_path = candidate
            break
        _log.debug('not found')

    if search_path is None:
        _log.error(
            'unable to find any directory matching [%s]',
            os.path.join('${CANDIDATE}', 'Gnumed', 'wxpython', plugin_dir))
        _log.error('candidates: %s', str(candidates))
        # read from config file
        _log.info('trying to read list of installed plugins from config files')
        plugins = _cfg.get(group='client',
                           option='installed plugins',
                           source_order=[('system', 'extend'),
                                         ('user', 'extend'),
                                         ('workbase', 'extend'),
                                         ('explicit', 'extend')])
        if plugins is None:
            _log.debug('no plugins found in config files')
            return []
        _log.debug("plugins found: %s" % str(plugins))
        return plugins

    _log.info("scanning plugin directory [%s]" % search_path)

    files = glob.glob(os.path.join(search_path, 'gm*.py'))
    plugins = []
    for f in files:
        path, fname = os.path.split(f)
        mod_name, ext = os.path.splitext(fname)
        plugins.append(mod_name)

    _log.debug("plugins found: %s" % str(plugins))

    return plugins
Beispiel #28
0
def _print_files_by_shellscript(filenames=None, jobtype=None, verbose=False):

	paths = gmTools.gmPaths()
	local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', 'gm-print_doc')
	#candidates = [u'gm-print_doc', u'gm-print_doc.bat', local_script, u'gm-print_doc.bat']
	candidates = ['gm-print_doc', local_script, 'gm-print_doc.bat']
	found, binary = gmShellAPI.find_first_binary(binaries = candidates)
	if not found:
		binary = r'gm-print_doc.bat'
	cmd_line = [binary,	jobtype]
	cmd_line.extend(filenames)
	success, returncode, stdout = gmShellAPI.run_process(cmd_line = cmd_line, verbose = verbose)
	if not success:
		return False
	return True
Beispiel #29
0
	def __init__(self):
		cGelbeListeWindowsInterface.__init__(self)

		_log.info('%s (WINE extension)', cGelbeListeWindowsInterface.version)

		# FIXME: if -CLOSETOTRAY is used GNUmed cannot detect the end of MMI
		self.path_to_binary = r'wine "C:\Programme\MMI PHARMINDEX\glwin.exe"'
		self.args = r'"-PRESCRIPTIONFILE %s -KEEPBACKGROUND"'

		paths = gmTools.gmPaths()

		self.default_csv_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'mmi2gm.csv')
		self.default_csv_filename_arg = r'c:\windows\temp\mmi2gm.csv'
		self.interactions_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'gm2mmi.bdt')
		self.data_date_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'Programme', 'MMI PHARMINDEX', 'datadate.txt')
Beispiel #30
0
	def _on_select_directory_button_pressed(self, event):
		event.Skip()
		curr_path = self._LBL_directory.Label.rstrip(os.sep).rstrip('/')
		if not os.path.isdir(curr_path):
			curr_path = os.path.join(gmTools.gmPaths().home_dir, 'gnumed')
		msg = _('Select directory where to save the archive or files.')
		dlg = wx.DirDialog(self, message = msg, defaultPath = curr_path, style = wx.DD_DEFAULT_STYLE)# | wx.DD_DIR_MUST_EXIST)
		choice = dlg.ShowModal()
		selected_path = dlg.GetPath().rstrip(os.sep).rstrip('/')
		dlg.DestroyLater()
		if choice != wx.ID_OK:
			return

		self._LBL_directory.Label = selected_path + os.sep
		self.__update_ui_state()
Beispiel #31
0
	def __init__(self):
		cGelbeListeWindowsInterface.__init__(self)

		_log.info('%s (WINE extension)', cGelbeListeWindowsInterface.version)

		# FIXME: if -CLOSETOTRAY is used GNUmed cannot detect the end of MMI
		self.path_to_binary = r'wine "C:\Programme\MMI PHARMINDEX\glwin.exe"'
		self.args = r'"-PRESCRIPTIONFILE %s -KEEPBACKGROUND"'

		paths = gmTools.gmPaths()

		self.default_csv_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'mmi2gm.csv')
		self.default_csv_filename_arg = r'c:\windows\temp\mmi2gm.csv'
		self.interactions_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'windows', 'temp', 'gm2mmi.bdt')
		self.data_date_filename = os.path.join(paths.home_dir, '.wine', 'drive_c', 'Programme', 'MMI PHARMINDEX', 'datadate.txt')
Beispiel #32
0
def setup_hook_dir():
	_old_path = os.path.join(gmTools.gmPaths().home_dir, '.gnumed', 'scripts')
	if os.path.isdir(_old_path):
		print('obsolete: [%s], use [%s]' %(_old_path, HOOK_SCRIPT_DIR))
		_log.debug('obsolete: %s', _old_path)
	_log.debug('known hooks:')
	for hook in known_hooks:
		_log.debug(hook)
	gmTools.mkdir(HOOK_SCRIPT_DIR)
	gmTools.create_directory_description_file(directory = HOOK_SCRIPT_DIR, readme = README_hook_dir)
	# create hook script example/template
	example_name = os.path.join(HOOK_SCRIPT_DIR, HOOK_SCRIPT_NAME + '.example')
	example = open(example_name, mode = 'wt', encoding = 'utf8')
	example.write(HOOK_SCRIPT_EXAMPLE)
	example.close()
	os.chmod(example_name, 384)
Beispiel #33
0
	def __init__(self):
		cDrugDataSourceInterface.__init__(self)
		_log.info(cFreeDiamsInterface.version)

		self.__imported_drugs = []

		self.__gm2fd_filename = gmTools.get_unique_filename(prefix = r'gm2freediams-', suffix = r'.xml')
		_log.debug('GNUmed -> FreeDiams "exchange-in" file: %s', self.__gm2fd_filename)
		self.__fd2gm_filename = gmTools.get_unique_filename(prefix = r'freediams2gm-', suffix = r'.xml')
		_log.debug('GNUmed <-> FreeDiams "exchange-out"/"prescription" file: %s', self.__fd2gm_filename)
		# this file can be modified by the user as needed (therefore in user_config_dir):
		self.__fd4gm_config_file = os.path.join(gmTools.gmPaths().user_config_dir, 'freediams4gm.conf')
		_log.debug('FreeDiams config file for GNUmed use: %s', self.__fd4gm_config_file)

		self.path_to_binary = None
		self.__detect_binary()
Beispiel #34
0
def _print_files_by_shellscript(filenames=None, jobtype=None, verbose=False):

    paths = gmTools.gmPaths()
    local_script = os.path.join(paths.local_base_dir, '..', 'external-tools',
                                'gm-print_doc')
    candidates = ['gm-print_doc', local_script, 'gm-print_doc.bat']
    found, binary = gmShellAPI.find_first_binary(binaries=candidates)
    if not found:
        binary = r'gm-print_doc.bat'
    cmd_line = [binary, jobtype]
    cmd_line.extend(filenames)
    success, returncode, stdout = gmShellAPI.run_process(cmd_line=cmd_line,
                                                         verbose=verbose)
    if not success:
        return False
    return True
Beispiel #35
0
	def __init__(self):
		cDrugDataSourceInterface.__init__(self)
		_log.info(cFreeDiamsInterface.version)

		self.__imported_drugs = []

		self.__gm2fd_filename = gmTools.get_unique_filename(prefix = r'gm2freediams-', suffix = r'.xml')
		_log.debug('GNUmed -> FreeDiams "exchange-in" file: %s', self.__gm2fd_filename)
		self.__fd2gm_filename = gmTools.get_unique_filename(prefix = r'freediams2gm-', suffix = r'.xml')
		_log.debug('GNUmed <-> FreeDiams "exchange-out"/"prescription" file: %s', self.__fd2gm_filename)
		paths = gmTools.gmPaths()
		# this file can be modified by the user as needed:
		self.__fd4gm_config_file = os.path.join(paths.home_dir, '.gnumed', 'freediams4gm.conf')
		_log.debug('FreeDiams config file for GNUmed use: %s', self.__fd4gm_config_file)

		self.path_to_binary = None
		self.__detect_binary()
Beispiel #36
0
    def __init_ui(self):

        self._LBL_dir_is_empty.Label = ''
        self._LBL_subdirectory.Label = ''

        if self.__burn2cd:
            self._LBL_existing_data.Hide()
            self._BTN_browse_directory.Disable()
            self._RBTN_include_data.Hide()
            self._RBTN_remove_data.Hide()
            self._CHBOX_include_directory.Show()
            self._CHBOX_use_subdirectory.Hide()
            self._LBL_subdirectory.Hide()
            self._CHBOX_generate_metadata.Hide()
            lines = [
                _('Preparing patient media for burning onto CD / DVD'), ''
            ]
            found, external_cmd = gmShellAPI.detect_external_binary(
                'gm-burn_doc')
            if not found:
                lines.append(_('Script <gm-burn_doc(.bat)> not found.'))
                lines.append('')
                lines.append(
                    _('Cannot attempt to burn patient media onto CD/DVD.'))
                self._BTN_save.Disable()
            else:
                lines.append(
                    _('Patient: %s') % self.__patient['description_gender'])
                lines.append('')
                lines.append(
                    _('Number of items to export onto CD/DVD: %s\n') %
                    self.__item_count)
            self._LBL_header.Label = '\n'.join(lines)
            return

        lines = [
            _('Preparing patient media for saving to disk (USB, harddrive).'),
            '',
            _('Patient: %s') % self.__patient['description_gender'], '',
            _('Number of items to export to disk: %s\n') % self.__item_count
        ]
        self._LBL_header.Label = '\n'.join(lines)
        self._LBL_directory.Label = os.path.join(gmTools.gmPaths().home_dir,
                                                 'gnumed')
        self.__refresh_dir_is_empty()
Beispiel #37
0
	def __get_session_xsanerc(self):

		# create an xsanerc for this session
		session_xsanerc = gmTools.get_unique_filename (
			prefix = 'gm-session_xsanerc-',
			suffix = '.conf'
		)
		_log.debug('GNUmed -> XSane session xsanerc: %s', session_xsanerc)

		# our closest bet, might contain umlauts
		enc = gmI18N.get_encoding()
		fread = io.open(self._gm_custom_xsanerc, mode = "rt", encoding = enc)
		fwrite = io.open(session_xsanerc, mode = "wt", encoding = enc)

		paths = gmTools.gmPaths()
		val_dict = {
			'tmp-path': paths.tmp_dir,
			'working-directory': paths.tmp_dir,
			'filename': '<--force-filename>',
			'filetype': cXSaneScanner._FILETYPE,
			'skip-existing-numbers': '1',
			'filename-counter-step': '1',
			'filename-counter-len': '3'
		}

		for idx, line in enumerate(fread):
			line = line.replace('\n', '')
			line = line.replace('\r', '')

			if idx % 2 == 0:			# even lines are keys
				curr_key = line.strip('"')
				fwrite.write('"%s"\n' % curr_key)
			else: 						# odd lines are corresponding values
				try:
					value = val_dict[curr_key]
					_log.debug('replaced [%s] with [%s]', curr_key, val_dict[curr_key])
				except KeyError:
					value = line
				fwrite.write('%s\n' % value)

		fwrite.flush()
		fwrite.close()
		fread.close()

		return session_xsanerc
Beispiel #38
0
	def __init__(self):

		cDrugDataSourceInterface.__init__(self)

		_log.info('%s (native Windows)', cGelbeListeWindowsInterface.version)

		self.path_to_binary = r'C:\Programme\MMI PHARMINDEX\glwin.exe'
		self.args = r'-KEEPBACKGROUND -PRESCRIPTIONFILE %s -CLOSETOTRAY'

		paths = gmTools.gmPaths()

		self.default_csv_filename = os.path.join(paths.tmp_dir, 'rezept.txt')
		self.default_csv_filename_arg = paths.tmp_dir
		self.interactions_filename = os.path.join(paths.tmp_dir, 'gm2mmi.bdt')
		self.data_date_filename = r'C:\Programme\MMI PHARMINDEX\datadate.txt'

		self.__data_date = None
		self.__online_update_date = None
Beispiel #39
0
	def __init__(self):

		cDrugDataSourceInterface.__init__(self)

		_log.info('%s (native Windows)', cGelbeListeWindowsInterface.version)

		self.path_to_binary = r'C:\Programme\MMI PHARMINDEX\glwin.exe'
		self.args = r'-KEEPBACKGROUND -PRESCRIPTIONFILE %s -CLOSETOTRAY'

		paths = gmTools.gmPaths()

		self.default_csv_filename = os.path.join(paths.tmp_dir, 'rezept.txt')
		self.default_csv_filename_arg = paths.tmp_dir
		self.interactions_filename = os.path.join(paths.tmp_dir, 'gm2mmi.bdt')
		self.data_date_filename = r'C:\Programme\MMI PHARMINDEX\datadate.txt'

		self.__data_date = None
		self.__online_update_date = None
Beispiel #40
0
def convert_file(filename=None, target_mime=None, target_filename=None, target_extension=None):
	"""Convert file from one format into another.

		target_mime: a mime type
	"""
	source_mime = guess_mimetype(filename = filename)
	if source_mime.lower() == target_mime.lower():
		_log.debug('source file [%s] already target mime type [%s]', filename, target_mime)
		shutil.copyfile(filename, target_filename)
		return True

	if target_extension is None:
		tmp, target_extension = os.path.splitext(target_filename)

	base_name = 'gm-convert_file'

	paths = gmTools.gmPaths()
	local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', base_name)

	candidates = [ base_name, local_script ]		#, base_name + u'.bat'
	found, binary = gmShellAPI.find_first_binary(binaries = candidates)
	if not found:
		binary = base_name# + r'.bat'

	cmd_line = [
		binary,
		filename,
		target_mime,
		target_extension.strip('.'),
		target_filename
	]
	_log.debug('converting: %s', cmd_line)
	try:
		gm_convert = subprocess.Popen(cmd_line)
	except OSError:
		_log.debug('cannot run <%s(.bat)>', base_name)
		return False
	gm_convert.communicate()
	if gm_convert.returncode != 0:
		_log.error('<%s(.bat)> returned [%s], failed to convert', base_name, gm_convert.returncode)
		return False

	return True
Beispiel #41
0
    def _on_save_button_pressed(self, event):
        if self.__tl_file is None:
            return
        dlg = wx.FileDialog(
            parent=self,
            message=_("Save timeline as images (SVG, PNG) under..."),
            defaultDir=gmTools.gmPaths().user_work_dir,
            defaultFile='timeline.svg',
            wildcard='%s (*.svg)|*.svg' % _('SVG files'),
            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        choice = dlg.ShowModal()
        fname = dlg.GetPath()
        dlg.DestroyLater()
        if choice != wx.ID_OK:
            return False

        self._PNL_timeline.export_as_svg(filename=fname)
        self._PNL_timeline.export_as_png(
            filename=gmTools.fname_stem_with_path(fname) + '.png')
Beispiel #42
0
def convert_file(filename=None, target_mime=None, target_filename=None, target_extension=None):
	"""Convert file from one format into another.

		target_mime: a mime type
	"""
	source_mime = guess_mimetype(filename = filename)
	if source_mime.lower() == target_mime.lower():
		_log.debug('source file [%s] already target mime type [%s]', filename, target_mime)
		shutil.copyfile(filename, target_filename)
		return True

	if target_extension is None:
		tmp, target_extension = os.path.splitext(target_filename)

	base_name = 'gm-convert_file'

	paths = gmTools.gmPaths()
	local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', base_name)

	candidates = [ base_name, local_script ]		#, base_name + u'.bat'
	found, binary = gmShellAPI.find_first_binary(binaries = candidates)
	if not found:
		binary = base_name# + r'.bat'

	cmd_line = [
		binary,
		filename,
		target_mime,
		target_extension.strip('.'),
		target_filename
	]
	_log.debug('converting: %s', cmd_line)
	try:
		gm_convert = subprocess.Popen(cmd_line)
	except OSError:
		_log.debug('cannot run <%s(.bat)>', base_name)
		return False
	gm_convert.communicate()
	if gm_convert.returncode != 0:
		_log.error('<%s(.bat)> returned [%s], failed to convert', base_name, gm_convert.returncode)
		return False

	return True
Beispiel #43
0
def __run_file_describer(filename=None):

	base_name = 'gm-describe_file'

	paths = gmTools.gmPaths()
	local_script = os.path.join(paths.local_base_dir, '..', 'external-tools', base_name)

	candidates = [ base_name, local_script ]		#, base_name + u'.bat'
	found, binary = gmShellAPI.find_first_binary(binaries = candidates)
	if not found:
		#binary = base_name# + r'.bat'
		_log.debug('cannot find <%s(.bat)>', base_name)
		return (False, _('<%s(.bat)> not found') % base_name)

	desc_fname = gmTools.get_unique_filename()

	cmd_line = [
		binary,
		filename,
		desc_fname
	]
	_log.debug('describing: %s', cmd_line)
	try:
		gm_describe = subprocess.Popen(cmd_line)
	except OSError:
		_log.debug('cannot run <%s>', binary)
		return (False, _('problem with <%s>') % binary)

	gm_describe.communicate()
	if gm_describe.returncode != 0:
		_log.error('<%s> returned [%s], failed to convert', binary, gm_describe.returncode)
		return (False, _('problem with <%s>') % binary)

	try:
		desc_file = io.open(desc_fname, mode = 'rt', encoding = 'utf8', errors = 'replace')
	except IOError:
		_log.exception('cannot open [%s]', desc_fname)
		return (False, _('problem with <%s>') % binary)

	desc = ''.join(desc_file)
	desc_file.close()
	return (True, desc)
Beispiel #44
0
def create_zip_archive_from_dir(source_dir, archive_name=None, comment=None, overwrite=True, verbose=False):

	source_dir = os.path.abspath(source_dir)
	if not os.path.isdir(source_dir):
		_log.error('<source_dir> does not exist or is not a directory: %s', source_dir)
		return False

	for cmd in ['7z', '7z.exe']:
		found, binary = gmShellAPI.detect_external_binary(binary = cmd)
		if found:
			break
	if not found:
		_log.warning('no 7z binary found')
		return None

	if archive_name is None:
		# do not assume we can write to "sourcedir/../"
		archive_path = gmTools.gmPaths().tmp_dir
		# but do take archive name from source_dir
		tmp, archive_fname = os.path.split(source_dir.rstrip(os.sep) + '.zip')
		archive_name = os.path.join(archive_path, archive_fname)
	# remove any existing archives so they don't get *updated*
	# rather than newly created
	if overwrite:
		if not gmTools.remove_file(archive_name, force = True):
			_log.error('cannot remove existing archive [%s]', archive_name)
			return False
	# 7z does not support ZIP comments so create
	# a text file holding the comment ...
	if comment is not None:
		comment_filename = os.path.abspath(archive_name) + '.comment.txt'
		if gmTools.remove_file(comment_filename, force = True):
			with open(comment_filename, mode = 'wt', encoding = 'utf8', errors = 'replace') as comment_file:
				comment_file.write(comment)
		else:
			_log.error('cannot remove existing archive comment file [%s]', comment_filename)
			comment = None

	# compress
	args = [
		binary,
		'a',				# create archive
		'-sas',				# be smart about archive name extension
		'-bd',				# no progress indicator
		'-mx9',				# best available zip compression ratio
		'-mcu=on',			# UTF8 filenames
		'-l',				# store content of links, not links
		'-scsUTF-8',		# console charset
		'-tzip'				# force ZIP format
	]
	if verbose:
		args.append('-bb3')
		args.append('-bt')
	else:
		args.append('-bb1')
	args.append(archive_name)
	args.append(source_dir)
	if comment is not None:
		args.append(comment_filename)
	success, exit_code, stdout = gmShellAPI.run_process(cmd_line = args, encoding = 'utf8', verbose = verbose)
	if comment is not None:
		gmTools.remove_file(comment_filename)
	if success:
		return archive_name

	return None
Beispiel #45
0
def create_encrypted_zip_archive_from_dir(source_dir, comment=None, overwrite=True, passphrase=None, verbose=False):
	"""Use 7z to create an encrypted ZIP archive of a directory.

	<source_dir>		will be included into the archive
	<comment>			included as a file containing the comment
	<overwrite>			remove existing archive before creation, avoiding
						*updating* of those, and thereby including unintended data
	<passphrase>		minimum length of 5

	The resulting zip archive will always be named
	"datawrapper.zip" for confidentiality reasons. If callers
	want another name they will have to shutil.move() the zip
	file themselves. This archive will be compressed and
	AES256 encrypted with the given passphrase. Therefore,
	the result will not decrypt with earlier versions of
	unzip software. On Windows, 7z oder WinZip are needed.

	The zip format does not support header encryption thereby
	allowing attackers to gain knowledge of patient details
	by observing the names of files and directories inside
	the encrypted archive.

	To reduce that attack surface, GNUmed will create
	_another_ zip archive inside "datawrapper.zip", which
	eventually wraps up the patient data as "data.zip". That
	archive is not compressed and not encrypted, and can thus
	be unpacked with any old unzipper.

	Note that GNUmed does NOT remember the passphrase for
	you. You will have to take care of that yourself, and
	possibly also safely hand over the passphrase to any
	receivers of the zip archive.
	"""
	if len(passphrase) < 5:
		_log.error('<passphrase> must be at least 5 characters/signs/digits')
		return None
	gmLog2.add_word2hide(passphrase)

	source_dir = os.path.abspath(source_dir)
	if not os.path.isdir(source_dir):
		_log.error('<source_dir> does not exist or is not a directory: %s', source_dir)
		return False

	for cmd in ['7z', '7z.exe']:
		found, binary = gmShellAPI.detect_external_binary(binary = cmd)
		if found:
			break
	if not found:
		_log.warning('no 7z binary found')
		return None

	sandbox_dir = gmTools.mk_sandbox_dir()
	archive_path_inner = os.path.join(sandbox_dir, 'data')
	if not gmTools.mkdir(archive_path_inner):
		_log.error('cannot create scratch space for inner achive: %s', archive_path_inner)
	archive_fname_inner = 'data.zip'
	archive_name_inner = os.path.join(archive_path_inner, archive_fname_inner)
	archive_path_outer = gmTools.gmPaths().tmp_dir
	archive_fname_outer = 'datawrapper.zip'
	archive_name_outer = os.path.join(archive_path_outer, archive_fname_outer)
	# remove existing archives so they don't get *updated* rather than newly created
	if overwrite:
		if not gmTools.remove_file(archive_name_inner, force = True):
			_log.error('cannot remove existing archive [%s]', archive_name_inner)
			return False

		if not gmTools.remove_file(archive_name_outer, force = True):
			_log.error('cannot remove existing archive [%s]', archive_name_outer)
			return False

	# 7z does not support ZIP comments so create a text file holding the comment
	if comment is not None:
		tmp, fname = os.path.split(source_dir.rstrip(os.sep))
		comment_filename = os.path.join(sandbox_dir, '000-%s-comment.txt' % fname)
		with open(comment_filename, mode = 'wt', encoding = 'utf8', errors = 'replace') as comment_file:
			comment_file.write(comment)

	# create inner (data) archive: uncompressed, unencrypted, similar to a tar archive
	args = [
		binary,
		'a',				# create archive
		'-sas',				# be smart about archive name extension
		'-bd',				# no progress indicator
		'-mx0',				# no compression (only store files)
		'-mcu=on',			# UTF8 filenames
		'-l',				# store content of links, not links
		'-scsUTF-8',		# console charset
		'-tzip'				# force ZIP format
	]
	if verbose:
		args.append('-bb3')
		args.append('-bt')
	else:
		args.append('-bb1')
	args.append(archive_name_inner)
	args.append(source_dir)
	if comment is not None:
		args.append(comment_filename)
	success, exit_code, stdout = gmShellAPI.run_process(cmd_line = args, encoding = 'utf8', verbose = verbose)
	if not success:
		_log.error('cannot create inner archive')
		return None

	# create "decompress instructions" file
	instructions_filename = os.path.join(archive_path_inner, '000-on_Windows-open_with-WinZip_or_7z_tools')
	open(instructions_filename, mode = 'wt').close()

	# create outer (wrapper) archive: compressed, encrypted
	args = [
		binary,
		'a',					# create archive
		'-sas',					# be smart about archive name extension
		'-bd',					# no progress indicator
		'-mx9',					# best available zip compression ratio
		'-mcu=on',				# UTF8 filenames
		'-l',					# store content of links, not links
		'-scsUTF-8',			# console charset
		'-tzip',				# force ZIP format
		'-mem=AES256',			# force useful encryption
		'-p%s' % passphrase		# set passphrase
	]
	if verbose:
		args.append('-bb3')
		args.append('-bt')
	else:
		args.append('-bb1')
	args.append(archive_name_outer)
	args.append(archive_path_inner)
	success, exit_code, stdout = gmShellAPI.run_process(cmd_line = args, encoding = 'utf8', verbose = verbose)
	if success:
		return archive_name_outer
	_log.error('cannot create outer archive')
	return None
Beispiel #46
0
#============================================================
# main
#------------------------------------------------------------
if __name__ == "__main__":

	if len(sys.argv) < 2:
		sys.exit()

	if sys.argv[1] != 'test':
		sys.exit()

	from Gnumed.pycommon import gmLog2

	gmDateTime.init()
	gmTools.gmPaths()

	#-------------------------------------------------------
	def test_import_HL7(filename):
		# would normally be set by external configuration:
		from Gnumed.business import gmPraxis
		gmPraxis.gmCurrentPraxisBranch(branch = gmPraxis.get_praxis_branches()[0])
		if not import_hl7_file(filename):
			print "error with", filename
	#-------------------------------------------------------
	def test_xml_extract():
		hl7 = extract_HL7_from_XML_CDATA(sys.argv[2], u'.//Message')
		print "HL7:", hl7
		#result, PID_fnames = split_hl7_file(hl7)
		#print "result:", result
		#print "per-PID MSH files:"
Beispiel #47
0
		_log.info(u'identity: %s', identity)
		filename = gmTools.get_unique_filename (
			prefix = u'gm_exp-%s-' % identity.dirname,
			suffix = u'.xdt',
			tmp_dir = path
		)
		_log.info(u'file: %s', filename)
		identity.export_as_gdt (
			filename = filename,
			encoding = u'utf8'
			#encoding = u'iso-8859-15'
		)

#============================================================
# main
#------------------------------------------------------------
if __name__ == '__main__':

	if len(sys.argv) < 2:
		sys.exit()

	if sys.argv[1] != "test":
		sys.exit()

	path = None
	if len(sys.argv) > 2:
		path = sys.argv[2]

	paths = gmTools.gmPaths(app_name = u'gnumed')
	export_patients_as_xdt(base_path = path)
Beispiel #48
0
    def __init__(
        self,
        parent,
        id,
        pos=wx.DefaultPosition,
        size=wx.DefaultSize,
        style=wx.TAB_TRAVERSAL,
        isDialog=0,
        client_version=u"*** unknown ***",
    ):
        """Create login panel.

		isDialog:	if this panel is the main panel of a dialog, the panel will
					resize the dialog automatically to display everything neatly
					if isDialog is set to True
		"""
        wx.Panel.__init__(self, parent, id, pos, size, style)
        self.parent = parent

        # True if dialog was cancelled by user
        # if the dialog is closed manually, login should be cancelled
        self.cancelled = True

        # True if this panel is displayed within a dialog (will resize the dialog automatically then)
        self.isDialog = isDialog

        self.topsizer = wx.BoxSizer(wx.VERTICAL)

        # find bitmap
        paths = gmTools.gmPaths(app_name=u"gnumed", wx=wx)
        bitmap = os.path.join(paths.system_app_data_dir, "bitmaps", "gnumedlogo.png")
        try:
            png = wx.Image(bitmap, wx.BITMAP_TYPE_PNG).ConvertToBitmap()
            bmp = wx.StaticBitmap(self, -1, png, wx.Point(10, 10), wx.Size(png.GetWidth(), png.GetHeight()))
            self.topsizer.Add(
                bmp, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, border=10
            )
        except:
            self.topsizer.Add(
                wx.StaticText(self, -1, label=_("Cannot find image") + bitmap, style=wx.ALIGN_CENTRE),
                proportion=0,
                flag=wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                border=10,
            )

        paramsbox_caption = _('Workplace "%s" (version %s)') % (
            gmPraxis.gmCurrentPraxisBranch().active_workplace,
            client_version,
        )

        # FIXME: why doesn't this align in the centre ?
        self.paramsbox = wx.StaticBox(self, -1, paramsbox_caption, style=wx.ALIGN_CENTRE_HORIZONTAL)
        self.paramsboxsizer = wx.StaticBoxSizer(self.paramsbox, wx.VERTICAL)
        self.paramsbox.SetForegroundColour(wx.Colour(35, 35, 142))
        self.paramsbox.SetFont(wx.Font(pointSize=12, family=wx.SWISS, style=wx.NORMAL, weight=wx.BOLD, underline=False))
        self.pboxgrid = wx.FlexGridSizer(5, 2, 5, 5)
        self.pboxgrid.AddGrowableCol(1)

        # PROFILE COMBO
        label = wx.StaticText(self, -1, _("Log into"), wx.DefaultPosition, wx.DefaultSize, 0)
        label.SetForegroundColour(wx.Colour(35, 35, 142))
        self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
        self.__backend_profiles = self.__get_backend_profiles()
        self._CBOX_profile = wx.ComboBox(
            self,
            -1,
            self.__backend_profiles.keys()[0],
            wx.DefaultPosition,
            size=wx.Size(550, -1),
            choices=self.__backend_profiles.keys(),
            style=wx.CB_READONLY,
        )
        self.pboxgrid.Add(self._CBOX_profile, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        # USER NAME COMBO
        label = wx.StaticText(self, -1, _("Username"), wx.DefaultPosition, wx.DefaultSize, 0)
        label.SetForegroundColour(wx.Colour(35, 35, 142))
        self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
        self.__previously_used_accounts = self.__get_previously_used_accounts()
        self._CBOX_user = wx.ComboBox(
            self,
            -1,
            self.__previously_used_accounts[0],
            wx.DefaultPosition,
            wx.Size(150, -1),
            self.__previously_used_accounts,
            wx.CB_DROPDOWN,
        )
        self.pboxgrid.Add(self._CBOX_user, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        # PASSWORD TEXT ENTRY
        label = wx.StaticText(self, -1, _("Password"), wx.DefaultPosition, wx.DefaultSize, 0)
        label.SetForegroundColour(wx.Colour(35, 35, 142))
        self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
        self.pwdentry = wx.TextCtrl(self, 1, "", wx.DefaultPosition, wx.Size(80, -1), wx.TE_PASSWORD)
        # set focus on password entry
        self.pwdentry.SetFocus()
        self.pboxgrid.Add(self.pwdentry, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        # --debug checkbox
        label = wx.StaticText(self, -1, _("Options"), wx.DefaultPosition, wx.DefaultSize, 0)
        label.SetForegroundColour(wx.Colour(35, 35, 142))
        self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
        self._CHBOX_debug = wx.CheckBox(self, -1, _("&Debug mode"))
        self._CHBOX_debug.SetToolTipString(_("Check this to run GNUmed client in debugging mode."))
        self.pboxgrid.Add(self._CHBOX_debug, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        # --slave checkbox
        label = wx.StaticText(self, -1, "", wx.DefaultPosition, wx.DefaultSize, 0)
        label.SetForegroundColour(wx.Colour(35, 35, 142))
        self.pboxgrid.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
        self._CHBOX_slave = wx.CheckBox(self, -1, _("Enable &remote control"))
        self._CHBOX_slave.SetToolTipString(_("Check this to run GNUmed client in slave mode for remote control."))
        self.pboxgrid.Add(self._CHBOX_slave, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        # ----------------------------------------------------------------------
        # new button code inserted rterry 06Sept02
        # button order re-arraged to make it consistant with usual dialog format
        # in most operating systems ie  btns ok and cancel are standard and
        # in that order
        # ie Order is now help, ok and cancel
        # The order of creation is the tab order
        # login-ok button automatically is the default when tabbing (or <enter>)
        # from password
        # this eliminates the heavy border when you use the default
        # ?is the default word needed for any other reason?
        # ----------------------------------------------------------------------
        self.button_gridsizer = wx.GridSizer(1, 3, 0, 0)
        # ---------------------
        # 3:create login ok button
        # ---------------------
        ID_BUTTON_LOGIN = wx.NewId()
        button_login_ok = wx.Button(self, ID_BUTTON_LOGIN, _("&Ok"), wx.DefaultPosition, wx.DefaultSize, 0)
        button_login_ok.SetToolTip(wx.ToolTip(_("Proceed with login.")))
        button_login_ok.SetDefault()

        # ---------------------
        # 3:create cancel button
        # ---------------------
        ID_BUTTON_CANCEL = wx.NewId()
        button_cancel = wx.Button(self, ID_BUTTON_CANCEL, _("&Cancel"), wx.DefaultPosition, wx.DefaultSize, 0)
        button_cancel.SetToolTip(wx.ToolTip(_("Cancel Login.")))
        # ---------------------
        # 2:create Help button
        # ---------------------
        ID_BUTTON_HELP = wx.NewId()
        button_help = wx.Button(self, ID_BUTTON_HELP, _("&Help"), wx.DefaultPosition, wx.DefaultSize, 0)
        button_help.SetToolTip(wx.ToolTip(_("Help for login screen")))
        # ----------------------------
        # Add buttons to the gridsizer
        # ----------------------------
        self.button_gridsizer.Add(button_help, 0, wx.EXPAND | wx.ALL, 5)
        self.button_gridsizer.Add(button_login_ok, 0, wx.EXPAND | wx.ALL, 5)
        self.button_gridsizer.Add(button_cancel, 0, wx.EXPAND | wx.ALL, 5)

        self.paramsboxsizer.Add(self.pboxgrid, 1, wx.GROW | wx.ALL, 10)
        self.topsizer.Add(self.paramsboxsizer, 1, wx.GROW | wx.ALL, 10)
        self.topsizer.Add(self.button_gridsizer, 0, wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        self.__load_state()

        self.SetAutoLayout(True)
        self.SetSizer(self.topsizer)
        self.topsizer.Fit(self)
        if self.isDialog:
            self.topsizer.SetSizeHints(parent)

        wx.EVT_BUTTON(self, ID_BUTTON_HELP, self.OnHelp)
        wx.EVT_BUTTON(self, ID_BUTTON_LOGIN, self.__on_login_button_pressed)
        wx.EVT_BUTTON(self, ID_BUTTON_CANCEL, self.OnCancel)