# Python X2Go (Client) API Documentation (v0.6.1.3)

## x2go.mimeboxactions

# Source code for x2go.mimeboxactions

    # -*- coding: utf-8 -*-

    # Copyright (C) 2010-2020 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
    #
    # Python X2Go is free software; you can redistribute it and/or modify
    # it under the terms of the GNU Affero General Public License as published by
    # the Free Software Foundation; either version 3 of the License, or
    # (at your option) any later version.
    #
    # Python X2Go is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU Affero General Public License for more details.
    #
    # You should have received a copy of the GNU Affero General Public License
    # along with this program; if not, write to the
    # Free Software Foundation, Inc.,
    # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

    """\
    For MIME box jobs there are currently three handling actions available:
    :class:`x2go.mimeboxactions.X2GoMIMEboxActionOPEN`, :class:`x2go.mimeboxactions.X2GoMIMEboxActionOPENWITH` and :class:`x2go.mimeboxactions.X2GoMIMEboxActionSAVEAS`.

    """
    __NAME__ = 'x2gomimeboxactions-pylib'

    __package__ = 'x2go'
    __name__    = 'x2go.mimeboxactions'

    # modules
    import os
    import copy
    import time

    from .defaults import X2GOCLIENT_OS as _X2GOCLIENT_OS
    if _X2GOCLIENT_OS in ("Windows"):
        import subprocess
        import win32api
    else:
        from . import gevent_subprocess as subprocess
        from . import x2go_exceptions
        WindowsErrror = x2go_exceptions.WindowsError

    # Python X2Go modules
    from . import log
    from . import x2go_exceptions

    _MIMEBOX_ENV = os.environ.copy()

    class X2GoMIMEboxAction(object):

        __name__ = 'NAME'
        __description__ = 'DESCRIPTION'

        def __init__(self, client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
            """\
            This is a meta class and has no functionality as such. It is used as parent
            class by »real« X2Go MIME box actions.

            :param client_instance: the underlying :class:`x2go.client.X2GoClient` instance
            :type client_instance: ``obj``
            :param logger: you can pass an :class:`x2go.log.X2GoLogger` object to the
                :class:`x2go.mimeboxactions.X2GoMIMEboxAction` constructor
            :type logger: ``obj``
            :param loglevel: if no :class:`x2go.log.X2GoLogger` object has been supplied a new one will be
                constructed with the given loglevel
            :type loglevel: ``int``

            """
            if logger is None:
                self.logger = log.X2GoLogger(loglevel=loglevel)
            else:
                self.logger = copy.deepcopy(logger)
            self.logger.tag = __NAME__

            # these get set from within the X2GoMIMEboxQueue class
            self.profile_name = 'UNKNOWN'
            self.session_name = 'UNKNOWN'

            self.client_instance = client_instance

        @property
        def name(self):
            """\
            Return the X2Go MIME box action's name.

            :returns: MIME box action name

            :rtype: ``str``

            """
            return self.__name__

        @property
        def description(self):
            """\
            Return the X2Go MIME box action's description text.

            :returns: MIME box action's description

            :rtype: ``str``

            """
            return self.__description__

        def _do_process(self, mimebox_file, mimebox_dir, ):
            """\
            Perform the defined MIME box action (doing nothing in :class:`x2go.mimeboxactions.X2GoMIMEboxAction` parent class).

            :param mimebox_file: file name as placed in to the X2Go MIME box directory
            :type mimebox_file: ``str``
            :param mimebox_dir: location of the X2Go session's MIME box directory
            :type mimebox_dir: ``str``

            """
            pass

        def do_process(self, mimebox_file, mimebox_dir, ):
            """\
            Wrapper method for the actual processing of MIME
            box actions.

            :param mimebox_file: file name as placed in to the X2Go MIME box directory
            :type mimebox_file: ``str``
            :param mimebox_dir: location of the X2Go session's MIME box directory
            :type mimebox_dir: ``str``

            """
            mimebox_file = os.path.normpath(mimebox_file)
            mimebox_dir = os.path.normpath(mimebox_dir)

            self._do_process(mimebox_file, mimebox_dir)

    class X2GoMIMEboxActionOPEN(X2GoMIMEboxAction):
        """\
        MIME box action that opens incoming files in the system's default application.

        """
        __name__= 'OPEN'
        __decription__= 'Open incoming file with local system\'s default application.'

        def __init__(self, client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
            """\
            :param client_instance: the underlying :class:`x2go.client.X2GoClient` instance
            :type client_instance: ``obj``
            :param logger: you can pass an :class:`x2go.log.X2GoLogger` object to the
                :class:`x2go.mimeboxactions.X2GoMIMEboxActionOPEN` constructor
            :type logger: ``obj``
            :param loglevel: if no :class:`x2go.log.X2GoLogger` object has been supplied a new one will be
                constructed with the given loglevel
            :type loglevel: ``int``

            """
            self.client_instance = client_instance
            X2GoMIMEboxAction.__init__(self, logger=logger, loglevel=loglevel)

        def _do_process(self, mimebox_file, mimebox_dir, ):
            """\
            Open an incoming MIME box file in the system's default application.

            :param mimebox_file: file name as placed in to the MIME box directory
            :type mimebox_file: ``str``
            :param mimebox_dir: location of the X2Go session's MIME box directory
            :type mimebox_dir: ``str``

            """
            mimebox_file = os.path.normpath(mimebox_file)
            mimebox_dir = os.path.normpath(mimebox_dir)

            if _X2GOCLIENT_OS == "Windows":
                self.logger('opening incoming MIME box file with Python\'s os.startfile() command: %s' % mimebox_file, loglevel=log.loglevel_DEBUG)
                try:
                    os.startfile(os.path.join(mimebox_dir, mimebox_file))
                except WindowsError as win_err:
                    if self.client_instance:
                        self.client_instance.HOOK_mimeboxaction_error(mimebox_file,
                                                                      profile_name=self.profile_name,
                                                                      session_name=self.session_name,
                                                                      err_msg=str(win_err)
                                                                     )
                    else:
                        self.logger('Encountered WindowsError: %s' % str(win_err), loglevel=log.loglevel_ERROR)
                time.sleep(20)
            else:
                cmd_line = [ 'xdg-open', os.path.join(mimebox_dir, mimebox_file), ]
                self.logger('opening MIME box file with command: %s' % ' '.join(cmd_line), loglevel=log.loglevel_DEBUG)
                subprocess.Popen(cmd_line, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=_MIMEBOX_ENV)
                time.sleep(20)

    class X2GoMIMEboxActionOPENWITH(X2GoMIMEboxAction):
        """\
        MIME box action that calls the system's ,,Open with...'' dialog on incoming files. Currently only
        properly implementable on Windows platforms.

        """
        __name__= 'OPENWITH'
        __decription__= 'Evoke ,,Open with...\'\' dialog on incoming MIME box files.'

        def __init__(self, client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
            """\
            :param client_instance: the underlying :class:`x2go.client.X2GoClient` instance
            :type client_instance: ``obj``
            :param logger: you can pass an :class:`x2go.log.X2GoLogger` object to the
                :class:`x2go.mimeboxactions.X2GoMIMEboxActionOPENWITH` constructor
            :type logger: ``obj``
            :param loglevel: if no :class:`x2go.log.X2GoLogger` object has been supplied a new one will be
                constructed with the given loglevel
            :type loglevel: ``int``

            """
            self.client_instance = client_instance
            X2GoMIMEboxAction.__init__(self, logger=logger, loglevel=loglevel)

        def _do_process(self, mimebox_file, mimebox_dir, ):
            """\
            Open an incoming MIME box file in the system's default application.

            :param mimebox_file: file name as placed in to the MIME box directory
            :type mimebox_file: ``str``
            :param mimebox_dir: location of the X2Go session's MIME box directory
            :type mimebox_dir: ``str``

            """
            mimebox_file = os.path.normpath(mimebox_file)
            mimebox_dir = os.path.normpath(mimebox_dir)

            if _X2GOCLIENT_OS == "Windows":
                self.logger('evoking Open-with dialog on incoming MIME box file: %s' % mimebox_file, loglevel=log.loglevel_DEBUG)
                win32api.ShellExecute (
                      0,
                      "open",
                      "rundll32.exe",
                      "shell32.dll,OpenAs_RunDLL %s" % os.path.join(mimebox_dir, mimebox_file),
                      None,
                      0,
                )
                time.sleep(20)
            else:
                self.logger('the evocation of the Open-with dialog box is currently not available on Linux, falling back to MIME box action OPEN', loglevel=log.loglevel_WARN)
                cmd_line = [ 'xdg-open', os.path.join(mimebox_dir, mimebox_file), ]
                self.logger('opening MIME box file with command: %s' % ' '.join(cmd_line), loglevel=log.loglevel_DEBUG)
                subprocess.Popen(cmd_line, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=_MIMEBOX_ENV)
                time.sleep(20)

    class X2GoMIMEboxActionSAVEAS(X2GoMIMEboxAction):
        """\
        MIME box action that allows saving incoming MIME box files to a local folder. What this
        MIME box actually does is calling a hook method in the :class:`x2go.client.X2GoClient` instance that
        can be hi-jacked by one of your application's methods which then can handle the ,,Save as...''
        request.

        """
        __name__ = 'SAVEAS'
        __decription__= 'Save incoming file as...'

        def __init__(self, client_instance=None, logger=None, loglevel=log.loglevel_DEFAULT):
            """\
            :param client_instance: an :class:`x2go.client.X2GoClient` instance, within your customized :class:`x2go.client.X2GoClient` make sure
                you have a ``HOOK_open_mimebox_saveas_dialog(filename=<str>)`` method defined that will actually
                handle the incoming mimebox file.
            :type client_instance: ``obj``
            :param logger: you can pass an :class:`x2go.log.X2GoLogger` object to the
                :class:`x2go.mimeboxactions.X2GoMIMEboxActionSAVEAS` constructor
            :type logger: ``obj``
            :param loglevel: if no :class:`x2go.log.X2GoLogger` object has been supplied a new one will be
                constructed with the given loglevel
            :type loglevel: ``int``

            :raises X2GoMIMEboxActionException: if the client_instance has not been passed to the SAVEAS MIME box action

            """
            if client_instance is None:
                raise x2go_exceptions.X2GoMIMEboxActionException('the SAVEAS MIME box action needs to know the X2GoClient instance (client=<instance>)')
            X2GoMIMEboxAction.__init__(self, client_instance=client_instance, logger=logger, loglevel=loglevel)

        def _do_process(self, mimebox_file, mimebox_dir):
            """\
            Call an :class:`x2go.client.X2GoClient` hook method (``HOOK_open_mimebox_saveas_dialog``) that
            can handle the MIME box's SAVEAS action.

            :param mimebox_file: file name as placed in to the MIME box directory
            :type mimebox_file: ``str``
            :param mimebox_dir: location of the X2Go session's MIME box directory
            :type mimebox_dir: ``str``
            :param mimebox_file: PDF file name as placed in to the X2Go spool directory

            """
            mimebox_file = os.path.normpath(mimebox_file)
            mimebox_dir = os.path.normpath(mimebox_dir)

            self.logger('Session %s (%s) is calling X2GoClient class hook method <client_instance>.HOOK_open_mimebox_saveas_dialog(%s)' % (self.session_name, self.profile_name, mimebox_file), loglevel=log.loglevel_NOTICE)
            self.client_instance.HOOK_open_mimebox_saveas_dialog(os.path.join(mimebox_dir, mimebox_file), profile_name=self.profile_name, session_name=self.session_name)
            time.sleep(60)