示例#1
0
文件: gmMimeLib.py 项目: ncqgm/gnumed
	def test_edit():

		mimetypes = [
			'application/x-latex',
			'application/x-tex',
			'text/latex',
			'text/tex',
			'text/plain'
		]

		for mimetype in mimetypes:
			editor_cmd = get_editor_cmd(mimetype, filename)
			if editor_cmd is not None:
				break

		if editor_cmd is None:
			# LaTeX code is text: also consider text *viewers*
			# since pretty much any of them will be an editor as well
			for mimetype in mimetypes:
				editor_cmd = get_viewer_cmd(mimetype, filename)
				if editor_cmd is not None:
					break

		if editor_cmd is None:
			return False

		result = gmShellAPI.run_command_in_shell(command = editor_cmd, blocking = True)

		return result
示例#2
0
    def _on_mail_items_button_pressed(self, event):
        event.Skip()

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

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

        files2mail = []
        for item in items:
            files2mail.append(item.save_to_file())

        cmd = '%s %s' % (external_cmd, ' '.join(files2mail))
        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 mailing documents.'),
                                       aTitle=_('Mailing documents'))
            return False

        self.save_soap_note(soap=_('Mailed:\n - %s') %
                            '\n - '.join([i['description'] for i in items]))
        return True
示例#3
0
    def test_edit():

        mimetypes = [
            'application/x-latex', 'application/x-tex', 'text/latex',
            'text/tex', 'text/plain'
        ]

        for mimetype in mimetypes:
            editor_cmd = get_editor_cmd(mimetype, filename)
            if editor_cmd is not None:
                break

        if editor_cmd is None:
            # LaTeX code is text: also consider text *viewers*
            # since pretty much any of them will be an editor as well
            for mimetype in mimetypes:
                editor_cmd = get_viewer_cmd(mimetype, filename)
                if editor_cmd is not None:
                    break

        if editor_cmd is None:
            return False

        result = gmShellAPI.run_command_in_shell(command=editor_cmd,
                                                 blocking=True)

        return result
示例#4
0
	def acquire_pages_into_files(self, delay=None, filename=None):
		"""Call XSane.

		<filename> name part must have format name-001.ext>
		"""
		if filename is None:
			filename = gmTools.get_unique_filename(prefix = 'gm-scan-')

		name, ext = os.path.splitext(filename)
		filename = '%s-001%s' % (name, cXSaneScanner._FILETYPE)
		filename = os.path.abspath(os.path.expanduser(filename))

		cmd = 'xsane --no-mode-selection --save --force-filename "%s" --xsane-rc "%s" %s %s' % (
			filename,
			self.__get_session_xsanerc(),
			gmTools.coalesce(self.device_settings_file, '', '--device-settings %s'),
			gmTools.coalesce(self.default_device, '')
		)
		normal_exit = gmShellAPI.run_command_in_shell(command = cmd, blocking = True)

		if normal_exit:
			flist = glob.glob(filename.replace('001', '*'))
			flist.sort()
			return flist

		raise OSError(-1, 'error running XSane as [%s]' % cmd)
示例#5
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
示例#6
0
	def get_data_source_version(self, force_reload=False):

		if self.__data_date is not None:
			if not force_reload:
				return {
					'data': self.__data_date,
					'online_update': self.__online_update_date
				}
		try:
			open(self.data_date_filename, 'wb').close()
		except Exception:
			_log.error('problem querying the MMI drug database for version information')
			_log.exception('cannot create MMI drug database version file [%s]', self.data_date_filename)
			self.__data_date = None
			self.__online_update_date = None
			return {
				'data': '?',
				'online_update': '?'
			}

		cmd = '%s -DATADATE' % self.path_to_binary
		if not gmShellAPI.run_command_in_shell(command = cmd, blocking = True):
			_log.error('problem querying the MMI drug database for version information')
			self.__data_date = None
			self.__online_update_date = None
			return {
				'data': '?',
				'online_update': '?'
			}

		try:
			version_file = io.open(self.data_date_filename, mode = 'rt', encoding = 'utf8')
		except Exception:
			_log.error('problem querying the MMI drug database for version information')
			_log.exception('cannot open MMI drug database version file [%s]', self.data_date_filename)
			self.__data_date = None
			self.__online_update_date = None
			return {
				'data': '?',
				'online_update': '?'
			}

		self.__data_date = version_file.readline()[:10]
		self.__online_update_date = version_file.readline()[:10]
		version_file.close()

		return {
			'data': self.__data_date,
			'online_update': self.__online_update_date
		}
