From 0cd682f2ce28a4ee963820f78242eeade5e96cde Mon Sep 17 00:00:00 2001 From: Dimitur Kirov Date: Mon, 1 Aug 2005 15:00:27 +0000 Subject: [PATCH] file transfer progress notification --- src/common/connection.py | 27 +++++++++++++++++++-------- src/common/xmpp/socks5.py | 20 +++++++++++++++++++- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/common/connection.py b/src/common/connection.py index 89bf88395..725e4c944 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -126,7 +126,7 @@ class Connection: 'ACC_OK': [], 'MYVCARD': [], 'OS_INFO': [], 'VCARD': [], 'GC_MSG': [], 'GC_SUBJECT': [], 'GC_CONFIG': [], 'BAD_PASSPHRASE': [], 'ROSTER_INFO': [], 'ERROR_ANSWER': [], 'BOOKMARKS': [], 'CON_TYPE': [], - 'FILE_REQUEST': [], 'FILE_RCV_COMPLETED': [] + 'FILE_REQUEST': [], 'FILE_RCV_COMPLETED': [], 'FILE_PROGRESS': [] } self.name = name self.connected = 0 # offline @@ -143,7 +143,8 @@ class Connection: self.last_sent = [] self.password = gajim.config.get_per('accounts', name, 'password') self.privacy_rules_supported = False - self.receiver = socks5.SocksQueue(self.complete_file_transfer) + self.receiver = socks5.SocksQueue(self.complete_file_transfer, + self.file_transfer_progress) if USE_GPG: self.gpg = GnuPG.GnuPG() gajim.config.set('usegpg', True) @@ -428,14 +429,20 @@ class Connection: iq = common.xmpp.Iq(to = frm, typ = 'result', queryNS =\ common.xmpp.NS_DISCO, frm = to) iq.setAttr('id', id) + query = iq.setTag('query') # bytestream transfers feature = common.xmpp.Node('feature') - feature.setNamespace(common.xmpp.NS_SI) - iq.addChild(node=feature) + feature.setAttr('var', common.xmpp.NS_BYTESTREAM) + query.addChild(node=feature) + # si methods + feature = common.xmpp.Node('feature') + feature.setAttr('var', common.xmpp.NS_SI) + query.addChild(node=feature) # filetransfers transfers - _feature = common.xmpp.Node('feature') - _feature.setNamespace(common.xmpp.NS_FILE) - iq.addChild(node=_feature) + feature = common.xmpp.Node('feature') + feature.setAttr('var', common.xmpp.NS_FILE) + query.addChild(node=feature) + self.to_be_sent.append(iq) raise common.xmpp.NodeProcessed @@ -449,7 +456,7 @@ class Connection: return feature = si.getTag('feature') file_tag = si.getTag('file') - file_props = {} + file_props = {'type':'r'} for attribute in file_tag.getAttrs(): attribute = attribute.encode('utf-8') if attribute in ['name', 'size', 'hash', 'date']: @@ -476,6 +483,10 @@ class Connection: def complete_file_transfer(self, file_props): ''' file transfer is completed or stopped ''' self.dispatch('FILE_RCV_COMPLETED', file_props) + + def file_transfer_progress(self, file_props): + ''' file transfer is completed or stopped ''' + self.dispatch('FILE_PROGRESS', file_props) def send_file_rejection(self, file_props): ''' informs sender that we refuse to download the file ''' diff --git a/src/common/xmpp/socks5.py b/src/common/xmpp/socks5.py index 9c2c23e6e..e6f4a0ae1 100644 --- a/src/common/xmpp/socks5.py +++ b/src/common/xmpp/socks5.py @@ -69,11 +69,14 @@ class SocksQueue: for idx in self.readers.keys(): receiver = self.readers[idx] if receiver.connected: + if receiver.file_props['paused']: + continue if receiver.pending_data(): result = receiver.get_file_contents(timeout) if result in [0, -1] and \ self.complete_transfer_cb is not None: self.complete_transfer_cb(receiver.file_props) + elif self.progress_transfer_cb is not None: self.progress_transfer_cb(receiver.file_props) else: @@ -164,7 +167,14 @@ class Socks5: addrlen, address, port = 0, 0, 0 if address_type == 0x03: addrlen = ord(buff[4]) - address, port= struct.unpack('!%dsH' % addrlen, buff[5:]) + address = struct.unpack('!%ds' % addrlen, buff[5:addrlen+5]) + + portlen = len(buff[addrlen+5]) + if portlen == 1: # Gaim bug :) + (port) = struct.unpack('!B', buff[addrlen+5]) + else: + (port) = struct.unpack('!H', buff[addrlen+5]) + return (version, command, rsvd, address_type, addrlen, address, port) @@ -203,6 +213,11 @@ class Socks5Receiver(Socks5): self.queue_idx = -1 self.queue = None self.file_props = file_props + if file_props: + file_props['disconnect_cb'] = self.disconnect + file_props['error'] = 0 + self.file_props['completed'] = False + self.file_props['paused'] = False Socks5.__init__(self, host, port, initiator, target, sid) def get_file_contents(self, timeout): @@ -237,11 +252,13 @@ class Socks5Receiver(Socks5): self.disconnect() self.file_props['error'] = -1 return -1 + if self.file_props['received-len'] == int(self.file_props['size']): # transfer completed fd.close() self.disconnect() self.file_props['error'] = 0 + self.file_props['completed'] = True return 0 # return number of read bytes. It can be used in progressbar return self.file_props['received-len'] @@ -253,5 +270,6 @@ class Socks5Receiver(Socks5): fcntl.fcntl(self._sock, fcntl.F_SETFL, 0); self._sock.close() self.connected = False + self.file_props['disconnect_cb'] = None if self.queue is not None: self.queue.remove_receiver(self.queue_idx)