From cdc1223ee42d056ecf7b7334aa921f6c1583b56e Mon Sep 17 00:00:00 2001 From: James Bunton Date: Sun, 29 Jul 2007 15:49:08 +1000 Subject: [PATCH] Applied patch from the old svn memorytest tree By only storing avatars in memory while they're being used, this should improve memory usage with avatars. --- src/legacy/glue.py | 4 ++-- src/legacy/msn/msn.py | 32 +++++++++++++++++++++----------- src/legacy/msn/msnw.py | 14 +++++++------- src/legacy/msn/test_msn.py | 8 ++++---- 4 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/legacy/glue.py b/src/legacy/glue.py index c1826ed..2655360 100644 --- a/src/legacy/glue.py +++ b/src/legacy/glue.py @@ -336,9 +336,9 @@ class LegacyConnection(msn.MSNConnection): global defaultJabberAvatarData if av: - msn.MSNConnection.changeAvatar(self, av.getImageData()) + msn.MSNConnection.changeAvatar(self, av.getImageData) else: - msn.MSNConnection.changeAvatar(self, defaultJabberAvatarData) + msn.MSNConnection.changeAvatar(self, lambda: defaultJabberAvatarData) def sendTypingNotifications(self): if not self.session: return diff --git a/src/legacy/msn/msn.py b/src/legacy/msn/msn.py index 41b0071..c271423 100644 --- a/src/legacy/msn/msn.py +++ b/src/legacy/msn/msn.py @@ -84,6 +84,9 @@ Use of this module requires that PyOpenSSL is installed. from __future__ import nested_scopes +import twistfix +twistfix.main() + # Sibling imports from twisted.protocols.basic import LineReceiver from twisted.web.http import HTTPClient @@ -465,7 +468,7 @@ class MSNObject: Used to represent a MSNObject. This can be currently only be an avatar. @ivar creator: The userHandle of the creator of this picture. - @ivar imageData: The PNG image data (only for our own avatar) + @ivar imageDataFunc: A function to return the PNG image data (only for our own avatar) @ivar type: Always set to 3, for avatar. @ivar size: The size of the image. @ivar location: The filename of the image. @@ -478,10 +481,11 @@ class MSNObject: if s: self.parse(s) - def setData(self, creator, imageData): + def setData(self, creator, imageDataFunc): """ Set the creator and imageData for this object """ + imageData = imageDataFunc() self.creator = creator - self.imageData = imageData + self.imageDataFunc = imageDataFunc self.size = len(imageData) self.type = 3 self.location = "TMP" + str(random.randint(1000,9999)) @@ -491,7 +495,7 @@ class MSNObject: def setNull(self): self.creator = "" - self.imageData = "" + self.imageDataFunc = lambda: None self.size = 0 self.type = 0 self.location = "" @@ -1943,11 +1947,11 @@ class NotificationClient(MSNEventBase): return (personal,) return d.addCallback(_cb) - def changeAvatar(self, imageData, push): + def changeAvatar(self, imageDataFunc, push): """ Used to change the avatar that other users see. - @param imageData: the PNG image data to set as the avatar + @param imageDataFunc: a function to return the PNG image data to set as the avatar @param push : whether to push the update to the server (it will otherwise be sent with the next changeStatus()) @@ -1957,12 +1961,18 @@ class NotificationClient(MSNEventBase): The callback argument will be the same as for changeStatus. """ - if self.msnobj and imageData == self.msnobj.imageData: return - if imageData: - self.msnobj.setData(self.factory.userHandle, imageData) + checkMsnobj = MSNObject() + checkMsnobj.setData(self.factory.userHandle, imageDataFunc) + if self.msnobj and self.msnobj.sha1d == checkMsnobj.sha1d: + return # Avatar hasn't changed + if imageDataFunc: + # We need to keep the same MSNObject instance, as it is + # passed on to SwitchboardClient objects + self.msnobj.setData(self.factory.userHandle, imageDataFunc) else: self.msnobj.setNull() - if push: return self.changeStatus(self.factory.status) # Push to server + if push: + return self.changeStatus(self.factory.status) # Push to server def requestSwitchboardServer(self): @@ -2153,7 +2163,7 @@ class SwitchboardClient(MSNEventBase): # Check that we have an avatar to send if self.msnobj: slpLink = SLPLink_AvatarSend(remoteUser=slpMessage.fro, switchboard=self, filesize=self.msnobj.size, sessionID=slpMessage.sessionID, sessionGuid=slpMessage.sessionGuid) - slpLink.write(self.msnobj.imageData) + slpLink.write(self.msnobj.imageDataFunc()) slpLink.close() else: # They shouldn't have sent a request if we have diff --git a/src/legacy/msn/msnw.py b/src/legacy/msn/msnw.py index e889690..3810f53 100644 --- a/src/legacy/msn/msnw.py +++ b/src/legacy/msn/msnw.py @@ -169,16 +169,16 @@ class MSNConnection: sb = self.switchboardSessions.get(userHandle) if sb: return sb.sendTypingNotification() - def changeAvatar(self, imageData): + def changeAvatar(self, imageDataFunc): """ Changes the user's avatar. - @param imageData: the new PNG avatar image data. + @param imageDataFunc: a function which returns the new PNG avatar image data. """ if self.notificationClient: LogEvent(INFO, self.ident) - self.notificationClient.changeAvatar(imageData, push=True) + self.notificationClient.changeAvatar(imageDataFunc, push=True) # Save the avatar for reuse on disconnection - self.savedEvents.avatarImageData = imageData + self.savedEvents.avatarImageDataFunc = imageDataFunc def changeStatus(self, statusCode, screenName, personal): """ @@ -342,13 +342,13 @@ class SavedEvents: self.screenName = "" self.statusCode = "" self.personal = "" - self.avatarImageData = "" + self.avatarImageDataFunc = None self.addContacts = [] self.remContacts = [] def send(self, msncon): - if self.avatarImageData: - msncon.notificationClient.changeAvatar(self.avatarImageData, push=False) + if self.avatarImageDataFunc: + msncon.notificationClient.changeAvatar(self.avatarImageDataFunc, push=False) if self.screenName or self.statusCode or self.personal: msncon.changeStatus(self.statusCode, self.screenName, self.personal) for listType, userHandle in self.addContacts: diff --git a/src/legacy/msn/test_msn.py b/src/legacy/msn/test_msn.py index b1548be..fbfae5f 100644 --- a/src/legacy/msn/test_msn.py +++ b/src/legacy/msn/test_msn.py @@ -569,11 +569,11 @@ class FakeNotificationClient(msn.NotificationClient): d = self.changePersonalMessage(personal) d.addCallback(testcb) - def doAvatarChange(self, data): + def doAvatarChange(self, dataFunc): def testcb(ignored): self.test = 'PASS' self.transport.loseConnection() - d = self.changeAvatar(data, True) + d = self.changeAvatar(dataFunc, True) d.addCallback(testcb) def doRequestSwitchboard(self): @@ -650,7 +650,7 @@ class FakeServerNotificationTests(unittest.TestCase): self.failUnless((self.client.test == 'PASS'), 'Failed to change personal message properly') def testChangeAvatar(self): - self.client.doAvatarChange("DATADATADATADATA") + self.client.doAvatarChange(lambda: "DATADATADATADATA") self.failUnless(self.loop.doSteps(10), 'Failed to disconnect') self.failUnless((self.client.test == 'PASS'), 'Failed to change avatar properly') @@ -1018,7 +1018,7 @@ class SwitchboardP2PTests(unittest.TestCase): # Set up the avatar for client1 imageData = self._generateData() self.client1.msnobj = msn.MSNObject() - self.client1.msnobj.setData('foo1@bar.com', imageData) + self.client1.msnobj.setData('foo1@bar.com', lambda: imageData) self.client1.msnobj.makeText() # Make client2 request the avatar -- 2.39.2