示例#7
0
	def get_data_source_version(self, force_reload=False):

		if self.__data_date is not None:
			if not force_reload:
				return {
					'data': self.__data_date,
					'online_update': self.__online_update_date
				}
		try:
			open(self.data_date_filename, 'wb').close()
		except Exception:
			_log.error('problem querying the MMI drug database for version information')
			_log.exception('cannot create MMI drug database version file [%s]', self.data_date_filename)
			self.__data_date = None
			self.__online_update_date = None
			return {
				'data': '?',
				'online_update': '?'
			}

		cmd = '%s -DATADATE' % self.path_to_binary
		if not gmShellAPI.run_command_in_shell(command = cmd, blocking = True):
			_log.error('problem querying the MMI drug database for version information')
			self.__data_date = None
			self.__online_update_date = None
			return {
				'data': '?',
				'online_update': '?'
			}

		try:
			version_file = io.open(self.data_date_filename, mode = 'rt', encoding = 'utf8')
		except Exception:
			_log.error('problem querying the MMI drug database for version information')
			_log.exception('cannot open MMI drug database version file [%s]', self.data_date_filename)
			self.__data_date = None
			self.__online_update_date = None
			return {
				'data': '?',
				'online_update': '?'
			}

		self.__data_date = version_file.readline()[:10]
		self.__online_update_date = version_file.readline()[:10]
		version_file.close()

		return {
			'data': self.__data_date,
			'online_update': self.__online_update_date
		}
示例#8
0
    def mixin_insert_unicode_character(self):
        #		if cUnicodeInsertion_TextCtrlMixin._unicode_selector is None:
        if __UNICODE_SELECTOR_APP is None:
            return False

        # read clipboard
        if wx.TheClipboard.IsOpened():
            _log.error('clipboard already open')
            return False

        if not wx.TheClipboard.Open():
            _log.error('cannot open clipboard')
            return False

        data_obj = wx.TextDataObject()
        prev_clip = None
        got_it = wx.TheClipboard.GetData(data_obj)
        if got_it:
            prev_clip = data_obj.Text
        # run selector
        #if not gmShellAPI.run_command_in_shell(command = cUnicodeInsertion_TextCtrlMixin._unicode_selector, blocking = True):
        if not gmShellAPI.run_command_in_shell(command=__UNICODE_SELECTOR_APP,
                                               blocking=True):
            wx.TheClipboard.Close()
            return False

        # read clipboard again
        got_it = wx.TheClipboard.GetData(data_obj)
        wx.TheClipboard.Close()
        if not got_it:
            _log.debug('clipboard does not contain text')
            return False

        curr_clip = data_obj.Text
        # insert clip if any
        if curr_clip == prev_clip:
            # nothing put into clipboard (that is, clipboard still the same)
            return False

        self.WriteText(curr_clip)
        return True
示例#9
0
	def switch_to_frontend(self, blocking=False, cmd=None):

		try:
			# must make sure csv file exists
			open(self.default_csv_filename, 'wb').close()
		except IOError:
			_log.exception('problem creating GL/MMI <-> GNUmed exchange file')
			return False

		if cmd is None:
			cmd = ('%s %s' % (self.path_to_binary, self.args)) % self.default_csv_filename_arg

		if os.name == 'nt':
			blocking = True
		if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
			_log.error('problem switching to the MMI drug database')
			# apparently on the first call MMI does not
			# consistently return 0 on success
#			return False

		return True
示例#10
0
	def switch_to_frontend(self, blocking=False, cmd=None):

		try:
			# must make sure csv file exists
			open(self.default_csv_filename, 'wb').close()
		except IOError:
			_log.exception('problem creating GL/MMI <-> GNUmed exchange file')
			return False

		if cmd is None:
			cmd = ('%s %s' % (self.path_to_binary, self.args)) % self.default_csv_filename_arg

		if os.name == 'nt':
			blocking = True
		if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
			_log.error('problem switching to the MMI drug database')
			# apparently on the first call MMI does not
			# consistently return 0 on success
#			return False

		return True
