2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
3
# See LICENSE for details.
6
from __future__ import nested_scopes
10
from twisted import copyright
11
from twisted.internet import defer
12
from twisted.python import failure, log, util
13
from twisted.spread import pb
14
from twisted.cred.credentials import UsernamePassword
16
from twisted.internet import error as netError
18
def login(client=None, **defaults):
25
@param perspectiveName:
27
@returntype: Deferred RemoteReference of Perspective
30
LoginDialog(client, d, defaults)
35
@cvar gladefile: The file in which the glade GUI definition is kept.
38
@cvar _widgets: Widgets that should be attached to me as attributes.
39
@type _widgets: list of strings
47
self.glade = glade.XML(self.gladefile)
49
# mold can go away when we get a newer pygtk (post 1.99.14)
52
mold[k] = getattr(self, k)
53
self.glade.signal_autoconnect(mold)
56
def _setWidgets(self):
57
get_widget = self.glade.get_widget
58
for widgetName in self._widgets:
59
setattr(self, "_" + widgetName, get_widget(widgetName))
62
class LoginDialog(GladeKeeper):
63
# IdentityConnector host port identityName password
64
# requestLogin -> identityWrapper or login failure
65
# requestService serviceName perspectiveName client
68
# cancel button pressed
69
# login button activated
71
fields = ['host','port','identityName','password',
74
_widgets = ("hostEntry", "portEntry", "identityNameEntry", "passwordEntry",
75
"perspectiveNameEntry", "statusBar",
78
_advancedControls = ['perspectiveLabel', 'perspectiveNameEntry',
79
'protocolLabel', 'versionLabel']
81
gladefile = util.sibpath(__file__, "login2.glade")
83
def __init__(self, client, deferred, defaults):
85
self.deferredResult = deferred
87
GladeKeeper.__init__(self)
89
self.setDefaults(defaults)
90
self._loginDialog.show()
93
def setDefaults(self, defaults):
94
if not defaults.has_key('port'):
95
defaults['port'] = str(pb.portno)
96
elif isinstance(defaults['port'], (int, long)):
97
defaults['port'] = str(defaults['port'])
99
for k, v in defaults.iteritems():
101
widget = getattr(self, "_%sEntry" % (k,))
104
def _setWidgets(self):
105
GladeKeeper._setWidgets(self)
106
self._statusContext = self._statusBar.get_context_id("Login dialog.")
107
get_widget = self.glade.get_widget
108
get_widget("versionLabel").set_text(copyright.longversion)
109
get_widget("protocolLabel").set_text("Protocol PB-%s" %
110
(pb.Broker.version,))
112
def _on_loginDialog_response(self, widget, response):
113
handlers = {gtk.RESPONSE_NONE: self._windowClosed,
114
gtk.RESPONSE_DELETE_EVENT: self._windowClosed,
115
gtk.RESPONSE_OK: self._doLogin,
116
gtk.RESPONSE_CANCEL: self._cancelled}
117
handler = handlers.get(response)
118
if handler is not None:
121
log.msg("Unexpected dialog response %r from %s" % (response,
124
def _on_loginDialog_close(self, widget, userdata=None):
127
def _on_loginDialog_destroy_event(self, widget, userdata=None):
130
def _cancelled(self):
131
if not self.deferredResult.called:
132
self.deferredResult.errback(netError.UserError("User hit Cancel."))
133
self._loginDialog.destroy()
135
def _windowClosed(self, reason=None):
136
if not self.deferredResult.called:
137
self.deferredResult.errback(netError.UserError("Window closed."))
142
idParams['host'] = self._hostEntry.get_text()
143
idParams['port'] = self._portEntry.get_text()
144
idParams['identityName'] = self._identityNameEntry.get_text()
145
idParams['password'] = self._passwordEntry.get_text()
148
idParams['port'] = int(idParams['port'])
152
f = pb.PBClientFactory()
153
from twisted.internet import reactor
154
reactor.connectTCP(idParams['host'], idParams['port'], f)
155
creds = UsernamePassword(idParams['identityName'], idParams['password'])
156
f.login(creds, self.client
157
).addCallbacks(self._cbGotPerspective, self._ebFailedLogin
160
self.statusMsg("Contacting server...")
162
# serviceName = self._serviceNameEntry.get_text()
163
# perspectiveName = self._perspectiveNameEntry.get_text()
164
# if not perspectiveName:
165
# perspectiveName = idParams['identityName']
167
# d = _identityConnector.requestService(serviceName, perspectiveName,
169
# d.addCallbacks(self._cbGotPerspective, self._ebFailedLogin)
170
# setCursor to waiting
172
def _cbGotPerspective(self, perspective):
173
self.statusMsg("Connected to server.")
174
self.deferredResult.callback(perspective)
175
# clear waiting cursor
176
self._loginDialog.destroy()
178
def _ebFailedLogin(self, reason):
179
if isinstance(reason, failure.Failure):
180
reason = reason.value
181
self.statusMsg(reason)
182
if isinstance(reason, (unicode, str)):
185
text = unicode(reason)
186
msg = gtk.MessageDialog(self._loginDialog,
187
gtk.DIALOG_DESTROY_WITH_PARENT,
192
msg.connect("response", lambda *a: msg.destroy())
197
# authentication failed
199
# no such perspective
200
# internal server error
202
def _on_advancedButton_toggled(self, widget, userdata=None):
203
active = widget.get_active()
208
for widgetName in self._advancedControls:
209
widget = self.glade.get_widget(widgetName)
210
getattr(widget, op)()
212
def statusMsg(self, text):
213
if not isinstance(text, (unicode, str)):
215
return self._statusBar.push(self._statusContext, text)