[X2Go-Commits] pyhoca-gui.git - twofactorauth (branch) updated: 81eeb4e708475585014567bb826564641777364b
X2Go dev team
git-admin at x2go.org
Sat Sep 14 15:54:10 CEST 2013
The branch, twofactorauth has been updated
via 81eeb4e708475585014567bb826564641777364b (commit)
from ca778d094c8e95177f2ac87b06b522413d95c79a (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
-----------------------------------------------------------------------
Summary of changes:
SessionProfile.py | 115 ++++++++++++++++----------
pyhocaguiImages.py | 147 ++++++++++++++++++++++++++++++++++
x2goLogon.py | 226 +++++++++++++++++++++++++++++++++++++++++++---------
3 files changed, 410 insertions(+), 78 deletions(-)
create mode 100644 pyhocaguiImages.py
The diff of changes is:
diff --git a/SessionProfile.py b/SessionProfile.py
index 4a38f63..40ca343 100644
--- a/SessionProfile.py
+++ b/SessionProfile.py
@@ -31,6 +31,7 @@ import os
import ConfigParser
from types import *
import exceptions
+import x2go
class profileError(exceptions.StandardError): pass
@@ -43,13 +44,14 @@ class processINI:
default values, so the resulting objects always contain
the same fields
"""
- def __init__(self, fileName):
+ def __init__(self, fileName, logger):
self.writeconfig = False
self.iniConfig = ConfigParser.SafeConfigParser()
+ logger('fileName %s' % fileName, x2go.loglevel_INFO, )
if fileName and os.path.exists(fileName):
+ logger('fileName %s found!' % fileName, x2go.loglevel_INFO, )
self.iniConfig.read(fileName)
-
def fillDefaultsSection(self):
for section, sectionvalue in self.defaultValues.items():
for key, value in sectionvalue.items():
@@ -105,18 +107,26 @@ class processINI:
else:
setattr(self, option, self.getValue(section, option))
+ def __repr__(self):
+ result = 'Ini('
+ for p in dir(self):
+ if '__' in p or not p in self.__dict__ or type(p) is InstanceType: continue
+ result += p + '=' + str(self.__dict__[p])
+ return result + ')'
+
class Settings(processINI):
"""
Settings object that contains all data that is generally necessary
"""
- defaultValues = { 'LDAP':{'useldap':False,'port':389,'server':'localhost','port1':0,'port2':0}, \
- 'General':{'clientport':22,'autoresume':True}, \
- 'Authorization': {'newprofile':True,'suspend':True,'editprofile':True,'resume':True}
- }
- def __init__(self, fileName=None):
+ defaultValues = { 'LDAP':{'useldap':False,'port':389,'server':'localhost','port1':0,'port2':0}, \
+ 'General':{'clientport':22,'autoresume':True}, \
+ 'Authorization': {'newprofile':True,'suspend':True,'editprofile':True,'resume':True}
+ }
+ def __init__(self, logger, fileName=None):
+ self.logger = logger
if fileName is None:
fileName = os.path.normpath(os.path.expanduser('~/.x2goclient/settings'))
- processINI.__init__(self, fileName)
+ processINI.__init__(self, fileName, logger)
self.fillDefaultsSection()
self.bldSessionObj()
@@ -125,15 +135,15 @@ class Printing(processINI):
Printing object that contains all data that is necessary for printing
"""
defaultValues = { 'General': {'showdialog':False,'pdfview':False}, \
- 'print': {'startcmd':False,'command':'lpr','stdin':False,'ps':False}, \
+ 'print': {'startcmd':False,'command':'lpr','stdin':False,'ps':False,'print_action':'PDFVIEW','print_action_args':''}, \
'view': {'open':True,'command':'xpdf'}, \
'CUPS': {'defaultprinter':None, 'options':'@Invalid()'}
}
- def __init__(self, fileName=None):
-
+ def __init__(self, logger, fileName=None):
+ self.logger = logger
if fileName is None:
fileName = os.path.normpath(os.path.expanduser('~/.x2goclient/printing'))
- processINI.__init__(self, fileName)
+ processINI.__init__(self, fileName, logger)
self.fillDefaultsSection()
self.bldSessionObj()
@@ -148,12 +158,15 @@ class SessionProfiles(processINI):
'setdpi':False,'usekbd':True,'layout':'us','type':'pc105/us','sound':False,'soundsystem':'pulse','startsoundsystem':True,'soundtunnel':True,
'defsndport':True,'sndport':4713, 'printing':True,'name':None,'icon':':icons/128x128/x2gosession.png','host':None,'user':None, 'key':None,
'sshport':22,'rootless':True,'applications':'dummy, WWWBROWSER, MAILCLIENT, OFFICE, TERMINAL','command':'dummy','rdpoptions':None,
- 'rdpserver':None,'default':False,'connected':False}
- def __init__(self, fileName=None):
+ 'rdpserver':None,'default':False,'connected':False,'add_to_known_hosts':True,'session_type':'application','link':'adsl',
+ }
+ def __init__(self, logger, fileName=None):
+ self.logger = logger
if fileName is None:
fileName = os.path.normpath(os.path.expanduser('~/.x2goclient/sessions'))
- processINI.__init__(self, fileName)
+ processINI.__init__(self, fileName, logger)
self.SessionProfiles = self.iniConfig.sections()
+ logger('SessionProfiles.SessionProfiles %s' % self.SessionProfiles, x2go.loglevel_INFO, )
for section in self.SessionProfiles:
for key, sectionvalue in self.defaultValues.items():
if not self.iniConfig.has_option(section,key):
@@ -174,12 +187,16 @@ class SessionProfiles(processINI):
self.storeValueTypes(name, key, value)
class SingleProfile:
- def __init__(self, prof, profiles):
+ def __init__(self, prof, profiles, logger, liblogger):
+ self.logger = logger
+ self.liblogger = liblogger
self.prof = prof
self.profiles = profiles
self.session_uuid = None
self.showConfigScreen = False
self.bldSessionObj()
+ self.c = None
+ self.connected = False
if self.host is None:
self.showConfigScreen = True
@@ -197,8 +214,8 @@ class SingleProfile:
def Connect(self, parent):
printing = parent.printProfile
geometry = str(self.width) + 'x' + str(self.height)
- self.c = x2go.X2goClient(logger=parent.liblogger)
- self.session_uuid = c.register_session(self.host, port=self.sshport,
+ self.c = x2go.X2goClient(logger=self.liblogger)
+ self.x2go_session_hash = self.c.register_session(self.host, port=self.sshport,
username=self.user,
password=self.password,
key_filename=self.key,
@@ -208,20 +225,21 @@ class SingleProfile:
link=self.link,
geometry=geometry,
pack=self.pack,
- cache_type=self.cache_type,
+ cache_type='unix-kde',
kblayout=self.layout,
kbtype=self.type,
snd_system=self.sound,
printing=self.printing,
print_action=printing.print_action,
print_action_args=printing.print_action_args,
- cmd=printing.command)
+ cmd=self.command)
+ self.with_session(self.x2go_session_hash).load_host_keys(ssh_known_hosts_filename)
self.c.session_start(session_uid)
self.profiles.updValue(self.prof, 'connected', True)
self.connected = True
self.profiles.writeIni()
- def Resume(self, parent, printing):
+ def Resume(self, parent):
pass
def DisConnect(self):
@@ -230,15 +248,24 @@ class SingleProfile:
self.profiles.writeIni()
def isAlive(self):
- return self.c.session_ok(self.session_uuid)
+ if self.c:
+ return self.c.session_ok(self.session_uuid)
+ return False
+
+ def updValue(self, key, value):
+ setattr(self, key, value)
class x2goProfiles:
- def __init__(self):
+ def __init__(self, logger, liblogger):
+ self.logger = logger
+ self.liblogger = liblogger
self.x2goprofs = []
+ self.x2gonames = {}
self.there_is_a_default = 0
- self.profiles = SessionProfiles()
+ self.profiles = SessionProfiles(logger)
for prof in self.profiles.SessionProfiles:
- newSession = SingleProfile(prof, self.profiles)
+ logger('profiles %s' % self.profiles, x2go.loglevel_INFO, )
+ newSession = SingleProfile(prof, self.profiles, logger, liblogger)
if newSession.default:
self.x2goprofs.insert(0,newSession)
self.there_is_a_default += 1
@@ -246,13 +273,16 @@ class x2goProfiles:
self.x2goprofs.append(newSession)
if len(self.profiles.SessionProfiles):
self.current_profile = self.x2goprofs[0]
+ for idx, prof in enumerate(self.x2goprofs):
+ self.x2gonames[prof.name] = idx
- def Append(self, name, **kw):
+ def AddProfile(self, name, **kw):
if self.profileExists(name):
raise profileError('Profile %s already exists' % name)
else:
self.profiles.newProfile(name, kw)
- self.x2goprofs.append(SingleProfile(name, self.profiles))
+ self.x2goprofs.append(SingleProfile(name, self.profiles, self.logger, self.liblogger))
+ self.x2gonames[name] = len(self.x2goprofs) -1
def writeIni(self):
for s in self.x2goprofs:
@@ -263,26 +293,21 @@ class x2goProfiles:
return self.there_is_a_default == 1
def profileExists(self, name):
- for profile in self.x2goprofs:
- if profile.prof == name or profile.name == name:
- self.current_profile = profile
- return True
- return False
+ return name in self.x2gonames
def runningSessions(self):
running = []
- for idx, profs in enumerate(self.profiles.iniConfig.sections()):
- connected = self.profiles.getValue(profs, 'connected', getType='bool')
- if connected:
- running.append(x2goprofs[idx])
+ for prof in self.x2goprofs:
+ if prof.connected:
+ running.append(prof)
return running
def suspendedSessions(self):
running = self.runningSessions()
suspended = []
for idx, run in enumerate(running):
- if running.isAlive(): continue
- suspended.appended(run)
+ if run.isAlive(): continue
+ suspended.append(run)
return suspended
def anyRunningSessions(self):
@@ -290,8 +315,8 @@ class x2goProfiles:
def listAllAvailableSessions(self):
availableSessions = []
- for idx, profs in enumerate(self.profiles.iniConfig.sections()):
- availableSessions.append([self.profiles.getValue(profs, 'name'), self.profiles.getValue(profs, 'connected', getType='bool')])
+ for prof in self.x2goprofs:
+ availableSessions.append([prof.name, prof.connected, prof.isAlive() ])
return availableSessions
def listNonRunningProfiles(self):
@@ -302,3 +327,13 @@ class x2goProfiles:
nonrunning.append(self.profiles.getValue(profs,'name'))
return nonrunning
+ def getProfileByName(self, name):
+ if name in self.x2gonames:
+ return self.x2goprofs[self.x2gonames[name]]
+
+ def __repr__(self):
+ result = 'x2goProfiles('
+ for p in dir(self):
+ if '__' in p or not p in self.__dict__ or type(p) is InstanceType: continue
+ result += p + '=' + str(self.__dict__[p])
+ return result + ')'
\ No newline at end of file
diff --git a/pyhocaguiImages.py b/pyhocaguiImages.py
new file mode 100644
index 0000000..0590532
--- /dev/null
+++ b/pyhocaguiImages.py
@@ -0,0 +1,147 @@
+#----------------------------------------------------------------------
+# This file was generated by /usr/bin/img2py
+#
+from wx.lib.embeddedimage import PyEmbeddedImage
+from wx import ImageFromStream, BitmapFromImage
+from wx import EmptyIcon
+import cStringIO
+
+
+resume = PyEmbeddedImage(
+ "iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABmJLR0QAAAAAAAD5Q7t/AAAA"
+ "CXBIWXMAAAsNAAALDQHtB8AsAAAAB3RJTUUH0wkJEjknnEqmFQAABRlJREFUeNp9lU1sXNUV"
+ "x3/33vfefM84jj3YkAwObpzSKGnqKAs2FaJqSwqriFbiY4OIqrJjU3VftWLVBWKBqKVKaVop"
+ "SCiqxIKoaSUkRIE2mDoQkhCSYDuJPTOe73nzPu+9XUwS2jrKlc7q6vzOX+f8j47gPm/x5RUX"
+ "7DSYWazNgwVsgDWbbtpsLMRvxSdPnrxnrrgP9DHgZ2APIagh3AIAJhph9TqwIkz69sHk9x8E"
+ "QaBPnTp1f/DiyyvzIF5Buc8VC/mJmamyfGBnln1TA3Ku5mq7yNcNw1azadq9IDBp8IFrh795"
+ "NP7jh2EYpncKOP8HfRjE63jlo4ceyfGTIyUO7LZUJxRK7gDGzegMUq5tVuW7y2Hh/c86P4oD"
+ "sfuy9+yv9po/nwGS/1F8W+nrxXL5x08eqcinFz0mSwohIIpTrLUopVBKIsU4zQ81/7g44tR7"
+ "bdtoda94uv3SnuGJD6Mo0v+l2P4Sr3T0h4sVnvqei+sINrZ8dBLiuZJcxiVKNAYXx/VwHQlY"
+ "juzNkaST4sTfzMJooH9eKBRWMpnMUI3VfvKYUJlXvztfzh5ddJESojimktXseWiCXdUS1Z0F"
+ "JssZJsseN1sJcWIIE0ucWiaLEj92WGsmc1t698qsunxdLf7inAu8UiqVvv+DQwWxowhBEDJb"
+ "sezbM03Gc5BSAqCURCnJlZsBo8gSJeMIE4OnYq7VjeeHaaLS3vsOMA0cKpcrciKb0ulbHpww"
+ "zNemARgGmuWvhnQGmlJeYozl5lZCPjvudb2Xcm69QsfPM6AoDd39fVGrOcAsQtamSoIgNmQc"
+ "y9xMDkdJusOUdz5qE8YGgEZ37IqsSpmZLHNkoUjWk7z4JjR9wHFAqFmUV3OAPDJTyLsJXd/g"
+ "OZbq5HgXbjRj+r7G2PF4d3g9DizMMFV2eKha3L5tQoDM5IShdNcV/dCl3rPkPO72tD2SfLxa"
+ "IEolR7/T5YUnv70NZowFBELcNjkgMNIBG2CiUd3P4ess1ZKh3onZXc0xVXbQwqE+UvST5J6r"
+ "3/VT4lQhxNh+6DAUNo0k1mxi9XpvZOhFWdY6Hv+8kqCN5dFdDr9+RnNgl+XCRo6rN3rbwJ2h"
+ "xhiLKyGOI7C6IY2/Kd202QBWiNrGVRaL4syFLFc3U4SA+dkMv3ve8NufJszvqmxXPNRgNZ6j"
+ "EXHLOIRfTtjVDbkQvxULk76to17P1R2m8z5JFPKHvwd8sRYRRAbPdZjaUcJaGIaG1UZCEBus"
+ "hdbAUHBGuLqDCTt+VtfPVtRWW50/f56nF+WNWxzcI2x6uDbtUM6kWJNyaT2k2UtoD1LWmwmX"
+ "b4Z8dNHn7L99Gp2YVl9zYS1iOIpZ32gR+Z0zB8RfTgCNO67QyoxeGwzEt1Zv8fjBR4rSc8df"
+ "1zYirm9GCAFmbGeyLlyvx6w2YqI4ZfXW0Az7vU92mot/QlIHAgWwvLzMU4tuq2Vr53qBs78/"
+ "SudKeZfJkoPnSlxH4CqB53wTroKtbsJn13psNvvnptNPX63J5X8BW4BWd4Zw+PBhW+VSu2Xn"
+ "Pu0FKt/sJXODUeplnVQUcg6OlEgB1mpaHZ/Pvx6ZS2uDYbfbP7NTX3jjNrQBJEtLS9svyPHj"
+ "xyVQ+Fw880Qqi8cM7n4pxWwpp3IAg0CHRpuGQ/hlVtfP7uWvHxtj6lLKlpQyXVpauvdpOnbs"
+ "GOVyWQBeM35g2hcze61Q+2SmYqXyEmHTSBp/c8Kubnjxum+M6UZR5Ftr09OnT9/l/AccmJbz"
+ "TUskMwAAAABJRU5ErkJggg==")
+getresumeData = resume.GetData
+getresumeImage = resume.GetImage
+getresumeBitmap = resume.GetBitmap
+#----------------------------------------------------------------------
+
+network_disconnected_lan = PyEmbeddedImage(
+ "iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAACsUlEQVR4nO2VPUtsRxiAn/k4"
+ "62Fx95jiFLexkY2KmCxuZyFkG7FLav9CSO1PCNj5L4wiJE1QC/u4iNegGFhh9TYJnnXPcb/O"
+ "2ePMpLg3chM8SUBIlRemmnmf+XjemYH/40OIoo6Dg4Pf2u2229ra+rJWq12urKwwmUye+5VS"
+ "CPE+3TkHgJQSY4zb29sb6CLw9fX1uzAMG/Pz899ubm5+6nkexhiMMXieR6/XI0kSrLWUSiVK"
+ "pRLWWjqdTqqU+qoQfHp6+sPGxkZjenq6sr6+/mY8HhNFEVprPM/j+PiYSqUCQL1eJ4oiwjDk"
+ "7u4OY8znheBms6nTNMU592StRSmFlJIsy8iyjKWlJQaDAdVqlTRNOTs7o9FooJQCELIIHAQB"
+ "1trn8wuCAOccWmvyPCfPc8rlMtZarq6ueHx8RAjB09MTQghXCDbGACCEIEkS8jwnTVOMMUgp"
+ "qVQqKKWYmZlheXmZZrNJrVYjyzIAdJH9LMtKxhi01ur+/p4kSdBac3NzQxzHzM3NIYQgjmNa"
+ "rRbD4ZDZ2VmkfL9WXWS/2+1WlFKsrq5+1mq1+DAJvu+TpilHR0f4vo/v+2RZxng85uLi4o8S"
+ "VPpf2Pe01mit/2T/9vaW/f39i3K5/DMghRCcnJxgrZVApF9jfzQa/TQajb4BPq4uATj5Svu3"
+ "wBjof9Qegb58pf07Cp6F5y1IKen1egyHQ3zfp91uE8cxtVoN51yhfcAVgoUQGGMIwxBjDHEc"
+ "U6/XOTw8pNPp0O/36ff7L9ovugdaCIEQAq21WlxcJE1TrLVIKVlYWGB3d5ednZ0fpZQPL9kv"
+ "BE9NTflCCKIoGmxvbw+stVop5SaTCUEQcH5+zsPDw3fA7kv2i8BibW3ti263+/Xl5eX3wK9A"
+ "9S8JCvgFeFsE+buoAp/8w5jCT+E/jd8BYeW2QhU9JDcAAAAASUVORK5CYII=")
+getnetwork_disconnected_lanData = network_disconnected_lan.GetData
+getnetwork_disconnected_lanImage = network_disconnected_lan.GetImage
+getnetwork_disconnected_lanBitmap = network_disconnected_lan.GetBitmap
+#----------------------------------------------------------------------
+
+x2goclient = PyEmbeddedImage(
+ "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAAZiS0dE"
+ "AP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9gKCQ83NL/ucHUAAAQ8"
+ "SURBVFjDxZdJiF1VEIa/vn3zXr/X07PTSToDzxARjVO0UFdRGhwQg7qQYFAadGVHNKgLNWI7"
+ "pEWIi6AhapuASBYGUXAi4oQ0CBFEShJFyMIBIRJDYhrNpD3owv9Icbl56VXnwKXevadOVZ36"
+ "q/5zXpuZXQM8BvwATDM3IwdWAJty4BFgrbufYA6HmXUBb2bA3rl2DuDux4Afc2BKEeVAF9AG"
+ "9EqvG2gHakAVmAecBL4CLmph/1t3n5bdAWCgTAeYyqU0T85bOe7UXDtQB4aAdcCSYPQ3YCfw"
+ "ZKinC4Fh4A69/wS8LR3ysLiiIHJF3AE09OTAUunNAKeA14EXgX0h8FF3f6mQ6nFg3Myu1dqr"
+ "3P2INv5fAO4+aWaHgL+07shpMpDgaQBN4GtgM/Bc2G1ZwQ0Ai4Ch5DyNLEAwP+y4T/Kc8K0R"
+ "nDeUrSbwKnBc9obMrLskhoeAvcCusn6MoyG5RJD0AT3CfIEyMaB1iwTTkHBfrwDvAbaG3S8G"
+ "HgDWufs/pQEIgj+Bn5WVCc2nmqgKjtghdQW5TLUwrPkNZrbN3Wekt1Gt/n4ZPBGCmqq/JxRg"
+ "VbKm771hri653N33Ax/K5nnALbLbBO4FnmlFiWmkOkC7ygMENWChdniudBanAM2sT1lYo7kH"
+ "gfeAEWCPu3/UMgBBcBSYlJOJWfBBowDTF8B3wCXAoJndDtwN3NCKEbMCEaVK7yykuSbZGfQS"
+ "FBXJpcpCGm8An4sHmA0EVRmvKN2RiCqq+lT91TBXFRw3AteJExZozZbZHIsJgmMiogrweyHN"
+ "nUp/RVmJc6kbKsD5wJiwB1gNfDxbCFIn1PW7ERwl7Osh5VnITuKKJvBJsD9sZrXZQpDarz/I"
+ "ekh1R0jtwiDrKtZuZWCzOD+TjSFg+5kCmAb+0HNSlf+rnLbLeKz4Dj2ZAgfYI721wP3Ay4mG"
+ "zWxHGQv+D4GcJNkeTsdUnOk915qOgD96/wV4FvjA3V8BxsMBdfOZMtAeMG/KSUpvjwgpHsmJ"
+ "qOZr16+pE24FrpTOFmAwENPuVl1wSkTUBvyt3R5oQTqpGzIgd/ftZvYO8K67fyPd3cB+4ALg"
+ "ejO7zN33teqCttBqBOf1QNV5SeoPmtkV4v+RcBGZAV4oHMmnhSALrbUsVHCXnn4F2CycAx1y"
+ "vAN4y92/L9jfCYxq/Z1mttHdD5YFMBP4Px2jh0LhdYVWzUIXfKnTbw1wacnN94SZjQFPyNZ6"
+ "4KmyLpgpyU6xGyrSj10wATwN7NKRXDbGwgX1PjPrLQsg9XO/bkPLgZXA5YCpmlcDtwFXA4d1"
+ "+hlwE/Bpi/v/AV3HkP1NrYgIdUEWIEgVnwjpsAw+qvYCeNzMGu6+rXAZXQncBVwcPm/QvXGk"
+ "yANJZqHqo4y0PQl8pieNqZIEHC3RS+N4inKUszTMbGsGrDKzyllwXgdWtJnZIPCwcJ3Lv+er"
+ "gOf/BaWXD+odPckfAAAAAElFTkSuQmCC")
+getx2goclientData = x2goclient.GetData
+getx2goclientImage = x2goclient.GetImage
+getx2goclientBitmap = x2goclient.GetBitmap
+#----------------------------------------------------------------------
+
+network_connected_lan_knc = PyEmbeddedImage(
+ "iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAADGUlEQVR4nO2VTWwUZRjHf+/M"
+ "7Gxntzv71S6lCqTBNqARFDAeSNNsFQ7WoAQ/7l68GBJPhESNB2O8efKoB9MDKhes0aSHalEi"
+ "Niuhlo92S6FsLWzT3W7bHXZmd3bm9bBCUHfwQOLJ/+39eH55kt/z5oX/82dE0MGpUzMr8/PX"
+ "5bvvv/aycbh+uftVaNqtAilA1SDktda+bO0JFRQHuXAcSwsC5/MXlrYktu9PDvPR4ZOPDehq"
+ "B35T4MomMftRrJUG+cQkroSIiGOIOK5wKcwXHaHLo4HgXG7y6xeG39gfMSOxVwZHtiZvVdk3"
+ "vkGlS+HiliwTP02z8OIkvgrDqRGWN4tsi/YzOnca2SjvDQQPDb2uOY4Fnmg2PZVqRxfjB+5Q"
+ "FXXWwjkSL9XZZTxDn/0U287t4/vSx4ihKBphEAglCGyaaXzpIZH4MkxnZIB8j8/tTIQNvcyq"
+ "WSCuZBCOwYXFHNWKiyIN3KYPAhnYsec1AYGnKqSuraKnd1Cv2/SsDlBTLEQ0Qs1zSMe6yezp"
+ "Iy1T9Ca3M+aOA6AF2bco603h4BuKGrv6O1d21tDNbtbPhriauERXfxbRSFORCyz9cJOCscjz"
+ "T3ShqGoLHGT/V++dmGntYDA1sOdk+EcaS4IwUaL9aTb8Nc5PXcS8/SbOgc9x9+qsN2oYi0Zr"
+ "fgWq9kD7PVkmfpkOFZ48h6tCNnWE5c0iT0cHGZ09zfRnH/4mzogZhFQECt/IMaSHApS0h7Ev"
+ "y0zJkjwOaODf1SMAqZlmmmpp5T77O5npuQEygmOXKZlrxL377Lt/sX8Tid1OvvaQ9gt3O/wH"
+ "+N54hVQys0Vm+n8mGu/lztlOLidydO96Dt+OBdpvB70HFoBWd8k/uxvf1/Drq/QdSjJ26zyV"
+ "2UNUKj7lR9rbD3oHmhCAIghpQh3ZmiK0buF0ZjDdAkOPn+DTr77lvQ8mvhOqWGtnPxCs650d"
+ "NWzWl13r7U9GrbDta0LVpV+30NK9TF26grzGlxL5RTv7QWBx8OCxbKm0+dZcfuIM0isC5t8K"
+ "VARzSKaDIA+KCST/5U7gp/Cf5g+ZXZ0wbxji4wAAAABJRU5ErkJggg==")
+getnetwork_connected_lan_kncData = network_connected_lan_knc.GetData
+getnetwork_connected_lan_kncImage = network_connected_lan_knc.GetImage
+getnetwork_connected_lan_kncBitmap = network_connected_lan_knc.GetBitmap
+#----------------------------------------------------------------------
+
+def getSmallUpArrowData():
+ return \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
+\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
+\x00\x00<IDAT8\x8dcddbf\xa0\x040Q\xa4{h\x18\xf0\xff\xdf\xdf\xffd\x1b\x00\xd3\
+\x8c\xcf\x10\x9c\x06\xa0k\xc2e\x08m\xc2\x00\x97m\xd8\xc41\x0c \x14h\xe8\xf2\
+\x8c\xa3)q\x10\x18\x00\x00R\xd8#\xec\xb2\xcd\xc1Y\x00\x00\x00\x00IEND\xaeB`\
+\x82'
+
+def getSmallUpArrowBitmap():
+ return BitmapFromImage(getSmallUpArrowImage())
+
+def getSmallUpArrowImage():
+ stream = cStringIO.StringIO(getSmallUpArrowData())
+ return ImageFromStream(stream)
+
+#----------------------------------------------------------------------
+
+def getSmallDnArrowData():
+ return \
+"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
+\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
+\x00\x00HIDAT8\x8dcddbf\xa0\x040Q\xa4{\xd4\x00\x06\x06\x06\x06\x06\x16t\x81\
+\xff\xff\xfe\xfe'\xa4\x89\x91\x89\x99\x11\xa7\x0b\x90%\ti\xc6j\x00>C\xb0\x89\
+\xd3.\x10\xd1m\xc3\xe5*\xbc.\x80i\xc2\x17.\x8c\xa3y\x81\x01\x00\xa1\x0e\x04e\
+?\x84B\xef\x00\x00\x00\x00IEND\xaeB`\x82"
+
+def getSmallDnArrowBitmap():
+ return BitmapFromImage(getSmallDnArrowImage())
+
+def getSmallDnArrowImage():
+ stream = cStringIO.StringIO(getSmallDnArrowData())
+ return ImageFromStream(stream)
+
diff --git a/x2goLogon.py b/x2goLogon.py
index 4e823cb..de101e4 100644
--- a/x2goLogon.py
+++ b/x2goLogon.py
@@ -31,8 +31,11 @@ import wx
import time
import sys
import wx.lib.scrolledpanel as scrolled
+import wx.lib.mixins.listctrl as listmix
import SessionProfile
import x2go
+import pyhocaguiImages
+
try:
from agw import knobctrl as KC
knobctrlavailable = True
@@ -46,8 +49,13 @@ except ImportError: # if it's not there locally, try the wxPython lib.
import wx.lib.sized_controls as sc
class menuActions(wx.Menu):
- def __init__(self, parent):
- self.parent = parent
+ def __init__(self, parent, fromTaskBarIcon=False, popupMenu=False):
+ if fromTaskBarIcon:
+ self.parent = parent.parent
+ else:
+ self.parent = parent
+ self.fromTaskBarIcon = fromTaskBarIcon
+ self.popupMenu = popupMenu
if hasattr(parent,'logger'):
self.logger = self.parent.logger
else:
@@ -60,6 +68,10 @@ class menuActions(wx.Menu):
self.settingsProfile = parent.parent.settingsProfile
self.SessionProfiles = parent.parent.SessionProfiles
self.printProfile = parent.parent.printProfile
+ if hasattr(parent,'selected_profile'):
+ self.selected_profile = parent.selected_profile
+ else:
+ self.selected_profile = parent.parent.selected_profile
ADDPROFILEMENUTXT = "Add &New profile"
OPENNEWMENUTXT = "&Open new Session"
@@ -80,33 +92,43 @@ class menuActions(wx.Menu):
wx.Menu.__init__(self)
self.logger('settingsProfile.newProfile %s' % dir(self.settingsProfile), x2go.loglevel_INFO, )
self.Append(MENU_NEWSESSION, OPENNEWMENUTXT)
- self.parent.Bind(wx.EVT_MENU, self.OnNewSession, id=MENU_NEWSESSION)
+ parent.Bind(wx.EVT_MENU, self.OnNewSession, id=MENU_NEWSESSION)
if self.settingsProfile.newprofile:
self.Append(MENU_NEWPROFILE, ADDPROFILEMENUTXT)
- self.parent.Bind(wx.EVT_MENU, self.OnAddProfile, id=MENU_NEWPROFILE)
- if self.SessionProfiles.runningSessions():
+ parent.Bind(wx.EVT_MENU, self.OnAddProfile, id=MENU_NEWPROFILE)
+ if self.SessionProfiles.runningSessions() and popupMenu is False:
self.Append(MENU_LISTSESSIONS, RUNNINGMENUTXT)
- self.parent.Bind(wx.EVT_MENU, self.OnListSessions, id=MENU_LISTSESSIONS)
+ parent.Bind(wx.EVT_MENU, self.OnListSessions, id=MENU_LISTSESSIONS)
+ if self.settingsProfile.suspend and ((popupMenu is False and self.SessionProfiles.runningSessions()) or (popupMenu and self.selected_profile.connected is False and self.selected_profile.isAlive())):
self.Append(MENU_SUSPEND, SUSPENDMENUTXT)
- self.parent.Bind(wx.EVT_MENU, self.OnSuspend, id=MENU_SUSPEND)
- if self.SessionProfiles.suspendedSessions() and self.settingsProfile.resume:
+ parent.Bind(wx.EVT_MENU, self.OnSuspend, id=MENU_SUSPEND)
+ if self.settingsProfile.resume and self.SessionProfiles.suspendedSessions():
self.Append(MENU_RESUME, RESUMEMENUTXT)
- self.parent.Bind(wx.EVT_MENU, self.OnResume, id=MENU_RESUME)
+ parent.Bind(wx.EVT_MENU, self.OnResume, id=MENU_RESUME)
if self.settingsProfile.editprofile:
self.AppendSeparator()
self.Append(MENU_EDITSESSION, UPDATEPROFMNUTEXT)
- self.parent.Bind(wx.EVT_MENU, self.OnUpdateProfile, id=MENU_EDITSESSION)
+ parent.Bind(wx.EVT_MENU, self.OnUpdateProfile, id=MENU_EDITSESSION)
self.AppendSeparator()
self.Append(MENU_EXIT, EXITMENUTXT)
- self.parent.Bind(wx.EVT_MENU, self.OnExit, id=MENU_EXIT)
- self.parent.Bind(wx.EVT_CLOSE, self.OnClose)
+ parent.Bind(wx.EVT_MENU, self.OnExit, id=MENU_EXIT)
+ #self.parent.Bind(wx.EVT_CLOSE, self.OnClose)
def OnAddProfile(self, evt):
self.logger('Add Profile started', x2go.loglevel_INFO, )
def OnNewSession(self, evt):
- self.logger('NewSession started', x2go.loglevel_INFO, )
- X2GoChooseSessionScrn(self.parent)
+ self.logger('NewSession started for self.parent.__class__.__name__ %s, len(self.SessionProfiles.x2goprofs) %s' % (self.parent.__class__.__name__, len(self.SessionProfiles.x2goprofs)), x2go.loglevel_INFO, )
+ if hasattr(self.parent,'selected_profile') and 1==0:
+ X2GoPasswordScrn(self.parent)
+ elif len(self.SessionProfiles.x2goprofs) > 1:
+ self.logger('self.parent.IsIconized() %s' % self.parent.IsIconized(), x2go.loglevel_INFO, )
+ if self.parent.IsIconized() or not self.parent.IsShown():
+ self.parent.Iconize(False)
+ if not self.parent.IsShown():
+ self.parent.Show(True)
+ self.parent.Raise()
+ self.parent.SetFocus()
def OnListSessions(self, evt):
self.logger('List Sessions started', x2go.loglevel_INFO, )
@@ -162,7 +184,7 @@ class X2GoResumeSessions(sc.SizedFrame):
style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
class X2GoPasswordScrn(sc.SizedFrame):
- def __init__(self, parent, Iconize):
+ def __init__(self, parent, Iconize=False):
"""
Screen to enter the userid and password for the session
@@ -189,12 +211,11 @@ class X2GoPasswordScrn(sc.SizedFrame):
self.Main_MenuBar = wx.MenuBar()
self.SetMenuBar(self.Main_MenuBar)
self.Main_MenuBar.Append(menuActions(self), '&Connection')
- self.tb = X2GoLogonTaskBarIcon(self)
- self.Bind(wx.EVT_CLOSE, self.OnCancel)
+ #self.Bind(wx.EVT_CLOSE, self.OnCancel)
if Iconize:
if not self.IsIconized():
self.Iconize(True)
- if parent.args.password and parent.args.username and parent.args.profile and SessionProfiles.profileExists(parent.args.profile):
+ if parent.parent.args.password and parent.parent.args.username and parent.parent.args.profile and SessionProfiles.profileExists(parent.parent.args.profile):
self.onConnect()
elif parent.args.profile:
Message(self, 'Not all credentials are available')
@@ -210,13 +231,14 @@ class X2GoPasswordScrn(sc.SizedFrame):
if hasattr(self.current_profile,'username'):
self.username_ctl.SetValue(self.SessionProfile.username)
else:
- self.username_ctl.SetValue(self.parent.args.username)
+ self.username_ctl.SetValue(self.parent.parent.args.username)
wx.StaticText(pnl, -1, 'Password'),
self.passwd_ctl = wx.TextCtrl(pnl, -1, style=wx.TE_PASSWORD)
self.ConnectButton = wx.Button(pnl, -1, "Connect")
self.ConnectButton.Bind(wx.EVT_BUTTON, self.OnOK)
+ self.ConnectButton.SetDefault()
self.CancelButton = wx.Button(pnl, -1, "Cancel")
self.CancelButton.Bind(wx.EVT_BUTTON, self.OnCancel)
@@ -230,7 +252,7 @@ class X2GoPasswordScrn(sc.SizedFrame):
if len(password) == 0:
Message(self,'Password is required')
return
- self.current_profile.updValue('server','username',username)
+ self.current_profile.updValue('username',username)
self.current_profile.password = password
self.onConnect()
@@ -251,29 +273,155 @@ class X2GoPasswordScrn(sc.SizedFrame):
return
def OnCancel(self, evt):
- if not self.SessionProfiles.anyRunningSessions():
- #self.Close()
- self.tb.Destroy()
self.Destroy()
+class X2GoListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin):
+ def __init__(self, parent, ID, pos=wx.DefaultPosition,
+ size=wx.DefaultSize, style=0):
+ wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
+ listmix.ListCtrlAutoWidthMixin.__init__(self)
+ self.sm_up = parent.il.Add(pyhocaguiImages.getSmallUpArrowBitmap())
+ self.sm_dn = parent.il.Add(pyhocaguiImages.getSmallDnArrowBitmap())
+ listmix.ColumnSorterMixin.__init__(self, 2)
+ self.SortListItems(0, True)
+
+ # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
+ def GetListCtrl(self):
+ return self
+
+ # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
+ def GetSortImages(self):
+ return (self.sm_dn, self.sm_up)
+
+
class X2GoChooseSessionScrn(wx.Frame):
- def __init__(self, parent):
- wx.Frame.__init__(self)
+ def __init__(self, parent, Iconize=False):
+ self.parent = parent
self.logger = parent.logger
+ self.settingsProfile = parent.settingsProfile
+ self.SessionProfiles = parent.SessionProfiles
+ self.current_profile = parent.SessionProfiles.current_profile
+ self.selected_profile = None
+ self.printProfile = parent.printProfile
self.logger('Choose Session screen started', x2go.loglevel_INFO, )
+ wx.Frame.__init__(self, None, -1)
+ self.CentreOnScreen()
+ self.il = wx.ImageList(16, 16)
+ self.list = X2GoListCtrl(self, -1,
+ style=wx.LC_REPORT | wx.BORDER_NONE | wx.LC_SORT_ASCENDING
+ )
+ self.idx1 = self.il.Add(pyhocaguiImages.getnetwork_disconnected_lanBitmap())
+ self.idx2 = self.il.Add(pyhocaguiImages.getnetwork_connected_lan_kncBitmap())
+ self.idx3 = self.il.Add(pyhocaguiImages.getresumeBitmap())
+
+ self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
+
+ self.PopulateList()
+
+ self.Main_MenuBar = wx.MenuBar()
+ self.SetMenuBar(self.Main_MenuBar)
+ self.Main_MenuBar.Append(menuActions(self), '&Connection')
+ self.tb = X2GoLogonTaskBarIcon(self)
+
+ self.Bind(wx.EVT_SIZE, self.OnSize)
- wx.SingleChoiceDialog(self, 'Choose profile', choices=parent.SessionProfiles.listNonRunningProfiles(), style=wx.CHOICEDLG_STYLE )
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
+ self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated, self.list)
-class X2GoSessionDefScrn(sc.SizedDialog):
+ self.list.Bind(wx.EVT_LEFT_DCLICK, self.OnDoubleClick)
+ self.list.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
+
+ # for wxMSW
+ self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
+
+ # for wxGTK
+ self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
+
+ self.Bind(wx.EVT_CLOSE, self.OnCancel)
+ if Iconize:
+ if not self.IsIconized():
+ self.Iconize(True)
+ else:
+ self.Show(True)
+
+ def OnSize(self, event):
+ w,h = self.GetClientSizeTuple()
+ self.list.SetDimensions(0, 0, w, h)
+
+ def PopulateList(self):
+ sessions = self.parent.SessionProfiles.listAllAvailableSessions()
+ info = wx.ListItem()
+ info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
+ info.m_image = -1
+ info.m_format = 0
+ info.m_text = "Profile"
+ self.list.InsertColumnInfo(0, info)
+
+ info.m_format = wx.LIST_FORMAT_RIGHT
+ info.m_text = "Status"
+ self.list.InsertColumnInfo(1, info)
+ for profilename, connected, alive in sessions:
+ if connected and alive:
+ index = self.list.InsertImageStringItem(sys.maxint, profilename, self.idx2)
+ self.list.SetStringItem(index, 1, 'Connected')
+ elif not connected and alive:
+ index = self.list.InsertImageStringItem(sys.maxint, profilename, self.idx3)
+ self.list.SetStringItem(index, 1, 'Suspended')
+ else:
+ index = self.list.InsertImageStringItem(sys.maxint, profilename, self.idx1)
+ self.list.SetStringItem(index, 1, 'Not Connected')
+
+ self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+
+ def OnRightDown(self, event):
+ x = event.GetX()
+ y = event.GetY()
+ item, flags = self.list.HitTest((x, y))
+
+ if flags & wx.LIST_HITTEST_ONITEM:
+ self.list.Select(item)
+ event.Skip()
+
+ def OnItemSelected(self, event):
+ ##print event.GetItem().GetTextColour()
+ self.currentItem = event.m_itemIndex
+ self.selected_profile = self.parent.SessionProfiles.getProfileByName(self.list.GetItemText(self.currentItem))
+
+ def OnDoubleClick(self, event):
+ self.logger('DoubleClick', x2go.loglevel_INFO, )
+ event.Skip()
+
+ def OnItemActivated(self, event):
+ self.currentItem = event.m_itemIndex
+ self.selected_profile = self.parent.SessionProfiles.getProfileByName(self.list.GetItemText(self.currentItem))
+
+ def OnRightClick(self, event):
+ # only do this part the first time so the events are only bound once
+
+ # Popup the menu. If an item is selected then its handler
+ # will be called before PopupMenu returns.
+ self.PopupMenu(menuActions(self, popupMenu=True))
+
+ def OnCancel(self, evt):
+ if not self.SessionProfiles.anyRunningSessions():
+ #self.Close()
+ self.tb.Destroy()
+ self.Destroy()
+
+class X2GoSessionDefScrn(wx.Frame):
SESSIONNOTEBOOK = wx.NewId()
TypeList = ['GNOME','LXDE','Connect to Windows terminal server','Custom desktop','Server security','Single application']
CommandList = ['Internet Browser','Email client','OpenOffice','Terminal']
ConnectList = ['Modem','ISDN','ADSL','WAN','LAN']
CommpressionList = ['nopack','64k','256k','2m','256-rdp','32k-rdp','64k-rdp','16m-rdp','16m-rdp-compressed','64k-tight','2m-tight','4k-jpeg','16m-jpeg','64k-png-jpeg','16m-png-jpeg','64k-png','16m-png','16m-rgb','16m-rle']
- def __init__(self, parent):
+ def __init__(self, parent, directCall=False):
parent.logger('Session definition screen started', x2go.loglevel_INFO, )
- self.pnl = wx.Panel(self, -1)
+ if directCall:
+ wx.Frame.__init__(self, parent=None, id=-1)
+ else:
+ wx.Frame.__init__(self, parent=parent, id=-1)
+ self.pnl = sc.SizedDialog(self, -1)
if self.current_profile and self.current_profile.connected:
self.StatusText = self.current_profile.StatusText
self.Environment = self.current_profile.Environment
@@ -418,7 +566,7 @@ class X2GoLogonTaskBarIcon(wx.TaskBarIcon):
the menu how you want it and return it from this function,
the base class takes care of the rest.
"""
- menu = menuActions(self)
+ menu = menuActions(self, fromTaskBarIcon=True)
return menu
def MakeIcon(self, img):
@@ -498,32 +646,34 @@ def startX2Go(parent):
"""
parent.logger('starting a new X2go GUI session', x2go.loglevel_INFO, )
- parent.printProfile = SessionProfile.Printing()
- parent.settingsProfile = SessionProfile.Settings()
- parent.SessionProfiles = SessionProfile.x2goProfiles()
+ parent.printProfile = SessionProfile.Printing(parent.logger)
+ parent.settingsProfile = SessionProfile.Settings(parent.logger)
+ parent.SessionProfiles = SessionProfile.x2goProfiles(parent.logger, parent.liblogger)
noSessionsDefined = len(parent.SessionProfiles.x2goprofs) == 0
moreSessionsDefined = len(parent.SessionProfiles.x2goprofs) > 1
#checkArgs(parent, parent.args, SessionProfiles)
+ parent.logger('parent.SessionProfiles %s' % parent.SessionProfiles, x2go.loglevel_INFO, )
sessionsSuspended = parent.SessionProfiles.suspendedSessions()
if len(sessionsSuspended) and parent.settingsProfile.autoresume:
parent.logger('autoresume sessionsSuspended %s' % sessionsSuspended, x2go.loglevel_INFO, )
+ ChoiceScrn = X2GoChooseSessionScrn(parent, Iconize=True)
for suspended in sessionsSuspended:
- suspended.Resume()
+ suspended.Resume(parent)
elif len(sessionsSuspended):
parent.logger('Choose SuspendedSessions %s' % sessionsSuspended, x2go.loglevel_INFO, )
X2GoResumeSessions(parent, sessionsSuspended)
else:
if parent.args.minimized:
parent.logger('Start minimized', x2go.loglevel_INFO, )
- pwScrn = X2GoPasswordScrn(parent, Iconize=True)
+ ChoiceScrn = X2GoChooseSessionScrn(parent, Iconize=True)
else:
- if not noSessionsDefined and (not moreSessionsDefined or SessionProfiles.defaultAvailable()):
+ if not noSessionsDefined and (not moreSessionsDefined or parent.SessionProfiles.defaultAvailable()):
parent.logger('Start password entry normally', x2go.loglevel_INFO, )
- pwScrn = X2GoPasswordScrn(parent)
+ ChoiceScrn = X2GoChooseSessionScrn(parent, Iconize=True)
elif noSessionsDefined:
parent.logger('Start Profile Definition', x2go.loglevel_INFO, )
- defScrn = X2GoSessionDefScrn(parent)
+ defScrn = X2GoSessionDefScrn(parent, directCall=True)
else:
parent.logger('Start Profile choice', x2go.loglevel_INFO, )
choiceScrn = X2GoChooseSessionScrn(parent)
hooks/post-receive
--
pyhoca-gui.git (Python X2Go Client (wxPython GUI))
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "pyhoca-gui.git" (Python X2Go Client (wxPython GUI)).
More information about the x2go-commits
mailing list