示例#11
0
    def _on_fax_items_button_pressed(self, event):
        event.Skip()

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

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

        files2fax = []
        for item in items:
            files2fax.append(item.save_to_file())

        fax_number = wx.GetTextFromUser(_(
            'Please enter the fax number here !\n\n'
            'It can be left empty if the external\n'
            'fax software knows how to get the number.'),
                                        caption=_('Faxing documents'),
                                        parent=self,
                                        centre=True)

        cmd = '%s "%s" %s' % (external_cmd, fax_number, ' '.join(files2fax))
        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 faxing documents to\n\n  %s') % fax_number,
                aTitle=_('Faxing documents'))
            return False

        self.save_soap_note(
            soap=_('Faxed to [%s]:\n - %s') %
            (fax_number, '\n - '.join([i['description'] for i in items])))
        return True
示例#12
0
	def mixin_insert_unicode_character(self):
		if cUnicodeInsertion_TextCtrlMixin._unicode_selector is None:
			return False

		# read clipboard
		if wx.TheClipboard.IsOpened():
			_log.error('clipboard already open')
			return False
		if not wx.TheClipboard.Open():
			_log.error('cannot open clipboard')
			return False
		data_obj = wx.TextDataObject()
		prev_clip = None
		got_it = wx.TheClipboard.GetData(data_obj)
		if got_it:
			prev_clip = data_obj.Text

		# run selector
		if not gmShellAPI.run_command_in_shell(command = cUnicodeInsertion_TextCtrlMixin._unicode_selector, blocking = True):
			wx.TheClipboard.Close()
			return False

		# read clipboard again
		got_it = wx.TheClipboard.GetData(data_obj)
		wx.TheClipboard.Close()
		if not got_it:
			_log.debug('clipboard does not contain text')
			return False
		curr_clip = data_obj.Text

		# insert clip if so
		if curr_clip == prev_clip:
			# nothing put into clipboard (that is, clipboard still the same)
			return False

		self.WriteText(curr_clip)
		return True
示例#13
0
	def switch_to_frontend(self, blocking=False, mode='interactions'):
		"""http://ericmaeker.fr/FreeMedForms/di-manual/en/html/ligne_commandes.html"""

		_log.debug('calling FreeDiams in [%s] mode', mode)

		self.__imported_drugs = []

		if not self.__detect_binary():
			return False

		self.__create_gm2fd_file(mode = mode)

		args = '--exchange-in="%s"' % (self.__gm2fd_filename)
		cmd = r'%s %s' % (self.path_to_binary, args)
		if os.name == 'nt':
			blocking = True
		if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
			_log.error('problem switching to the FreeDiams drug database')
			return False

		if blocking == True:
			self.import_fd2gm_file_as_drugs()

		return True
示例#14
0
	def switch_to_frontend(self, blocking=False, mode='interactions'):
		"""https://ericmaeker.fr/FreeMedForms/di-manual/en/html/ligne_commandes.html"""

		_log.debug('calling FreeDiams in [%s] mode', mode)

		self.__imported_drugs = []

		if not self.__detect_binary():
			return False

		self.__create_gm2fd_file(mode = mode)

		args = '--exchange-in="%s"' % (self.__gm2fd_filename)
		cmd = r'%s %s' % (self.path_to_binary, args)
		if os.name == 'nt':
			blocking = True
		if not gmShellAPI.run_command_in_shell(command = cmd, blocking = blocking):
			_log.error('problem switching to the FreeDiams drug database')
			return False

		if blocking == True:
			self.import_fd2gm_file_as_drugs()

		return True
