[X2Go-Commits] [pyhoca-gui] 01/01: Move most code of the pyhoca-gui executable into a dedicated class named PyHocaGUI_Launcher.
git-admin at x2go.org
git-admin at x2go.org
Wed Feb 5 09:33:40 CET 2014
This is an automated email from the git hooks/post-receive script.
x2go pushed a commit to branch brokerclient
in repository pyhoca-gui.
commit 7bd3d3ac9e41d4b43a6b9073297611f2b77969fd
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date: Wed Feb 5 09:32:54 2014 +0100
Move most code of the pyhoca-gui executable into a dedicated class named PyHocaGUI_Launcher.
---
debian/changelog | 2 +
pyhoca-gui | 403 ++--------------------------------------------
pyhoca/wxgui/__init__.py | 1 +
pyhoca/wxgui/launcher.py | 335 ++++++++++++++++++++++++++++++++++++++
pyhoca/wxgui/options.py | 109 +++++++++++++
5 files changed, 457 insertions(+), 393 deletions(-)
diff --git a/debian/changelog b/debian/changelog
index 9f1bbaf..86beb5d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,8 @@
pyhoca-gui (0.5.0.0-0x2go1) UNRELEASED; urgency=low
* Adapt to new backend concept found in Python X2Go (>= 0.5.0.0).
+ * Move most code of the pyhoca-gui executable into a dedicated class
+ named PyHocaGUI_Launcher.
-- Mike Gabriel <mike.gabriel at das-netzwerkteam.de> Wed, 08 Jan 2014 21:28:37 +0100
diff --git a/pyhoca-gui b/pyhoca-gui
index e22fd18..cd6bcf4 100755
--- a/pyhoca-gui
+++ b/pyhoca-gui
@@ -19,403 +19,20 @@
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-modules ={}
-
-import sys
import os
-import re
-import shutil
-PROG_NAME = os.path.basename(sys.argv[0]).replace('.exe', '')
-PROG_PID = os.getpid()
-
-if hasattr(sys, 'frozen') and str(sys.frozen) in ("windows_exe", "console_exe", "1", ):
- class Win32_Logging(object):
-
- softspace = 0
- _fname = os.path.join(os.environ['AppData'], PROG_NAME, '%s.log' % PROG_NAME)
- _file = None
-
- def __init__(self, filemode='a'):
- self._filemode = filemode
- if os.path.isfile(self._fname) and self._filemode == "w+":
- os.remove(self._fname)
-
- def write(self, text, **kwargs):
- if self._file is None:
- try:
- try:
- os.mkdir(os.path.dirname(self._fname))
- except:
- pass
- self._file = open(self._fname, self._filemode)
- except:
- pass
- else:
- self._file.write(text)
- self._file.flush()
-
- def flush(self):
- if self._file is not None:
- self._file.flush()
-
- sys.stdout = Win32_Logging(filemode='w+')
- sys.stderr = Win32_Logging(filemode='a')
- del Win32_Logging
-
-import gevent
-import gevent.monkey
-gevent.monkey.patch_all()
-
-import subprocess
-
-try:
- import wxversion
- wxversion.select('2.9')
-except: pass
-try:
- import wxversion
- wxversion.select('2.8')
-except: pass
-
-import argparse
-import os
-import exceptions
-import locale
-import gettext
-import wx
-
-from x2go import X2GOCLIENT_OS as _X2GOCLIENT_OS
-
-if _X2GOCLIENT_OS in ('Linux', 'Mac'):
- import setproctitle
- setproctitle.setproctitle(PROG_NAME)
-
-if sys.argv[0].startswith('./') or sys.argv[0].startswith('python'):
- sys.path.insert(0, os.getcwd())
- os.environ['PYHOCAGUI_DEVELOPMENT'] = '1'
- print '### %s running in development mode ###' % PROG_NAME
-
-from pyhoca.wxgui.basepath import locale_basepath
-
-# Python X2Go modules
-from x2go import CURRENT_LOCAL_USER as _CURRENT_LOCAL_USER
-if _X2GOCLIENT_OS == 'Windows':
- from x2go import X2GoClientXConfig as _X2GoClientXConfig
-from x2go import X2GoLogger as _X2GoLogger
-from x2go import x2go_cleanup as _x2go_cleanup
-
-# X2Go backends
-from x2go.defaults import BACKENDS as _BACKENDS
-
-from pyhoca.wxgui import __VERSION__ as _version
-from pyhoca.wxgui import messages
-from pyhoca.wxgui import PyHocaGUI
+import sys
-if _X2GOCLIENT_OS == 'Windows':
- from pyhoca.wxgui.basepath import nxproxy_binary
- os.environ.update({'NXPROXY_BINARY': nxproxy_binary, })
+from pyhoca.wxgui import *
+from pyhoca.wxgui import __VERSION__
__author__ = "Mike Gabriel, Dick Kniep"
-__version__ = _version
-
-# version information
-VERSION=_version
-VERSION_TEXT="""
-%s[%s] - an X2Go GUI client written in Python
-----------------------------------------------------------------------
-developed by Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
-sponsored by Dick Kniep <dick.kniep at lindix.nl> (2010-2013)
-
-VERSION: %s
-
-""" % (PROG_NAME, PROG_PID, VERSION)
-
-def check_running():
- if _X2GOCLIENT_OS in ('Linux', 'Mac'):
-
- p = subprocess.Popen(['ps', '-U', _CURRENT_LOCAL_USER, '-u', _CURRENT_LOCAL_USER], stdout=subprocess.PIPE)
- psA_out = p.communicate()
- if psA_out[0].count(PROG_NAME) <= 1:
-
- if os.path.isdir(os.path.expanduser("~/.x2go/pyhoca-gui/")):
- shutil.rmtree(os.path.expanduser("~/.x2go/pyhoca-gui/"))
-
- my_pid = str(os.getpid())
- if not os.path.exists(os.path.expanduser("~/.x2go/pyhoca-gui/")):
- os.makedirs(os.path.expanduser("~/.x2go/pyhoca-gui/"))
- my_pidfile = os.path.expanduser("~/.x2go/pyhoca-gui/display.{pid}".format(pid=my_pid))
-
- my_display = os.environ['DISPLAY']
- open(my_pidfile, 'w').write(my_display)
-
- already_running_for_this_display = False
- for pidfile in os.listdir(os.path.expanduser("~/.x2go/pyhoca-gui/")):
-
- # this is our own pid file...
- if my_pidfile.endswith(pidfile):
- continue
-
- display = open(os.path.expanduser("~/.x2go/pyhoca-gui/") + pidfile, 'r').read()
-
- if display.split('.')[0] == my_display.split('.')[0]:
- other_pid = pidfile.split('.')[1]
- print
- print('One instance of PyHoca-GUI (PID: {other_pid}) is already running for this $DISPLAY {display}'.format(other_pid=other_pid, display=my_display))
-
- return True
-
- return False
-
- elif _X2GOCLIENT_OS == 'Windows':
- import wmi
- w = wmi.WMI()
- _p_names = []
- for process in w.Win32_Process():
- _p_names.append(process.Name)
- return len([ _p_name for _p_name in _p_names if _p_name == PROG_NAME]) > 1
-
-
-def version():
- # print version text and exit
- sys.stderr.write ("%s\n" % VERSION_TEXT)
- remove_pidfile()
-
- sys.exit(0)
-
-
-# sometimes we have to fail...
-def runtime_error(m, parser=None, exitcode=-1):
- """\
- STILL UNDOCUMENTED
- """
- if parser is not None:
- parser.print_usage()
- sys.stderr.write ("%s: error: %s\n" % (PROG_NAME, m))
+__version__ = __VERSION__
- remove_pidfile()
- sys.exit(exitcode)
-
-
-if _X2GOCLIENT_OS == 'Windows':
- _x = _X2GoClientXConfig()
- _known_xservers = _x.known_xservers
- _installed_xservers = _x.installed_xservers
-
-if _X2GOCLIENT_OS == 'Windows':
- _config_backends = ('FILE', 'WINREG')
-elif _X2GOCLIENT_OS == 'Linux':
- _config_backends = ('FILE', 'GCONF')
-else:
- _config_backends = ('FILE')
-
-_profiles_backend_default = _BACKENDS['X2GoSessionProfiles']['default']
-_settings_backend_default = _BACKENDS['X2GoClientSettings']['default']
-_printing_backend_default = _BACKENDS['X2GoClientPrinting']['default']
-
-# debug options...
-debug_options = [
- {'args':['-d','--debug'], 'default': False, 'action': 'store_true', 'help': 'enable application debugging code', },
- {'args':['--quiet'], 'default': False, 'action': 'store_true', 'help': 'disable any kind of log output', },
- {'args':['--libdebug'], 'default': False, 'action': 'store_true', 'help': 'enable debugging code of the underlying Python X2Go module', },
- {'args':['--libdebug-sftpxfer'], 'default': False, 'action': 'store_true', 'help': 'enable debugging code of Python X2Go\'s sFTP server code (very verbose, and even promiscuous)', },
- {'args':['-V', '--version'], 'default': False, 'action': 'store_true', 'help': 'print version number and exit', },
- ]
-x2go_gui_options = [
- {'args':['-P','--session-profile'], 'default': None, 'metavar': '<profile-name>', 'help': 'directly connect to a session profile', },
- {'args':['--remember-username'], 'default': False, 'action': 'store_true', 'help': 'for profiles with interactive authentication, remember the last-used username', },
- {'args':['--non-interactive'], 'default': False, 'action': 'store_true', 'help': 'run the session manager in non-interactive mode, this option sets the following options to true: --restricted-trayicon, --single_session_profile, --start-on-connect, --resume-all-on-connect, --exit-on-disconnect, --disconnect-on-suspend and --disconnect-on-terminate', },
- {'args':['--auto-connect'], 'default': False, 'action': 'store_true', 'help': 'connect sessions via SSH pubkey authentication if possible', },
- {'args':['--show-profile-metatypes'], 'default': False, 'action': 'store_true', 'help': 'show descriptive meta information on session profiles in menus (NOTE: this makes menus appear a bit more sluggish, use it mostly for debugging)', },
- {'args':['--single-session-profile'], 'default': False, 'action': 'store_true', 'help': 'disable support of handling multiple session profiles', },
- {'args':['--tray-icon'], 'default': None, 'metavar': '<your-logo>', 'help': 'define an alternative system tray icon file (PNG files only, leave out file extension here, size 22x22 on Linux, 16x16 on Windows)', },
- {'args':['--tray-icon-connecting'], 'default': None, 'metavar': '<your-logo-while-connecting>', 'help': 'define an alternative system tray icon file while connecting to a server (PNG files only, leave out file extension here, size 22x22 on Linux, 16x16 on Windows)', },
- {'args':['--restricted-trayicon'], 'default': False, 'action': 'store_true', 'help': 'restricts session manager\'s main icon functionality to information window and application exit; on left-click only a minimal session menu is shown', },
- {'args':['--add-to-known-hosts'], 'default': False, 'action': 'store_true', 'help': 'automatically add SSH host keys to the known_hosts files of the client-side user', },
- {'args':['--start-on-connect'], 'default': False, 'action': 'store_true', 'help': 'This is now the hard-coded default. start a session directly after authentication if no session is currently running/suspended', },
- {'args':['--exit-on-disconnect'], 'default': False, 'action': 'store_true', 'help': 'exit the session manager after a server connection has died', },
- {'args':['--resume-newest-on-connect', '--resume-on-connect'], 'default': False, 'action': 'store_true', 'help': 'This is now the hard-coded default. On connect auto-resume the newest suspended session', },
- {'args':['--resume-oldest-on-connect'], 'default': False, 'action': 'store_true', 'help': 'on connect auto-resume the oldest suspended session', },
- {'args':['--resume-all-on-connect'], 'default': False, 'action': 'store_true', 'help': 'auto-resume all suspended sessions on connect', },
- {'args':['--disconnect-on-suspend'], 'default': False, 'action': 'store_true', 'help': 'disconnect a server if a session has been suspended', },
- {'args':['--disconnect-on-terminate'], 'default': False, 'action': 'store_true', 'help': 'disconnect a server if a session has been terminated', },
- {'args':['--splash-image'], 'default': None, 'metavar': '<your-splash-image>', 'help': 'define an alternative splash image that gets shown on application startup (PNG files only, full path or filename as found in <share>/img)', },
- {'args':['--about-image'], 'default': None, 'metavar': '<your-about-window-image>', 'help': 'define an alternative image for the application\'s ,,About\'\' window (PNG files only, full path or filename as found in <share>/img)', },
- {'args':['--disable-splash'], 'default': False, 'action': 'store_true', 'help': 'disable the applications splash screen', },
- {'args':['--disable-options'], 'default': False, 'action': 'store_true', 'help': 'disable the client options configuration window', },
- {'args':['--disable-printingprefs'], 'default': False, 'action': 'store_true', 'help': 'disable the client\'s printing preferences window', },
- {'args':['--disable-profilemanager'], 'default': False, 'action': 'store_true', 'help': 'disable the session profile manager window', },
- {'args':['--disable-notifications'], 'default': False, 'action': 'store_true', 'help': 'disable all applet notifications', },
- {'args':['--display'], 'default': None, 'metavar': '<hostname>:<screennumber>', 'help': 'set the DISPLAY environment variable to <hostname>:<screennumber>', },
- {'args':['--logon-window-position'], 'default': None, 'metavar': '<x-pos>x<y-pos>', 'help': 'give a custom position for the logon window, use negative values to position relative to right/bottom border', },
- {'args':['--published-applications-no-submenus'], 'default': 10, 'metavar': '<number>', 'help': 'the number of published applications that will be rendered without submenus', },
- ]
-if _X2GOCLIENT_OS == 'Windows':
- x2go_gui_options.append(
- {'args':['--lang'], 'default': None, 'metavar': 'LANGUAGE', 'help': 'set the GUI language (currently available: en, de, nl, es)', },
- )
-
-backend_options = [
- {'args':['--backend-controlsession'], 'default': None, 'metavar': '<CONTROLSESSION_BACKEND>', 'choices': _BACKENDS['X2GoControlSession'].keys(), 'help': 'force usage of a certain CONTROLSESSION_BACKEND (do not use this unless you know exactly what you are doing)', },
- {'args':['--backend-terminalsession'], 'default': None, 'metavar': '<TERMINALSESSION_BACKEND>', 'choices': _BACKENDS['X2GoTerminalSession'].keys(), 'help': 'force usage of a certain TERMINALSESSION_BACKEND (do not use this unless you know exactly what you are doing)', },
- {'args':['--backend-serversessioninfo'], 'default': None, 'metavar': '<SERVERSESSIONINFO_BACKEND>', 'choices': _BACKENDS['X2GoServerSessionInfo'].keys(), 'help': 'force usage of a certain SERVERSESSIONINFO_BACKEND (do not use this unless you know exactly what you are doing)', },
- {'args':['--backend-serversessionlist'], 'default': None, 'metavar': '<SERVERSESSIONLIST_BACKEND>', 'choices': _BACKENDS['X2GoServerSessionList'].keys(), 'help': 'force usage of a certain SERVERSESSIONLIST_BACKEND (do not use this unless you know exactly what you are doing)', },
- {'args':['--backend-proxy'], 'default': None, 'metavar': '<PROXY_BACKEND>', 'choices': _BACKENDS['X2GoProxy'].keys(), 'help': 'force usage of a certain PROXY_BACKEND (do not use this unless you know exactly what you are doing)', },
- {'args':['--backend-sessionprofiles'], 'default': None, 'metavar': '<SESSIONPROFILES_BACKEND>', 'choices': _config_backends, 'help': 'use given backend for accessing session profiles, available backends on your system: %s (default: %s)' % (', '.join(_config_backends), _profiles_backend_default), },
- {'args':['--backend-clientsettings'], 'default': None, 'metavar': '<CLIENTSETTINGS_BACKEND>', 'choices': _config_backends, 'help': 'use given backend for accessing the client settings configuration, available backends on your system: %s (default: %s)' % (', '.join(_config_backends), _settings_backend_default), },
- {'args':['--backend-clientprinting'], 'default': None, 'metavar': '<CLIENTPRINTING_BACKEND>', 'choices': _config_backends, 'help': 'use given backend for accessing the client printing configuration, available backends on your system: %s (default: %s)' % (', '.join(_config_backends), _printing_backend_default), },
- ]
-
-if _X2GOCLIENT_OS == 'Windows':
- contrib_options = [
- {'args':['--start-xserver'], 'default': False, 'action': 'store_true', 'help': 'start the XServer before starting the session manager application, detect best XServer automatically, if more than one XServer is installed on your system', },
- {'args':['-X', '--preferred-xserver'], 'default': None, 'metavar': '<XSERVER>', 'choices': _known_xservers, 'help': 'start either of the currently supported XServers: %s -- make sure your preferred XServer is installed on your system' % _known_xservers, },
- {'args':['--start-pulseaudio'], 'default': False, 'action': 'store_true', 'help': 'start the PulseAudio server before starting the session manager application', },
- ]
-
-portable_options = [
- {'args':['--client-rootdir'], 'default': None, 'metavar': '</path/to/.x2goclient/dir>', 'help': 'define an alternative location where to find plain text config files (default: <HOME>/.x2goclient). This option will set ,,--backend-profiles FILE\'\', ,,--backend-clientsettings FILE\'\' and ,,--backend-clientprinting FILE\'\'', },
- {'args':['--sessions-rootdir'], 'default': None, 'metavar': '</path/to/.x2go/dir>', 'help': 'define an alternative location for session runtime files'},
- {'args':['--ssh-rootdir'], 'default': None, 'metavar': '</path/to/.ssh/dir>', 'help': 'define an alternative location for SSH files', },
- ]
-
-
-def remove_pidfile():
-
- if _X2GOCLIENT_OS in ('Linux', 'Mac'):
- my_pid = str(os.getpid())
- if os.path.exists(os.path.expanduser("~/.x2go/pyhoca-gui/display.{pid}".format(pid=my_pid))):
- os.remove(os.path.expanduser("~/.x2go/pyhoca-gui/display.{pid}".format(pid=my_pid)))
-
-
-def parseargs():
-
- global DEBUG
- global print_action_args
-
- p = argparse.ArgumentParser(description='Graphical X2Go client implemented in (wx)Python.',\
- formatter_class=argparse.RawDescriptionHelpFormatter, \
- add_help=True, argument_default=None)
- p_debugopts = p.add_argument_group('Debug options')
- p_guiopts = p.add_argument_group('%s options' % PROG_NAME)
- p_portableopts = p.add_argument_group('Portable application support')
- p_backendopts = p.add_argument_group('Python X2Go backend options (for experts only)')
-
- if _X2GOCLIENT_OS == 'Windows':
- p_contribopts = p.add_argument_group('XServer options (MS Windows only)')
- p_portableopts = p.add_argument_group('File locations for portable setups (MS Windows only)')
- _option_groups = ((p_guiopts, x2go_gui_options), (p_debugopts, debug_options), (p_contribopts, contrib_options), (p_portableopts, portable_options), (p_backendopts, backend_options), )
- else:
- _option_groups = ((p_guiopts, x2go_gui_options), (p_debugopts, debug_options), (p_portableopts, portable_options), (p_backendopts, backend_options), )
- for (p_group, opts) in _option_groups:
- required = False
- for opt in opts:
-
- args = opt['args']
- del opt['args']
- p_group.add_argument(*args, **opt)
-
- a = p.parse_args()
-
- logger = _X2GoLogger(tag=PROG_NAME)
- liblogger = _X2GoLogger()
-
- if a.debug:
- logger.set_loglevel_debug()
-
- if a.libdebug:
- liblogger.set_loglevel_debug()
-
- if a.quiet:
- logger.set_loglevel_quiet()
- liblogger.set_loglevel_quiet()
-
- if a.libdebug_sftpxfer:
- liblogger.enable_debug_sftpxfer()
-
- if a.version:
- version()
-
- if a.single_session_profile and a.session_profile is None:
- runtime_error('The --single-session-profile option requires naming of a specific session profile!', parser=p)
-
- if a.non_interactive:
- if a.session_profile is None:
- runtime_error('In non-interactive mode you have to use the --session-profile option (or -P) to specify a certain session profile name!', parser=p)
- a.restricted_trayicon = True
- a.auto_connect = True
- a.start_on_connect = True
- a.resume_all_on_connect = True
- a.exit_on_disconnect = True
- a.disconnect_on_suspend = True
- a.disconnect_on_terminate = True
- a.single_session_profile = True
-
- if a.non_interactive and (a.resume_newest_on_connect or a.resume_oldest_on_connect):
- # allow override...
- a.resume_all_on_connect = False
-
- if _X2GOCLIENT_OS == 'Windows' and a.preferred_xserver:
- if a.preferred_xserver not in _installed_xservers:
- runtime_error('Xserver ,,%s\'\' is not installed on your Windows system' % a.preferred_xserver, parser=p)
- a.start_xserver = a.preferred_xserver
-
- if _X2GOCLIENT_OS == 'Windows' and a.start_xserver and a.display:
- runtime_error('You can tell %s to handle XServer startup and then specify a DISPLAY environment variable!' % PROG_NAME, parser=p)
-
- if a.display:
- os.environ.update({'DISPLAY': a.display})
- else:
- if _X2GOCLIENT_OS == 'Windows' and not a.start_xserver:
- os.environ.update({'DISPLAY': 'localhost:0'})
-
- if a.client_rootdir:
- a.client_rootdir = os.path.expanduser(a.client_rootdir)
-
- if a.sessions_rootdir:
- a.sessions_rootdir = os.path.expanduser(a.sessions_rootdir)
-
- if a.ssh_rootdir:
- a.ssh_rootdir = os.path.expanduser(a.ssh_rootdir)
-
- if a.client_rootdir:
- a.backend_sessionprofiles='FILE'
- a.backend_clientsettings='FILE'
- a.backend_clientprinting='FILE'
-
- return a, logger, liblogger
-
-def main():
- args, logger, liblogger = parseargs()
- if _X2GOCLIENT_OS == 'Windows':
- if args.lang:
- lang = gettext.translation('PyHoca-GUI', localedir=locale_basepath, languages=[args.lang], )
- else:
- lang = gettext.translation('PyHoca-GUI', localedir=locale_basepath, languages=['en'], )
- lang.install(unicode=True)
- else:
- gettext.install('PyHoca-GUI', localedir=locale_basepath, unicode=True)
-
- if check_running():
- sys.stderr.write("\n###############################\n### %s: already running for user %s\n###############################\n" % (PROG_NAME, _CURRENT_LOCAL_USER))
- m = messages.PyHoca_MessageWindow_Ok(wx.App(), shortmsg='ALREADY_RUNNING', title=u'%s (%s)...' % (PROG_NAME, VERSION), icon='pyhoca-trayicon')
- m.ShowModal()
- version()
-
- thisPyHocaGUI = None
- try:
- thisPyHocaGUI = PyHocaGUI(args, logger, liblogger, appname=PROG_NAME, version=VERSION)
- thisPyHocaGUI.MainLoop()
- except KeyboardInterrupt:
- if thisPyHocaGUI is not None:
- thisPyHocaGUI.WakeUpIdle()
- thisPyHocaGUI.ExitMainLoop()
- except SystemExit:
- if thisPyHocaGUI is not None:
- thisPyHocaGUI.WakeUpIdle()
- thisPyHocaGUI.ExitMainLoop()
-
- remove_pidfile()
if __name__ == '__main__':
- main()
-
+ app = PyHocaGUI_Launcher()
+ #app.setup_progname('MyProgramme')
+ app.setup_consolelog()
+ app.setup_process()
+ app.setup_devmode()
+ app.main()
diff --git a/pyhoca/wxgui/__init__.py b/pyhoca/wxgui/__init__.py
index a0ea0fa..89a1d1f 100644
--- a/pyhoca/wxgui/__init__.py
+++ b/pyhoca/wxgui/__init__.py
@@ -21,3 +21,4 @@
__VERSION__ = '0.5.0.0'
from frontend import *
+from launcher import *
\ No newline at end of file
diff --git a/pyhoca/wxgui/launcher.py b/pyhoca/wxgui/launcher.py
new file mode 100644
index 0000000..5d43a4d
--- /dev/null
+++ b/pyhoca/wxgui/launcher.py
@@ -0,0 +1,335 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2014 by Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+# Copyright (C) 2010-2014 by Dick Kniep <dick.kniep at lindix.nl>
+#
+# PyHoca GUI 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.
+#
+# PyHoca GUI 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.
+
+modules ={}
+
+import sys
+import os
+import re
+import shutil
+import argparse
+import gettext
+import subprocess
+
+import gevent.monkey
+gevent.monkey.patch_all()
+
+try:
+ import wxversion
+ wxversion.select('2.9')
+except: pass
+
+try:
+ import wxversion
+ wxversion.select('2.8')
+except: pass
+
+
+from x2go import X2GOCLIENT_OS
+from x2go import CURRENT_LOCAL_USER
+from x2go import X2GoLogger
+from pyhoca.wxgui import PyHocaGUI, __VERSION__
+from options import *
+from basepath import *
+from messages import PyHoca_MessageWindow_Ok
+import wx
+
+class PyHocaGUI_Launcher(object):
+
+ def __init__(self):
+ self.PROG_NAME = os.path.basename(sys.argv[0]).replace('.exe', '')
+ self.PROG_PID = os.getpid()
+ self.VERSION=__VERSION__
+ self.VERSION_TEXT="""
+%s[%s] - an X2Go GUI client written in Python
+----------------------------------------------------------------------
+developed by Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+sponsored by Dick Kniep <dick.kniep at lindix.nl> (2010-2013)
+
+VERSION: %s
+
+""" % (self.PROG_NAME, self.PROG_PID, self.VERSION)
+
+ def setup_progname(self, pname):
+ self.PROG_NAME = pname
+
+ def setup_version(self, v):
+ self.VERSION = v
+
+ def setup_version_text(self, text):
+ self.VERSION_TEXT = text
+
+ def setup_process(self):
+ if X2GOCLIENT_OS in ('Linux', 'Mac'):
+ import setproctitle
+ setproctitle.setproctitle(self.PROG_NAME)
+
+ if X2GOCLIENT_OS == 'Windows':
+ from pyhoca.wxgui.basepath import nxproxy_binary
+ os.environ.update({'NXPROXY_BINARY': nxproxy_binary, })
+
+ def setup_devmode(self):
+ if sys.argv[0].startswith('./') or sys.argv[0].startswith('python'):
+ sys.path.insert(0, os.getcwd())
+ os.environ['PYHOCAGUI_DEVELOPMENT'] = '1'
+ print '### %s running in development mode ###' % self.PROG_NAME
+
+
+ def setup_consolelog(self):
+ if hasattr(sys, 'frozen') and str(sys.frozen) in ("windows_exe", "console_exe", "1", ):
+ class Win32_Logging(object):
+
+ softspace = 0
+ _fname = os.path.join(os.environ['AppData'], self.PROG_NAME, '%s.log' % self.PROG_NAME)
+ _file = None
+
+ def __init__(self, filemode='a'):
+ self._filemode = filemode
+ if os.path.isfile(self._fname) and self._filemode == "w+":
+ os.remove(self._fname)
+
+ def write(self, text, **kwargs):
+ if self._file is None:
+ try:
+ try:
+ os.mkdir(os.path.dirname(self._fname))
+ except:
+ pass
+ self._file = open(self._fname, self._filemode)
+ except:
+ pass
+ else:
+ self._file.write(text)
+ self._file.flush()
+
+ def flush(self):
+ if self._file is not None:
+ self._file.flush()
+
+ sys.stdout = Win32_Logging(filemode='w+')
+ sys.stderr = Win32_Logging(filemode='a')
+ del Win32_Logging
+
+
+ def check_running(self):
+ if X2GOCLIENT_OS in ('Linux', 'Mac'):
+
+ p = subprocess.Popen(['ps', '-U', CURRENT_LOCAL_USER, '-u', CURRENT_LOCAL_USER], stdout=subprocess.PIPE)
+ psA_out = p.communicate()
+ if psA_out[0].count(self.PROG_NAME) <= 1:
+
+ if os.path.isdir(os.path.expanduser("~/.x2go/pyhoca-gui/")):
+ shutil.rmtree(os.path.expanduser("~/.x2go/pyhoca-gui/"))
+
+ my_pid = str(os.getpid())
+ if not os.path.exists(os.path.expanduser("~/.x2go/pyhoca-gui/")):
+ os.makedirs(os.path.expanduser("~/.x2go/pyhoca-gui/"))
+ my_pidfile = os.path.expanduser("~/.x2go/pyhoca-gui/display.{pid}".format(pid=my_pid))
+
+ my_display = os.environ['DISPLAY']
+ open(my_pidfile, 'w').write(my_display)
+
+ already_running_for_this_display = False
+ for pidfile in os.listdir(os.path.expanduser("~/.x2go/pyhoca-gui/")):
+
+ # this is our own pid file...
+ if my_pidfile.endswith(pidfile):
+ continue
+
+ display = open(os.path.expanduser("~/.x2go/pyhoca-gui/") + pidfile, 'r').read()
+
+ if display.split('.')[0] == my_display.split('.')[0]:
+ other_pid = pidfile.split('.')[1]
+ print
+ print('One instance of PyHoca-GUI (PID: {other_pid}) is already running for this $DISPLAY {display}'.format(other_pid=other_pid, display=my_display))
+
+ return True
+
+ return False
+
+ elif X2GOCLIENT_OS == 'Windows':
+ import wmi
+ w = wmi.WMI()
+ _p_names = []
+ for process in w.Win32_Process():
+ _p_names.append(process.Name)
+ return len([ _p_name for _p_name in _p_names if _p_name == self.PROG_NAME]) > 1
+
+
+ def version(self):
+ # version information
+
+ # print version text and exit
+ sys.stderr.write ("%s\n" % self.VERSION_TEXT)
+ self.remove_pidfile()
+
+ sys.exit(0)
+
+
+ # sometimes we have to fail...
+ def runtime_error(m, parser=None, exitcode=-1):
+ """\
+ STILL UNDOCUMENTED
+ """
+ if parser is not None:
+ parser.print_usage()
+ sys.stderr.write ("%s: error: %s\n" % (self.PROG_NAME, m))
+
+ self.remove_pidfile()
+ sys.exit(exitcode)
+
+
+ def remove_pidfile(self):
+
+ if X2GOCLIENT_OS in ('Linux', 'Mac'):
+ my_pid = str(os.getpid())
+ if os.path.exists(os.path.expanduser("~/.x2go/pyhoca-gui/display.{pid}".format(pid=my_pid))):
+ os.remove(os.path.expanduser("~/.x2go/pyhoca-gui/display.{pid}".format(pid=my_pid)))
+
+
+ def parseargs(self):
+
+ global DEBUG
+ global print_action_args
+
+ p = argparse.ArgumentParser(description='Graphical X2Go client implemented in (wx)Python.',\
+ formatter_class=argparse.RawDescriptionHelpFormatter, \
+ add_help=True, argument_default=None)
+ p_debugopts = p.add_argument_group('Debug options')
+ p_guiopts = p.add_argument_group('%s options' % self.PROG_NAME)
+ p_portableopts = p.add_argument_group('Portable application support')
+ p_backendopts = p.add_argument_group('Python X2Go backend options (for experts only)')
+
+ if X2GOCLIENT_OS == 'Windows':
+ p_contribopts = p.add_argument_group('XServer options (MS Windows only)')
+ p_portableopts = p.add_argument_group('File locations for portable setups (MS Windows only)')
+ _option_groups = ((p_guiopts, x2go_gui_options), (p_debugopts, debug_options), (p_contribopts, contrib_options), (p_portableopts, portable_options), (p_backendopts, backend_options), )
+ else:
+ _option_groups = ((p_guiopts, x2go_gui_options), (p_debugopts, debug_options), (p_portableopts, portable_options), (p_backendopts, backend_options), )
+ for (p_group, opts) in _option_groups:
+ required = False
+ for opt in opts:
+
+ args = opt['args']
+ del opt['args']
+ p_group.add_argument(*args, **opt)
+
+ a = p.parse_args()
+
+ logger = X2GoLogger(tag=self.PROG_NAME)
+ liblogger = X2GoLogger()
+
+ if a.debug:
+ logger.set_loglevel_debug()
+
+ if a.libdebug:
+ liblogger.set_loglevel_debug()
+
+ if a.quiet:
+ logger.set_loglevel_quiet()
+ liblogger.set_loglevel_quiet()
+
+ if a.libdebug_sftpxfer:
+ liblogger.enable_debug_sftpxfer()
+
+ if a.version:
+ self.version()
+
+ if a.single_session_profile and a.session_profile is None:
+ self.runtime_error('The --single-session-profile option requires naming of a specific session profile!', parser=p)
+
+ if a.non_interactive:
+ if a.session_profile is None:
+ self.runtime_error('In non-interactive mode you have to use the --session-profile option (or -P) to specify a certain session profile name!', parser=p)
+ a.restricted_trayicon = True
+ a.auto_connect = True
+ a.start_on_connect = True
+ a.resume_all_on_connect = True
+ a.exit_on_disconnect = True
+ a.disconnect_on_suspend = True
+ a.disconnect_on_terminate = True
+ a.single_session_profile = True
+
+ if a.non_interactive and (a.resume_newest_on_connect or a.resume_oldest_on_connect):
+ # allow override...
+ a.resume_all_on_connect = False
+
+ if X2GOCLIENT_OS == 'Windows' and a.preferred_xserver:
+ if a.preferred_xserver not in _installed_xservers:
+ self.runtime_error('Xserver ,,%s\'\' is not installed on your Windows system' % a.preferred_xserver, parser=p)
+ a.start_xserver = a.preferred_xserver
+
+ if X2GOCLIENT_OS == 'Windows' and a.start_xserver and a.display:
+ self.runtime_error('You can tell %s to handle XServer startup and then specify a DISPLAY environment variable!' % self.PROG_NAME, parser=p)
+
+ if a.display:
+ os.environ.update({'DISPLAY': a.display})
+ else:
+ if X2GOCLIENT_OS == 'Windows' and not a.start_xserver:
+ os.environ.update({'DISPLAY': 'localhost:0'})
+
+ if a.client_rootdir:
+ a.client_rootdir = os.path.expanduser(a.client_rootdir)
+
+ if a.sessions_rootdir:
+ a.sessions_rootdir = os.path.expanduser(a.sessions_rootdir)
+
+ if a.ssh_rootdir:
+ a.ssh_rootdir = os.path.expanduser(a.ssh_rootdir)
+
+ if a.client_rootdir:
+ a.backend_sessionprofiles='FILE'
+ a.backend_clientsettings='FILE'
+ a.backend_clientprinting='FILE'
+
+ return a, logger, liblogger
+
+
+ def main(self):
+ args, logger, liblogger = self.parseargs()
+ if X2GOCLIENT_OS == 'Windows':
+ if args.lang:
+ lang = gettext.translation('PyHoca-GUI', localedir=locale_basepath, languages=[args.lang], )
+ else:
+ lang = gettext.translation('PyHoca-GUI', localedir=locale_basepath, languages=['en'], )
+ lang.install(unicode=True)
+ else:
+ gettext.install('PyHoca-GUI', localedir=locale_basepath, unicode=True)
+
+ if self.check_running():
+ sys.stderr.write("\n###############################\n### %s: already running for user %s\n###############################\n" % (self.PROG_NAME, CURRENT_LOCAL_USER))
+ m = PyHoca_MessageWindow_Ok(wx.App(), shortmsg='ALREADY_RUNNING', title=u'%s (%s)...' % (self.PROG_NAME, self.VERSION), icon='pyhoca-trayicon')
+ m.ShowModal()
+ version()
+
+ thisPyHocaGUI = None
+ try:
+ thisPyHocaGUI = PyHocaGUI(args, logger, liblogger, appname=self.PROG_NAME, version=self.VERSION)
+ thisPyHocaGUI.MainLoop()
+ except KeyboardInterrupt:
+ if thisPyHocaGUI is not None:
+ thisPyHocaGUI.WakeUpIdle()
+ thisPyHocaGUI.ExitMainLoop()
+ except SystemExit:
+ if thisPyHocaGUI is not None:
+ thisPyHocaGUI.WakeUpIdle()
+ thisPyHocaGUI.ExitMainLoop()
+
+ self.remove_pidfile()
diff --git a/pyhoca/wxgui/options.py b/pyhoca/wxgui/options.py
new file mode 100644
index 0000000..3a79cce
--- /dev/null
+++ b/pyhoca/wxgui/options.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-2013 by Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+# Copyright (C) 2010-2013 by Dick Kniep <dick.kniep at lindix.nl>
+#
+# PyHoca GUI 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.
+#
+# PyHoca GUI 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.
+
+from x2go import X2GOCLIENT_OS
+from x2go import BACKENDS
+
+_profiles_backend_default = BACKENDS['X2GoSessionProfiles']['default']
+_settings_backend_default = BACKENDS['X2GoClientSettings']['default']
+_printing_backend_default = BACKENDS['X2GoClientPrinting']['default']
+
+if X2GOCLIENT_OS == 'Windows':
+ from x2go import X2GoClientXConfig
+ _x = X2GoClientXConfig()
+ _known_xservers = _x.known_xservers
+ _installed_xservers = _x.installed_xservers
+
+if X2GOCLIENT_OS == 'Windows':
+ _config_backends = ('FILE', 'WINREG')
+elif X2GOCLIENT_OS == 'Linux':
+ _config_backends = ('FILE', 'GCONF')
+else:
+ _config_backends = ('FILE')
+
+
+# debug options...
+debug_options = [
+ {'args':['-d','--debug'], 'default': False, 'action': 'store_true', 'help': 'enable application debugging code', },
+ {'args':['--quiet'], 'default': False, 'action': 'store_true', 'help': 'disable any kind of log output', },
+ {'args':['--libdebug'], 'default': False, 'action': 'store_true', 'help': 'enable debugging code of the underlying Python X2Go module', },
+ {'args':['--libdebug-sftpxfer'], 'default': False, 'action': 'store_true', 'help': 'enable debugging code of Python X2Go\'s sFTP server code (very verbose, and even promiscuous)', },
+ {'args':['-V', '--version'], 'default': False, 'action': 'store_true', 'help': 'print version number and exit', },
+ ]
+x2go_gui_options = [
+ {'args':['-P','--session-profile'], 'default': None, 'metavar': '<profile-name>', 'help': 'directly connect to a session profile', },
+ {'args':['--remember-username'], 'default': False, 'action': 'store_true', 'help': 'for profiles with interactive authentication, remember the last-used username', },
+ {'args':['--non-interactive'], 'default': False, 'action': 'store_true', 'help': 'run the session manager in non-interactive mode, this option sets the following options to true: --restricted-trayicon, --single_session_profile, --start-on-connect, --resume-all-on-connect, --exit-on-disconnect, --disconnect-on-suspend and --disconnect-on-terminate', },
+ {'args':['--auto-connect'], 'default': False, 'action': 'store_true', 'help': 'connect sessions via SSH pubkey authentication if possible', },
+ {'args':['--show-profile-metatypes'], 'default': False, 'action': 'store_true', 'help': 'show descriptive meta information on session profiles in menus (NOTE: this makes menus appear a bit more sluggish, use it mostly for debugging)', },
+ {'args':['--single-session-profile'], 'default': False, 'action': 'store_true', 'help': 'disable support of handling multiple session profiles', },
+ {'args':['--tray-icon'], 'default': None, 'metavar': '<your-logo>', 'help': 'define an alternative system tray icon file (PNG files only, leave out file extension here, size 22x22 on Linux, 16x16 on Windows)', },
+ {'args':['--tray-icon-connecting'], 'default': None, 'metavar': '<your-logo-while-connecting>', 'help': 'define an alternative system tray icon file while connecting to a server (PNG files only, leave out file extension here, size 22x22 on Linux, 16x16 on Windows)', },
+ {'args':['--restricted-trayicon'], 'default': False, 'action': 'store_true', 'help': 'restricts session manager\'s main icon functionality to information window and application exit; on left-click only a minimal session menu is shown', },
+ {'args':['--add-to-known-hosts'], 'default': False, 'action': 'store_true', 'help': 'automatically add SSH host keys to the known_hosts files of the client-side user', },
+ {'args':['--start-on-connect'], 'default': False, 'action': 'store_true', 'help': 'This is now the hard-coded default. start a session directly after authentication if no session is currently running/suspended', },
+ {'args':['--exit-on-disconnect'], 'default': False, 'action': 'store_true', 'help': 'exit the session manager after a server connection has died', },
+ {'args':['--resume-newest-on-connect', '--resume-on-connect'], 'default': False, 'action': 'store_true', 'help': 'This is now the hard-coded default. On connect auto-resume the newest suspended session', },
+ {'args':['--resume-oldest-on-connect'], 'default': False, 'action': 'store_true', 'help': 'on connect auto-resume the oldest suspended session', },
+ {'args':['--resume-all-on-connect'], 'default': False, 'action': 'store_true', 'help': 'auto-resume all suspended sessions on connect', },
+ {'args':['--disconnect-on-suspend'], 'default': False, 'action': 'store_true', 'help': 'disconnect a server if a session has been suspended', },
+ {'args':['--disconnect-on-terminate'], 'default': False, 'action': 'store_true', 'help': 'disconnect a server if a session has been terminated', },
+ {'args':['--splash-image'], 'default': None, 'metavar': '<your-splash-image>', 'help': 'define an alternative splash image that gets shown on application startup (PNG files only, full path or filename as found in <share>/img)', },
+ {'args':['--about-image'], 'default': None, 'metavar': '<your-about-window-image>', 'help': 'define an alternative image for the application\'s ,,About\'\' window (PNG files only, full path or filename as found in <share>/img)', },
+ {'args':['--disable-splash'], 'default': False, 'action': 'store_true', 'help': 'disable the applications splash screen', },
+ {'args':['--disable-options'], 'default': False, 'action': 'store_true', 'help': 'disable the client options configuration window', },
+ {'args':['--disable-printingprefs'], 'default': False, 'action': 'store_true', 'help': 'disable the client\'s printing preferences window', },
+ {'args':['--disable-profilemanager'], 'default': False, 'action': 'store_true', 'help': 'disable the session profile manager window', },
+ {'args':['--disable-notifications'], 'default': False, 'action': 'store_true', 'help': 'disable all applet notifications', },
+ {'args':['--display'], 'default': None, 'metavar': '<hostname>:<screennumber>', 'help': 'set the DISPLAY environment variable to <hostname>:<screennumber>', },
+ {'args':['--logon-window-position'], 'default': None, 'metavar': '<x-pos>x<y-pos>', 'help': 'give a custom position for the logon window, use negative values to position relative to right/bottom border', },
+ {'args':['--published-applications-no-submenus'], 'default': 10, 'metavar': '<number>', 'help': 'the number of published applications that will be rendered without submenus', },
+ ]
+if X2GOCLIENT_OS == 'Windows':
+ x2go_gui_options.append(
+ {'args':['--lang'], 'default': None, 'metavar': 'LANGUAGE', 'help': 'set the GUI language (currently available: en, de, nl, es)', },
+ )
+
+backend_options = [
+ {'args':['--backend-controlsession'], 'default': None, 'metavar': '<CONTROLSESSION_BACKEND>', 'choices': BACKENDS['X2GoControlSession'].keys(), 'help': 'force usage of a certain CONTROLSESSION_BACKEND (do not use this unless you know exactly what you are doing)', },
+ {'args':['--backend-terminalsession'], 'default': None, 'metavar': '<TERMINALSESSION_BACKEND>', 'choices': BACKENDS['X2GoTerminalSession'].keys(), 'help': 'force usage of a certain TERMINALSESSION_BACKEND (do not use this unless you know exactly what you are doing)', },
+ {'args':['--backend-serversessioninfo'], 'default': None, 'metavar': '<SERVERSESSIONINFO_BACKEND>', 'choices': BACKENDS['X2GoServerSessionInfo'].keys(), 'help': 'force usage of a certain SERVERSESSIONINFO_BACKEND (do not use this unless you know exactly what you are doing)', },
+ {'args':['--backend-serversessionlist'], 'default': None, 'metavar': '<SERVERSESSIONLIST_BACKEND>', 'choices': BACKENDS['X2GoServerSessionList'].keys(), 'help': 'force usage of a certain SERVERSESSIONLIST_BACKEND (do not use this unless you know exactly what you are doing)', },
+ {'args':['--backend-proxy'], 'default': None, 'metavar': '<PROXY_BACKEND>', 'choices': BACKENDS['X2GoProxy'].keys(), 'help': 'force usage of a certain PROXY_BACKEND (do not use this unless you know exactly what you are doing)', },
+ {'args':['--backend-sessionprofiles'], 'default': None, 'metavar': '<SESSIONPROFILES_BACKEND>', 'choices': _config_backends, 'help': 'use given backend for accessing session profiles, available backends on your system: %s (default: %s)' % (', '.join(_config_backends), _profiles_backend_default), },
+ {'args':['--backend-clientsettings'], 'default': None, 'metavar': '<CLIENTSETTINGS_BACKEND>', 'choices': _config_backends, 'help': 'use given backend for accessing the client settings configuration, available backends on your system: %s (default: %s)' % (', '.join(_config_backends), _settings_backend_default), },
+ {'args':['--backend-clientprinting'], 'default': None, 'metavar': '<CLIENTPRINTING_BACKEND>', 'choices': _config_backends, 'help': 'use given backend for accessing the client printing configuration, available backends on your system: %s (default: %s)' % (', '.join(_config_backends), _printing_backend_default), },
+ ]
+
+if X2GOCLIENT_OS == 'Windows':
+ contrib_options = [
+ {'args':['--start-xserver'], 'default': False, 'action': 'store_true', 'help': 'start the XServer before starting the session manager application, detect best XServer automatically, if more than one XServer is installed on your system', },
+ {'args':['-X', '--preferred-xserver'], 'default': None, 'metavar': '<XSERVER>', 'choices': _known_xservers, 'help': 'start either of the currently supported XServers: %s -- make sure your preferred XServer is installed on your system' % _known_xservers, },
+ {'args':['--start-pulseaudio'], 'default': False, 'action': 'store_true', 'help': 'start the PulseAudio server before starting the session manager application', },
+ ]
+
+portable_options = [
+ {'args':['--client-rootdir'], 'default': None, 'metavar': '</path/to/.x2goclient/dir>', 'help': 'define an alternative location where to find plain text config files (default: <HOME>/.x2goclient). This option will set ,,--backend-profiles FILE\'\', ,,--backend-clientsettings FILE\'\' and ,,--backend-clientprinting FILE\'\'', },
+ {'args':['--sessions-rootdir'], 'default': None, 'metavar': '</path/to/.x2go/dir>', 'help': 'define an alternative location for session runtime files'},
+ {'args':['--ssh-rootdir'], 'default': None, 'metavar': '</path/to/.ssh/dir>', 'help': 'define an alternative location for SSH files', },
+ ]
+
+
--
Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/pyhoca-gui.git
More information about the x2go-commits
mailing list