From c95778ec00086d02220260b8ebc67dd23ce06182 Mon Sep 17 00:00:00 2001 From: jamesbunton Date: Sat, 10 Dec 2005 11:13:30 +0000 Subject: [PATCH] Preliminary p2p file transfer passing tests! :) git-svn-id: http://delx.cjb.net/svn/pymsnt/trunk@46 55fbd22a-6204-0410-b2f0-b6c764c7e90a committer: jamesbunton --- src/tlib/msn/msn.py | 240 ++++++++++++++++++++++++++++++--------- src/tlib/msn/test_msn.py | 58 ++++++++-- 2 files changed, 240 insertions(+), 58 deletions(-) diff --git a/src/tlib/msn/msn.py b/src/tlib/msn/msn.py index 818c373..02adcdd 100644 --- a/src/tlib/msn/msn.py +++ b/src/tlib/msn/msn.py @@ -153,9 +153,15 @@ CR = "\r" LF = "\n" PINGSPEED = 50.0 -LINEDEBUG = True -MESSAGEDEBUG = True -MSNP2PDEBUG = True +DEBUGALL = False +LINEDEBUG = False +MESSAGEDEBUG = False +MSNP2PDEBUG = False + +if DEBUGALL: + LINEDEBUG = True + MESSAGEDEBUG = True + MSNP2PDEBUG = True def getVal(inp): return inp.split('=')[1] @@ -2067,15 +2073,16 @@ class SwitchboardClient(MSNEventBase): if slpMessage.method == "INVITE": if slpMessage.euf_guid == MSN_MSNFTP_GUID: #FIXME! - slpLink = SLPLink_Receive(remoteUser=slpMessage.fro, switchboard=self, consumer=FIXME, transferGuid=MSN_MSNFTP_GUID, sessionID=slpMessage.sessionID, sessionGuid=slpMessage.sessionGuid) context = FileContext(slpMessage.context) - fileReceive = msnft.MSNP2P_Receive(context.filename, context.filesize, slpMessage.fro) + slpLink = SLPLink_FileReceive(remoteUser=slpMessage.fro, switchboard=self, filename=context.filename, filesize=context.filesize, sessionID=slpMessage.sessionID, sessionGuid=slpMessage.sessionGuid) + self.slpLinks[slpMessage.sessionID] = slpLink + self.gotFileReceive(slpLink) elif slpMessage.euf_guid == MSN_AVATAR_GUID: # Check that we have an avatar to send if self.msnobj: - slpLink = SLPLink_Send(remoteUser=slpMessage.fro, switchboard=self, length=self.msnobj.size, transferGuid=MSN_AVATAR_GUID, sessionID=slpMessage.sessionID, sessionGuid=slpMessage.sessionGuid) + slpLink = SLPLink_AvatarSend(remoteUser=slpMessage.fro, switchboard=self, filesize=self.msnobj.size, sessionID=slpMessage.sessionID, sessionGuid=slpMessage.sessionGuid) slpLink.write(self.msnobj.imageData) - slpLink.finish() + slpLink.close() else: # They shouldn't have sent a request if we have # no avatar. So we'll just ignore them. @@ -2199,6 +2206,15 @@ class SwitchboardClient(MSNEventBase): """ pass + def gotFileReceive(self, fileReceive): + """ + called when we receive a file send request from a contact + + @param fileReceive: msnft.MSNFTReceive_Base instance + """ + pass + + def gotSendRequest(self, fileReceive): """ called when we receive a file send request from a contact @@ -2282,11 +2298,34 @@ class SwitchboardClient(MSNEventBase): def bufferClosed(data): d.callback((data,)) buffer = StringBuffer(bufferClosed) - slpLink = SLPLink_Receive(remoteUser=msnContact.userHandle, switchboard=self, consumer=buffer, transferGuid=MSN_AVATAR_GUID, context=msnContact.msnobj.text) + slpLink = SLPLink_AvatarReceive(remoteUser=msnContact.userHandle, switchboard=self, consumer=buffer, context=msnContact.msnobj.text) slpLink.avatarDataBuffer = buffer self.slpLinks[slpLink.sessionID] = slpLink return d + def sendFile(self, msnContact, filename, filesize): + """ + used to send a file to a contact. + + @param msnContact: the MSNContact object to send a file to. + @param filename: the name of the file to send. + @param filesize: the size of the file to send. + + @return: (fileSend, d) A FileSend object and a Deferred. + The Deferred will pass one argument in a tuple, + whether or not the transfer is accepted. If you + receive a True, then you can call write() on the + fileSend object to send your file. Call close() + when the file is done. + NOTE: You MUST write() exactly as much as you + declare in filesize. + """ + if not msnContact.userHandle: return + # FIXME, check msnContact.caps to see if we should use old-style + fileSend = SLPLink_FileSend(remoteUser=msnContact.userHandle, switchboard=self, filename=filename, filesize=filesize) + self.slpLinks[fileSend.sessionID] = fileSend + return fileSend, fileSend.acceptDeferred + def sendTypingNotification(self): """ Used to send a typing notification. Upon receiving this @@ -2361,6 +2400,66 @@ class SwitchboardClient(MSNEventBase): self.sendMessage(m) +class FileReceive: + def __init__(self, filename, filesize, userHandle): + self.consumer = None + self.finished = False + self.error = False + self.buffer = [] + self.filename, self.filesize, self.userHandle = filename, filesize, userHandle + + def reject(self): + raise NotImplementedError + + def accept(self, consumer): + if self.consumer: raise "AlreadyAccepted" + self.consumer = consumer + for data in self.buffer: + self.consumer.write(data) + self.buffer = None + if self.finished: + self.consumer.close() + if self.error: + self.consumer.error() + + def write(self, data): + if self.error or self.finished: + raise IOError, "Attempt to write in an invalid state" + if self.consumer: + self.consumer.write(data) + else: + self.buffer.append(data) + + def close(self): + self.finished = True + if self.consumer: + self.consumer.close() + +class FileContext: + """ Represents the Context field for P2P file transfers """ + def __init__(self, data=""): + if data: + self.parse(data) + else: + self.filename = "" + self.filesize = 0 + + def pack(self): + if MSNP2PDEBUG: print "FileContext packing:", self.filename, self.filesize + data = struct.pack("client1) + msnContact = msn.MSNContact(userHandle='foo1@bar.com', caps=msn.MSNContact.MSNC1) + fileSend, d = self.client2.sendFile(msnContact, "myfile.txt", len(fileData)) + def accepted((yes,)): + if yes: + fileSend.write(fileData) + fileSend.close() + else: + raise "TransferDeclined" + def failed(): + raise "TransferError" + d.addCallback(accepted) + d.addErrback(failed) + + # Let the request get pushed to client1 + self._loop(10) + + # Receive the file + def finished(data): + self.gotFile = (data == fileData) + fileBuffer = msn.StringBuffer(finished) + fileReceive = self.client1.fileReceive + fileReceive.accept(fileBuffer) + + # Lets transfer!! + self._loop(100) + + self.failUnless((self.gotFile), "Failed to transfer file") + ################ # MSNFTP tests # -- 2.39.2