示例#15
0
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.save_to_file()
        if filename is None:
            gmDispatcher.send(
                signal='statustext',
                msg=_('Cannot export visual progress note to file.'))
            return None

    editor = gmCfgDB.get4user(
        option='external.tools.visual_soap_editor_cmd',
        workplace=gmPraxis.gmCurrentPraxisBranch().active_workplace)

    if editor is None:
        _log.error(
            'no editor for visual progress notes configured, trying mimetype editor'
        )
        gmDispatcher.send(
            signal='statustext',
            msg=_('Editor for visual progress note not configured.'),
            beep=False)
        mimetype = gmMimeLib.guess_mimetype(filename=filename)
        editor = gmMimeLib.get_editor_cmd(mimetype=mimetype, filename=filename)
        if editor is None:
            _log.error(
                'no editor for mimetype <%s> configured, trying mimetype viewer',
                mimetype)
            success, msg = gmMimeLib.call_viewer_on_file(aFile=filename,
                                                         block=True)
            if not success:
                _log.debug('problem running mimetype <%s> viewer', mimetype)
                gmGuiHelpers.gm_show_error(
                    _('There is no editor for visual progress notes defined.\n'
                      'Also, there is no editor command defined for the file type\n'
                      '\n'
                      ' [%s].\n'
                      '\n'
                      'Therefor GNUmed attempted to at least *show* this\n'
                      'visual progress note. That failed as well, however:\n'
                      '\n'
                      '%s') % (mimetype, msg),
                    _('Editing visual progress note'))
                editor = configure_visual_progress_note_editor()
                if editor is None:
                    gmDispatcher.send(
                        signal='statustext',
                        msg=_(
                            'Editor for visual progress note not configured.'),
                        beep=True)
                    return None

    if '%(img)s' in editor:
        editor = editor % {'img': filename}
    else:
        editor = '%s %s' % (editor, filename)

    if discard_unmodified:
        original_stat = os.stat(filename)
        original_md5 = gmTools.file2md5(filename)

    success = gmShellAPI.run_command_in_shell(editor, blocking=True)
    if not success:
        success, msg = gmMimeLib.call_viewer_on_file(aFile=filename,
                                                     block=True)
        if not success:
            _log.debug('problem running mimetype <%s> viewer', mimetype)
            gmGuiHelpers.gm_show_error(
                _('There was a problem running the editor\n'
                  '\n'
                  ' [%s] (%s)\n'
                  '\n'
                  'on the visual progress note.\n'
                  '\n'
                  'Therefor GNUmed attempted to at least *show* it.\n'
                  'That failed as well, however:\n'
                  '\n'
                  '%s') % (editor, mimetype, msg),
                _('Editing visual progress note'))
            editor = configure_visual_progress_note_editor()
            if editor is None:
                gmDispatcher.send(
                    signal='statustext',
                    msg=_('Editor for visual progress note not configured.'),
                    beep=True)
        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 = _(
                    'You either created a visual progress note from a template\n'
                    'in the database (rather than from a file on disk) or you\n'
                    'edited an existing visual progress note.\n'
                    '\n'
                    'The template/original was not modified at all, however.\n'
                    '\n'
                    'Do you still want to save the unmodified image as a\n'
                    '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'],
        date_generated=gmDateTime.pydt_now_here())
    doc.set_reviewed(technically_abnormal=False, clinically_relevant=True)

    return doc
示例#16
0
    def _on_burn_items_button_pressed(self, event):
        event.Skip()

        # anything to do ?
        found, external_cmd = gmShellAPI.detect_external_binary('gm-burn_doc')
        if not found:
            return
        items = self._LCTRL_items.get_selected_item_data(only_one=False)
        if len(items) == 0:
            items = self._LCTRL_items.get_item_data()
        if len(items) == 0:
            return

        pat = gmPerson.gmCurrentPatient()
        dlg = cCreatePatientMediaDlg(self,
                                     -1,
                                     burn2cd=True,
                                     patient=pat,
                                     item_count=len(items))
        choice = dlg.ShowModal()
        if choice != wx.ID_SAVE:
            return
        path2include = dlg._LBL_directory.Label.strip()
        include_selected_dir = dlg._CHBOX_include_directory.IsChecked()
        dlg.Destroy()

        # do the export
        base_dir = None
        if include_selected_dir:
            if gmTools.dir_is_empty(path2include) is False:
                base_dir = gmTools.get_unique_filename(suffix='.iso')
                try:
                    shutil.copytree(path2include, base_dir)
                except shutil.Error:
                    _log.exception(
                        'cannot copy include directory [%s] -> [%s]',
                        path2include, base_dir)
                    return

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

        # burn onto media
        cmd = '%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

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

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

        return True
