X-Git-Url: https://code.delx.au/pymsnt/blobdiff_plain/e0796ce470d600ba00f3f8b48ef937e1ad410315..eb611d5937b59b7176ad47fe605cae4b9dabc911:/src/tlib/msn/msnw.py diff --git a/src/tlib/msn/msnw.py b/src/tlib/msn/msnw.py index 55e02ff..7b2c22c 100644 --- a/src/tlib/msn/msnw.py +++ b/src/tlib/msn/msnw.py @@ -50,8 +50,9 @@ class MSNConnection: def _getNotificationReferral(self): def timeout(): + self.timeout = None if not d.called: - d.errback() + d.errback(Exception("Timeout")) self.logOut() # Clean up everything self.timeout = reactor.callLater(30, timeout) dispatchFactory = msn.DispatchFactory() @@ -65,6 +66,7 @@ class MSNConnection: def _gotNotificationReferral(self, (host, port)): self.timeout.cancel() + self.timeout = None # Create the NotificationClient self.notificationFactory = msn.NotificationFactory() self.notificationFactory.userHandle = self.username @@ -76,7 +78,6 @@ class MSNConnection: def _sendSavedEvents(self): self.savedEvents.send(self) - self.savedEvents = None def _notificationClientReady(self, notificationClient): self.notificationClient = notificationClient @@ -175,8 +176,8 @@ class MSNConnection: if self.notificationClient: LogEvent(INFO, self.ident) self.notificationClient.changeAvatar(imageData, push=True) - else: - self.savedEvents.avatarImageData = imageData + # Save the avatar for reuse on disconnection + self.savedEvents.avatarImageData = imageData def changeStatus(self, statusCode, screenName, personal): """ @@ -189,6 +190,8 @@ class MSNConnection: """ if not screenName: screenName = self.username + if not statusCode: statusCode = msn.STATUS_ONLINE + if not personal: personal = "" if self.notificationClient: changeCount = [0] # Hack def cb(ignored=None): @@ -198,12 +201,11 @@ class MSNConnection: LogEvent(INFO, self.ident) self.notificationClient.changeStatus(statusCode.encode("utf-8")).addCallback(cb) self.notificationClient.changeScreenName(screenName.encode("utf-8")).addCallback(cb) - if not personal: personal = "" self.notificationClient.changePersonalMessage(personal.encode("utf-8")).addCallback(cb) - else: - self.savedEvents.statusCode = statusCode - self.savedEvents.screenName = screenName - self.savedEvents.personal = personal + # Remember the saved status + self.savedEvents.statusCode = statusCode + self.savedEvents.screenName = screenName + self.savedEvents.personal = personal def addContact(self, listType, userHandle): """ See msn.NotificationClient.addContact """ @@ -233,6 +235,9 @@ class MSNConnection: if hasattr(sbs, "transport") and sbs.transport: sbs.transport.loseConnection() self.switchboardSessions = {} + if self.timeout: + self.timeout.cancel() + self.timeout = None LogEvent(INFO, self.ident) @@ -355,6 +360,10 @@ class DispatchClient(msn.DispatchClient): class NotificationClient(msn.NotificationClient): + def doDisconnect(self, *args): + if hasattr(self, "transport") and self.transport: + self.transport.loseConnection() + def loginFailure(self, message): self.factory.msncon.loginFailed(message) @@ -368,13 +377,19 @@ class NotificationClient(msn.NotificationClient): def logOut(self): msn.NotificationClient.logOut(self) + # If we explicitly log out, then all of these events + # are now redundant + self.loginFailure = self.doDisconnect + self.loggedIn = self.doDisconnect + self.connectionLost = self.doDisconnect def connectionLost(self, reason): - if not self.factory.msncon: return # If we called logOut def wait(): LogEvent(INFO, self.factory.msncon.ident) msn.NotificationClient.connectionLost(self, reason) - self.factory.msncon.connectionLost(reason) + if self.factory.maxRetries > self.factory.retries: + self.factory.stopTrying() + self.factory.msncon.connectionLost(reason) # Make sure this event is handled after any others reactor.callLater(0, wait) @@ -454,10 +469,13 @@ class SwitchboardSessionBase(msn.SwitchboardClient): self.funcBuffer = [] self.ready = False - def __del__(self): + def connectionLost(self, reason): + msn.SwitchboardClient.connectionLost(self, reason) LogEvent(INFO, self.ident) - del self.msncon - self.transport.disconnect() + self.ready = False + self.msncon = None + self.msnobj = None + self.ident = (self.ident[0], self.ident[1], "Disconnected!") def loggedIn(self): LogEvent(INFO, self.ident) @@ -527,13 +545,13 @@ class SwitchboardSessionBase(msn.SwitchboardClient): self.messageBuffer.append((text, noerror)) else: LogEvent(INFO, self.ident) + text = str(text.replace("\n", "\r\n").encode("utf-8")) def failedMessage(ignored): if not noerror: self.failedMessage(text) if len(text) < MSNConnection.MAXMESSAGESIZE: - message = msn.MSNMessage(message=str(text.replace("\n", "\r\n").encode("utf-8"))) - message.setHeader("Content-Type", "text/plain; charset=UTF-8") + message = msn.MSNMessage(message=text) message.ack = msn.MSNMessage.MESSAGE_NACK d = msn.SwitchboardClient.sendMessage(self, message) @@ -546,13 +564,14 @@ class SwitchboardSessionBase(msn.SwitchboardClient): guid = msn.random_guid() while chunk < chunks: offset = chunk * MSNConnection.MAXMESSAGESIZE - text = text[offset : offset + MSNConnection.MAXMESSAGESIZE] - message = msn.MSNMessage(message=str(text.replace("\n", "\r\n").encode("utf-8"))) + message = msn.MSNMessage(message=text[offset : offset + MSNConnection.MAXMESSAGESIZE]) message.ack = msn.MSNMessage.MESSAGE_NACK + message.setHeader("Message-ID", guid) if chunk == 0: - message.setHeader("Content-Type", "text/plain; charset=UTF-8") message.setHeader("Chunks", str(chunks)) else: + message.delHeader("MIME-Version") + message.delHeader("Content-Type") message.setHeader("Chunk", str(chunk)) d = msn.SwitchboardClient.sendMessage(self, message) @@ -568,7 +587,7 @@ class MultiSwitchboardSession(SwitchboardSessionBase): def __init__(self, msncon): """ Automatically creates a new switchboard connection to the server """ SwitchboardSessionBase.__init__(self, msncon) - self.ident = (self.msncon.ident, self) + self.ident = (self.msncon.ident, repr(self)) self.contactCount = 0 self.groupchat = None self.connect() @@ -619,13 +638,14 @@ class OneSwitchboardSession(SwitchboardSessionBase): self.chattingUsers = [] self.timeout = None - def __del__(self): + def connectionLost(self, reason): if self.timeout: self.timeout.cancel() self.timeout = None for message, noerror in self.messageBuffer: if not noerror: self.failedMessage(message) + SwitchboardSessionBase.connectionLost(self, reason) def _ready(self): LogEvent(INFO, self.ident) @@ -644,9 +664,7 @@ class OneSwitchboardSession(SwitchboardSessionBase): del self.remoteUser self.contactCount = 0 self.msncon.gotGroupchat(self, userHandle) - if not self.groupchat: - LogEvent(ERROR, self.ident) - raise Exception("YouNeedAGroupchat-WeHaveAProblemError") # FIXME + assert self.groupchat def failedMessage(self, text): self.msncon.failedMessage(self.remoteUser, text) @@ -661,6 +679,7 @@ class OneSwitchboardSession(SwitchboardSessionBase): LogEvent(INFO, self.ident, "User has not joined after 30 seconds.") del self.msncon.switchboardSessions[self.remoteUser] self.timeout = None + self.transport.loseConnection() d = self.inviteUser(self.remoteUser) d.addErrback(failCB) self.timeout = reactor.callLater(30.0, failCB)