示例#17
0
def call_editor_on_file(filename=None, block=True):
    """Try to find an appropriate editor with all tricks and call it.

	block: try to detach from editor or not, None means to use mailcap default.
	"""
    if not os.path.isdir(filename):
        # is the file accessible at all ?
        try:
            open(filename).close()
        except Exception:
            _log.exception('cannot read [%s]', filename)
            msg = _('[%s] is not a readable file') % filename
            return False, msg

    mime_type = guess_mimetype(filename)

    editor_cmd = get_editor_cmd(mime_type, filename)
    if editor_cmd is not None:
        if gmShellAPI.run_command_in_shell(command=editor_cmd, blocking=block):
            return True, ''
    viewer_cmd = get_viewer_cmd(mime_type, filename)
    if viewer_cmd is not None:
        if gmShellAPI.run_command_in_shell(command=viewer_cmd, blocking=block):
            return True, ''
    _log.warning("no editor or viewer found via standard mailcap system")

    if os.name == "posix":
        _log.warning(
            "you should add an editor and/or viewer for this mime type to your mailcap file"
        )

    _log.info("let's see what the OS can do about that")
    # does the file already have a useful extension ?
    (path_name, f_ext) = os.path.splitext(filename)
    if f_ext in ['', '.tmp']:
        # try to guess one
        f_ext = guess_ext_by_mimetype(mime_type)
        if f_ext is None:
            _log.warning("no suitable file extension found, trying anyway")
            file_to_display = filename
            f_ext = '?unknown?'
        else:
            file_to_display = filename + f_ext
            shutil.copyfile(filename, file_to_display)
    else:
        file_to_display = filename

    file_to_display = os.path.normpath(file_to_display)
    _log.debug("file %s <type %s> (ext %s) -> file %s" %
               (filename, mime_type, f_ext, file_to_display))

    # try to detect any of the UNIX openers (will only find viewers)
    found, startfile_cmd = _get_system_startfile_cmd(filename)
    if found:
        if gmShellAPI.run_command_in_shell(command=startfile_cmd,
                                           blocking=block):
            return True, ''

    # last resort: hand over to Python itself
    try:
        os.startfile(file_to_display)
        return True, ''
    except AttributeError:
        _log.exception('os.startfile() does not exist on this platform')
    except Exception:
        _log.exception('os.startfile(%s) failed', file_to_display)

    msg = _("Unable to edit/view the file:\n\n"
            " [%s]\n\n"
            "Your system does not seem to have a (working)\n"
            "editor or viewer registered for the file type\n"
            " [%s]") % (file_to_display, mime_type)
    return False, msg
示例#18
0
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
示例#19
0
文件: gmMimeLib.py 项目: ncqgm/gnumed
def call_editor_on_file(filename=None, block=True):
	"""Try to find an appropriate editor with all tricks and call it.

	block: try to detach from editor or not, None means to use mailcap default.
	"""
	if not os.path.isdir(filename):
		# is the file accessible at all ?
		try:
			open(filename).close()
		except:
			_log.exception('cannot read [%s]', filename)
			msg = _('[%s] is not a readable file') % filename
			return False, msg

	mime_type = guess_mimetype(filename)

	editor_cmd = get_editor_cmd(mime_type, filename)
	if editor_cmd is not None:
		if gmShellAPI.run_command_in_shell(command = editor_cmd, blocking = block):
			return True, ''
	viewer_cmd = get_viewer_cmd(mime_type, filename)
	if viewer_cmd is not None:
		if gmShellAPI.run_command_in_shell(command = viewer_cmd, blocking = block):
			return True, ''
	_log.warning("no editor or viewer found via standard mailcap system")

	if os.name == "posix":
		_log.warning("you should add an editor and/or viewer for this mime type to your mailcap file")

	_log.info("let's see what the OS can do about that")
	# does the file already have a useful extension ?
	(path_name, f_ext) = os.path.splitext(filename)
	if f_ext in ['', '.tmp']:
		# try to guess one
		f_ext = guess_ext_by_mimetype(mime_type)
		if f_ext is None:
			_log.warning("no suitable file extension found, trying anyway")
			file_to_display = filename
			f_ext = '?unknown?'
		else:
			file_to_display = filename + f_ext
			shutil.copyfile(filename, file_to_display)
	else:
		file_to_display = filename

	file_to_display = os.path.normpath(file_to_display)
	_log.debug("file %s <type %s> (ext %s) -> file %s" % (filename, mime_type, f_ext, file_to_display))

	# try to detect any of the UNIX openers (will only find viewers)
	found, startfile_cmd = _get_system_startfile_cmd(filename)
	if found:
		if gmShellAPI.run_command_in_shell(command = startfile_cmd, blocking = block):
			return True, ''

	# last resort: hand over to Python itself
	try:
		os.startfile(file_to_display)
		return True, ''
	except AttributeError:
		_log.exception('os.startfile() does not exist on this platform')
	except Exception:
		_log.exception('os.startfile(%s) failed', file_to_display)

	msg = _("Unable to edit/view the file:\n\n"
			" [%s]\n\n"
			"Your system does not seem to have a (working)\n"
			"editor or viewer registered for the file type\n"
			" [%s]"
	) % (file_to_display, mime_type)
	return False, msg