file_props refactoring
This commit is contained in:
parent
b6b44cb328
commit
2af1af2011
|
@ -3203,11 +3203,11 @@ class ChatControl(ChatControlBase):
|
||||||
"""
|
"""
|
||||||
Show an InfoBar on top of control
|
Show an InfoBar on top of control
|
||||||
"""
|
"""
|
||||||
markup = '<b>%s:</b> %s' % (_('File transfer'), file_props['name'])
|
markup = '<b>%s:</b> %s' % (_('File transfer'), file_props.name)
|
||||||
if 'desc' in file_props and file_props['desc']:
|
if file_props.desc:
|
||||||
markup += ' (%s)' % file_props['desc']
|
markup += ' (%s)' % file_props.desc
|
||||||
markup += '\n%s: %s' % (_('Size'), helpers.convert_bytes(
|
markup += '\n%s: %s' % (_('Size'), helpers.convert_bytes(
|
||||||
file_props['size']))
|
file_props.size))
|
||||||
b1 = gtk.Button(_('_Accept'))
|
b1 = gtk.Button(_('_Accept'))
|
||||||
b1.connect('clicked', self._on_accept_file_request, file_props)
|
b1.connect('clicked', self._on_accept_file_request, file_props)
|
||||||
b2 = gtk.Button(stock=gtk.STOCK_CANCEL)
|
b2 = gtk.Button(stock=gtk.STOCK_CANCEL)
|
||||||
|
@ -3216,9 +3216,7 @@ class ChatControl(ChatControlBase):
|
||||||
gtk.MESSAGE_QUESTION)
|
gtk.MESSAGE_QUESTION)
|
||||||
|
|
||||||
def _on_open_ft_folder(self, widget, file_props):
|
def _on_open_ft_folder(self, widget, file_props):
|
||||||
if 'file-name' not in file_props:
|
path = os.path.split(file_props.file_name)[0]
|
||||||
return
|
|
||||||
path = os.path.split(file_props['file-name'])[0]
|
|
||||||
if os.path.exists(path) and os.path.isdir(path):
|
if os.path.exists(path) and os.path.isdir(path):
|
||||||
helpers.launch_file_manager(path)
|
helpers.launch_file_manager(path)
|
||||||
ev = self._get_file_props_event(file_props, 'file-completed')
|
ev = self._get_file_props_event(file_props, 'file-completed')
|
||||||
|
@ -3232,9 +3230,9 @@ class ChatControl(ChatControlBase):
|
||||||
|
|
||||||
def _got_file_completed(self, file_props):
|
def _got_file_completed(self, file_props):
|
||||||
markup = '<b>%s:</b> %s' % (_('File transfer completed'),
|
markup = '<b>%s:</b> %s' % (_('File transfer completed'),
|
||||||
file_props['name'])
|
file_props.name)
|
||||||
if 'desc' in file_props and file_props['desc']:
|
if file_props.desc:
|
||||||
markup += ' (%s)' % file_props['desc']
|
markup += ' (%s)' % file_props.desc
|
||||||
b1 = gtk.Button(_('_Open Containing Folder'))
|
b1 = gtk.Button(_('_Open Containing Folder'))
|
||||||
b1.connect('clicked', self._on_open_ft_folder, file_props)
|
b1.connect('clicked', self._on_open_ft_folder, file_props)
|
||||||
b2 = gtk.Button(stock=gtk.STOCK_OK)
|
b2 = gtk.Button(stock=gtk.STOCK_OK)
|
||||||
|
|
|
@ -37,6 +37,7 @@ from common.logger import LOG_DB_PATH
|
||||||
from common.pep import SUPPORTED_PERSONAL_USER_EVENTS
|
from common.pep import SUPPORTED_PERSONAL_USER_EVENTS
|
||||||
from common.xmpp.protocol import NS_CHATSTATES
|
from common.xmpp.protocol import NS_CHATSTATES
|
||||||
from common.jingle_transport import JingleTransportSocks5
|
from common.jingle_transport import JingleTransportSocks5
|
||||||
|
from common.file_props import FilesProp
|
||||||
|
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
|
|
||||||
|
@ -1940,16 +1941,44 @@ class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
||||||
self.get_id()
|
self.get_id()
|
||||||
self.fjid = self.conn._ft_get_from(self.stanza)
|
self.fjid = self.conn._ft_get_from(self.stanza)
|
||||||
self.jid = gajim.get_jid_without_resource(self.fjid)
|
self.jid = gajim.get_jid_without_resource(self.fjid)
|
||||||
self.file_props = {'type': 'r'}
|
|
||||||
self.file_props['sender'] = self.fjid
|
|
||||||
self.file_props['request-id'] = self.id_
|
|
||||||
if self.jingle_content:
|
if self.jingle_content:
|
||||||
self.file_props['session-type'] = 'jingle'
|
self.FT_content.use_security = bool(self.jingle_content.getTag(
|
||||||
self.file_props['stream-methods'] = xmpp.NS_BYTESTREAM
|
'security'))
|
||||||
|
if not self.FT_content.transport:
|
||||||
|
self.FT_content.transport = JingleTransportSocks5()
|
||||||
|
self.FT_content.transport.set_our_jid(
|
||||||
|
self.FT_content.session.ourjid)
|
||||||
|
self.FT_content.transport.set_connection(
|
||||||
|
self.FT_content.session.connection)
|
||||||
|
sid = self.FT_content.transport.sid
|
||||||
|
self.file_props = FilesProp.getNewFileProp(self.conn.name, sid)
|
||||||
|
self.file_props.session_sid = unicode(
|
||||||
|
self.stanza.getTag('jingle').getAttr('sid')
|
||||||
|
)
|
||||||
|
self.FT_content.file_props = self.file_props
|
||||||
|
self.FT_content.transport.set_file_props(self.file_props)
|
||||||
|
if self.file_props.streamhosts:
|
||||||
|
self.file_props.streamhosts.extend(
|
||||||
|
self.FT_content.transport.remote_candidates)
|
||||||
|
else:
|
||||||
|
self.file_props.streamhosts = \
|
||||||
|
self.FT_content.transport.remote_candidates
|
||||||
|
for host in self.file_props.streamhosts:
|
||||||
|
host['initiator'] = self.FT_content.session.initiator
|
||||||
|
host['target'] = self.FT_content.session.responder
|
||||||
|
else:
|
||||||
|
si = self.stanza.getTag('si')
|
||||||
|
self.file_props = FilesProp.getNewFileProp(self.conn.name,
|
||||||
|
unicode(si.getAttr('id'))
|
||||||
|
)
|
||||||
|
self.file_props.sender = self.fjid
|
||||||
|
self.file_props.request_id = self.id_
|
||||||
|
if self.jingle_content:
|
||||||
|
self.file_props.session_type = 'jingle'
|
||||||
|
self.file_props.stream_methods = xmpp.NS_BYTESTREAM
|
||||||
file_tag = self.jingle_content.getTag('description').getTag(
|
file_tag = self.jingle_content.getTag('description').getTag(
|
||||||
'offer').getTag('file')
|
'offer').getTag('file')
|
||||||
else:
|
else:
|
||||||
si = self.stanza.getTag('si')
|
|
||||||
profile = si.getAttr('profile')
|
profile = si.getAttr('profile')
|
||||||
if profile != xmpp.NS_FILE:
|
if profile != xmpp.NS_FILE:
|
||||||
self.conn.send_file_rejection(self.file_props, code='400',
|
self.conn.send_file_rejection(self.file_props, code='400',
|
||||||
|
@ -1965,7 +1994,7 @@ class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
||||||
for f in self.dataform.iter_fields():
|
for f in self.dataform.iter_fields():
|
||||||
if f.var == 'stream-method' and f.type == 'list-single':
|
if f.var == 'stream-method' and f.type == 'list-single':
|
||||||
values = [o[1] for o in f.options]
|
values = [o[1] for o in f.options]
|
||||||
self.file_props['stream-methods'] = ' '.join(values)
|
self.file_props.stream_methods = ' '.join(values)
|
||||||
if xmpp.NS_BYTESTREAM in values or xmpp.NS_IBB in values:
|
if xmpp.NS_BYTESTREAM in values or xmpp.NS_IBB in values:
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
@ -1975,54 +2004,30 @@ class FileRequestReceivedEvent(nec.NetworkIncomingEvent, HelperEvent):
|
||||||
file_tag = si.getTag('file')
|
file_tag = si.getTag('file')
|
||||||
for child in file_tag.getChildren():
|
for child in file_tag.getChildren():
|
||||||
name = child.getName()
|
name = child.getName()
|
||||||
if name in ('name', 'size', 'hash', 'date'):
|
val = child.getData()
|
||||||
val = child.getData()
|
if val is None:
|
||||||
if val is None:
|
continue
|
||||||
continue
|
if name == 'name':
|
||||||
self.file_props[name] = val
|
self.file_props.name = val
|
||||||
# Delete this, it shouldn't be necesary after file_props gets
|
if name == 'size':
|
||||||
# refactored.
|
self.file_props.size = val
|
||||||
if name == 'hash':
|
if name == 'hash':
|
||||||
self.file_props['algo'] = child.getAttr('algo')
|
self.file_props.algo = child.getAttr('algo')
|
||||||
|
self.file_props.hash_ = val
|
||||||
|
if name == 'date':
|
||||||
|
self.file_props.date = val
|
||||||
file_desc_tag = file_tag.getTag('desc')
|
file_desc_tag = file_tag.getTag('desc')
|
||||||
if file_desc_tag is not None:
|
if file_desc_tag is not None:
|
||||||
self.file_props['desc'] = file_desc_tag.getData()
|
self.file_props.desc = file_desc_tag.getData()
|
||||||
|
|
||||||
if not self.jingle_content:
|
if not self.jingle_content:
|
||||||
mime_type = si.getAttr('mime-type')
|
mime_type = si.getAttr('mime-type')
|
||||||
if mime_type is not None:
|
if mime_type is not None:
|
||||||
self.file_props['mime-type'] = mime_type
|
self.file_props.mime_type = mime_type
|
||||||
|
|
||||||
self.file_props['receiver'] = self.conn._ft_get_our_jid()
|
self.file_props.receiver = self.conn._ft_get_our_jid()
|
||||||
self.file_props['transfered_size'] = []
|
self.file_props.transfered_size = []
|
||||||
if self.jingle_content:
|
|
||||||
self.FT_content.use_security = bool(self.jingle_content.getTag(
|
|
||||||
'security'))
|
|
||||||
self.file_props['session-sid'] = unicode(self.stanza.getTag(
|
|
||||||
'jingle').getAttr('sid'))
|
|
||||||
|
|
||||||
self.FT_content.file_props = self.file_props
|
|
||||||
if not self.FT_content.transport:
|
|
||||||
self.FT_content.transport = JingleTransportSocks5()
|
|
||||||
self.FT_content.transport.set_our_jid(
|
|
||||||
self.FT_content.session.ourjid)
|
|
||||||
self.FT_content.transport.set_connection(
|
|
||||||
self.FT_content.session.connection)
|
|
||||||
self.file_props['sid'] = self.FT_content.transport.sid
|
|
||||||
self.FT_content.session.connection.files_props[
|
|
||||||
self.file_props['sid']] = self.file_props
|
|
||||||
self.FT_content.transport.set_file_props(self.file_props)
|
|
||||||
if self.file_props.has_key('streamhosts'):
|
|
||||||
self.file_props['streamhosts'].extend(
|
|
||||||
self.FT_content.transport.remote_candidates)
|
|
||||||
else:
|
|
||||||
self.file_props['streamhosts'] = \
|
|
||||||
self.FT_content.transport.remote_candidates
|
|
||||||
for host in self.file_props['streamhosts']:
|
|
||||||
host['initiator'] = self.FT_content.session.initiator
|
|
||||||
host['target'] = self.FT_content.session.responder
|
|
||||||
else:
|
|
||||||
self.file_props['sid'] = unicode(si.getAttr('id'))
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class FileRequestErrorEvent(nec.NetworkIncomingEvent):
|
class FileRequestErrorEvent(nec.NetworkIncomingEvent):
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
"""
|
||||||
|
This module is in charge of taking care of all the infomation related to
|
||||||
|
individual files. Files are identified by the account name and its sid.
|
||||||
|
|
||||||
|
|
||||||
|
>>> print FilesProp.getFileProp('jabberid', '10')
|
||||||
|
None
|
||||||
|
>>> fp = FilesProp()
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
Exception: this class should not be instatiated
|
||||||
|
>>> print FilesProp.getAllFileProp()
|
||||||
|
[]
|
||||||
|
>>> fp = FilesProp.getNewFileProp('jabberid', '10')
|
||||||
|
>>> fp2 = FilesProp.getFileProp('jabberid', '10')
|
||||||
|
>>> fp == fp2
|
||||||
|
True
|
||||||
|
"""
|
||||||
|
|
||||||
|
class FilesProp:
|
||||||
|
_files_props = {}
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
raise Exception('this class should not be instatiated')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getNewFileProp(cls, account, sid):
|
||||||
|
fp = FileProp(account, sid)
|
||||||
|
cls.setFileProp(fp, account, sid)
|
||||||
|
return fp
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getFileProp(cls, account, sid):
|
||||||
|
if (account, sid) in cls._files_props.keys():
|
||||||
|
return cls._files_props[account, sid]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getFilePropByAccount(cls, account):
|
||||||
|
# Returns a list of file_props in one account
|
||||||
|
file_props = []
|
||||||
|
for account, sid in cls._files_props:
|
||||||
|
if account == account:
|
||||||
|
file_props.append(cls._files_props[account, sid])
|
||||||
|
return file_props
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getFilePropByType(cls, type_, sid):
|
||||||
|
# This method should be deleted. Getting fileprop by type and sid is not
|
||||||
|
# unique enough. More than one fileprop might have the same type and sid
|
||||||
|
files_prop = cls.getAllFileProp()
|
||||||
|
for fp in files_prop:
|
||||||
|
if fp.type_ == type_ and fp.sid == sid:
|
||||||
|
return fp
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getFilePropBySid(cls, sid):
|
||||||
|
# This method should be deleted. It is kept to make things compatible
|
||||||
|
# This method should be replaced and instead get the file_props by
|
||||||
|
# account and sid
|
||||||
|
files_prop = cls.getAllFileProp()
|
||||||
|
for fp in files_prop:
|
||||||
|
if fp.sid == sid:
|
||||||
|
return fp
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getAllFileProp(cls):
|
||||||
|
return cls._files_props.values()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setFileProp(cls, fp, account, sid):
|
||||||
|
cls._files_props[account, sid] = fp
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def deleteFileProp(cls, file_prop):
|
||||||
|
files_props = cls._files_props
|
||||||
|
a = s = None
|
||||||
|
for account, sid in files_props:
|
||||||
|
fp = files_props[account, sid]
|
||||||
|
if fp is file_prop:
|
||||||
|
a = account
|
||||||
|
s = sid
|
||||||
|
if a != None and s != None:
|
||||||
|
del files_props[a, s]
|
||||||
|
|
||||||
|
|
||||||
|
class FileProp(object):
|
||||||
|
|
||||||
|
def __init__(self, account, sid):
|
||||||
|
# Do not instatiate this class directly. Call FilesProp.getNeFileProp
|
||||||
|
# instead
|
||||||
|
self.streamhosts = []
|
||||||
|
self.transfered_size = []
|
||||||
|
self.started = False
|
||||||
|
self.completed = False
|
||||||
|
self.paused = False
|
||||||
|
self.stalled = False
|
||||||
|
self.connected = False
|
||||||
|
self.stopped = False
|
||||||
|
self.is_a_proxy = False
|
||||||
|
self.proxyhost = None
|
||||||
|
self.proxy_sender = None
|
||||||
|
self.proxy_receiver = None
|
||||||
|
self.streamhost_used = None
|
||||||
|
# method callback called in case of transfer failure
|
||||||
|
self.failure_cb = None
|
||||||
|
# method callback called when disconnecting
|
||||||
|
self.disconnect_cb = None
|
||||||
|
self.continue_cb = None
|
||||||
|
self.sha_str = None
|
||||||
|
# transfer type: 's' for sending and 'r' for receiving
|
||||||
|
self.type_ = None
|
||||||
|
self.error = None
|
||||||
|
self.elapsed_time = None
|
||||||
|
self.last_time = None
|
||||||
|
self.received_len = None
|
||||||
|
# full file path
|
||||||
|
self.file_name = None
|
||||||
|
self.name = None
|
||||||
|
self.file_desc = None
|
||||||
|
self.offset = None
|
||||||
|
self.sender = None
|
||||||
|
self.receiver = None
|
||||||
|
self.tt_account = None
|
||||||
|
self.size = None
|
||||||
|
self._sid = sid
|
||||||
|
self.account = account
|
||||||
|
self.mime_type = None
|
||||||
|
self.algo = None
|
||||||
|
self.direction = None
|
||||||
|
self.syn_id = None
|
||||||
|
self.seq = None
|
||||||
|
self.hash_ = None
|
||||||
|
self.session_sid = None
|
||||||
|
self.fd = None
|
||||||
|
self.startexmpp = None
|
||||||
|
self.session_type = None
|
||||||
|
|
||||||
|
def getsid(self):
|
||||||
|
# Getter of the property sid
|
||||||
|
return self._sid
|
||||||
|
|
||||||
|
def setsid(self, value):
|
||||||
|
# The sid value will change
|
||||||
|
# we need to change the in _files_props key as well
|
||||||
|
del FilesProp._files_props[self.account, self._sid]
|
||||||
|
self._sid = value
|
||||||
|
FilesProp._files_props[self.account, self._sid] = self
|
||||||
|
|
||||||
|
sid = property(getsid, setsid)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import doctest
|
||||||
|
doctest.testmod()
|
|
@ -152,7 +152,7 @@ class ConnectionJingle(object):
|
||||||
# this is a file transfer
|
# this is a file transfer
|
||||||
jingle.session_type_FT = True
|
jingle.session_type_FT = True
|
||||||
self._sessions[jingle.sid] = jingle
|
self._sessions[jingle.sid] = jingle
|
||||||
file_props['sid'] = jingle.sid
|
file_props.sid = jingle.sid
|
||||||
if contact.supports(xmpp.NS_JINGLE_BYTESTREAM):
|
if contact.supports(xmpp.NS_JINGLE_BYTESTREAM):
|
||||||
transport = JingleTransportSocks5()
|
transport = JingleTransportSocks5()
|
||||||
elif contact.supports(xmpp.NS_JINGLE_IBB):
|
elif contact.supports(xmpp.NS_JINGLE_IBB):
|
||||||
|
|
|
@ -172,25 +172,25 @@ class JingleContent(object):
|
||||||
simode = xmpp.simplexml.Node(tag='offer')
|
simode = xmpp.simplexml.Node(tag='offer')
|
||||||
|
|
||||||
file_tag = simode.setTag('file', namespace=xmpp.NS_FILE)
|
file_tag = simode.setTag('file', namespace=xmpp.NS_FILE)
|
||||||
if 'name' in self.file_props:
|
if self.file_props.name:
|
||||||
node = xmpp.simplexml.Node(tag='name')
|
node = xmpp.simplexml.Node(tag='name')
|
||||||
node.addData(self.file_props['name'])
|
node.addData(self.file_props.name)
|
||||||
file_tag.addChild(node=node)
|
file_tag.addChild(node=node)
|
||||||
if 'size' in self.file_props:
|
if self.file_props.size:
|
||||||
node = xmpp.simplexml.Node(tag='size')
|
node = xmpp.simplexml.Node(tag='size')
|
||||||
node.addData(self.file_props['size'])
|
node.addData(self.file_props.size)
|
||||||
file_tag.addChild(node=node)
|
file_tag.addChild(node=node)
|
||||||
if 'hash' in self.file_props:
|
if self.file_props.hash_:
|
||||||
# TODO: use xep-300 for this bit
|
# TODO: use xep-300 for this bit
|
||||||
pass
|
pass
|
||||||
# if the file is less than 10 mb, then it is small
|
# if the file is less than 10 mb, then it is small
|
||||||
# lets calculate it right away
|
# lets calculate it right away
|
||||||
if int(self.file_props['size']) < 10000000:
|
if int(self.file_props.size) < 10000000:
|
||||||
h = self._calcHash()
|
h = self._calcHash()
|
||||||
file_tag.addChild(node=h)
|
file_tag.addChild(node=h)
|
||||||
desc = file_tag.setTag('desc')
|
desc = file_tag.setTag('desc')
|
||||||
if 'desc' in self.file_props:
|
if self.file_props.desc:
|
||||||
desc.setData(self.file_props['desc'])
|
desc.setData(self.file_props.desc)
|
||||||
|
|
||||||
description_node.addChild(node=simode)
|
description_node.addChild(node=simode)
|
||||||
|
|
||||||
|
|
|
@ -76,11 +76,11 @@ class JingleFileTransfer(JingleContent):
|
||||||
self.weinitiate = True
|
self.weinitiate = True
|
||||||
|
|
||||||
if self.file_props is not None:
|
if self.file_props is not None:
|
||||||
self.file_props['sender'] = session.ourjid
|
self.file_props.sender = session.ourjid
|
||||||
self.file_props['receiver'] = session.peerjid
|
self.file_props.receiver = session.peerjid
|
||||||
self.file_props['session-type'] = 'jingle'
|
self.file_props.session_type = 'jingle'
|
||||||
self.file_props['session-sid'] = session.sid
|
self.file_props.session_sid = session.sid
|
||||||
self.file_props['transfered_size'] = []
|
self.file_props.transfered_size = []
|
||||||
|
|
||||||
log.info("FT request: %s" % file_props)
|
log.info("FT request: %s" % file_props)
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ class JingleFileTransfer(JingleContent):
|
||||||
log.info('ourjid: %s' % session.ourjid)
|
log.info('ourjid: %s' % session.ourjid)
|
||||||
|
|
||||||
if self.file_props is not None:
|
if self.file_props is not None:
|
||||||
self.file_props['sid'] = self.transport.sid
|
self.file_props.sid = self.transport.sid
|
||||||
|
|
||||||
self.session = session
|
self.session = session
|
||||||
self.media = 'file'
|
self.media = 'file'
|
||||||
|
@ -119,13 +119,12 @@ class JingleFileTransfer(JingleContent):
|
||||||
FT_content=self))
|
FT_content=self))
|
||||||
self._listen_host()
|
self._listen_host()
|
||||||
# Delete this after file_props refactoring this shouldn't be necesary
|
# Delete this after file_props refactoring this shouldn't be necesary
|
||||||
self.session.file_hash = self.file_props['hash']
|
self.session.file_hash = self.file_props.hash_
|
||||||
self.session.hash_algo = self.file_props['algo']
|
self.session.hash_algo = self.file_props.algo
|
||||||
|
|
||||||
def __on_session_initiate_sent(self, stanza, content, error, action):
|
def __on_session_initiate_sent(self, stanza, content, error, action):
|
||||||
# Calculate file_hash in a new thread
|
# Calculate file_hash in a new thread
|
||||||
# if we haven't sent the hash already.
|
# if we haven't sent the hash already.
|
||||||
if 'hash' not in self.file_props:
|
if self.file_props.hash_ is None:
|
||||||
self.hashThread = threading.Thread(target=self.__send_hash)
|
self.hashThread = threading.Thread(target=self.__send_hash)
|
||||||
self.hashThread.start()
|
self.hashThread.start()
|
||||||
|
|
||||||
|
@ -143,7 +142,7 @@ class JingleFileTransfer(JingleContent):
|
||||||
if self.session.hash_algo == None:
|
if self.session.hash_algo == None:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
file_ = open(self.file_props['file-name'], 'r')
|
file_ = open(self.file_props.file_name, 'r')
|
||||||
except:
|
except:
|
||||||
# can't open file
|
# can't open file
|
||||||
return
|
return
|
||||||
|
@ -154,7 +153,7 @@ class JingleFileTransfer(JingleContent):
|
||||||
if not hash_:
|
if not hash_:
|
||||||
# Hash alogrithm not supported
|
# Hash alogrithm not supported
|
||||||
return
|
return
|
||||||
self.file_props['hash'] = hash_
|
self.file_props.hash_ = hash_
|
||||||
h.addHash(hash_, self.session.hash_algo)
|
h.addHash(hash_, self.session.hash_algo)
|
||||||
return h
|
return h
|
||||||
|
|
||||||
|
@ -175,26 +174,21 @@ class JingleFileTransfer(JingleContent):
|
||||||
self.__state_changed(STATE_TRANSFERING)
|
self.__state_changed(STATE_TRANSFERING)
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
||||||
self.file_props['streamhosts'] = self.transport.remote_candidates
|
self.file_props.streamhosts = self.transport.remote_candidates
|
||||||
for host in self.file_props['streamhosts']:
|
for host in self.file_props.streamhosts:
|
||||||
host['initiator'] = self.session.initiator
|
host['initiator'] = self.session.initiator
|
||||||
host['target'] = self.session.responder
|
host['target'] = self.session.responder
|
||||||
host['sid'] = self.file_props['sid']
|
host['sid'] = self.file_props.sid
|
||||||
|
|
||||||
response = stanza.buildReply('result')
|
response = stanza.buildReply('result')
|
||||||
response.delChild(response.getQuery())
|
response.delChild(response.getQuery())
|
||||||
con.connection.send(response)
|
con.connection.send(response)
|
||||||
|
|
||||||
if not gajim.socks5queue.get_file_props(
|
|
||||||
self.session.connection.name, self.file_props['sid']):
|
|
||||||
gajim.socks5queue.add_file_props(self.session.connection.name,
|
|
||||||
self.file_props)
|
|
||||||
fingerprint = None
|
fingerprint = None
|
||||||
if self.use_security:
|
if self.use_security:
|
||||||
fingerprint = 'client'
|
fingerprint = 'client'
|
||||||
if self.transport.type == TransportType.SOCKS5:
|
if self.transport.type == TransportType.SOCKS5:
|
||||||
gajim.socks5queue.connect_to_hosts(self.session.connection.name,
|
gajim.socks5queue.connect_to_hosts(self.session.connection.name,
|
||||||
self.file_props['sid'], self.on_connect,
|
self.file_props.sid, self.on_connect,
|
||||||
self._on_connect_error, fingerprint=fingerprint,
|
self._on_connect_error, fingerprint=fingerprint,
|
||||||
receiving=False)
|
receiving=False)
|
||||||
return
|
return
|
||||||
|
@ -310,15 +304,15 @@ class JingleFileTransfer(JingleContent):
|
||||||
|
|
||||||
def _store_socks5_sid(self, sid, hash_id):
|
def _store_socks5_sid(self, sid, hash_id):
|
||||||
# callback from socsk5queue.start_listener
|
# callback from socsk5queue.start_listener
|
||||||
self.file_props['hash'] = hash_id
|
self.file_props.hash_ = hash_id
|
||||||
|
|
||||||
def _listen_host(self):
|
def _listen_host(self):
|
||||||
|
|
||||||
receiver = self.file_props['receiver']
|
receiver = self.file_props.receiver
|
||||||
sender = self.file_props['sender']
|
sender = self.file_props.sender
|
||||||
sha_str = helpers.get_auth_sha(self.file_props['sid'], sender,
|
sha_str = helpers.get_auth_sha(self.file_props.sid, sender,
|
||||||
receiver)
|
receiver)
|
||||||
self.file_props['sha_str'] = sha_str
|
self.file_props.sha_str = sha_str
|
||||||
|
|
||||||
port = gajim.config.get('file_transfers_port')
|
port = gajim.config.get('file_transfers_port')
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
import gajim
|
import gajim
|
||||||
import xmpp
|
import xmpp
|
||||||
from jingle_transport import *
|
from jingle_transport import *
|
||||||
|
from common.socks5 import Socks5ReceiverClient, Socks5SenderClient
|
||||||
|
|
||||||
class JingleFileTransferStates:
|
class JingleFileTransferStates:
|
||||||
|
|
||||||
|
@ -37,26 +38,18 @@ class StateInitialized(JingleFileTransferStates):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def action(self, args=None):
|
def action(self, args=None):
|
||||||
self.jft._listen_host()
|
|
||||||
if self.jft.weinitiate:
|
if self.jft.weinitiate:
|
||||||
# update connection's fileprops
|
# update connection's fileprops
|
||||||
self.jft.session.connection.files_props[self.jft.file_props['sid']] = \
|
self.jft._listen_host()
|
||||||
self.jft.file_props
|
|
||||||
# Listen on configured port for file transfer
|
# Listen on configured port for file transfer
|
||||||
else:
|
else:
|
||||||
# Add file_props to the queue
|
|
||||||
if not gajim.socks5queue.get_file_props(
|
|
||||||
self.jft.session.connection.name, self.jft.file_props['sid']):
|
|
||||||
gajim.socks5queue.add_file_props(
|
|
||||||
self.jft.session.connection.name,
|
|
||||||
self.jft.file_props)
|
|
||||||
fingerprint = None
|
fingerprint = None
|
||||||
if self.jft.use_security:
|
if self.jft.use_security:
|
||||||
fingerprint = 'client'
|
fingerprint = 'client'
|
||||||
# Connect to the candidate host, on success call on_connect method
|
# Connect to the candidate host, on success call on_connect method
|
||||||
gajim.socks5queue.connect_to_hosts(
|
gajim.socks5queue.connect_to_hosts(
|
||||||
self.jft.session.connection.name,
|
self.jft.session.connection.name,
|
||||||
self.jft.file_props['sid'], self.jft.on_connect,
|
self.jft.file_props.sid, self.jft.on_connect,
|
||||||
self.jft._on_connect_error, fingerprint=fingerprint)
|
self.jft._on_connect_error, fingerprint=fingerprint)
|
||||||
|
|
||||||
|
|
||||||
|
@ -156,9 +149,7 @@ class StateTransfering(JingleFileTransferStates):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def __start_IBB_transfer(self, con):
|
def __start_IBB_transfer(self, con):
|
||||||
con.files_props[self.jft.file_props['sid']] = \
|
fp = open(self.jft.file_props.file_name, 'r')
|
||||||
self.jft.file_props
|
|
||||||
fp = open(self.jft.file_props['file-name'], 'r')
|
|
||||||
con.OpenStream( self.jft.transport.sid,
|
con.OpenStream( self.jft.transport.sid,
|
||||||
self.jft.session.peerjid, fp, blocksize=4096)
|
self.jft.session.peerjid, fp, blocksize=4096)
|
||||||
|
|
||||||
|
@ -174,14 +165,14 @@ class StateTransfering(JingleFileTransferStates):
|
||||||
streamhost_used = self.jft.nominated_cand['peer-cand']
|
streamhost_used = self.jft.nominated_cand['peer-cand']
|
||||||
|
|
||||||
if streamhost_used['type'] == 'proxy':
|
if streamhost_used['type'] == 'proxy':
|
||||||
self.jft.file_props['is_a_proxy'] = True
|
self.jft.file_props.is_a_proxy = True
|
||||||
# This needs to be changed when requesting
|
# This needs to be changed when requesting
|
||||||
if self.jft.weinitiate:
|
if self.jft.weinitiate:
|
||||||
self.jft.file_props['proxy_sender'] = streamhost_used['initiator']
|
self.jft.file_props.proxy_sender = streamhost_used['initiator']
|
||||||
self.jft.file_props['proxy_receiver'] = streamhost_used['target']
|
self.jft.file_props.proxy_receiver = streamhost_used['target']
|
||||||
else:
|
else:
|
||||||
self.jft.file_props['proxy_sender'] = streamhost_used['target']
|
self.jft.file_props.proxy_sender = streamhost_used['target']
|
||||||
self.jft.file_props['proxy_receiver'] = streamhost_used['initiator']
|
self.jft.file_props.proxy_receiver = streamhost_used['initiator']
|
||||||
|
|
||||||
# This needs to be changed when requesting
|
# This needs to be changed when requesting
|
||||||
if not self.jft.weinitiate and streamhost_used['type'] == 'proxy':
|
if not self.jft.weinitiate and streamhost_used['type'] == 'proxy':
|
||||||
|
@ -200,12 +191,12 @@ class StateTransfering(JingleFileTransferStates):
|
||||||
return
|
return
|
||||||
|
|
||||||
if streamhost_used['type'] == 'proxy':
|
if streamhost_used['type'] == 'proxy':
|
||||||
self.jft.file_props['streamhost-used'] = True
|
self.jft.file_props.streamhost_used = True
|
||||||
streamhost_used['sid'] = self.jft.file_props['sid']
|
streamhost_used['sid'] = self.jft.file_props.sid
|
||||||
self.jft.file_props['streamhosts'] = []
|
self.jft.file_props.streamhosts = []
|
||||||
self.jft.file_props['streamhosts'].append(streamhost_used)
|
self.jft.file_props.streamhosts.append(streamhost_used)
|
||||||
self.jft.file_props['proxyhosts'] = []
|
self.jft.file_props.proxyhosts = []
|
||||||
self.jft.file_props['proxyhosts'].append(streamhost_used)
|
self.jft.file_props.proxyhosts.append(streamhost_used)
|
||||||
|
|
||||||
# This needs to be changed when requesting
|
# This needs to be changed when requesting
|
||||||
if self.jft.weinitiate:
|
if self.jft.weinitiate:
|
||||||
|
@ -218,7 +209,7 @@ class StateTransfering(JingleFileTransferStates):
|
||||||
connected=False, file_props=self.jft.file_props)
|
connected=False, file_props=self.jft.file_props)
|
||||||
else:
|
else:
|
||||||
sockobj = Socks5ReceiverClient(gajim.idlequeue, streamhost_used,
|
sockobj = Socks5ReceiverClient(gajim.idlequeue, streamhost_used,
|
||||||
sid=self.jft.file_props['sid'],
|
sid=self.jft.file_props.sid,
|
||||||
file_props=self.jft.file_props, fingerprint=None)
|
file_props=self.jft.file_props, fingerprint=None)
|
||||||
sockobj.proxy = True
|
sockobj.proxy = True
|
||||||
sockobj.streamhost = streamhost_used
|
sockobj.streamhost = streamhost_used
|
||||||
|
@ -228,7 +219,7 @@ class StateTransfering(JingleFileTransferStates):
|
||||||
# If we offered the nominated candidate used, we activate
|
# If we offered the nominated candidate used, we activate
|
||||||
# the proxy
|
# the proxy
|
||||||
if not self.jft.isOurCandUsed():
|
if not self.jft.isOurCandUsed():
|
||||||
gajim.socks5queue.on_success[self.jft.file_props['sid']] = \
|
gajim.socks5queue.on_success[self.jft.file_props.sid] = \
|
||||||
self.jft.transport._on_proxy_auth_ok
|
self.jft.transport._on_proxy_auth_ok
|
||||||
# TODO: add on failure
|
# TODO: add on failure
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -190,8 +190,8 @@ class JingleTransportSocks5(JingleTransport):
|
||||||
c['type'] = 'direct'
|
c['type'] = 'direct'
|
||||||
c['jid'] = self.ourjid
|
c['jid'] = self.ourjid
|
||||||
c['priority'] = (2**16) * type_preference
|
c['priority'] = (2**16) * type_preference
|
||||||
c['initiator'] = self.file_props['sender']
|
c['initiator'] = self.file_props.sender
|
||||||
c['target'] = self.file_props['receiver']
|
c['target'] = self.file_props.receiver
|
||||||
local_ip_cand.append(c)
|
local_ip_cand.append(c)
|
||||||
|
|
||||||
self._add_candidates(local_ip_cand)
|
self._add_candidates(local_ip_cand)
|
||||||
|
@ -213,8 +213,8 @@ class JingleTransportSocks5(JingleTransport):
|
||||||
c['type'] = 'direct'
|
c['type'] = 'direct'
|
||||||
c['jid'] = self.ourjid
|
c['jid'] = self.ourjid
|
||||||
c['priority'] = (2**16) * type_preference
|
c['priority'] = (2**16) * type_preference
|
||||||
c['initiator'] = self.file_props['sender']
|
c['initiator'] = self.file_props.sender
|
||||||
c['target'] = self.file_props['receiver']
|
c['target'] = self.file_props.receiver
|
||||||
additional_ip_cand.append(c)
|
additional_ip_cand.append(c)
|
||||||
|
|
||||||
self._add_candidates(additional_ip_cand)
|
self._add_candidates(additional_ip_cand)
|
||||||
|
@ -228,7 +228,7 @@ class JingleTransportSocks5(JingleTransport):
|
||||||
proxyhosts = socks5conn._get_file_transfer_proxies_from_config(self.file_props)
|
proxyhosts = socks5conn._get_file_transfer_proxies_from_config(self.file_props)
|
||||||
|
|
||||||
if proxyhosts:
|
if proxyhosts:
|
||||||
self.file_props['proxyhosts'] = proxyhosts
|
self.file_props.proxyhosts = proxyhosts
|
||||||
|
|
||||||
for proxyhost in proxyhosts:
|
for proxyhost in proxyhosts:
|
||||||
c = {'host': proxyhost['host']}
|
c = {'host': proxyhost['host']}
|
||||||
|
@ -237,15 +237,15 @@ class JingleTransportSocks5(JingleTransport):
|
||||||
c['type'] = 'proxy'
|
c['type'] = 'proxy'
|
||||||
c['jid'] = proxyhost['jid']
|
c['jid'] = proxyhost['jid']
|
||||||
c['priority'] = (2**16) * type_preference
|
c['priority'] = (2**16) * type_preference
|
||||||
c['initiator'] = self.file_props['sender']
|
c['initiator'] = self.file_props.sender
|
||||||
c['target'] = self.file_props['receiver']
|
c['target'] = self.file_props.receiver
|
||||||
proxy_cand.append(c)
|
proxy_cand.append(c)
|
||||||
|
|
||||||
self._add_candidates(proxy_cand)
|
self._add_candidates(proxy_cand)
|
||||||
|
|
||||||
def get_content(self):
|
def get_content(self):
|
||||||
sesn = self.connection.get_jingle_session(self.ourjid,
|
sesn = self.connection.get_jingle_session(self.ourjid,
|
||||||
self.file_props['session-sid'])
|
self.file_props.session_sid)
|
||||||
for content in sesn.contents.values():
|
for content in sesn.contents.values():
|
||||||
if content.transport == self:
|
if content.transport == self:
|
||||||
return content
|
return content
|
||||||
|
@ -256,7 +256,7 @@ class JingleTransportSocks5(JingleTransport):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
sesn = self.connection.get_jingle_session(self.ourjid,
|
sesn = self.connection.get_jingle_session(self.ourjid,
|
||||||
self.file_props['session-sid'])
|
self.file_props.session_sid)
|
||||||
if sesn is None:
|
if sesn is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ import socket
|
||||||
import base64
|
import base64
|
||||||
import gobject
|
import gobject
|
||||||
import time
|
import time
|
||||||
|
import pdb
|
||||||
|
|
||||||
from common import xmpp
|
from common import xmpp
|
||||||
from common import gajim
|
from common import gajim
|
||||||
|
@ -39,40 +40,42 @@ from common import helpers
|
||||||
from common import dataforms
|
from common import dataforms
|
||||||
from common import ged
|
from common import ged
|
||||||
from common import jingle_xtls
|
from common import jingle_xtls
|
||||||
|
from common.file_props import FilesProp
|
||||||
from common.socks5 import Socks5Receiver
|
from common.socks5 import Socks5Receiver
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
log = logging.getLogger('gajim.c.p.bytestream')
|
log = logging.getLogger('gajim.c.p.bytestream')
|
||||||
|
|
||||||
def is_transfer_paused(file_props):
|
def is_transfer_paused(file_props):
|
||||||
if 'stopped' in file_props and file_props['stopped']:
|
if file_props.stopped:
|
||||||
return False
|
return False
|
||||||
if 'completed' in file_props and file_props['completed']:
|
if file_props.completed:
|
||||||
return False
|
return False
|
||||||
if 'disconnect_cb' not in file_props:
|
if file_props.disconnect_cb:
|
||||||
return False
|
return False
|
||||||
return file_props['paused']
|
return file_props.paused
|
||||||
|
|
||||||
def is_transfer_active(file_props):
|
def is_transfer_active(file_props):
|
||||||
if 'stopped' in file_props and file_props['stopped']:
|
if file_props.stopped:
|
||||||
return False
|
return False
|
||||||
if 'completed' in file_props and file_props['completed']:
|
if file_props.completed:
|
||||||
return False
|
return False
|
||||||
if 'started' not in file_props or not file_props['started']:
|
if not file_props.started:
|
||||||
return False
|
return False
|
||||||
if 'paused' not in file_props:
|
if file_props.paused:
|
||||||
return True
|
return True
|
||||||
return not file_props['paused']
|
return not file_props.paused
|
||||||
|
|
||||||
def is_transfer_stopped(file_props):
|
def is_transfer_stopped(file_props):
|
||||||
if 'error' in file_props and file_props['error'] != 0:
|
if not file_props:
|
||||||
return True
|
return True
|
||||||
if 'completed' in file_props and file_props['completed']:
|
if file_props.error != 0:
|
||||||
return True
|
return True
|
||||||
if 'connected' in file_props and file_props['connected'] == False:
|
if file_props.completed:
|
||||||
return True
|
return True
|
||||||
if 'stopped' not in file_props or not file_props['stopped']:
|
if not file_props.connected:
|
||||||
|
return True
|
||||||
|
if not file_props.stopped:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -80,7 +83,6 @@ def is_transfer_stopped(file_props):
|
||||||
class ConnectionBytestream:
|
class ConnectionBytestream:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.files_props = {}
|
|
||||||
gajim.ged.register_event_handler('file-request-received', ged.GUI1,
|
gajim.ged.register_event_handler('file-request-received', ged.GUI1,
|
||||||
self._nec_file_request_received)
|
self._nec_file_request_received)
|
||||||
|
|
||||||
|
@ -94,7 +96,7 @@ class ConnectionBytestream:
|
||||||
return our_jid + '/' + resource
|
return our_jid + '/' + resource
|
||||||
|
|
||||||
def _ft_get_receiver_jid(self, file_props):
|
def _ft_get_receiver_jid(self, file_props):
|
||||||
return file_props['receiver'].jid + '/' + file_props['receiver'].resource
|
return file_props.receiver.jid + '/' + file_props.receiver.resource
|
||||||
|
|
||||||
def _ft_get_from(self, iq_obj):
|
def _ft_get_from(self, iq_obj):
|
||||||
return helpers.get_full_jid_from_iq(iq_obj)
|
return helpers.get_full_jid_from_iq(iq_obj)
|
||||||
|
@ -108,20 +110,19 @@ class ConnectionBytestream:
|
||||||
"""
|
"""
|
||||||
if not self.connection or self.connected < 2:
|
if not self.connection or self.connected < 2:
|
||||||
return
|
return
|
||||||
file_props['sender'] = self._ft_get_our_jid()
|
file_props.sender = self._ft_get_our_jid()
|
||||||
fjid = self._ft_get_receiver_jid(file_props)
|
fjid = self._ft_get_receiver_jid(file_props)
|
||||||
iq = xmpp.Iq(to=fjid, typ='set')
|
iq = xmpp.Iq(to=fjid, typ='set')
|
||||||
iq.setID(file_props['sid'])
|
iq.setID(file_props.sid)
|
||||||
self.files_props[file_props['sid']] = file_props
|
|
||||||
si = iq.setTag('si', namespace=xmpp.NS_SI)
|
si = iq.setTag('si', namespace=xmpp.NS_SI)
|
||||||
si.setAttr('profile', xmpp.NS_FILE)
|
si.setAttr('profile', xmpp.NS_FILE)
|
||||||
si.setAttr('id', file_props['sid'])
|
si.setAttr('id', file_props.sid)
|
||||||
file_tag = si.setTag('file', namespace=xmpp.NS_FILE)
|
file_tag = si.setTag('file', namespace=xmpp.NS_FILE)
|
||||||
file_tag.setAttr('name', file_props['name'])
|
file_tag.setAttr('name', file_props.name)
|
||||||
file_tag.setAttr('size', file_props['size'])
|
file_tag.setAttr('size', file_props.size)
|
||||||
desc = file_tag.setTag('desc')
|
desc = file_tag.setTag('desc')
|
||||||
if 'desc' in file_props:
|
if file_props.desc:
|
||||||
desc.setData(file_props['desc'])
|
desc.setData(file_props.desc)
|
||||||
file_tag.setTag('range')
|
file_tag.setTag('range')
|
||||||
feature = si.setTag('feature', namespace=xmpp.NS_FEATURE)
|
feature = si.setTag('feature', namespace=xmpp.NS_FEATURE)
|
||||||
_feature = xmpp.DataForm(typ='form')
|
_feature = xmpp.DataForm(typ='form')
|
||||||
|
@ -142,24 +143,22 @@ class ConnectionBytestream:
|
||||||
|
|
||||||
# file transfer initiated by a jingle session
|
# file transfer initiated by a jingle session
|
||||||
log.info("send_file_approval: jingle session accept")
|
log.info("send_file_approval: jingle session accept")
|
||||||
if file_props.get('session-type') == 'jingle':
|
if file_props.session_type == 'jingle':
|
||||||
session = self.get_jingle_session(file_props['sender'],
|
session = self.get_jingle_session(file_props.sender,
|
||||||
file_props['session-sid'])
|
file_props.session_sid)
|
||||||
if not session:
|
if not session:
|
||||||
return
|
return
|
||||||
content = None
|
content = None
|
||||||
for c in session.contents.values():
|
for c in session.contents.values():
|
||||||
if c.transport.sid == file_props['sid']:
|
if c.transport.sid == file_props.sid:
|
||||||
content = c
|
content = c
|
||||||
break
|
break
|
||||||
if not content:
|
if not content:
|
||||||
return
|
return
|
||||||
gajim.socks5queue.add_file_props(self.name, file_props)
|
|
||||||
|
|
||||||
if not session.accepted:
|
if not session.accepted:
|
||||||
if session.get_content('file', content.name).use_security:
|
if session.get_content('file', content.name).use_security:
|
||||||
id_ = jingle_xtls.send_cert_request(self,
|
id_ = jingle_xtls.send_cert_request(self,
|
||||||
file_props['sender'])
|
file_props.sender)
|
||||||
jingle_xtls.key_exchange_pend(id_, content)
|
jingle_xtls.key_exchange_pend(id_, content)
|
||||||
return
|
return
|
||||||
session.approve_session()
|
session.approve_session()
|
||||||
|
@ -167,19 +166,19 @@ class ConnectionBytestream:
|
||||||
session.approve_content('file', content.name)
|
session.approve_content('file', content.name)
|
||||||
return
|
return
|
||||||
|
|
||||||
iq = xmpp.Iq(to=unicode(file_props['sender']), typ='result')
|
iq = xmpp.Iq(to=unicode(file_props.sender), typ='result')
|
||||||
iq.setAttr('id', file_props['request-id'])
|
iq.setAttr('id', file_props.request_id)
|
||||||
si = iq.setTag('si', namespace=xmpp.NS_SI)
|
si = iq.setTag('si', namespace=xmpp.NS_SI)
|
||||||
if 'offset' in file_props and file_props['offset']:
|
if file_props.offset:
|
||||||
file_tag = si.setTag('file', namespace=xmpp.NS_FILE)
|
file_tag = si.setTag('file', namespace=xmpp.NS_FILE)
|
||||||
range_tag = file_tag.setTag('range')
|
range_tag = file_tag.setTag('range')
|
||||||
range_tag.setAttr('offset', file_props['offset'])
|
range_tag.setAttr('offset', file_props.offset)
|
||||||
feature = si.setTag('feature', namespace=xmpp.NS_FEATURE)
|
feature = si.setTag('feature', namespace=xmpp.NS_FEATURE)
|
||||||
_feature = xmpp.DataForm(typ='submit')
|
_feature = xmpp.DataForm(typ='submit')
|
||||||
feature.addChild(node=_feature)
|
feature.addChild(node=_feature)
|
||||||
field = _feature.setField('stream-method')
|
field = _feature.setField('stream-method')
|
||||||
field.delAttr('type')
|
field.delAttr('type')
|
||||||
if xmpp.NS_BYTESTREAM in file_props['stream-methods']:
|
if xmpp.NS_BYTESTREAM in file_props.stream_methods:
|
||||||
field.setValue(xmpp.NS_BYTESTREAM)
|
field.setValue(xmpp.NS_BYTESTREAM)
|
||||||
else:
|
else:
|
||||||
field.setValue(xmpp.NS_IBB)
|
field.setValue(xmpp.NS_IBB)
|
||||||
|
@ -195,12 +194,12 @@ class ConnectionBytestream:
|
||||||
# user response to ConfirmationDialog may come after we've disconneted
|
# user response to ConfirmationDialog may come after we've disconneted
|
||||||
if not self.connection or self.connected < 2:
|
if not self.connection or self.connected < 2:
|
||||||
return
|
return
|
||||||
if file_props['session-type'] == 'jingle':
|
if file_props.session_type == 'jingle':
|
||||||
jingle = self._sessions[file_props['session-sid']]
|
jingle = self._sessions[file_props.session_sid]
|
||||||
jingle.cancel_session()
|
jingle.cancel_session()
|
||||||
return
|
return
|
||||||
iq = xmpp.Iq(to=unicode(file_props['sender']), typ='error')
|
iq = xmpp.Iq(to=unicode(file_props.sender), typ='error')
|
||||||
iq.setAttr('id', file_props['request-id'])
|
iq.setAttr('id', file_props.request_id)
|
||||||
if code == '400' and typ in ('stream', 'profile'):
|
if code == '400' and typ in ('stream', 'profile'):
|
||||||
name = 'bad-request'
|
name = 'bad-request'
|
||||||
text = ''
|
text = ''
|
||||||
|
@ -217,13 +216,13 @@ class ConnectionBytestream:
|
||||||
self.connection.send(iq)
|
self.connection.send(iq)
|
||||||
|
|
||||||
def _siResultCB(self, con, iq_obj):
|
def _siResultCB(self, con, iq_obj):
|
||||||
file_props = self.files_props.get(iq_obj.getAttr('id'))
|
file_props = FilesProp.getFileProp(con.name, iq_obj.getAttr('id'))
|
||||||
if not file_props:
|
if not file_props:
|
||||||
return
|
return
|
||||||
if 'request-id' in file_props:
|
if file_props.request_id:
|
||||||
# we have already sent streamhosts info
|
# we have already sent streamhosts info
|
||||||
return
|
return
|
||||||
file_props['receiver'] = self._ft_get_from(iq_obj)
|
file_props.receiver = self._ft_get_from(iq_obj)
|
||||||
si = iq_obj.getTag('si')
|
si = iq_obj.getTag('si')
|
||||||
file_tag = si.getTag('file')
|
file_tag = si.getTag('file')
|
||||||
range_tag = None
|
range_tag = None
|
||||||
|
@ -232,10 +231,10 @@ class ConnectionBytestream:
|
||||||
if range_tag:
|
if range_tag:
|
||||||
offset = range_tag.getAttr('offset')
|
offset = range_tag.getAttr('offset')
|
||||||
if offset:
|
if offset:
|
||||||
file_props['offset'] = int(offset)
|
file_props.offset = int(offset)
|
||||||
length = range_tag.getAttr('length')
|
length = range_tag.getAttr('length')
|
||||||
if length:
|
if length:
|
||||||
file_props['length'] = int(length)
|
file_props.length = int(length)
|
||||||
feature = si.setTag('feature')
|
feature = si.setTag('feature')
|
||||||
if feature.getNamespace() != xmpp.NS_FEATURE:
|
if feature.getNamespace() != xmpp.NS_FEATURE:
|
||||||
return
|
return
|
||||||
|
@ -246,9 +245,9 @@ class ConnectionBytestream:
|
||||||
self._send_socks5_info(file_props)
|
self._send_socks5_info(file_props)
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
if field.getValue() == xmpp.NS_IBB:
|
if field.getValue() == xmpp.NS_IBB:
|
||||||
sid = file_props['sid']
|
sid = file_props.sid
|
||||||
fp = open(file_props['file-name'], 'r')
|
fp = open(file_props.file_name, 'r')
|
||||||
self.OpenStream(sid, file_props['receiver'], fp)
|
self.OpenStream(sid, file_props.receiver, fp)
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
||||||
def _siSetCB(self, con, iq_obj):
|
def _siSetCB(self, con, iq_obj):
|
||||||
|
@ -258,20 +257,18 @@ class ConnectionBytestream:
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
||||||
def _nec_file_request_received(self, obj):
|
def _nec_file_request_received(self, obj):
|
||||||
if obj.conn.name != self.name:
|
pass
|
||||||
return
|
|
||||||
gajim.socks5queue.add_file_props(self.name, obj.file_props)
|
|
||||||
|
|
||||||
def _siErrorCB(self, con, iq_obj):
|
def _siErrorCB(self, con, iq_obj):
|
||||||
si = iq_obj.getTag('si')
|
si = iq_obj.getTag('si')
|
||||||
profile = si.getAttr('profile')
|
profile = si.getAttr('profile')
|
||||||
if profile != xmpp.NS_FILE:
|
if profile != xmpp.NS_FILE:
|
||||||
return
|
return
|
||||||
file_props = self.files_props.get(iq_obj.getAttr('id'))
|
file_props = FilesProp.getFileProp(con.name, iq_obj.getAttr('id'))
|
||||||
if not file_props:
|
if not file_props:
|
||||||
return
|
return
|
||||||
jid = self._ft_get_from(iq_obj)
|
jid = self._ft_get_from(iq_obj)
|
||||||
file_props['error'] = -3
|
file_props.error = -3
|
||||||
from common.connection_handlers_events import FileRequestErrorEvent
|
from common.connection_handlers_events import FileRequestErrorEvent
|
||||||
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
|
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
|
||||||
jid=jid, file_props=file_props, error_msg=''))
|
jid=jid, file_props=file_props, error_msg=''))
|
||||||
|
@ -299,59 +296,54 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
"""
|
"""
|
||||||
Stop all active transfer to or from the given contact
|
Stop all active transfer to or from the given contact
|
||||||
"""
|
"""
|
||||||
for file_props in self.files_props.values():
|
for file_props in FilesProp.getAllFileProp():
|
||||||
if is_transfer_stopped(file_props):
|
if is_transfer_stopped(file_props):
|
||||||
continue
|
continue
|
||||||
receiver_jid = unicode(file_props['receiver'])
|
receiver_jid = unicode(file_props.receiver)
|
||||||
if contact.get_full_jid() == receiver_jid:
|
if contact.get_full_jid() == receiver_jid:
|
||||||
file_props['error'] = -5
|
file_props.error = -5
|
||||||
self.remove_transfer(file_props)
|
self.remove_transfer(file_props)
|
||||||
from common.connection_handlers_events import \
|
from common.connection_handlers_events import \
|
||||||
FileRequestErrorEvent
|
FileRequestErrorEvent
|
||||||
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
|
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
|
||||||
conn=self, jid=contact.jid, file_props=file_props,
|
conn=self, jid=contact.jid, file_props=file_props,
|
||||||
error_msg=''))
|
error_msg=''))
|
||||||
sender_jid = unicode(file_props['sender'])
|
sender_jid = unicode(file_props.sender)
|
||||||
if contact.get_full_jid() == sender_jid:
|
if contact.get_full_jid() == sender_jid:
|
||||||
file_props['error'] = -3
|
file_props.error = -3
|
||||||
self.remove_transfer(file_props)
|
self.remove_transfer(file_props)
|
||||||
|
|
||||||
def remove_all_transfers(self):
|
def remove_all_transfers(self):
|
||||||
"""
|
"""
|
||||||
Stop and remove all active connections from the socks5 pool
|
Stop and remove all active connections from the socks5 pool
|
||||||
"""
|
"""
|
||||||
for file_props in self.files_props.values():
|
for file_props in FilesProp.getAllFileProp():
|
||||||
self.remove_transfer(file_props, remove_from_list=False)
|
self.remove_transfer(file_props, remove_from_list=False)
|
||||||
self.files_props = {}
|
|
||||||
|
|
||||||
def remove_transfer(self, file_props, remove_from_list=True):
|
def remove_transfer(self, file_props, remove_from_list=True):
|
||||||
if file_props is None:
|
if file_props is None:
|
||||||
return
|
return
|
||||||
self.disconnect_transfer(file_props)
|
self.disconnect_transfer(file_props)
|
||||||
sid = file_props['sid']
|
sid = file_props.sid
|
||||||
gajim.socks5queue.remove_file_props(self.name, sid)
|
gajim.socks5queue.remove_file_props(self.name, sid)
|
||||||
|
|
||||||
if remove_from_list:
|
|
||||||
if 'sid' in self.files_props:
|
|
||||||
del(self.files_props['sid'])
|
|
||||||
|
|
||||||
def disconnect_transfer(self, file_props):
|
def disconnect_transfer(self, file_props):
|
||||||
if file_props is None:
|
if file_props is None:
|
||||||
return
|
return
|
||||||
if 'hash' in file_props:
|
if file_props.hash_:
|
||||||
gajim.socks5queue.remove_sender(file_props['hash'])
|
gajim.socks5queue.remove_sender(file_props.hash_)
|
||||||
|
|
||||||
if 'streamhosts' in file_props:
|
if file_props.streamhosts:
|
||||||
for host in file_props['streamhosts']:
|
for host in file_props.streamhosts:
|
||||||
if 'idx' in host and host['idx'] > 0:
|
if 'idx' in host and host['idx'] > 0:
|
||||||
gajim.socks5queue.remove_receiver(host['idx'])
|
gajim.socks5queue.remove_receiver(host['idx'])
|
||||||
gajim.socks5queue.remove_sender(host['idx'])
|
gajim.socks5queue.remove_sender(host['idx'])
|
||||||
|
|
||||||
if 'direction' in file_props:
|
if file_props.direction:
|
||||||
# it's a IBB
|
# it's a IBB
|
||||||
sid = file_props['sid']
|
FilesProp.deleteFileProp(file_props)
|
||||||
if sid in self.files_props:
|
del(file_props)
|
||||||
del self.files_props[sid]
|
|
||||||
|
|
||||||
def _send_socks5_info(self, file_props):
|
def _send_socks5_info(self, file_props):
|
||||||
"""
|
"""
|
||||||
|
@ -359,28 +351,28 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
"""
|
"""
|
||||||
if not self.connection or self.connected < 2:
|
if not self.connection or self.connected < 2:
|
||||||
return
|
return
|
||||||
receiver = file_props['receiver']
|
receiver = file_props.receiver
|
||||||
sender = file_props['sender']
|
sender = file_props.sender
|
||||||
|
|
||||||
sha_str = helpers.get_auth_sha(file_props['sid'], sender, receiver)
|
sha_str = helpers.get_auth_sha(file_props.sid, sender, receiver)
|
||||||
file_props['sha_str'] = sha_str
|
file_props.sha_str = sha_str
|
||||||
|
|
||||||
port = gajim.config.get('file_transfers_port')
|
port = gajim.config.get('file_transfers_port')
|
||||||
listener = gajim.socks5queue.start_listener(port, sha_str,
|
listener = gajim.socks5queue.start_listener(port, sha_str,
|
||||||
self._result_socks5_sid, file_props)
|
self._result_socks5_sid, file_props)
|
||||||
if not listener:
|
if not listener:
|
||||||
file_props['error'] = -5
|
file_props.error = -5
|
||||||
from common.connection_handlers_events import FileRequestErrorEvent
|
from common.connection_handlers_events import FileRequestErrorEvent
|
||||||
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
|
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
|
||||||
jid=unicode(receiver), file_props=file_props, error_msg=''))
|
jid=unicode(receiver), file_props=file_props, error_msg=''))
|
||||||
self._connect_error(unicode(receiver), file_props['sid'],
|
self._connect_error(unicode(receiver), file_props.sid,
|
||||||
file_props['sid'], code=406)
|
file_props.sid, code=406)
|
||||||
else:
|
else:
|
||||||
iq = xmpp.Iq(to=unicode(receiver), typ='set')
|
iq = xmpp.Iq(to=unicode(receiver), typ='set')
|
||||||
file_props['request-id'] = 'id_' + file_props['sid']
|
file_props.request_id = 'id_' + file_props.sid
|
||||||
iq.setID(file_props['request-id'])
|
iq.setID(file_props.request_id)
|
||||||
query = iq.setTag('query', namespace=xmpp.NS_BYTESTREAM)
|
query = iq.setTag('query', namespace=xmpp.NS_BYTESTREAM)
|
||||||
query.setAttr('sid', file_props['sid'])
|
query.setAttr('sid', file_props.sid)
|
||||||
|
|
||||||
self._add_addiditional_streamhosts_to_query(query, file_props)
|
self._add_addiditional_streamhosts_to_query(query, file_props)
|
||||||
self._add_local_ips_as_streamhosts_to_query(query, file_props)
|
self._add_local_ips_as_streamhosts_to_query(query, file_props)
|
||||||
|
@ -406,7 +398,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
if not addr[4][0] in my_ips and not addr[4][0].startswith('127'):
|
if not addr[4][0] in my_ips and not addr[4][0].startswith('127'):
|
||||||
my_ips.append(addr[4][0])
|
my_ips.append(addr[4][0])
|
||||||
|
|
||||||
sender = file_props['sender']
|
sender = file_props.sender
|
||||||
port = gajim.config.get('file_transfers_port')
|
port = gajim.config.get('file_transfers_port')
|
||||||
self._add_streamhosts_to_query(query, sender, port, my_ips)
|
self._add_streamhosts_to_query(query, sender, port, my_ips)
|
||||||
except socket.gaierror:
|
except socket.gaierror:
|
||||||
|
@ -416,7 +408,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
sec_txt=_('Invalid local address? :-O')))
|
sec_txt=_('Invalid local address? :-O')))
|
||||||
|
|
||||||
def _add_addiditional_streamhosts_to_query(self, query, file_props):
|
def _add_addiditional_streamhosts_to_query(self, query, file_props):
|
||||||
sender = file_props['sender']
|
sender = file_props.sender
|
||||||
port = gajim.config.get('file_transfers_port')
|
port = gajim.config.get('file_transfers_port')
|
||||||
ft_add_hosts_to_send = gajim.config.get('ft_add_hosts_to_send')
|
ft_add_hosts_to_send = gajim.config.get('ft_add_hosts_to_send')
|
||||||
additional_hosts = []
|
additional_hosts = []
|
||||||
|
@ -469,12 +461,12 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
log.debug('Got GUPnP-IGD answer: external: %s:%s, internal: %s:%s',
|
log.debug('Got GUPnP-IGD answer: external: %s:%s, internal: %s:%s',
|
||||||
ext_ip, ext_port, local_ip, local_port)
|
ext_ip, ext_port, local_ip, local_port)
|
||||||
if local_port != gajim.config.get('file_transfers_port'):
|
if local_port != gajim.config.get('file_transfers_port'):
|
||||||
sender = file_props['sender']
|
sender = file_props.sender
|
||||||
receiver = file_props['receiver']
|
receiver = file_props.receiver
|
||||||
sha_str = helpers.get_auth_sha(file_props['sid'], sender,
|
sha_str = helpers.get_auth_sha(file_props.sid, sender,
|
||||||
receiver)
|
receiver)
|
||||||
listener = gajim.socks5queue.start_listener(local_port, sha_str,
|
listener = gajim.socks5queue.start_listener(local_port, sha_str,
|
||||||
self._result_socks5_sid, file_props['sid'])
|
self._result_socks5_sid, file_props.sid)
|
||||||
if listener:
|
if listener:
|
||||||
self._add_streamhosts_to_query(query, sender, ext_port,
|
self._add_streamhosts_to_query(query, sender, ext_port,
|
||||||
[ext_ip])
|
[ext_ip])
|
||||||
|
@ -507,9 +499,9 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
def _add_proxy_streamhosts_to_query(self, query, file_props):
|
def _add_proxy_streamhosts_to_query(self, query, file_props):
|
||||||
proxyhosts = self._get_file_transfer_proxies_from_config(file_props)
|
proxyhosts = self._get_file_transfer_proxies_from_config(file_props)
|
||||||
if proxyhosts:
|
if proxyhosts:
|
||||||
file_props['proxy_receiver'] = unicode(file_props['receiver'])
|
file_props.proxy_receiver = unicode(file_props.receiver)
|
||||||
file_props['proxy_sender'] = unicode(file_props['sender'])
|
file_props.proxy_sender = unicode(file_props.sender)
|
||||||
file_props['proxyhosts'] = proxyhosts
|
file_props.proxyhosts = proxyhosts
|
||||||
|
|
||||||
for proxyhost in proxyhosts:
|
for proxyhost in proxyhosts:
|
||||||
self._add_streamhosts_to_query(query, proxyhost['jid'],
|
self._add_streamhosts_to_query(query, proxyhost['jid'],
|
||||||
|
@ -536,9 +528,9 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
continue
|
continue
|
||||||
host_dict = {
|
host_dict = {
|
||||||
'state': 0,
|
'state': 0,
|
||||||
'target': unicode(file_props['receiver']),
|
'target': unicode(file_props.receiver),
|
||||||
'id': file_props['sid'],
|
'id': file_props.sid,
|
||||||
'sid': file_props['sid'],
|
'sid': file_props.sid,
|
||||||
'initiator': proxy,
|
'initiator': proxy,
|
||||||
'host': host,
|
'host': host,
|
||||||
'port': unicode(_port),
|
'port': unicode(_port),
|
||||||
|
@ -553,10 +545,8 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
"""
|
"""
|
||||||
Store the result of SHA message from auth
|
Store the result of SHA message from auth
|
||||||
"""
|
"""
|
||||||
if sid not in self.files_props:
|
file_props = FilesProp.getFilePropBySid(sid)
|
||||||
return
|
file_props.hash_ = hash_id
|
||||||
file_props = self.files_props[sid]
|
|
||||||
file_props['hash'] = hash_id
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def _connect_error(self, to, _id, sid, code=404):
|
def _connect_error(self, to, _id, sid, code=404):
|
||||||
|
@ -579,10 +569,10 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
err.setData(msg)
|
err.setData(msg)
|
||||||
self.connection.send(iq)
|
self.connection.send(iq)
|
||||||
if code == 404:
|
if code == 404:
|
||||||
file_props = gajim.socks5queue.get_file_props(self.name, sid)
|
file_props = FilesProp.getFileProp(self.name, sid)
|
||||||
if file_props is not None:
|
if file_props is not None:
|
||||||
self.disconnect_transfer(file_props)
|
self.disconnect_transfer(file_props)
|
||||||
file_props['error'] = -3
|
file_props.error = -3
|
||||||
from common.connection_handlers_events import \
|
from common.connection_handlers_events import \
|
||||||
FileRequestErrorEvent
|
FileRequestErrorEvent
|
||||||
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
|
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
|
||||||
|
@ -594,14 +584,14 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
"""
|
"""
|
||||||
if not self.connection or self.connected < 2:
|
if not self.connection or self.connected < 2:
|
||||||
return
|
return
|
||||||
file_props = self.files_props[proxy['sid']]
|
file_props = FilesProp.getFileProp(self.connection, proxy['sid'])
|
||||||
iq = xmpp.Iq(to=proxy['initiator'], typ='set')
|
iq = xmpp.Iq(to=proxy['initiator'], typ='set')
|
||||||
auth_id = "au_" + proxy['sid']
|
auth_id = "au_" + proxy['sid']
|
||||||
iq.setID(auth_id)
|
iq.setID(auth_id)
|
||||||
query = iq.setTag('query', namespace=xmpp.NS_BYTESTREAM)
|
query = iq.setTag('query', namespace=xmpp.NS_BYTESTREAM)
|
||||||
query.setAttr('sid', proxy['sid'])
|
query.setAttr('sid', proxy['sid'])
|
||||||
activate = query.setTag('activate')
|
activate = query.setTag('activate')
|
||||||
activate.setData(file_props['proxy_receiver'])
|
activate.setData(file_props.proxy_receiver)
|
||||||
iq.setID(auth_id)
|
iq.setID(auth_id)
|
||||||
self.connection.send(iq)
|
self.connection.send(iq)
|
||||||
|
|
||||||
|
@ -613,10 +603,10 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
gajim.proxy65_manager.error_cb(frm, query)
|
gajim.proxy65_manager.error_cb(frm, query)
|
||||||
jid = helpers.get_jid_from_iq(iq_obj)
|
jid = helpers.get_jid_from_iq(iq_obj)
|
||||||
id_ = id_[3:]
|
id_ = id_[3:]
|
||||||
if id_ not in self.files_props:
|
file_props = FilesProp.getFilePropBySid(id_)
|
||||||
|
if not file_props:
|
||||||
return
|
return
|
||||||
file_props = self.files_props[id_]
|
file_props.error = -4
|
||||||
file_props['error'] = -4
|
|
||||||
from common.connection_handlers_events import FileRequestErrorEvent
|
from common.connection_handlers_events import FileRequestErrorEvent
|
||||||
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
|
gajim.nec.push_incoming_event(FileRequestErrorEvent(None, conn=self,
|
||||||
jid=jid, file_props=file_props, error_msg=''))
|
jid=jid, file_props=file_props, error_msg=''))
|
||||||
|
@ -627,7 +617,7 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
id_ = unicode(iq_obj.getAttr('id'))
|
id_ = unicode(iq_obj.getAttr('id'))
|
||||||
query = iq_obj.getTag('query')
|
query = iq_obj.getTag('query')
|
||||||
sid = unicode(query.getAttr('sid'))
|
sid = unicode(query.getAttr('sid'))
|
||||||
file_props = gajim.socks5queue.get_file_props(self.name, sid)
|
file_props = FilesProp.getFileProp(self.name, sid)
|
||||||
streamhosts = []
|
streamhosts = []
|
||||||
for item in query.getChildren():
|
for item in query.getChildren():
|
||||||
if item.getName() == 'streamhost':
|
if item.getName() == 'streamhost':
|
||||||
|
@ -647,28 +637,24 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
if 'port' not in host_dict:
|
if 'port' not in host_dict:
|
||||||
continue
|
continue
|
||||||
streamhosts.append(host_dict)
|
streamhosts.append(host_dict)
|
||||||
if file_props is None:
|
file_props = FilesProp.getFilePropBySid(sid)
|
||||||
if sid in self.files_props:
|
if file_props is not None:
|
||||||
file_props = self.files_props[sid]
|
file_props.fast = streamhosts
|
||||||
file_props['fast'] = streamhosts
|
if file_props.type_ == 's': # FIXME: remove fast xmlns
|
||||||
if file_props['type'] == 's': # FIXME: remove fast xmlns
|
# only psi do this
|
||||||
# only psi do this
|
if file_props.streamhosts:
|
||||||
if 'streamhosts' in file_props:
|
file_props.streamhosts.extend(streamhosts)
|
||||||
file_props['streamhosts'].extend(streamhosts)
|
else:
|
||||||
else:
|
file_props.streamhosts = streamhosts
|
||||||
file_props['streamhosts'] = streamhosts
|
gajim.socks5queue.connect_to_hosts(self.name, sid,
|
||||||
if not gajim.socks5queue.get_file_props(self.name, sid):
|
self.send_success_connect_reply, None)
|
||||||
gajim.socks5queue.add_file_props(self.name, file_props)
|
raise xmpp.NodeProcessed
|
||||||
gajim.socks5queue.connect_to_hosts(self.name, sid,
|
else:
|
||||||
self.send_success_connect_reply, None)
|
|
||||||
raise xmpp.NodeProcessed
|
|
||||||
|
|
||||||
if file_props is None:
|
|
||||||
log.warn('Gajim got streamhosts for unknown transfer. Ignoring it.')
|
log.warn('Gajim got streamhosts for unknown transfer. Ignoring it.')
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
||||||
file_props['streamhosts'] = streamhosts
|
file_props.streamhosts = streamhosts
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
gajim.socks5queue.connect_to_hosts(self.name, sid,
|
gajim.socks5queue.connect_to_hosts(self.name, sid,
|
||||||
self.send_success_connect_reply, self._connect_error)
|
self.send_success_connect_reply, self._connect_error)
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
@ -681,13 +667,12 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
return
|
return
|
||||||
frm = self._ft_get_from(iq_obj)
|
frm = self._ft_get_from(iq_obj)
|
||||||
id_ = real_id[3:]
|
id_ = real_id[3:]
|
||||||
if id_ in self.files_props:
|
file_props = FilesProp.getFilePropBySid(id_)
|
||||||
file_props = self.files_props[id_]
|
if file_props.streamhost_used:
|
||||||
if file_props['streamhost-used']:
|
for host in file_props.proxyhosts:
|
||||||
for host in file_props['proxyhosts']:
|
if host['initiator'] == frm and 'idx' in host:
|
||||||
if host['initiator'] == frm and 'idx' in host:
|
gajim.socks5queue.activate_proxy(host['idx'])
|
||||||
gajim.socks5queue.activate_proxy(host['idx'])
|
raise xmpp.NodeProcessed
|
||||||
raise xmpp.NodeProcessed
|
|
||||||
|
|
||||||
def _bytestreamResultCB(self, con, iq_obj):
|
def _bytestreamResultCB(self, con, iq_obj):
|
||||||
frm = self._ft_get_from(iq_obj)
|
frm = self._ft_get_from(iq_obj)
|
||||||
|
@ -700,67 +685,62 @@ class ConnectionSocks5Bytestream(ConnectionBytestream):
|
||||||
except Exception: # this bytestream result is not what we need
|
except Exception: # this bytestream result is not what we need
|
||||||
pass
|
pass
|
||||||
id_ = real_id[3:]
|
id_ = real_id[3:]
|
||||||
if id_ in self.files_props:
|
file_props = FilesProp.getFileProp(con.name, id_)
|
||||||
file_props = self.files_props[id_]
|
if file_props is None:
|
||||||
else:
|
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
if streamhost is None:
|
if streamhost is None:
|
||||||
# proxy approves the activate query
|
# proxy approves the activate query
|
||||||
if real_id.startswith('au_'):
|
if real_id.startswith('au_'):
|
||||||
if 'streamhost-used' not in file_props or \
|
if file_props.streamhost_used is False:
|
||||||
file_props['streamhost-used'] is False:
|
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
if 'proxyhosts' not in file_props:
|
if not file_props.proxyhosts:
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
for host in file_props['proxyhosts']:
|
for host in file_props.proxyhosts:
|
||||||
if host['initiator'] == frm and \
|
if host['initiator'] == frm and \
|
||||||
unicode(query.getAttr('sid')) == file_props['sid']:
|
unicode(query.getAttr('sid')) == file_props.sid:
|
||||||
gajim.socks5queue.activate_proxy(host['idx'])
|
gajim.socks5queue.activate_proxy(host['idx'])
|
||||||
break
|
break
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
jid = self._ft_get_streamhost_jid_attr(streamhost)
|
jid = self._ft_get_streamhost_jid_attr(streamhost)
|
||||||
if 'streamhost-used' in file_props and \
|
if file_props.streamhost_used is True:
|
||||||
file_props['streamhost-used'] is True:
|
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
||||||
if real_id.startswith('au_'):
|
if real_id.startswith('au_'):
|
||||||
if 'stopped' in file_props and file_props['stopped']:
|
if file_props.stopped:
|
||||||
self.remove_transfer(file_props)
|
self.remove_transfer(file_props)
|
||||||
else:
|
else:
|
||||||
gajim.socks5queue.send_file(file_props, self.name)
|
gajim.socks5queue.send_file(file_props, self.name)
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
||||||
proxy = None
|
proxy = None
|
||||||
if 'proxyhosts' in file_props:
|
if file_props.proxyhosts:
|
||||||
for proxyhost in file_props['proxyhosts']:
|
for proxyhost in file_props.proxyhosts:
|
||||||
if proxyhost['jid'] == jid:
|
if proxyhost['jid'] == jid:
|
||||||
proxy = proxyhost
|
proxy = proxyhost
|
||||||
|
|
||||||
if 'stopped' in file_props and file_props['stopped']:
|
if file_props.stopped:
|
||||||
self.remove_transfer(file_props)
|
self.remove_transfer(file_props)
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
if proxy is not None:
|
if proxy is not None:
|
||||||
file_props['streamhost-used'] = True
|
file_props.streamhost_used = True
|
||||||
if 'streamhosts' not in file_props:
|
file_props.streamhosts.append(proxy)
|
||||||
file_props['streamhosts'] = []
|
file_props.is_a_proxy = True
|
||||||
file_props['streamhosts'].append(proxy)
|
|
||||||
file_props['is_a_proxy'] = True
|
|
||||||
receiver = Socks5Receiver(gajim.idlequeue, proxy,
|
receiver = Socks5Receiver(gajim.idlequeue, proxy,
|
||||||
file_props['sid'], file_props)
|
file_props.sid, file_props)
|
||||||
gajim.socks5queue.add_receiver(self.name, receiver)
|
gajim.socks5queue.add_receiver(self.name, receiver)
|
||||||
proxy['idx'] = receiver.queue_idx
|
proxy['idx'] = receiver.queue_idx
|
||||||
gajim.socks5queue.on_success = self._proxy_auth_ok
|
gajim.socks5queue.on_success = self._proxy_auth_ok
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if 'stopped' in file_props and file_props['stopped']:
|
if file_props.stopped:
|
||||||
self.remove_transfer(file_props)
|
self.remove_transfer(file_props)
|
||||||
else:
|
else:
|
||||||
gajim.socks5queue.send_file(file_props, self.name, 'client')
|
gajim.socks5queue.send_file(file_props, self.name, 'client')
|
||||||
if 'fast' in file_props:
|
if file_props.fast:
|
||||||
fasts = file_props['fast']
|
fasts = file_props.fast
|
||||||
if len(fasts) > 0:
|
if len(fasts) > 0:
|
||||||
self._connect_error(frm, fasts[0]['id'], file_props['sid'],
|
self._connect_error(frm, fasts[0]['id'], file_props.sid,
|
||||||
code=406)
|
code=406)
|
||||||
|
|
||||||
raise xmpp.NodeProcessed
|
raise xmpp.NodeProcessed
|
||||||
|
@ -800,33 +780,33 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
blocksize = stanza.getTagAttr('open', 'block-size')
|
blocksize = stanza.getTagAttr('open', 'block-size')
|
||||||
log.debug('StreamOpenHandler called sid->%s blocksize->%s' % (sid,
|
log.debug('StreamOpenHandler called sid->%s blocksize->%s' % (sid,
|
||||||
blocksize))
|
blocksize))
|
||||||
|
file_props = FilesProp.getFileProp(self.name, sid)
|
||||||
try:
|
try:
|
||||||
blocksize = int(blocksize)
|
blocksize = int(blocksize)
|
||||||
except:
|
except:
|
||||||
err = xmpp.ERR_BAD_REQUEST
|
err = xmpp.ERR_BAD_REQUEST
|
||||||
if not sid or not blocksize:
|
if not sid or not blocksize:
|
||||||
err = xmpp.ERR_BAD_REQUEST
|
err = xmpp.ERR_BAD_REQUEST
|
||||||
elif not gajim.socks5queue.get_file_props(self.name, sid):
|
elif not file_props:
|
||||||
err = xmpp.ERR_UNEXPECTED_REQUEST
|
err = xmpp.ERR_UNEXPECTED_REQUEST
|
||||||
if err:
|
if err:
|
||||||
rep = xmpp.Error(stanza, err)
|
rep = xmpp.Error(stanza, err)
|
||||||
else:
|
else:
|
||||||
file_props = gajim.socks5queue.get_file_props(self.name, sid)
|
|
||||||
log.debug("Opening stream: id %s, block-size %s" % (sid, blocksize))
|
log.debug("Opening stream: id %s, block-size %s" % (sid, blocksize))
|
||||||
rep = xmpp.Protocol('iq', stanza.getFrom(), 'result',
|
rep = xmpp.Protocol('iq', stanza.getFrom(), 'result',
|
||||||
stanza.getTo(), {'id': stanza.getID()})
|
stanza.getTo(), {'id': stanza.getID()})
|
||||||
file_props['block-size'] = blocksize
|
file_props.block_size = blocksize
|
||||||
file_props['seq'] = 0
|
file_props.seq = 0
|
||||||
file_props['received-len'] = 0
|
file_props.received_len = 0
|
||||||
file_props['last-time'] = time.time()
|
file_props.last_time = time.time()
|
||||||
file_props['error'] = 0
|
file_props.error = 0
|
||||||
file_props['paused'] = False
|
file_props.paused = False
|
||||||
file_props['connected'] = True
|
file_props.connected = True
|
||||||
file_props['completed'] = False
|
file_props.completed = False
|
||||||
file_props['disconnect_cb'] = None
|
file_props.disconnect_cb = None
|
||||||
file_props['continue_cb'] = None
|
file_props.continue_cb = None
|
||||||
file_props['syn_id'] = stanza.getID()
|
file_props.syn_id = stanza.getID()
|
||||||
file_props['fp'] = open(file_props['file-name'], 'w')
|
file_props.fp = open(file_props.file_name, 'w')
|
||||||
conn.send(rep)
|
conn.send(rep)
|
||||||
|
|
||||||
def OpenStream(self, sid, to, fp, blocksize=4096):
|
def OpenStream(self, sid, to, fp, blocksize=4096):
|
||||||
|
@ -837,62 +817,59 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
Take into account that recommended stanza size is 4k and IBB uses
|
Take into account that recommended stanza size is 4k and IBB uses
|
||||||
base64 encoding that increases size of data by 1/3.
|
base64 encoding that increases size of data by 1/3.
|
||||||
"""
|
"""
|
||||||
if sid not in self.files_props.keys():
|
|
||||||
return
|
|
||||||
if not xmpp.JID(to).getResource():
|
if not xmpp.JID(to).getResource():
|
||||||
return
|
return
|
||||||
self.files_props[sid]['direction'] = '|>' + to
|
file_props = FilesProp.getFilePropBySid(sid)
|
||||||
self.files_props[sid]['block-size'] = blocksize
|
file_props.direction = '|>' + to
|
||||||
self.files_props[sid]['fp'] = fp
|
file_props.block_size = blocksize
|
||||||
self.files_props[sid]['seq'] = 0
|
file_props.fp = fp
|
||||||
self.files_props[sid]['error'] = 0
|
file_props.seq = 0
|
||||||
self.files_props[sid]['paused'] = False
|
file_props.error = 0
|
||||||
self.files_props[sid]['received-len'] = 0
|
file_props.paused = False
|
||||||
self.files_props[sid]['last-time'] = time.time()
|
file_props.received_len = 0
|
||||||
self.files_props[sid]['connected'] = True
|
file_props.last_time = time.time()
|
||||||
self.files_props[sid]['completed'] = False
|
file_props.connected = True
|
||||||
self.files_props[sid]['disconnect_cb'] = None
|
file_props.completed = False
|
||||||
self.files_props[sid]['continue_cb'] = None
|
file_props.disconnect_cb = None
|
||||||
|
file_props.continue_cb = None
|
||||||
syn = xmpp.Protocol('iq', to, 'set', payload=[xmpp.Node(xmpp.NS_IBB + \
|
syn = xmpp.Protocol('iq', to, 'set', payload=[xmpp.Node(xmpp.NS_IBB + \
|
||||||
' open', {'sid': sid, 'block-size': blocksize, 'stanza': 'iq'})])
|
' open', {'sid': sid, 'block-size': blocksize, 'stanza': 'iq'})])
|
||||||
self.connection.send(syn)
|
self.connection.send(syn)
|
||||||
self.files_props[sid]['syn_id'] = syn.getID()
|
file_props.syn_id = syn.getID()
|
||||||
return self.files_props[sid]
|
return file_props
|
||||||
|
|
||||||
def SendHandler(self):
|
def SendHandler(self):
|
||||||
"""
|
"""
|
||||||
Send next portion of data if it is time to do it. Used internally.
|
Send next portion of data if it is time to do it. Used internally.
|
||||||
"""
|
"""
|
||||||
log.debug('SendHandler called')
|
log.debug('SendHandler called')
|
||||||
if not self.files_props:
|
#pdb.set_trace()
|
||||||
return
|
for file_props in FilesProp.getAllFileProp():
|
||||||
for file_props in self.files_props.values():
|
if not file_props.direction:
|
||||||
if 'direction' not in file_props:
|
|
||||||
# it's socks5 bytestream
|
# it's socks5 bytestream
|
||||||
continue
|
continue
|
||||||
sid = file_props['sid']
|
sid = file_props.sid
|
||||||
if file_props['direction'][:2] == '|>':
|
if file_props.direction[:2] == '|>':
|
||||||
# We waitthat other part accept stream
|
# We waitthat other part accept stream
|
||||||
continue
|
continue
|
||||||
if file_props['direction'][0] == '>':
|
if file_props.direction[0] == '>':
|
||||||
if 'paused' in file_props and file_props['paused']:
|
if file_props.paused:
|
||||||
continue
|
continue
|
||||||
chunk = file_props['fp'].read(file_props['block-size'])
|
chunk = file_props.fp.read(file_props.block_size)
|
||||||
if chunk:
|
if chunk:
|
||||||
datanode = xmpp.Node(xmpp.NS_IBB + ' data', {'sid': sid,
|
datanode = xmpp.Node(xmpp.NS_IBB + ' data', {'sid': sid,
|
||||||
'seq': file_props['seq']}, base64.encodestring(chunk))
|
'seq': file_props.seq}, base64.encodestring(chunk))
|
||||||
file_props['seq'] += 1
|
file_props.seq += 1
|
||||||
file_props['started'] = True
|
file_props.started = True
|
||||||
if file_props['seq'] == 65536:
|
if file_props.seq == 65536:
|
||||||
file_props['seq'] = 0
|
file_props.seq = 0
|
||||||
self.last_sent_ibb_id = self.connection.send(xmpp.Protocol(
|
self.last_sent_ibb_id = self.connection.send(xmpp.Protocol(
|
||||||
name='iq', to=file_props['direction'][1:], typ='set',
|
name='iq', to=file_props.direction[1:], typ='set',
|
||||||
payload=[datanode]))
|
payload=[datanode]))
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
file_props['elapsed-time'] += current_time - file_props[
|
file_props.elapsed_time += current_time - file_props.last_time
|
||||||
'last-time']
|
file_props.last_time = current_time
|
||||||
file_props['last-time'] = current_time
|
file_props.received_len += len(chunk)
|
||||||
file_props['received-len'] += len(chunk)
|
|
||||||
gajim.socks5queue.progress_transfer_cb(self.name,
|
gajim.socks5queue.progress_transfer_cb(self.name,
|
||||||
file_props)
|
file_props)
|
||||||
else:
|
else:
|
||||||
|
@ -900,11 +877,12 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
# notify the local user about sucessfull send
|
# notify the local user about sucessfull send
|
||||||
# delete the local stream
|
# delete the local stream
|
||||||
self.connection.send(xmpp.Protocol('iq',
|
self.connection.send(xmpp.Protocol('iq',
|
||||||
file_props['direction'][1:], 'set',
|
file_props.direction[1:], 'set',
|
||||||
payload=[xmpp.Node(xmpp.NS_IBB + ' close',
|
payload=[xmpp.Node(xmpp.NS_IBB + ' close',
|
||||||
{'sid':sid})]))
|
{'sid':sid})]))
|
||||||
file_props['completed'] = True
|
file_props.completed = True
|
||||||
del self.files_props[sid]
|
FilesProp.deleteFileProp(file_props)
|
||||||
|
del(file_props)
|
||||||
|
|
||||||
def IBBMessageHandler(self, conn, stanza):
|
def IBBMessageHandler(self, conn, stanza):
|
||||||
"""
|
"""
|
||||||
|
@ -922,28 +900,27 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
seq = ''
|
seq = ''
|
||||||
data = ''
|
data = ''
|
||||||
err = None
|
err = None
|
||||||
if not gajim.socks5queue.get_file_props(self.name, sid):
|
file_props = FilesProp.getFileProp(self.name, sid)
|
||||||
|
if file_props is None:
|
||||||
err = xmpp.ERR_ITEM_NOT_FOUND
|
err = xmpp.ERR_ITEM_NOT_FOUND
|
||||||
else:
|
else:
|
||||||
file_props = gajim.socks5queue.get_file_props(self.name, sid)
|
|
||||||
if not data:
|
if not data:
|
||||||
err = xmpp.ERR_BAD_REQUEST
|
err = xmpp.ERR_BAD_REQUEST
|
||||||
elif seq <> file_props['seq']:
|
elif seq <> file_props.seq:
|
||||||
err = xmpp.ERR_UNEXPECTED_REQUEST
|
err = xmpp.ERR_UNEXPECTED_REQUEST
|
||||||
else:
|
else:
|
||||||
log.debug('Successfull receive sid->%s %s+%s bytes' % (sid,
|
log.debug('Successfull receive sid->%s %s+%s bytes' % (sid,
|
||||||
file_props['fp'].tell(), len(data)))
|
file_props.fp.tell(), len(data)))
|
||||||
file_props['seq'] += 1
|
file_props.seq += 1
|
||||||
file_props['started'] = True
|
file_props.started = True
|
||||||
file_props['fp'].write(data)
|
file_props.fp.write(data)
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
file_props['elapsed-time'] += current_time - file_props[
|
file_props.elapsed_time += current_time - file_props.last_time
|
||||||
'last-time']
|
file_props.last_time = current_time
|
||||||
file_props['last-time'] = current_time
|
file_props.received_len += len(data)
|
||||||
file_props['received-len'] += len(data)
|
|
||||||
gajim.socks5queue.progress_transfer_cb(self.name, file_props)
|
gajim.socks5queue.progress_transfer_cb(self.name, file_props)
|
||||||
if file_props['received-len'] >= file_props['size']:
|
if file_props.received_len >= file_props.size:
|
||||||
file_props['completed'] = True
|
file_props.completed = True
|
||||||
if err:
|
if err:
|
||||||
log.debug('Error on receive: %s' % err)
|
log.debug('Error on receive: %s' % err)
|
||||||
conn.send(xmpp.Error(xmpp.Iq(to=stanza.getFrom(),
|
conn.send(xmpp.Error(xmpp.Iq(to=stanza.getFrom(),
|
||||||
|
@ -960,19 +937,16 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
sid = stanza.getTagAttr('close', 'sid')
|
sid = stanza.getTagAttr('close', 'sid')
|
||||||
log.debug('StreamCloseHandler called sid->%s' % sid)
|
log.debug('StreamCloseHandler called sid->%s' % sid)
|
||||||
# look in sending files
|
# look in sending files
|
||||||
if sid in self.files_props.keys():
|
file_props = FilesProp.getFileProp(self.name, sid)
|
||||||
|
if file_props:
|
||||||
reply = stanza.buildReply('result')
|
reply = stanza.buildReply('result')
|
||||||
reply.delChild('close')
|
reply.delChild('close')
|
||||||
conn.send(reply)
|
conn.send(reply)
|
||||||
gajim.socks5queue.complete_transfer_cb(self.name, self.files_props[sid])
|
# look in receiving files
|
||||||
del self.files_props[sid]
|
|
||||||
# look in receiving files
|
|
||||||
elif gajim.socks5queue.get_file_props(self.name, sid):
|
|
||||||
file_props = gajim.socks5queue.get_file_props(self.name, sid)
|
|
||||||
reply = stanza.buildReply('result')
|
reply = stanza.buildReply('result')
|
||||||
reply.delChild('close')
|
reply.delChild('close')
|
||||||
conn.send(reply)
|
conn.send(reply)
|
||||||
file_props['fp'].close()
|
file_props.fp.close()
|
||||||
gajim.socks5queue.complete_transfer_cb(self.name, file_props)
|
gajim.socks5queue.complete_transfer_cb(self.name, file_props)
|
||||||
gajim.socks5queue.remove_file_props(self.name, sid)
|
gajim.socks5queue.remove_file_props(self.name, sid)
|
||||||
else:
|
else:
|
||||||
|
@ -987,21 +961,21 @@ class ConnectionIBBytestream(ConnectionBytestream):
|
||||||
"""
|
"""
|
||||||
syn_id = stanza.getID()
|
syn_id = stanza.getID()
|
||||||
log.debug('IBBAllIqHandler called syn_id->%s' % syn_id)
|
log.debug('IBBAllIqHandler called syn_id->%s' % syn_id)
|
||||||
for sid in self.files_props.keys():
|
for file_props in FilesProp.getAllFileProp():
|
||||||
file_props = self.files_props[sid]
|
if not file_props.direction:
|
||||||
if not 'direction' in file_props:
|
|
||||||
# It's socks5 bytestream
|
# It's socks5 bytestream
|
||||||
continue
|
continue
|
||||||
if file_props['syn_id'] == syn_id:
|
if file_props.syn_id == syn_id:
|
||||||
if stanza.getType() == 'error':
|
if stanza.getType() == 'error':
|
||||||
if file_props['direction'][0] == '<':
|
if file_props.direction[0] == '<':
|
||||||
conn.Event('IBB', 'ERROR ON RECEIVE', file_props)
|
conn.Event('IBB', 'ERROR ON RECEIVE', file_props)
|
||||||
else:
|
else:
|
||||||
conn.Event('IBB', 'ERROR ON SEND', file_props)
|
conn.Event('IBB', 'ERROR ON SEND', file_props)
|
||||||
del self.files_props[sid]
|
FilesProp.deleteFileProp(file_props)
|
||||||
|
del(file_props)
|
||||||
elif stanza.getType() == 'result':
|
elif stanza.getType() == 'result':
|
||||||
if file_props['direction'][0] == '|':
|
if file_props.direction[0] == '|':
|
||||||
file_props['direction'] = file_props['direction'][1:]
|
file_props.direction = file_props.direction[1:]
|
||||||
self.SendHandler()
|
self.SendHandler()
|
||||||
else:
|
else:
|
||||||
conn.send(xmpp.Error(stanza,
|
conn.send(xmpp.Error(stanza,
|
||||||
|
@ -1026,7 +1000,7 @@ class ConnectionSocks5BytestreamZeroconf(ConnectionSocks5Bytestream):
|
||||||
return gajim.get_jid_from_account(self.name)
|
return gajim.get_jid_from_account(self.name)
|
||||||
|
|
||||||
def _ft_get_receiver_jid(self, file_props):
|
def _ft_get_receiver_jid(self, file_props):
|
||||||
return file_props['receiver'].jid
|
return file_props.receiver.jid
|
||||||
|
|
||||||
def _ft_get_streamhost_jid_attr(self, streamhost):
|
def _ft_get_streamhost_jid_attr(self, streamhost):
|
||||||
return streamhost.getAttr('jid')
|
return streamhost.getAttr('jid')
|
||||||
|
|
|
@ -31,6 +31,7 @@ from common import gajim
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from socks5 import Socks5
|
from socks5 import Socks5
|
||||||
from common.xmpp.idlequeue import IdleObject
|
from common.xmpp.idlequeue import IdleObject
|
||||||
|
from common.file_props import FilesProp
|
||||||
|
|
||||||
S_INITIAL = 0
|
S_INITIAL = 0
|
||||||
S_STARTED = 1
|
S_STARTED = 1
|
||||||
|
@ -248,9 +249,10 @@ class HostTester(Socks5, IdleObject):
|
||||||
self.on_success = on_success
|
self.on_success = on_success
|
||||||
self.on_failure = on_failure
|
self.on_failure = on_failure
|
||||||
self._sock = None
|
self._sock = None
|
||||||
self.file_props = {'is_a_proxy': True,
|
self.file_props = FilesProp.getNewFileProp(jid, sid)
|
||||||
'proxy_sender': sender_jid,
|
self.file_props.is_a_proxy = True
|
||||||
'proxy_receiver': 'test@gajim.org/test2'}
|
self.file_props.proxy_sender = sender_jid
|
||||||
|
self.file_props.proxy_receiver = 'test@gajim.org/test2'
|
||||||
Socks5.__init__(self, gajim.idlequeue, host, port, None, None, None)
|
Socks5.__init__(self, gajim.idlequeue, host, port, None, None, None)
|
||||||
self.sid = sid
|
self.sid = sid
|
||||||
|
|
||||||
|
@ -367,9 +369,10 @@ class ReceiverTester(Socks5, IdleObject):
|
||||||
self.on_success = on_success
|
self.on_success = on_success
|
||||||
self.on_failure = on_failure
|
self.on_failure = on_failure
|
||||||
self._sock = None
|
self._sock = None
|
||||||
self.file_props = {'is_a_proxy': True,
|
self.file_props = FilesProp.getNewFileProp(jid, sid)
|
||||||
'proxy_sender': sender_jid,
|
self.file_props.is_a_proxy = True
|
||||||
'proxy_receiver': 'test@gajim.org/test2'}
|
self.file_props.proxy_sender = sender_jid
|
||||||
|
self.file_props.proxy_receiver = 'test@gajim.org/test2'
|
||||||
Socks5.__init__(self, gajim.idlequeue, host, port, None, None, None)
|
Socks5.__init__(self, gajim.idlequeue, host, port, None, None, None)
|
||||||
self.sid = sid
|
self.sid = sid
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ from errno import EISCONN
|
||||||
from errno import EINPROGRESS
|
from errno import EINPROGRESS
|
||||||
from errno import EAFNOSUPPORT
|
from errno import EAFNOSUPPORT
|
||||||
from xmpp.idlequeue import IdleObject
|
from xmpp.idlequeue import IdleObject
|
||||||
|
from file_props import FilesProp
|
||||||
import jingle_xtls
|
import jingle_xtls
|
||||||
|
|
||||||
if jingle_xtls.PYOPENSSL_PRESENT:
|
if jingle_xtls.PYOPENSSL_PRESENT:
|
||||||
|
@ -69,7 +69,6 @@ class SocksQueue:
|
||||||
progress_transfer_cb=None, error_cb=None):
|
progress_transfer_cb=None, error_cb=None):
|
||||||
self.connected = 0
|
self.connected = 0
|
||||||
self.readers = {}
|
self.readers = {}
|
||||||
self.files_props = {}
|
|
||||||
self.senders = {}
|
self.senders = {}
|
||||||
self.idx = 1
|
self.idx = 1
|
||||||
self.listener = None
|
self.listener = None
|
||||||
|
@ -83,58 +82,54 @@ class SocksQueue:
|
||||||
self.on_success = {} # {id: cb}
|
self.on_success = {} # {id: cb}
|
||||||
self.on_failure = {} # {id: cb}
|
self.on_failure = {} # {id: cb}
|
||||||
|
|
||||||
def start_listener(self, port, sha_str, sha_handler, fp, fingerprint=None,
|
def start_listener(self, port, sha_str, sha_handler, file_props, fingerprint=None,
|
||||||
type='sender'):
|
type='sender'):
|
||||||
"""
|
"""
|
||||||
Start waiting for incomming connections on (host, port) and do a socks5
|
Start waiting for incomming connections on (host, port) and do a socks5
|
||||||
authentication using sid for generated SHA
|
authentication using sid for generated SHA
|
||||||
"""
|
"""
|
||||||
sid = fp['sid']
|
sid = file_props.sid
|
||||||
self.type = type # It says whether we are sending or receiving
|
self.type = type # It says whether we are sending or receiving
|
||||||
self.sha_handlers[sha_str] = (sha_handler, sid)
|
self.sha_handlers[sha_str] = (sha_handler, sid)
|
||||||
if self.listener is None or self.listener.connections == []:
|
if self.listener is None or self.listener.connections == []:
|
||||||
self.listener = Socks5Listener(self.idlequeue, port, fp,
|
self.listener = Socks5Listener(self.idlequeue, port, file_props,
|
||||||
fingerprint=fingerprint)
|
fingerprint=fingerprint)
|
||||||
self.listener.queue = self
|
self.listener.queue = self
|
||||||
self.listener.bind()
|
self.listener.bind()
|
||||||
else:
|
else:
|
||||||
# There is already a listener, we update the file's information
|
# There is already a listener, we update the file's information
|
||||||
# on the new connection.
|
# on the new connection.
|
||||||
self.listener.file_props = fp
|
self.listener.file_props = file_props
|
||||||
|
|
||||||
self.connected += 1
|
self.connected += 1
|
||||||
return self.listener
|
return self.listener
|
||||||
|
|
||||||
def send_success_reply(self, file_props, streamhost):
|
def send_success_reply(self, file_props, streamhost):
|
||||||
if 'streamhost-used' in file_props and \
|
if file_props.streamhost_used == True:
|
||||||
file_props['streamhost-used'] is True:
|
for proxy in file_props.proxyhosts:
|
||||||
if 'proxyhosts' in file_props:
|
if proxy['host'] == streamhost['host']:
|
||||||
for proxy in file_props['proxyhosts']:
|
self.on_success[file_props.sid](proxy)
|
||||||
if proxy['host'] == streamhost['host']:
|
return 1
|
||||||
self.on_success[file_props['sid']](proxy)
|
|
||||||
return 1
|
|
||||||
return 0
|
return 0
|
||||||
if 'streamhosts' in file_props:
|
for host in file_props.streamhosts:
|
||||||
for host in file_props['streamhosts']:
|
if streamhost['state'] == 1:
|
||||||
if streamhost['state'] == 1:
|
return 0
|
||||||
return 0
|
streamhost['state'] = 1
|
||||||
streamhost['state'] = 1
|
self.on_success[file_props.sid](streamhost)
|
||||||
self.on_success[file_props['sid']](streamhost)
|
return 1
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def connect_to_hosts(self, account, sid, on_success=None, on_failure=None,
|
def connect_to_hosts(self, account, sid, on_success=None, on_failure=None,
|
||||||
fingerprint=None, receiving=True):
|
fingerprint=None, receiving=True):
|
||||||
self.on_success[sid] = on_success
|
self.on_success[sid] = on_success
|
||||||
self.on_failure[sid] = on_failure
|
self.on_failure[sid] = on_failure
|
||||||
file_props = self.files_props[account][sid]
|
file_props = FilesProp.getFileProp(account, sid)
|
||||||
file_props['failure_cb'] = on_failure
|
file_props.failure_cb = on_failure
|
||||||
|
|
||||||
if not file_props['streamhosts']:
|
if not file_props.streamhosts:
|
||||||
on_failure(file_props['sid'])
|
on_failure(file_props.sid)
|
||||||
|
|
||||||
# add streamhosts to the queue
|
# add streamhosts to the queue
|
||||||
for streamhost in file_props['streamhosts']:
|
for streamhost in file_props.streamhosts:
|
||||||
if 'type' in streamhost and streamhost['type'] == 'proxy':
|
if 'type' in streamhost and streamhost['type'] == 'proxy':
|
||||||
fp = None
|
fp = None
|
||||||
else:
|
else:
|
||||||
|
@ -145,16 +140,16 @@ class SocksQueue:
|
||||||
file_props, fingerprint=fp)
|
file_props, fingerprint=fp)
|
||||||
self.add_sockobj(account, socks5obj)
|
self.add_sockobj(account, socks5obj)
|
||||||
else:
|
else:
|
||||||
if 'sha_str' in file_props:
|
if file_props.sha_str:
|
||||||
idx = file_props['sha_str']
|
idx = file_props.sha_str
|
||||||
else:
|
else:
|
||||||
idx = self.idx
|
idx = self.idx
|
||||||
self.idx = self.idx + 1
|
self.idx = self.idx + 1
|
||||||
self.type = 'sender'
|
self.type = 'sender'
|
||||||
if 'type' in streamhost and streamhost['type'] == 'proxy':
|
if 'type' in streamhost and streamhost['type'] == 'proxy':
|
||||||
file_props['is_a_proxy'] = True
|
file_props.is_a_proxy = True
|
||||||
file_props['proxy_sender'] = streamhost['target']
|
file_props.proxy_sender = streamhost['target']
|
||||||
file_props['proxy_receiver'] = streamhost['initiator']
|
file_props.proxy_receiver = streamhost['initiator']
|
||||||
socks5obj = Socks5SenderClient(self.idlequeue, idx,
|
socks5obj = Socks5SenderClient(self.idlequeue, idx,
|
||||||
self, _sock=None,host=str(streamhost['host']),
|
self, _sock=None,host=str(streamhost['host']),
|
||||||
port=int(streamhost['port']),fingerprint=fp,
|
port=int(streamhost['port']),fingerprint=fp,
|
||||||
|
@ -169,7 +164,7 @@ class SocksQueue:
|
||||||
Called when there is a host connected to one of the senders's
|
Called when there is a host connected to one of the senders's
|
||||||
streamhosts. Stop other attempts for connections
|
streamhosts. Stop other attempts for connections
|
||||||
"""
|
"""
|
||||||
for host in file_props['streamhosts']:
|
for host in file_props.streamhosts:
|
||||||
if host != streamhost and 'idx' in host:
|
if host != streamhost and 'idx' in host:
|
||||||
if host['state'] == 1:
|
if host['state'] == 1:
|
||||||
# remove current
|
# remove current
|
||||||
|
@ -200,14 +195,14 @@ class SocksQueue:
|
||||||
streamhost['state'] = -1
|
streamhost['state'] = -1
|
||||||
# boolean, indicates that there are hosts, which are not tested yet
|
# boolean, indicates that there are hosts, which are not tested yet
|
||||||
unused_hosts = False
|
unused_hosts = False
|
||||||
for host in file_props['streamhosts']:
|
for host in file_props.streamhosts:
|
||||||
if 'idx' in host:
|
if 'idx' in host:
|
||||||
if host['state'] >= 0:
|
if host['state'] >= 0:
|
||||||
return
|
return
|
||||||
elif host['state'] == -2:
|
elif host['state'] == -2:
|
||||||
unused_hosts = True
|
unused_hosts = True
|
||||||
if unused_hosts:
|
if unused_hosts:
|
||||||
for host in file_props['streamhosts']:
|
for host in file_props.streamhosts:
|
||||||
if host['state'] == -2:
|
if host['state'] == -2:
|
||||||
host['state'] = 0
|
host['state'] = 0
|
||||||
# FIXME: make the sender reconnect also
|
# FIXME: make the sender reconnect also
|
||||||
|
@ -217,13 +212,13 @@ class SocksQueue:
|
||||||
host['idx'] = client.queue_idx
|
host['idx'] = client.queue_idx
|
||||||
# we still have chances to connect
|
# we still have chances to connect
|
||||||
return
|
return
|
||||||
if 'received-len' not in file_props or file_props['received-len'] == 0:
|
if file_props.received_len == 0:
|
||||||
# there are no other streamhosts and transfer hasn't started
|
# there are no other streamhosts and transfer hasn't started
|
||||||
self._connection_refused(streamhost, file_props, client.queue_idx)
|
self._connection_refused(streamhost, file_props, client.queue_idx)
|
||||||
else:
|
else:
|
||||||
# transfer stopped, it is most likely stopped from sender
|
# transfer stopped, it is most likely stopped from sender
|
||||||
client.disconnect()
|
client.disconnect()
|
||||||
file_props['error'] = -1
|
file_props.error = -1
|
||||||
self.process_result(-1, client)
|
self.process_result(-1, client)
|
||||||
|
|
||||||
def _connection_refused(self, streamhost, file_props, idx):
|
def _connection_refused(self, streamhost, file_props, idx):
|
||||||
|
@ -235,15 +230,14 @@ class SocksQueue:
|
||||||
streamhost['state'] = -1
|
streamhost['state'] = -1
|
||||||
# FIXME: should only the receiver be remove? what if we are sending?
|
# FIXME: should only the receiver be remove? what if we are sending?
|
||||||
self.remove_receiver(idx, False)
|
self.remove_receiver(idx, False)
|
||||||
if 'streamhosts' in file_props:
|
for host in file_props.streamhosts:
|
||||||
for host in file_props['streamhosts']:
|
if host['state'] != -1:
|
||||||
if host['state'] != -1:
|
return
|
||||||
return
|
|
||||||
self.readers = {}
|
self.readers = {}
|
||||||
# failure_cb exists - this means that it has never been called
|
# failure_cb exists - this means that it has never been called
|
||||||
if 'failure_cb' in file_props and file_props['failure_cb']:
|
if file_props.failure_cb:
|
||||||
file_props['failure_cb'](file_props['sid'])
|
file_props.failure_cb(file_props.sid)
|
||||||
del(file_props['failure_cb'])
|
file_props.failure_cb = None
|
||||||
|
|
||||||
def add_sockobj(self, account, sockobj, type='receiver'):
|
def add_sockobj(self, account, sockobj, type='receiver'):
|
||||||
"""
|
"""
|
||||||
|
@ -266,11 +260,11 @@ class SocksQueue:
|
||||||
return 1
|
return 1
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _add(self, sockobj, sockobjects, fp, hash):
|
def _add(self, sockobj, sockobjects, file_props, hash_):
|
||||||
'''
|
'''
|
||||||
Adds the sockobj to the current list of sockobjects
|
Adds the sockobj to the current list of sockobjects
|
||||||
'''
|
'''
|
||||||
keys = (fp['sid'], fp['name'], hash)
|
keys = (file_props.sid, file_props.name, hash_)
|
||||||
sockobjects[keys] = sockobj
|
sockobjects[keys] = sockobj
|
||||||
|
|
||||||
def result_sha(self, sha_str, idx):
|
def result_sha(self, sha_str, idx):
|
||||||
|
@ -284,21 +278,21 @@ class SocksQueue:
|
||||||
for key in self.readers.keys():
|
for key in self.readers.keys():
|
||||||
if idx in key:
|
if idx in key:
|
||||||
reader = self.readers[key]
|
reader = self.readers[key]
|
||||||
if reader.file_props['type'] != 's':
|
if reader.file_props.type_ != 's':
|
||||||
return
|
return
|
||||||
if reader.state != 5:
|
if reader.state != 5:
|
||||||
return
|
return
|
||||||
reader.state = 6
|
reader.state = 6
|
||||||
if reader.connected:
|
if reader.connected:
|
||||||
reader.file_props['error'] = 0
|
reader.file_props.error = 0
|
||||||
reader.file_props['disconnect_cb'] = reader.disconnect
|
reader.file_props.disconnect_cb = reader.disconnect
|
||||||
reader.file_props['started'] = True
|
reader.file_props.started = True
|
||||||
reader.file_props['completed'] = False
|
reader.file_props.completed = False
|
||||||
reader.file_props['paused'] = False
|
reader.file_props.paused = False
|
||||||
reader.file_props['stalled'] = False
|
reader.file_props.stalled = False
|
||||||
reader.file_props['elapsed-time'] = 0
|
reader.file_props.elapsed_time = 0
|
||||||
reader.file_props['last-time'] = self.idlequeue.current_time()
|
reader.file_props.last_time = self.idlequeue.current_time()
|
||||||
reader.file_props['received-len'] = 0
|
reader.file_props.received_len = 0
|
||||||
reader.pauses = 0
|
reader.pauses = 0
|
||||||
# start sending file to proxy
|
# start sending file to proxy
|
||||||
self.idlequeue.set_read_timeout(reader.fd, STALLED_TIMEOUT)
|
self.idlequeue.set_read_timeout(reader.fd, STALLED_TIMEOUT)
|
||||||
|
@ -314,53 +308,34 @@ class SocksQueue:
|
||||||
# Maybe it is my machine. Without this there is a KeyError
|
# Maybe it is my machine. Without this there is a KeyError
|
||||||
# traceback.
|
# traceback.
|
||||||
return
|
return
|
||||||
if file_props['name'] in key and file_props['sid'] in key \
|
if file_props.name in key and file_props.sid in key \
|
||||||
and self.senders[key].mode == mode:
|
and self.senders[key].mode == mode:
|
||||||
|
|
||||||
log.info("socks5: sending file")
|
log.info("socks5: sending file")
|
||||||
sender = self.senders[key]
|
sender = self.senders[key]
|
||||||
file_props['streamhost-used'] = True
|
file_props.streamhost_used = True
|
||||||
sender.account = account
|
sender.account = account
|
||||||
|
|
||||||
sender.file_props = file_props
|
sender.file_props = file_props
|
||||||
result = sender.send_file()
|
result = sender.send_file()
|
||||||
self.process_result(result, sender)
|
self.process_result(result, sender)
|
||||||
|
|
||||||
def add_file_props(self, account, file_props):
|
|
||||||
"""
|
|
||||||
File_prop to the dict of current file_props. It is identified by account
|
|
||||||
name and sid
|
|
||||||
"""
|
|
||||||
if file_props is None or ('sid' in file_props) is False:
|
|
||||||
return
|
|
||||||
_id = file_props['sid']
|
|
||||||
if account not in self.files_props:
|
|
||||||
self.files_props[account] = {}
|
|
||||||
self.files_props[account][_id] = file_props
|
|
||||||
|
|
||||||
def remove_file_props(self, account, sid):
|
def remove_file_props(self, account, sid):
|
||||||
if account in self.files_props:
|
fp = FilesProp.getFileProp(account, sid)
|
||||||
fl_props = self.files_props[account]
|
if not fp:
|
||||||
if sid in fl_props:
|
log.warning('trying to remove a file props that doesnt exist ' +
|
||||||
if sid in self.on_success:
|
'from account ' + str(account) + ' and sid ' + str(sid))
|
||||||
del self.on_success[sid]
|
return
|
||||||
if sid in self.on_failure:
|
if sid in self.on_success:
|
||||||
del self.on_failure[sid]
|
del self.on_success[fp.sid]
|
||||||
del(fl_props[sid])
|
if sid in self.on_failure:
|
||||||
|
del self.on_failure[fp.sid]
|
||||||
|
|
||||||
if len(self.files_props) == 0:
|
FilesProp.deleteFileProp(fp)
|
||||||
|
|
||||||
|
if len(FilesProp.getFilePropByAccount(account)) == 0:
|
||||||
self.connected = 0
|
self.connected = 0
|
||||||
|
|
||||||
def get_file_props(self, account, sid):
|
|
||||||
"""
|
|
||||||
Get fil_prop by account name and session id
|
|
||||||
"""
|
|
||||||
if account in self.files_props:
|
|
||||||
fl_props = self.files_props[account]
|
|
||||||
if sid in fl_props:
|
|
||||||
return fl_props[sid]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def isHashInSockObjs(self, sockobjs, hash):
|
def isHashInSockObjs(self, sockobjs, hash):
|
||||||
'''
|
'''
|
||||||
It tells wether there is a particular hash in sockobjs or not
|
It tells wether there is a particular hash in sockobjs or not
|
||||||
|
@ -413,8 +388,8 @@ class SocksQueue:
|
||||||
return
|
return
|
||||||
if result in (0, -1) and self.complete_transfer_cb is not None:
|
if result in (0, -1) and self.complete_transfer_cb is not None:
|
||||||
account = actor.account
|
account = actor.account
|
||||||
if account is None and 'tt_account' in actor.file_props:
|
if account is None and actor.file_props.tt_account:
|
||||||
account = actor.file_props['tt_account']
|
account = actor.file_props.tt_account
|
||||||
self.complete_transfer_cb(account, actor.file_props)
|
self.complete_transfer_cb(account, actor.file_props)
|
||||||
elif self.progress_transfer_cb is not None:
|
elif self.progress_transfer_cb is not None:
|
||||||
self.progress_transfer_cb(actor.account, actor.file_props)
|
self.progress_transfer_cb(actor.account, actor.file_props)
|
||||||
|
@ -553,9 +528,9 @@ class Socks5:
|
||||||
self._recv=self._sock.recv
|
self._recv=self._sock.recv
|
||||||
self.buff = ''
|
self.buff = ''
|
||||||
self.connected = True
|
self.connected = True
|
||||||
self.file_props['connected'] = True
|
self.file_props.connected = True
|
||||||
self.file_props['disconnect_cb'] = self.disconnect
|
self.file_props.disconnect_cb = self.disconnect
|
||||||
self.file_props['paused'] = False
|
self.file_props.paused = False
|
||||||
self.state = 1 # connected
|
self.state = 1 # connected
|
||||||
|
|
||||||
# stop all others connections to sender's streamhosts
|
# stop all others connections to sender's streamhosts
|
||||||
|
@ -567,11 +542,11 @@ class Socks5:
|
||||||
self.idlequeue.remove_timeout(self.fd)
|
self.idlequeue.remove_timeout(self.fd)
|
||||||
if self.state > 5:
|
if self.state > 5:
|
||||||
# no activity for foo seconds
|
# no activity for foo seconds
|
||||||
if self.file_props['stalled'] == False:
|
if self.file_props.stalled == False:
|
||||||
self.file_props['stalled'] = True
|
self.file_props.stalled = True
|
||||||
self.queue.process_result(-1, self)
|
self.queue.process_result(-1, self)
|
||||||
if 'received-len' not in self.file_props:
|
if not self.file_props.received_len:
|
||||||
self.file_props['received-len'] = 0
|
self.file_props.received_len = 0
|
||||||
if SEND_TIMEOUT > 0:
|
if SEND_TIMEOUT > 0:
|
||||||
self.idlequeue.set_read_timeout(self.fd, SEND_TIMEOUT)
|
self.idlequeue.set_read_timeout(self.fd, SEND_TIMEOUT)
|
||||||
else:
|
else:
|
||||||
|
@ -585,11 +560,11 @@ class Socks5:
|
||||||
def open_file_for_reading(self):
|
def open_file_for_reading(self):
|
||||||
if self.file is None:
|
if self.file is None:
|
||||||
try:
|
try:
|
||||||
self.file = open(self.file_props['file-name'], 'rb')
|
self.file = open(self.file_props.file_name, 'rb')
|
||||||
if 'offset' in self.file_props and self.file_props['offset']:
|
if self.file_props.offset:
|
||||||
self.size = self.file_props['offset']
|
self.size = self.file_props.offset
|
||||||
self.file.seek(self.size)
|
self.file.seek(self.size)
|
||||||
self.file_props['received-len'] = self.size
|
self.file_props.received_len = self.size
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
self.close_file()
|
self.close_file()
|
||||||
raise IOError, e
|
raise IOError, e
|
||||||
|
@ -608,24 +583,24 @@ class Socks5:
|
||||||
Test if file is already open and return its fd, or just open the file and
|
Test if file is already open and return its fd, or just open the file and
|
||||||
return the fd
|
return the fd
|
||||||
"""
|
"""
|
||||||
if 'fd' in self.file_props:
|
if self.file_props.fd:
|
||||||
fd = self.file_props['fd']
|
fd = self.file_props.fd
|
||||||
else:
|
else:
|
||||||
offset = 0
|
offset = 0
|
||||||
opt = 'wb'
|
opt = 'wb'
|
||||||
if 'offset' in self.file_props and self.file_props['offset']:
|
if self.file_props.offset:
|
||||||
offset = self.file_props['offset']
|
offset = self.file_props.offset
|
||||||
opt = 'ab'
|
opt = 'ab'
|
||||||
fd = open(self.file_props['file-name'], opt)
|
fd = open(self.file_props.file_name, opt)
|
||||||
self.file_props['fd'] = fd
|
self.file_props.fd = fd
|
||||||
self.file_props['elapsed-time'] = 0
|
self.file_props.elapsed_time = 0
|
||||||
self.file_props['last-time'] = self.idlequeue.current_time()
|
self.file_props.last_time = self.idlequeue.current_time()
|
||||||
self.file_props['received-len'] = offset
|
self.file_props.received_len = offset
|
||||||
return fd
|
return fd
|
||||||
|
|
||||||
def rem_fd(self, fd):
|
def rem_fd(self, fd):
|
||||||
if 'fd' in self.file_props:
|
if self.file_props.fd:
|
||||||
del(self.file_props['fd'])
|
self.file_props.fd = None
|
||||||
try:
|
try:
|
||||||
fd.close()
|
fd.close()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -674,7 +649,7 @@ class Socks5:
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
self.state = 8 # end connection
|
self.state = 8 # end connection
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.file_props['error'] = -7 # unable to read from file
|
self.file_props.error = -7 # unable to read from file
|
||||||
return -1
|
return -1
|
||||||
buff = self.file.read(MAX_BUFF_LEN)
|
buff = self.file.read(MAX_BUFF_LEN)
|
||||||
if len(buff) > 0:
|
if len(buff) > 0:
|
||||||
|
@ -690,17 +665,17 @@ class Socks5:
|
||||||
# peer stopped reading
|
# peer stopped reading
|
||||||
self.state = 8 # end connection
|
self.state = 8 # end connection
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.file_props['error'] = -1
|
self.file_props.error = -1
|
||||||
return -1
|
return -1
|
||||||
self.size += lenn
|
self.size += lenn
|
||||||
current_time = self.idlequeue.current_time()
|
current_time = self.idlequeue.current_time()
|
||||||
self.file_props['elapsed-time'] += current_time - \
|
self.file_props.elapsed_time += current_time - \
|
||||||
self.file_props['last-time']
|
self.file_props.last_time
|
||||||
self.file_props['last-time'] = current_time
|
self.file_props.last_time = current_time
|
||||||
self.file_props['received-len'] = self.size
|
self.file_props.received_len = self.size
|
||||||
if self.size >= int(self.file_props['size']):
|
if self.size >= int(self.file_props.size):
|
||||||
self.state = 8 # end connection
|
self.state = 8 # end connection
|
||||||
self.file_props['error'] = 0
|
self.file_props.error = 0
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
return -1
|
return -1
|
||||||
if lenn != len(buff):
|
if lenn != len(buff):
|
||||||
|
@ -710,7 +685,7 @@ class Socks5:
|
||||||
self.state = 7 # continue to write in the socket
|
self.state = 7 # continue to write in the socket
|
||||||
if lenn == 0:
|
if lenn == 0:
|
||||||
return None
|
return None
|
||||||
self.file_props['stalled'] = False
|
self.file_props.stalled = False
|
||||||
return lenn
|
return lenn
|
||||||
else:
|
else:
|
||||||
self.state = 8 # end connection
|
self.state = 8 # end connection
|
||||||
|
@ -722,8 +697,8 @@ class Socks5:
|
||||||
Read file contents from socket and write them to file
|
Read file contents from socket and write them to file
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self.file_props is None or ('file-name' in self.file_props) is False:
|
if self.file_props is None or not self.file_props.file_name:
|
||||||
self.file_props['error'] = -2
|
self.file_props.error = -2
|
||||||
return None
|
return None
|
||||||
fd = None
|
fd = None
|
||||||
if self.remaining_buff != '':
|
if self.remaining_buff != '':
|
||||||
|
@ -731,28 +706,28 @@ class Socks5:
|
||||||
fd = self.get_fd()
|
fd = self.get_fd()
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
self.disconnect(False)
|
self.disconnect(False)
|
||||||
self.file_props['error'] = -6 # file system error
|
self.file_props.error = -6 # file system error
|
||||||
return 0
|
return 0
|
||||||
fd.write(self.remaining_buff)
|
fd.write(self.remaining_buff)
|
||||||
lenn = len(self.remaining_buff)
|
lenn = len(self.remaining_buff)
|
||||||
current_time = self.idlequeue.current_time()
|
current_time = self.idlequeue.current_time()
|
||||||
self.file_props['elapsed-time'] += current_time - \
|
self.file_props.elapsed_time += current_time - \
|
||||||
self.file_props['last-time']
|
self.file_props.last_time
|
||||||
self.file_props['last-time'] = current_time
|
self.file_props.last_time = current_time
|
||||||
self.file_props['received-len'] += lenn
|
self.file_props.received_len += lenn
|
||||||
self.remaining_buff = ''
|
self.remaining_buff = ''
|
||||||
if self.file_props['received-len'] == int(self.file_props['size']):
|
if self.file_props.received_len == int(self.file_props.size):
|
||||||
self.rem_fd(fd)
|
self.rem_fd(fd)
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.file_props['error'] = 0
|
self.file_props.error = 0
|
||||||
self.file_props['completed'] = True
|
self.file_props.completed = True
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
fd = self.get_fd()
|
fd = self.get_fd()
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
self.disconnect(False)
|
self.disconnect(False)
|
||||||
self.file_props['error'] = -6 # file system error
|
self.file_props.error = -6 # file system error
|
||||||
return 0
|
return 0
|
||||||
try:
|
try:
|
||||||
buff = self._recv(MAX_BUFF_LEN)
|
buff = self._recv(MAX_BUFF_LEN)
|
||||||
|
@ -763,39 +738,39 @@ class Socks5:
|
||||||
except Exception:
|
except Exception:
|
||||||
buff = ''
|
buff = ''
|
||||||
current_time = self.idlequeue.current_time()
|
current_time = self.idlequeue.current_time()
|
||||||
self.file_props['elapsed-time'] += current_time - \
|
self.file_props.elapsed_time += current_time - \
|
||||||
self.file_props['last-time']
|
self.file_props.last_time
|
||||||
self.file_props['last-time'] = current_time
|
self.file_props.last_time = current_time
|
||||||
self.file_props['received-len'] += len(buff)
|
self.file_props.received_len += len(buff)
|
||||||
if len(buff) == 0:
|
if len(buff) == 0:
|
||||||
# Transfer stopped somehow:
|
# Transfer stopped somehow:
|
||||||
# reset, paused or network error
|
# reset, paused or network error
|
||||||
self.rem_fd(fd)
|
self.rem_fd(fd)
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.file_props['error'] = -1
|
self.file_props.error = -1
|
||||||
return 0
|
return 0
|
||||||
try:
|
try:
|
||||||
fd.write(buff)
|
fd.write(buff)
|
||||||
except IOError, e:
|
except IOError, e:
|
||||||
self.rem_fd(fd)
|
self.rem_fd(fd)
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.file_props['error'] = -6 # file system error
|
self.file_props.error = -6 # file system error
|
||||||
return 0
|
return 0
|
||||||
if self.file_props['received-len'] >= int(self.file_props['size']):
|
if self.file_props.received_len >= int(self.file_props.size):
|
||||||
# transfer completed
|
# transfer completed
|
||||||
self.rem_fd(fd)
|
self.rem_fd(fd)
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.file_props['error'] = 0
|
self.file_props.error = 0
|
||||||
self.file_props['completed'] = True
|
self.file_props.completed = True
|
||||||
return 0
|
return 0
|
||||||
# return number of read bytes. It can be used in progressbar
|
# return number of read bytes. It can be used in progressbar
|
||||||
if fd is not None:
|
if fd is not None:
|
||||||
self.file_props['stalled'] = False
|
self.file_props.stalled = False
|
||||||
if fd is None and self.file_props['stalled'] is False:
|
if fd is None and self.file_props.stalled is False:
|
||||||
return None
|
return None
|
||||||
if 'received-len' in self.file_props:
|
if self.file_props.received_len:
|
||||||
if self.file_props['received-len'] != 0:
|
if self.file_props.received_len != 0:
|
||||||
return self.file_props['received-len']
|
return self.file_props.received_len
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
|
@ -910,7 +885,7 @@ class Socks5:
|
||||||
def continue_paused_transfer(self):
|
def continue_paused_transfer(self):
|
||||||
if self.state < 5:
|
if self.state < 5:
|
||||||
return
|
return
|
||||||
if self.file_props['type'] == 'r':
|
if self.file_props.type_ == 'r':
|
||||||
self.idlequeue.plug_idle(self, False, True)
|
self.idlequeue.plug_idle(self, False, True)
|
||||||
else:
|
else:
|
||||||
self.idlequeue.plug_idle(self, True, False)
|
self.idlequeue.plug_idle(self, True, False)
|
||||||
|
@ -920,11 +895,11 @@ class Socks5:
|
||||||
Get sha of sid + Initiator jid + Target jid
|
Get sha of sid + Initiator jid + Target jid
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if 'is_a_proxy' in self.file_props:
|
if self.file_props.is_a_proxy:
|
||||||
del(self.file_props['is_a_proxy'])
|
self.file_props.is_a_proxy = None # Is this necesary?
|
||||||
return hashlib.sha1('%s%s%s' % (self.sid,
|
return hashlib.sha1('%s%s%s' % (self.sid,
|
||||||
self.file_props['proxy_sender'],
|
self.file_props.proxy_sender,
|
||||||
self.file_props['proxy_receiver'])).hexdigest()
|
self.file_props.proxy_receiver)).hexdigest()
|
||||||
return hashlib.sha1('%s%s%s' % (self.sid, self.initiator, self.target)).\
|
return hashlib.sha1('%s%s%s' % (self.sid, self.initiator, self.target)).\
|
||||||
hexdigest()
|
hexdigest()
|
||||||
|
|
||||||
|
@ -961,17 +936,17 @@ class Socks5Sender(IdleObject):
|
||||||
self.state = 1 # waiting for first bytes
|
self.state = 1 # waiting for first bytes
|
||||||
self.connect_timeout = 0
|
self.connect_timeout = 0
|
||||||
|
|
||||||
self.file_props['error'] = 0
|
self.file_props.error = 0
|
||||||
self.file_props['disconnect_cb'] = self.disconnect
|
self.file_props.disconnect_cb = self.disconnect
|
||||||
self.file_props['started'] = True
|
self.file_props.started = True
|
||||||
self.file_props['completed'] = False
|
self.file_props.completed = False
|
||||||
self.file_props['paused'] = False
|
self.file_props.paused = False
|
||||||
self.file_props['continue_cb'] = self.continue_paused_transfer
|
self.file_props.continue_cb = self.continue_paused_transfer
|
||||||
self.file_props['stalled'] = False
|
self.file_props.stalled = False
|
||||||
self.file_props['connected'] = True
|
self.file_props.connected = True
|
||||||
self.file_props['elapsed-time'] = 0
|
self.file_props.elapsed_time = 0
|
||||||
self.file_props['last-time'] = self.idlequeue.current_time()
|
self.file_props.last_time = self.idlequeue.current_time()
|
||||||
self.file_props['received-len'] = 0
|
self.file_props.received_len = 0
|
||||||
self.type = 'sender'
|
self.type = 'sender'
|
||||||
|
|
||||||
def start_transfer(self):
|
def start_transfer(self):
|
||||||
|
@ -1018,8 +993,8 @@ class Socks5Sender(IdleObject):
|
||||||
# close connection and remove us from the queue
|
# close connection and remove us from the queue
|
||||||
Socks5.disconnect(self)
|
Socks5.disconnect(self)
|
||||||
if self.file_props is not None:
|
if self.file_props is not None:
|
||||||
self.file_props['connected'] = False
|
self.file_props.connected = False
|
||||||
self.file_props['disconnect_cb'] = None
|
self.file_props.disconnect_cb = None
|
||||||
if self.queue is not None:
|
if self.queue is not None:
|
||||||
self.queue.remove_sender(self.queue_idx, False)
|
self.queue.remove_sender(self.queue_idx, False)
|
||||||
|
|
||||||
|
@ -1039,33 +1014,33 @@ class Socks5Receiver(IdleObject):
|
||||||
self.connected = False
|
self.connected = False
|
||||||
self.pauses = 0
|
self.pauses = 0
|
||||||
self.file_props = file_props
|
self.file_props = file_props
|
||||||
self.file_props['disconnect_cb'] = self.disconnect
|
self.file_props.disconnect_cb = self.disconnect
|
||||||
self.file_props['error'] = 0
|
self.file_props.error = 0
|
||||||
self.file_props['started'] = True
|
self.file_props.started = True
|
||||||
self.file_props['completed'] = False
|
self.file_props.completed = False
|
||||||
self.file_props['paused'] = False
|
self.file_props.paused = False
|
||||||
self.file_props['continue_cb'] = self.continue_paused_transfer
|
self.file_props.continue_cb = self.continue_paused_transfer
|
||||||
self.file_props['stalled'] = False
|
self.file_props.stalled = False
|
||||||
self.file_props['received-len'] = 0
|
self.file_props.received_len = 0
|
||||||
|
|
||||||
|
|
||||||
def receive_file(self):
|
def receive_file(self):
|
||||||
"""
|
"""
|
||||||
Start receiving the file over verified connection
|
Start receiving the file over verified connection
|
||||||
"""
|
"""
|
||||||
if self.file_props['started']:
|
if self.file_props.started:
|
||||||
return
|
return
|
||||||
self.file_props['error'] = 0
|
self.file_props.error = 0
|
||||||
self.file_props['disconnect_cb'] = self.disconnect
|
self.file_props.disconnect_cb = self.disconnect
|
||||||
self.file_props['started'] = True
|
self.file_props.started = True
|
||||||
self.file_props['completed'] = False
|
self.file_props.completed = False
|
||||||
self.file_props['paused'] = False
|
self.file_props.paused = False
|
||||||
self.file_props['continue_cb'] = self.continue_paused_transfer
|
self.file_props.continue_cb = self.continue_paused_transfer
|
||||||
self.file_props['stalled'] = False
|
self.file_props.stalled = False
|
||||||
self.file_props['connected'] = True
|
self.file_props.connected = True
|
||||||
self.file_props['elapsed-time'] = 0
|
self.file_props.elapsed_time = 0
|
||||||
self.file_props['last-time'] = self.idlequeue.current_time()
|
self.file_props.last_time = self.idlequeue.current_time()
|
||||||
self.file_props['received-len'] = 0
|
self.file_props.received_len = 0
|
||||||
self.pauses = 0
|
self.pauses = 0
|
||||||
self.state = 7
|
self.state = 7
|
||||||
# plug for reading
|
# plug for reading
|
||||||
|
@ -1096,7 +1071,7 @@ class Socks5Receiver(IdleObject):
|
||||||
# close connection
|
# close connection
|
||||||
Socks5.disconnect(self)
|
Socks5.disconnect(self)
|
||||||
if cb is True:
|
if cb is True:
|
||||||
self.file_props['disconnect_cb'] = None
|
self.file_props.disconnect_cb = None
|
||||||
if self.queue is not None:
|
if self.queue is not None:
|
||||||
self.queue.remove_receiver(self.queue_idx, False)
|
self.queue.remove_receiver(self.queue_idx, False)
|
||||||
|
|
||||||
|
@ -1152,8 +1127,8 @@ class Socks5Server(Socks5):
|
||||||
return
|
return
|
||||||
|
|
||||||
elif self.state == 7:
|
elif self.state == 7:
|
||||||
if self.file_props['paused']:
|
if self.file_props.paused:
|
||||||
self.file_props['continue_cb'] = self.continue_paused_transfer
|
self.file_props.continue_cb = self.continue_paused_transfer
|
||||||
self.idlequeue.plug_idle(self, False, False)
|
self.idlequeue.plug_idle(self, False, False)
|
||||||
return
|
return
|
||||||
self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
|
self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
|
||||||
|
@ -1169,7 +1144,7 @@ class Socks5Server(Socks5):
|
||||||
def pollend(self):
|
def pollend(self):
|
||||||
self.state = 8 # end connection
|
self.state = 8 # end connection
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.file_props['error'] = -1
|
self.file_props.error = -1
|
||||||
self.queue.process_result(-1, self)
|
self.queue.process_result(-1, self)
|
||||||
|
|
||||||
def pollout(self):
|
def pollout(self):
|
||||||
|
@ -1182,8 +1157,8 @@ class Socks5Server(Socks5):
|
||||||
elif self.state == 4: # send positive response to the 'connect'
|
elif self.state == 4: # send positive response to the 'connect'
|
||||||
self.send_raw(self._get_request_buff(self.sha_msg, 0x00))
|
self.send_raw(self._get_request_buff(self.sha_msg, 0x00))
|
||||||
elif self.state == 7:
|
elif self.state == 7:
|
||||||
if self.file_props['paused']:
|
if self.file_props.paused:
|
||||||
self.file_props['continue_cb'] = self.continue_paused_transfer
|
self.file_props.continue_cb = self.continue_paused_transfer
|
||||||
self.idlequeue.plug_idle(self, False, False)
|
self.idlequeue.plug_idle(self, False, False)
|
||||||
return
|
return
|
||||||
result = self.start_transfer() # send
|
result = self.start_transfer() # send
|
||||||
|
@ -1262,16 +1237,16 @@ class Socks5Client(Socks5):
|
||||||
|
|
||||||
# for senders: init file_props
|
# for senders: init file_props
|
||||||
if result == 1 and self.state == 5:
|
if result == 1 and self.state == 5:
|
||||||
if self.file_props['type'] == 's':
|
if self.file_props.type_ == 's':
|
||||||
self.file_props['error'] = 0
|
self.file_props.error = 0
|
||||||
self.file_props['disconnect_cb'] = self.disconnect
|
self.file_props.disconnect_cb = self.disconnect
|
||||||
self.file_props['started'] = True
|
self.file_props.started = True
|
||||||
self.file_props['completed'] = False
|
self.file_props.completed = False
|
||||||
self.file_props['paused'] = False
|
self.file_props.paused = False
|
||||||
self.file_props['stalled'] = False
|
self.file_props.stalled = False
|
||||||
self.file_props['elapsed-time'] = 0
|
self.file_props.elapsed_time = 0
|
||||||
self.file_props['last-time'] = self.idlequeue.current_time()
|
self.file_props.last_time = self.idlequeue.current_time()
|
||||||
self.file_props['received-len'] = 0
|
self.file_props.received_len = 0
|
||||||
self.pauses = 0
|
self.pauses = 0
|
||||||
# start sending file contents to socket
|
# start sending file contents to socket
|
||||||
#self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
|
#self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
|
||||||
|
@ -1281,7 +1256,7 @@ class Socks5Client(Socks5):
|
||||||
# receiving file contents from socket
|
# receiving file contents from socket
|
||||||
self.idlequeue.plug_idle(self, False, True)
|
self.idlequeue.plug_idle(self, False, True)
|
||||||
|
|
||||||
self.file_props['continue_cb'] = self.continue_paused_transfer
|
self.file_props.continue_cb = self.continue_paused_transfer
|
||||||
# we have set up the connection, next - retrieve file
|
# we have set up the connection, next - retrieve file
|
||||||
self.state = 6
|
self.state = 6
|
||||||
if self.state < 5:
|
if self.state < 5:
|
||||||
|
@ -1294,7 +1269,7 @@ class Socks5Client(Socks5):
|
||||||
self.idlequeue.remove_timeout(self.fd)
|
self.idlequeue.remove_timeout(self.fd)
|
||||||
if self.connected:
|
if self.connected:
|
||||||
try:
|
try:
|
||||||
if self.file_props['paused']:
|
if self.file_props.paused:
|
||||||
self.idlequeue.plug_idle(self, False, False)
|
self.idlequeue.plug_idle(self, False, False)
|
||||||
return
|
return
|
||||||
if self.state < 5:
|
if self.state < 5:
|
||||||
|
@ -1303,7 +1278,7 @@ class Socks5Client(Socks5):
|
||||||
self.queue.process_result(result, self)
|
self.queue.process_result(result, self)
|
||||||
elif self.state == 5: # wait for proxy reply
|
elif self.state == 5: # wait for proxy reply
|
||||||
pass
|
pass
|
||||||
elif self.file_props['type'] == 'r':
|
elif self.file_props.type_ == 'r':
|
||||||
self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
|
self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT)
|
||||||
result = self.start_transfer() # receive
|
result = self.start_transfer() # receive
|
||||||
self.queue.process_result(result, self)
|
self.queue.process_result(result, self)
|
||||||
|
@ -1324,8 +1299,8 @@ class Socks5Client(Socks5):
|
||||||
self.send_raw(self._get_auth_buff())
|
self.send_raw(self._get_auth_buff())
|
||||||
elif self.state == 3: # send 'connect' request
|
elif self.state == 3: # send 'connect' request
|
||||||
self.send_raw(self._get_request_buff(self._get_sha1_auth()))
|
self.send_raw(self._get_request_buff(self._get_sha1_auth()))
|
||||||
elif self.file_props['type'] != 'r':
|
elif self.file_props.type_ != 'r':
|
||||||
if self.file_props['paused']:
|
if self.file_props.paused:
|
||||||
self.idlequeue.plug_idle(self, False, False)
|
self.idlequeue.plug_idle(self, False, False)
|
||||||
return
|
return
|
||||||
result = self.start_transfer() # send
|
result = self.start_transfer() # send
|
||||||
|
@ -1344,7 +1319,7 @@ class Socks5Client(Socks5):
|
||||||
if self.state >= 5:
|
if self.state >= 5:
|
||||||
# error during transfer
|
# error during transfer
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.file_props['error'] = -1
|
self.file_props.error = -1
|
||||||
self.queue.process_result(-1, self)
|
self.queue.process_result(-1, self)
|
||||||
else:
|
else:
|
||||||
self.queue.reconnect_client(self, self.streamhost)
|
self.queue.reconnect_client(self, self.streamhost)
|
||||||
|
@ -1357,7 +1332,7 @@ class Socks5SenderClient(Socks5Client, Socks5Sender):
|
||||||
port=None, fingerprint = None, connected=True, file_props={}):
|
port=None, fingerprint = None, connected=True, file_props={}):
|
||||||
|
|
||||||
Socks5Client.__init__(self, idlequeue, host, port, None, None,
|
Socks5Client.__init__(self, idlequeue, host, port, None, None,
|
||||||
file_props['sid'])
|
file_props.sid)
|
||||||
|
|
||||||
Socks5Sender.__init__(self,idlequeue, sock_hash, parent,_sock,
|
Socks5Sender.__init__(self,idlequeue, sock_hash, parent,_sock,
|
||||||
host, port, fingerprint , connected, file_props)
|
host, port, fingerprint , connected, file_props)
|
||||||
|
@ -1372,7 +1347,7 @@ class Socks5SenderServer(Socks5Server, Socks5Sender):
|
||||||
port=None, fingerprint = None, connected=True, file_props={}):
|
port=None, fingerprint = None, connected=True, file_props={}):
|
||||||
|
|
||||||
Socks5Server.__init__(self, idlequeue, host, port, None, None,
|
Socks5Server.__init__(self, idlequeue, host, port, None, None,
|
||||||
file_props['sid'])
|
file_props.sid)
|
||||||
|
|
||||||
Socks5Sender.__init__(self,idlequeue, sock_hash, parent, _sock,
|
Socks5Sender.__init__(self,idlequeue, sock_hash, parent, _sock,
|
||||||
host, port, fingerprint , connected, file_props)
|
host, port, fingerprint , connected, file_props)
|
||||||
|
|
|
@ -33,6 +33,7 @@ import dialogs
|
||||||
|
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import helpers
|
from common import helpers
|
||||||
|
from common.file_props import FilesProp
|
||||||
from common.protocol.bytestream import (is_transfer_active, is_transfer_paused,
|
from common.protocol.bytestream import (is_transfer_active, is_transfer_paused,
|
||||||
is_transfer_stopped)
|
is_transfer_stopped)
|
||||||
from common.xmpp.protocol import NS_JINGLE_FILE_TRANSFER
|
from common.xmpp.protocol import NS_JINGLE_FILE_TRANSFER
|
||||||
|
@ -147,22 +148,20 @@ class FileTransfersWindow:
|
||||||
Find all transfers with peer 'jid' that belong to 'account'
|
Find all transfers with peer 'jid' that belong to 'account'
|
||||||
"""
|
"""
|
||||||
active_transfers = [[], []] # ['senders', 'receivers']
|
active_transfers = [[], []] # ['senders', 'receivers']
|
||||||
|
allfp = FilesProp.getAllFileProp()
|
||||||
# 'account' is the sender
|
for file_props in allfp:
|
||||||
for file_props in self.files_props['s'].values():
|
if file_props.type_ == 's' and file_props.tt_account == account:
|
||||||
if file_props['tt_account'] == account:
|
# 'account' is the sender
|
||||||
receiver_jid = unicode(file_props['receiver']).split('/')[0]
|
receiver_jid = unicode(file_props.receiver).split('/')[0]
|
||||||
if jid == receiver_jid:
|
if jid == receiver_jid and not is_transfer_stopped(file_props):
|
||||||
if not is_transfer_stopped(file_props):
|
active_transfers[0].append(file_props)
|
||||||
active_transfers[0].append(file_props)
|
elif file_props.type_ == 'r' and file_props.tt_account == account:
|
||||||
|
# 'account' is the recipient
|
||||||
# 'account' is the recipient
|
sender_jid = unicode(file_props.sender).split('/')[0]
|
||||||
for file_props in self.files_props['r'].values():
|
if jid == sender_jid and not is_transfer_stopped(file_props):
|
||||||
if file_props['tt_account'] == account:
|
active_transfers[1].append(file_props)
|
||||||
sender_jid = unicode(file_props['sender']).split('/')[0]
|
else:
|
||||||
if jid == sender_jid:
|
raise Exception('file_props has no type')
|
||||||
if not is_transfer_stopped(file_props):
|
|
||||||
active_transfers[1].append(file_props)
|
|
||||||
return active_transfers
|
return active_transfers
|
||||||
|
|
||||||
def show_completed(self, jid, file_props):
|
def show_completed(self, jid, file_props):
|
||||||
|
@ -171,46 +170,46 @@ class FileTransfersWindow:
|
||||||
"""
|
"""
|
||||||
def on_open(widget, file_props):
|
def on_open(widget, file_props):
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
if 'file-name' not in file_props:
|
if not file_props.file_name:
|
||||||
return
|
return
|
||||||
path = os.path.split(file_props['file-name'])[0]
|
path = os.path.split(file_props.file_name)[0]
|
||||||
if os.path.exists(path) and os.path.isdir(path):
|
if os.path.exists(path) and os.path.isdir(path):
|
||||||
helpers.launch_file_manager(path)
|
helpers.launch_file_manager(path)
|
||||||
self.tree.get_selection().unselect_all()
|
self.tree.get_selection().unselect_all()
|
||||||
|
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
# file path is used below in 'Save in'
|
# file path is used below in 'Save in'
|
||||||
(file_path, file_name) = os.path.split(file_props['file-name'])
|
(file_path, file_name) = os.path.split(file_props.file_name)
|
||||||
else:
|
else:
|
||||||
file_name = file_props['name']
|
file_name = file_props.name
|
||||||
sectext = '\t' + _('Filename: %s') % gobject.markup_escape_text(
|
sectext = '\t' + _('Filename: %s') % gobject.markup_escape_text(
|
||||||
file_name)
|
file_name)
|
||||||
sectext += '\n\t' + _('Size: %s') % \
|
sectext += '\n\t' + _('Size: %s') % \
|
||||||
helpers.convert_bytes(file_props['size'])
|
helpers.convert_bytes(file_props.size)
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
jid = unicode(file_props['sender']).split('/')[0]
|
jid = unicode(file_props.sender).split('/')[0]
|
||||||
sender_name = gajim.contacts.get_first_contact_from_jid(
|
sender_name = gajim.contacts.get_first_contact_from_jid(
|
||||||
file_props['tt_account'], jid).get_shown_name()
|
file_props.tt_account, jid).get_shown_name()
|
||||||
sender = sender_name
|
sender = sender_name
|
||||||
else:
|
else:
|
||||||
#You is a reply of who sent a file
|
#You is a reply of who sent a file
|
||||||
sender = _('You')
|
sender = _('You')
|
||||||
sectext += '\n\t' + _('Sender: %s') % sender
|
sectext += '\n\t' + _('Sender: %s') % sender
|
||||||
sectext += '\n\t' + _('Recipient: ')
|
sectext += '\n\t' + _('Recipient: ')
|
||||||
if file_props['type'] == 's':
|
if file_props.type_ == 's':
|
||||||
jid = unicode(file_props['receiver']).split('/')[0]
|
jid = unicode(file_props.receiver).split('/')[0]
|
||||||
receiver_name = gajim.contacts.get_first_contact_from_jid(
|
receiver_name = gajim.contacts.get_first_contact_from_jid(
|
||||||
file_props['tt_account'], jid).get_shown_name()
|
file_props.tt_account, jid).get_shown_name()
|
||||||
recipient = receiver_name
|
recipient = receiver_name
|
||||||
else:
|
else:
|
||||||
#You is a reply of who received a file
|
#You is a reply of who received a file
|
||||||
recipient = _('You')
|
recipient = _('You')
|
||||||
sectext += recipient
|
sectext += recipient
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
sectext += '\n\t' + _('Saved in: %s') % file_path
|
sectext += '\n\t' + _('Saved in: %s') % file_path
|
||||||
dialog = dialogs.HigDialog(None, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE,
|
dialog = dialogs.HigDialog(None, gtk.MESSAGE_INFO, gtk.BUTTONS_NONE,
|
||||||
_('File transfer completed'), sectext)
|
_('File transfer completed'), sectext)
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
button = gtk.Button(_('_Open Containing Folder'))
|
button = gtk.Button(_('_Open Containing Folder'))
|
||||||
button.connect('clicked', on_open, file_props)
|
button.connect('clicked', on_open, file_props)
|
||||||
dialog.action_area.pack_start(button)
|
dialog.action_area.pack_start(button)
|
||||||
|
@ -236,10 +235,10 @@ class FileTransfersWindow:
|
||||||
self.tree.get_selection().unselect_all()
|
self.tree.get_selection().unselect_all()
|
||||||
|
|
||||||
def show_stopped(self, jid, file_props, error_msg=''):
|
def show_stopped(self, jid, file_props, error_msg=''):
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
file_name = os.path.basename(file_props['file-name'])
|
file_name = os.path.basename(file_props.file_name)
|
||||||
else:
|
else:
|
||||||
file_name = file_props['name']
|
file_name = file_props.name
|
||||||
sectext = '\t' + _('Filename: %s') % gobject.markup_escape_text(
|
sectext = '\t' + _('Filename: %s') % gobject.markup_escape_text(
|
||||||
file_name)
|
file_name)
|
||||||
sectext += '\n\t' + _('Recipient: %s') % jid
|
sectext += '\n\t' + _('Recipient: %s') % jid
|
||||||
|
@ -254,13 +253,13 @@ class FileTransfersWindow:
|
||||||
sid = gajim.connections[account].start_file_transfer(jid,
|
sid = gajim.connections[account].start_file_transfer(jid,
|
||||||
file_props,
|
file_props,
|
||||||
True)
|
True)
|
||||||
file_props['sid'] = sid
|
file_props.sid = sid
|
||||||
|
|
||||||
|
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
file_name = os.path.basename(file_props['file-name'])
|
file_name = os.path.basename(file_props.file_name)
|
||||||
else:
|
else:
|
||||||
file_name = file_props['name']
|
file_name = file_props.name
|
||||||
dialogs.YesNoDialog(('File transfer error'),
|
dialogs.YesNoDialog(('File transfer error'),
|
||||||
_('The file %(file)s has been fully received, but it seems to be '
|
_('The file %(file)s has been fully received, but it seems to be '
|
||||||
'wrongly received.\nDo you want to reload it?') % \
|
'wrongly received.\nDo you want to reload it?') % \
|
||||||
|
@ -339,10 +338,8 @@ class FileTransfersWindow:
|
||||||
return False
|
return False
|
||||||
if contact.supports(NS_JINGLE_FILE_TRANSFER):
|
if contact.supports(NS_JINGLE_FILE_TRANSFER):
|
||||||
log.info("contact %s supports jingle file transfer"%(contact.get_full_jid()))
|
log.info("contact %s supports jingle file transfer"%(contact.get_full_jid()))
|
||||||
# this call has the side effect of setting file_props['sid'] to the jingle sid, but for the sake of clarity
|
gajim.connections[account].start_file_transfer(contact.get_full_jid(),
|
||||||
# make it explicit here
|
file_props)
|
||||||
sid = gajim.connections[account].start_file_transfer(contact.get_full_jid(), file_props)
|
|
||||||
file_props['sid'] = sid
|
|
||||||
self.add_transfer(account, contact, file_props)
|
self.add_transfer(account, contact, file_props)
|
||||||
else:
|
else:
|
||||||
log.info("contact does not support jingle file transfer")
|
log.info("contact does not support jingle file transfer")
|
||||||
|
@ -354,7 +351,8 @@ class FileTransfersWindow:
|
||||||
file_dir = os.path.dirname(file_path)
|
file_dir = os.path.dirname(file_path)
|
||||||
if file_dir:
|
if file_dir:
|
||||||
gajim.config.set('last_save_dir', file_dir)
|
gajim.config.set('last_save_dir', file_dir)
|
||||||
file_props['file-name'] = file_path
|
file_props.file_name = file_path
|
||||||
|
file_props.type_ = 'r'
|
||||||
self.add_transfer(account, contact, file_props)
|
self.add_transfer(account, contact, file_props)
|
||||||
gajim.connections[account].send_file_approval(file_props)
|
gajim.connections[account].send_file_approval(file_props)
|
||||||
|
|
||||||
|
@ -375,14 +373,14 @@ class FileTransfersWindow:
|
||||||
return
|
return
|
||||||
stat = os.stat(file_path)
|
stat = os.stat(file_path)
|
||||||
dl_size = stat.st_size
|
dl_size = stat.st_size
|
||||||
file_size = file_props['size']
|
file_size = file_props.size
|
||||||
dl_finished = dl_size >= file_size
|
dl_finished = dl_size >= file_size
|
||||||
|
|
||||||
def on_response(response):
|
def on_response(response):
|
||||||
if response < 0:
|
if response < 0:
|
||||||
return
|
return
|
||||||
elif response == 100:
|
elif response == 100:
|
||||||
file_props['offset'] = dl_size
|
file_props.offset = dl_size
|
||||||
dialog2.destroy()
|
dialog2.destroy()
|
||||||
self._start_receive(file_path, account, contact, file_props)
|
self._start_receive(file_path, account, contact, file_props)
|
||||||
|
|
||||||
|
@ -419,7 +417,7 @@ class FileTransfersWindow:
|
||||||
on_response_ok=(on_ok, account, contact, file_props),
|
on_response_ok=(on_ok, account, contact, file_props),
|
||||||
on_response_cancel=(on_cancel, account, contact, file_props))
|
on_response_cancel=(on_cancel, account, contact, file_props))
|
||||||
|
|
||||||
dialog2.set_current_name(file_props['name'])
|
dialog2.set_current_name(file_props.name)
|
||||||
dialog2.connect('delete-event', lambda widget, event:
|
dialog2.connect('delete-event', lambda widget, event:
|
||||||
on_cancel(widget, account, contact, file_props))
|
on_cancel(widget, account, contact, file_props))
|
||||||
|
|
||||||
|
@ -428,17 +426,17 @@ class FileTransfersWindow:
|
||||||
Show dialog asking for comfirmation and store location of new file
|
Show dialog asking for comfirmation and store location of new file
|
||||||
requested by a contact
|
requested by a contact
|
||||||
"""
|
"""
|
||||||
if file_props is None or 'name' not in file_props:
|
if not file_props or not file_props.name:
|
||||||
return
|
return
|
||||||
sec_text = '\t' + _('File: %s') % gobject.markup_escape_text(
|
sec_text = '\t' + _('File: %s') % gobject.markup_escape_text(
|
||||||
file_props['name'])
|
file_props.name)
|
||||||
if 'size' in file_props:
|
if file_props.size:
|
||||||
sec_text += '\n\t' + _('Size: %s') % \
|
sec_text += '\n\t' + _('Size: %s') % \
|
||||||
helpers.convert_bytes(file_props['size'])
|
helpers.convert_bytes(file_props.size)
|
||||||
if 'mime-type' in file_props:
|
if file_props.mime_type:
|
||||||
sec_text += '\n\t' + _('Type: %s') % file_props['mime-type']
|
sec_text += '\n\t' + _('Type: %s') % file_props.mime_type
|
||||||
if 'desc' in file_props:
|
if file_props.desc:
|
||||||
sec_text += '\n\t' + _('Description: %s') % file_props['desc']
|
sec_text += '\n\t' + _('Description: %s') % file_props.desc
|
||||||
prim_text = _('%s wants to send you a file:') % contact.jid
|
prim_text = _('%s wants to send you a file:') % contact.jid
|
||||||
dialog = None
|
dialog = None
|
||||||
|
|
||||||
|
@ -459,22 +457,21 @@ class FileTransfersWindow:
|
||||||
return self.images.setdefault(ident,
|
return self.images.setdefault(ident,
|
||||||
self.window.render_icon(self.icons[ident], gtk.ICON_SIZE_MENU))
|
self.window.render_icon(self.icons[ident], gtk.ICON_SIZE_MENU))
|
||||||
|
|
||||||
def set_status(self, typ, sid, status):
|
def set_status(self,file_props, status):
|
||||||
"""
|
"""
|
||||||
Change the status of a transfer to state 'status'
|
Change the status of a transfer to state 'status'
|
||||||
"""
|
"""
|
||||||
iter_ = self.get_iter_by_sid(typ, sid)
|
iter_ = self.get_iter_by_sid(file_props.type_, file_props.sid)
|
||||||
if iter_ is None:
|
if iter_ is None:
|
||||||
return
|
return
|
||||||
sid = self.model[iter_][C_SID].decode('utf-8')
|
self.model[iter_][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
|
||||||
if status == 'stop':
|
if status == 'stop':
|
||||||
file_props['stopped'] = True
|
file_props.stopped = True
|
||||||
elif status == 'ok':
|
elif status == 'ok':
|
||||||
file_props['completed'] = True
|
file_props.completed = True
|
||||||
text = self._format_percent(100)
|
text = self._format_percent(100)
|
||||||
received_size = int(file_props['received-len'])
|
received_size = int(file_props.received_len)
|
||||||
full_size = int(file_props['size'])
|
full_size = int(file_props.size)
|
||||||
text += helpers.convert_bytes(received_size) + '/' + \
|
text += helpers.convert_bytes(received_size) + '/' + \
|
||||||
helpers.convert_bytes(full_size)
|
helpers.convert_bytes(full_size)
|
||||||
self.model.set(iter_, C_PROGRESS, text)
|
self.model.set(iter_, C_PROGRESS, text)
|
||||||
|
@ -482,8 +479,8 @@ class FileTransfersWindow:
|
||||||
elif status == 'computing':
|
elif status == 'computing':
|
||||||
self.model.set(iter_, C_PULSE, 1)
|
self.model.set(iter_, C_PULSE, 1)
|
||||||
text = _('Checking file...') + '\n'
|
text = _('Checking file...') + '\n'
|
||||||
received_size = int(file_props['received-len'])
|
received_size = int(file_props.received_len)
|
||||||
full_size = int(file_props['size'])
|
full_size = int(file_props.size)
|
||||||
text += helpers.convert_bytes(received_size) + '/' + \
|
text += helpers.convert_bytes(received_size) + '/' + \
|
||||||
helpers.convert_bytes(full_size)
|
helpers.convert_bytes(full_size)
|
||||||
self.model.set(iter_, C_PROGRESS, text)
|
self.model.set(iter_, C_PROGRESS, text)
|
||||||
|
@ -496,8 +493,8 @@ class FileTransfersWindow:
|
||||||
gobject.timeout_add(100, pulse)
|
gobject.timeout_add(100, pulse)
|
||||||
elif status == 'hash_error':
|
elif status == 'hash_error':
|
||||||
text = _('File error') + '\n'
|
text = _('File error') + '\n'
|
||||||
received_size = int(file_props['received-len'])
|
received_size = int(file_props.received_len)
|
||||||
full_size = int(file_props['size'])
|
full_size = int(file_props.size)
|
||||||
text += helpers.convert_bytes(received_size) + '/' + \
|
text += helpers.convert_bytes(received_size) + '/' + \
|
||||||
helpers.convert_bytes(full_size)
|
helpers.convert_bytes(full_size)
|
||||||
self.model.set(iter_, C_PROGRESS, text)
|
self.model.set(iter_, C_PROGRESS, text)
|
||||||
|
@ -535,14 +532,14 @@ class FileTransfersWindow:
|
||||||
return _('%(hours)02.d:%(minutes)02.d:%(seconds)02.d') % times
|
return _('%(hours)02.d:%(minutes)02.d:%(seconds)02.d') % times
|
||||||
|
|
||||||
def _get_eta_and_speed(self, full_size, transfered_size, file_props):
|
def _get_eta_and_speed(self, full_size, transfered_size, file_props):
|
||||||
if len(file_props['transfered_size']) == 0:
|
if len(file_props.transfered_size) == 0:
|
||||||
return 0., 0.
|
return 0., 0.
|
||||||
elif len(file_props['transfered_size']) == 1:
|
elif len(file_props.transfered_size) == 1:
|
||||||
speed = round(float(transfered_size) / file_props['elapsed-time'])
|
speed = round(float(transfered_size) / file_props.elapsed_time)
|
||||||
else:
|
else:
|
||||||
# first and last are (time, transfered_size)
|
# first and last are (time, transfered_size)
|
||||||
first = file_props['transfered_size'][0]
|
first = file_props.transfered_size[0]
|
||||||
last = file_props['transfered_size'][-1]
|
last = file_props.transfered_size[-1]
|
||||||
transfered = last[1] - first[1]
|
transfered = last[1] - first[1]
|
||||||
tim = last[0] - first[0]
|
tim = last[0] - first[0]
|
||||||
if tim == 0:
|
if tim == 0:
|
||||||
|
@ -556,16 +553,16 @@ class FileTransfersWindow:
|
||||||
|
|
||||||
def _remove_transfer(self, iter_, sid, file_props):
|
def _remove_transfer(self, iter_, sid, file_props):
|
||||||
self.model.remove(iter_)
|
self.model.remove(iter_)
|
||||||
if 'tt_account' in file_props:
|
if file_props.tt_account:
|
||||||
# file transfer is set
|
# file transfer is set
|
||||||
account = file_props['tt_account']
|
account = file_props.tt_account
|
||||||
if account in gajim.connections:
|
if account in gajim.connections:
|
||||||
# there is a connection to the account
|
# there is a connection to the account
|
||||||
gajim.connections[account].remove_transfer(file_props)
|
gajim.connections[account].remove_transfer(file_props)
|
||||||
if file_props['type'] == 'r': # we receive a file
|
if file_props.type_ == 'r': # we receive a file
|
||||||
other = file_props['sender']
|
other = file_props.sender
|
||||||
else: # we send a file
|
else: # we send a file
|
||||||
other = file_props['receiver']
|
other = file_props.receiver
|
||||||
if isinstance(other, unicode):
|
if isinstance(other, unicode):
|
||||||
jid = gajim.get_jid_without_resource(other)
|
jid = gajim.get_jid_without_resource(other)
|
||||||
else: # It's a Contact instance
|
else: # It's a Contact instance
|
||||||
|
@ -573,21 +570,19 @@ class FileTransfersWindow:
|
||||||
for ev_type in ('file-error', 'file-completed', 'file-request-error',
|
for ev_type in ('file-error', 'file-completed', 'file-request-error',
|
||||||
'file-send-error', 'file-stopped'):
|
'file-send-error', 'file-stopped'):
|
||||||
for event in gajim.events.get_events(account, jid, [ev_type]):
|
for event in gajim.events.get_events(account, jid, [ev_type]):
|
||||||
if event.parameters['sid'] == file_props['sid']:
|
if event.parameters['sid'] == file_props.sid:
|
||||||
gajim.events.remove_events(account, jid, event)
|
gajim.events.remove_events(account, jid, event)
|
||||||
gajim.interface.roster.draw_contact(jid, account)
|
gajim.interface.roster.draw_contact(jid, account)
|
||||||
gajim.interface.roster.show_title()
|
gajim.interface.roster.show_title()
|
||||||
del(self.files_props[sid[0]][sid[1:]])
|
FilesProp.deleteFileProp(files_props)
|
||||||
del(file_props)
|
del(file_props)
|
||||||
|
|
||||||
def set_progress(self, typ, sid, transfered_size, iter_=None):
|
def set_progress(self, typ, sid, transfered_size, iter_=None):
|
||||||
"""
|
"""
|
||||||
Change the progress of a transfer with new transfered size
|
Change the progress of a transfer with new transfered size
|
||||||
"""
|
"""
|
||||||
if sid not in self.files_props[typ]:
|
file_props = FilesProp.getFilePropByType(typ, sid)
|
||||||
return
|
full_size = int(file_props.size)
|
||||||
file_props = self.files_props[typ][sid]
|
|
||||||
full_size = int(file_props['size'])
|
|
||||||
if full_size == 0:
|
if full_size == 0:
|
||||||
percent = 0
|
percent = 0
|
||||||
else:
|
else:
|
||||||
|
@ -607,14 +602,14 @@ class FileTransfersWindow:
|
||||||
# Kb/s
|
# Kb/s
|
||||||
|
|
||||||
# remaining time
|
# remaining time
|
||||||
if 'offset' in file_props and file_props['offset']:
|
if file_props.offset:
|
||||||
transfered_size -= file_props['offset']
|
transfered_size -= file_props.offset
|
||||||
full_size -= file_props['offset']
|
full_size -= file_props.offset
|
||||||
|
|
||||||
if file_props['elapsed-time'] > 0:
|
if file_props.elapsed_time > 0:
|
||||||
file_props['transfered_size'].append((file_props['last-time'], transfered_size))
|
file_props.transfered_size.append((file_props.last_time, transfered_size))
|
||||||
if len(file_props['transfered_size']) > 6:
|
if len(file_props.transfered_size) > 6:
|
||||||
file_props['transfered_size'].pop(0)
|
file_props.transfered_size.pop(0)
|
||||||
eta, speed = self._get_eta_and_speed(full_size, transfered_size,
|
eta, speed = self._get_eta_and_speed(full_size, transfered_size,
|
||||||
file_props)
|
file_props)
|
||||||
|
|
||||||
|
@ -630,24 +625,24 @@ class FileTransfersWindow:
|
||||||
self.model.set(iter_, C_TIME, text)
|
self.model.set(iter_, C_TIME, text)
|
||||||
|
|
||||||
# try to guess what should be the status image
|
# try to guess what should be the status image
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
status = 'download'
|
status = 'download'
|
||||||
else:
|
else:
|
||||||
status = 'upload'
|
status = 'upload'
|
||||||
if 'paused' in file_props and file_props['paused'] == True:
|
if file_props.paused == True:
|
||||||
status = 'pause'
|
status = 'pause'
|
||||||
elif 'stalled' in file_props and file_props['stalled'] == True:
|
elif file_props.stalled == True:
|
||||||
status = 'waiting'
|
status = 'waiting'
|
||||||
if 'connected' in file_props and file_props['connected'] == False:
|
if file_props.connected == False:
|
||||||
status = 'stop'
|
status = 'stop'
|
||||||
self.model.set(iter_, 0, self.get_icon(status))
|
self.model.set(iter_, 0, self.get_icon(status))
|
||||||
if transfered_size == full_size:
|
if transfered_size == full_size:
|
||||||
# If we are receiver and this is a jingle session
|
# If we are receiver and this is a jingle session
|
||||||
if file_props['type'] == 'r' and 'session-sid' in file_props:
|
if file_props.type_ == 'r' and file_props.session_sid:
|
||||||
# Show that we are computing the hash
|
# Show that we are computing the hash
|
||||||
self.set_status(typ, sid, 'computing')
|
self.set_status(file_props, 'computing')
|
||||||
else:
|
else:
|
||||||
self.set_status(typ, sid, 'ok')
|
self.set_status(file_props, 'ok')
|
||||||
elif just_began:
|
elif just_began:
|
||||||
path = self.model.get_path(iter_)
|
path = self.model.get_path(iter_)
|
||||||
self.select_func(path)
|
self.select_func(path)
|
||||||
|
@ -668,8 +663,6 @@ class FileTransfersWindow:
|
||||||
"""
|
"""
|
||||||
Create new file_props dict and set initial file transfer properties in it
|
Create new file_props dict and set initial file transfer properties in it
|
||||||
"""
|
"""
|
||||||
file_props = {'file-name' : file_path, 'name' : file_name,
|
|
||||||
'type' : 's', 'desc' : file_desc}
|
|
||||||
if os.path.isfile(file_path):
|
if os.path.isfile(file_path):
|
||||||
stat = os.stat(file_path)
|
stat = os.stat(file_path)
|
||||||
else:
|
else:
|
||||||
|
@ -679,16 +672,17 @@ class FileTransfersWindow:
|
||||||
dialogs.ErrorDialog(_('Invalid File'),
|
dialogs.ErrorDialog(_('Invalid File'),
|
||||||
_('It is not possible to send empty files'))
|
_('It is not possible to send empty files'))
|
||||||
return None
|
return None
|
||||||
file_props['elapsed-time'] = 0
|
file_props = FilesProp.getNewFileProp(account,
|
||||||
file_props['size'] = unicode(stat[6])
|
sid=helpers.get_random_string_16())
|
||||||
file_props['sid'] = helpers.get_random_string_16()
|
file_props.file_name = file_path
|
||||||
file_props['completed'] = False
|
file_props.name = file_name
|
||||||
file_props['started'] = False
|
file_props.type_ = 's'
|
||||||
file_props['sender'] = account
|
file_props.desc = file_desc
|
||||||
file_props['receiver'] = contact
|
file_props.elapsed_time = 0
|
||||||
file_props['tt_account'] = account
|
file_props.size = unicode(stat[6])
|
||||||
# keep the last time: transfered_size to compute transfer speed
|
file_props.sender = account
|
||||||
file_props['transfered_size'] = []
|
file_props.receiver = contact
|
||||||
|
file_props.tt_account = account
|
||||||
return file_props
|
return file_props
|
||||||
|
|
||||||
def add_transfer(self, account, contact, file_props):
|
def add_transfer(self, account, contact, file_props):
|
||||||
|
@ -698,32 +692,31 @@ class FileTransfersWindow:
|
||||||
self.on_transfers_list_leave_notify_event(None)
|
self.on_transfers_list_leave_notify_event(None)
|
||||||
if file_props is None:
|
if file_props is None:
|
||||||
return
|
return
|
||||||
file_props['elapsed-time'] = 0
|
file_props.elapsed_time = 0
|
||||||
self.files_props[file_props['type']][file_props['sid']] = file_props
|
|
||||||
iter_ = self.model.prepend()
|
iter_ = self.model.prepend()
|
||||||
text_labels = '<b>' + _('Name: ') + '</b>\n'
|
text_labels = '<b>' + _('Name: ') + '</b>\n'
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
text_labels += '<b>' + _('Sender: ') + '</b>'
|
text_labels += '<b>' + _('Sender: ') + '</b>'
|
||||||
else:
|
else:
|
||||||
text_labels += '<b>' + _('Recipient: ') + '</b>'
|
text_labels += '<b>' + _('Recipient: ') + '</b>'
|
||||||
|
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
file_name = os.path.split(file_props['file-name'])[1]
|
file_name = os.path.split(file_props.file_name)[1]
|
||||||
else:
|
else:
|
||||||
file_name = file_props['name']
|
file_name = file_props.name
|
||||||
text_props = gobject.markup_escape_text(file_name) + '\n'
|
text_props = gobject.markup_escape_text(file_name) + '\n'
|
||||||
text_props += contact.get_shown_name()
|
text_props += contact.get_shown_name()
|
||||||
self.model.set(iter_, 1, text_labels, 2, text_props, C_PULSE, -1, C_SID,
|
self.model.set(iter_, 1, text_labels, 2, text_props, C_PULSE, -1, C_SID,
|
||||||
file_props['type'] + file_props['sid'])
|
file_props.type_ + file_props.sid)
|
||||||
self.set_progress(file_props['type'], file_props['sid'], 0, iter_)
|
self.set_progress(file_props.type_, file_props.sid, 0, iter_)
|
||||||
if 'started' in file_props and file_props['started'] is False:
|
if file_props.started is False:
|
||||||
status = 'waiting'
|
status = 'waiting'
|
||||||
elif file_props['type'] == 'r':
|
elif file_props.type_ == 'r':
|
||||||
status = 'download'
|
status = 'download'
|
||||||
else:
|
else:
|
||||||
status = 'upload'
|
status = 'upload'
|
||||||
file_props['tt_account'] = account
|
file_props.tt_account = account
|
||||||
self.set_status(file_props['type'], file_props['sid'], status)
|
self.set_status(file_props, status)
|
||||||
self.set_cleanup_sensitivity()
|
self.set_cleanup_sensitivity()
|
||||||
self.window.show_all()
|
self.window.show_all()
|
||||||
|
|
||||||
|
@ -743,7 +736,7 @@ class FileTransfersWindow:
|
||||||
self.tooltip.hide_tooltip()
|
self.tooltip.hide_tooltip()
|
||||||
return
|
return
|
||||||
sid = self.model[iter_][C_SID].decode('utf-8')
|
sid = self.model[iter_][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
|
||||||
if file_props is not None:
|
if file_props is not None:
|
||||||
if self.tooltip.timeout == 0 or self.tooltip.id != props[0]:
|
if self.tooltip.timeout == 0 or self.tooltip.id != props[0]:
|
||||||
self.tooltip.id = row
|
self.tooltip.id = row
|
||||||
|
@ -798,7 +791,7 @@ class FileTransfersWindow:
|
||||||
return
|
return
|
||||||
current_iter = self.model.get_iter(path)
|
current_iter = self.model.get_iter(path)
|
||||||
sid = self.model[current_iter][C_SID].decode('utf-8')
|
sid = self.model[current_iter][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
|
||||||
self.remove_menuitem.set_sensitive(is_row_selected)
|
self.remove_menuitem.set_sensitive(is_row_selected)
|
||||||
self.open_folder_menuitem.set_sensitive(is_row_selected)
|
self.open_folder_menuitem.set_sensitive(is_row_selected)
|
||||||
is_stopped = False
|
is_stopped = False
|
||||||
|
@ -856,7 +849,7 @@ class FileTransfersWindow:
|
||||||
while i >= 0:
|
while i >= 0:
|
||||||
iter_ = self.model.get_iter((i))
|
iter_ = self.model.get_iter((i))
|
||||||
sid = self.model[iter_][C_SID].decode('utf-8')
|
sid = self.model[iter_][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
|
||||||
if is_transfer_stopped(file_props):
|
if is_transfer_stopped(file_props):
|
||||||
self._remove_transfer(iter_, sid, file_props)
|
self._remove_transfer(iter_, sid, file_props)
|
||||||
i -= 1
|
i -= 1
|
||||||
|
@ -891,20 +884,20 @@ class FileTransfersWindow:
|
||||||
return
|
return
|
||||||
s_iter = selected[1]
|
s_iter = selected[1]
|
||||||
sid = self.model[s_iter][C_SID].decode('utf-8')
|
sid = self.model[s_iter][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
|
||||||
if is_transfer_paused(file_props):
|
if is_transfer_paused(file_props):
|
||||||
file_props['last-time'] = time.time()
|
file_props.last_time = time.time()
|
||||||
file_props['paused'] = False
|
file_props.paused = False
|
||||||
types = {'r' : 'download', 's' : 'upload'}
|
types = {'r' : 'download', 's' : 'upload'}
|
||||||
self.set_status(file_props['type'], file_props['sid'], types[sid[0]])
|
self.set_status(file_props, types[sid[0]])
|
||||||
self.toggle_pause_continue(True)
|
self.toggle_pause_continue(True)
|
||||||
if file_props['continue_cb']:
|
if file_props.continue_cb:
|
||||||
file_props['continue_cb']()
|
file_props.continue_cb()
|
||||||
elif is_transfer_active(file_props):
|
elif is_transfer_active(file_props):
|
||||||
file_props['paused'] = True
|
file_props.paused = True
|
||||||
self.set_status(file_props['type'], file_props['sid'], 'pause')
|
self.set_status(file_props, 'pause')
|
||||||
# reset that to compute speed only when we resume
|
# reset that to compute speed only when we resume
|
||||||
file_props['transfered_size'] = []
|
file_props.transfered_size = []
|
||||||
self.toggle_pause_continue(False)
|
self.toggle_pause_continue(False)
|
||||||
|
|
||||||
def on_cancel_button_clicked(self, widget):
|
def on_cancel_button_clicked(self, widget):
|
||||||
|
@ -913,14 +906,12 @@ class FileTransfersWindow:
|
||||||
return
|
return
|
||||||
s_iter = selected[1]
|
s_iter = selected[1]
|
||||||
sid = self.model[s_iter][C_SID].decode('utf-8')
|
sid = self.model[s_iter][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
|
||||||
if 'tt_account' not in file_props:
|
account = file_props.tt_account
|
||||||
return
|
|
||||||
account = file_props['tt_account']
|
|
||||||
if account not in gajim.connections:
|
if account not in gajim.connections:
|
||||||
return
|
return
|
||||||
gajim.connections[account].disconnect_transfer(file_props)
|
gajim.connections[account].disconnect_transfer(file_props)
|
||||||
self.set_status(file_props['type'], file_props['sid'], 'stop')
|
self.set_status(file_props, 'stop')
|
||||||
|
|
||||||
def show_tooltip(self, widget):
|
def show_tooltip(self, widget):
|
||||||
if self.height_diff == 0:
|
if self.height_diff == 0:
|
||||||
|
@ -934,7 +925,7 @@ class FileTransfersWindow:
|
||||||
if props and self.tooltip.id == props[0]:
|
if props and self.tooltip.id == props[0]:
|
||||||
iter_ = self.model.get_iter(props[0])
|
iter_ = self.model.get_iter(props[0])
|
||||||
sid = self.model[iter_][C_SID].decode('utf-8')
|
sid = self.model[iter_][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
|
||||||
# bounding rectangle of coordinates for the cell within the treeview
|
# bounding rectangle of coordinates for the cell within the treeview
|
||||||
rect = self.tree.get_cell_area(props[0], props[1])
|
rect = self.tree.get_cell_area(props[0], props[1])
|
||||||
# position of the treeview on the screen
|
# position of the treeview on the screen
|
||||||
|
@ -1022,10 +1013,10 @@ class FileTransfersWindow:
|
||||||
return
|
return
|
||||||
s_iter = selected[1]
|
s_iter = selected[1]
|
||||||
sid = self.model[s_iter][C_SID].decode('utf-8')
|
sid = self.model[s_iter][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
|
||||||
if 'file-name' not in file_props:
|
if not file_props.file_name:
|
||||||
return
|
return
|
||||||
path = os.path.split(file_props['file-name'])[0]
|
path = os.path.split(file_props.file_name)[0]
|
||||||
if os.path.exists(path) and os.path.isdir(path):
|
if os.path.exists(path) and os.path.isdir(path):
|
||||||
helpers.launch_file_manager(path)
|
helpers.launch_file_manager(path)
|
||||||
|
|
||||||
|
@ -1044,7 +1035,7 @@ class FileTransfersWindow:
|
||||||
return
|
return
|
||||||
s_iter = selected[1]
|
s_iter = selected[1]
|
||||||
sid = self.model[s_iter][C_SID].decode('utf-8')
|
sid = self.model[s_iter][C_SID].decode('utf-8')
|
||||||
file_props = self.files_props[sid[0]][sid[1:]]
|
file_props = FilesProp.getFilePropByType(sid[0], sid[1:])
|
||||||
self._remove_transfer(s_iter, sid, file_props)
|
self._remove_transfer(s_iter, sid, file_props)
|
||||||
self.set_all_insensitive()
|
self.set_all_insensitive()
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,7 @@ from common.connection_handlers_events import OurShowEvent, \
|
||||||
FileRequestErrorEvent, InformationEvent
|
FileRequestErrorEvent, InformationEvent
|
||||||
from common.connection import Connection
|
from common.connection import Connection
|
||||||
from common import jingle
|
from common import jingle
|
||||||
|
from common.file_props import FilesProp
|
||||||
|
|
||||||
import roster_window
|
import roster_window
|
||||||
import profile_window
|
import profile_window
|
||||||
|
@ -168,12 +169,12 @@ class Interface:
|
||||||
sid = obj.id_
|
sid = obj.id_
|
||||||
if len(obj.id_) > 3 and obj.id_[2] == '_':
|
if len(obj.id_) > 3 and obj.id_[2] == '_':
|
||||||
sid = obj.id_[3:]
|
sid = obj.id_[3:]
|
||||||
if sid in ft.files_props['s']:
|
file_props = FilesProp.getFileProp(obj.conn.name, sid)
|
||||||
file_props = ft.files_props['s'][sid]
|
if file_props :
|
||||||
if unicode(obj.errcode) == '400':
|
if unicode(obj.errcode) == '400':
|
||||||
file_props['error'] = -3
|
file_props.error = -3
|
||||||
else:
|
else:
|
||||||
file_props['error'] = -4
|
file_props.error = -4
|
||||||
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
|
gajim.nec.push_incoming_event(FileRequestErrorEvent(None,
|
||||||
conn=obj.conn, jid=obj.jid, file_props=file_props,
|
conn=obj.conn, jid=obj.jid, file_props=file_props,
|
||||||
error_msg=obj.errmsg))
|
error_msg=obj.errmsg))
|
||||||
|
@ -183,12 +184,11 @@ class Interface:
|
||||||
sid = obj.id_
|
sid = obj.id_
|
||||||
if len(obj.id_) > 3 and obj.id_[2] == '_':
|
if len(obj.id_) > 3 and obj.id_[2] == '_':
|
||||||
sid = obj.id_[3:]
|
sid = obj.id_[3:]
|
||||||
if sid in obj.conn.files_props:
|
file_props = FilesProp.getFileProp(obj.conn.name, sid)
|
||||||
file_props = obj.conn.files_props[sid]
|
self.handle_event_file_send_error(obj.conn.name, (obj.fjid,
|
||||||
self.handle_event_file_send_error(obj.conn.name, (obj.fjid,
|
file_props))
|
||||||
file_props))
|
obj.conn.disconnect_transfer(file_props)
|
||||||
obj.conn.disconnect_transfer(file_props)
|
return
|
||||||
return
|
|
||||||
|
|
||||||
ctrl = self.msg_win_mgr.get_control(obj.fjid, obj.conn.name)
|
ctrl = self.msg_win_mgr.get_control(obj.fjid, obj.conn.name)
|
||||||
if ctrl and ctrl.type_id == message_control.TYPE_GC:
|
if ctrl and ctrl.type_id == message_control.TYPE_GC:
|
||||||
|
@ -802,7 +802,7 @@ class Interface:
|
||||||
jid = array[0]
|
jid = array[0]
|
||||||
file_props = array[1]
|
file_props = array[1]
|
||||||
ft = self.instances['file_transfers']
|
ft = self.instances['file_transfers']
|
||||||
ft.set_status(file_props['type'], file_props['sid'], 'stop')
|
ft.set_status(file_props, 'stop')
|
||||||
|
|
||||||
if helpers.allow_popup_window(account):
|
if helpers.allow_popup_window(account):
|
||||||
ft.show_send_error(file_props)
|
ft.show_send_error(file_props)
|
||||||
|
@ -814,7 +814,7 @@ class Interface:
|
||||||
path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
|
path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
|
||||||
event_type = _('File Transfer Error')
|
event_type = _('File Transfer Error')
|
||||||
notify.popup(event_type, jid, account, 'file-send-error', path,
|
notify.popup(event_type, jid, account, 'file-send-error', path,
|
||||||
event_type, file_props['name'])
|
event_type, file_props.name)
|
||||||
|
|
||||||
def handle_event_gmail_notify(self, obj):
|
def handle_event_gmail_notify(self, obj):
|
||||||
jid = obj.jid
|
jid = obj.jid
|
||||||
|
@ -856,8 +856,8 @@ class Interface:
|
||||||
def handle_event_file_request_error(self, obj):
|
def handle_event_file_request_error(self, obj):
|
||||||
# ('FILE_REQUEST_ERROR', account, (jid, file_props, error_msg))
|
# ('FILE_REQUEST_ERROR', account, (jid, file_props, error_msg))
|
||||||
ft = self.instances['file_transfers']
|
ft = self.instances['file_transfers']
|
||||||
ft.set_status(obj.file_props['type'], obj.file_props['sid'], 'stop')
|
ft.set_status(obj.file_props, 'stop')
|
||||||
errno = obj.file_props['error']
|
errno = obj.file_props.error
|
||||||
|
|
||||||
if helpers.allow_popup_window(obj.conn.name):
|
if helpers.allow_popup_window(obj.conn.name):
|
||||||
if errno in (-4, -5):
|
if errno in (-4, -5):
|
||||||
|
@ -878,7 +878,7 @@ class Interface:
|
||||||
path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
|
path = gtkgui_helpers.get_icon_path('gajim-ft_error', 48)
|
||||||
event_type = _('File Transfer Error')
|
event_type = _('File Transfer Error')
|
||||||
notify.popup(event_type, obj.jid, obj.conn.name, msg_type, path,
|
notify.popup(event_type, obj.jid, obj.conn.name, msg_type, path,
|
||||||
title=event_type, text=obj.file_props['name'])
|
title=event_type, text=obj.file_props.name)
|
||||||
|
|
||||||
def handle_event_file_request(self, obj):
|
def handle_event_file_request(self, obj):
|
||||||
account = obj.conn.name
|
account = obj.conn.name
|
||||||
|
@ -916,92 +916,90 @@ class Interface:
|
||||||
if time.time() - self.last_ftwindow_update > 0.5:
|
if time.time() - self.last_ftwindow_update > 0.5:
|
||||||
# update ft window every 500ms
|
# update ft window every 500ms
|
||||||
self.last_ftwindow_update = time.time()
|
self.last_ftwindow_update = time.time()
|
||||||
self.instances['file_transfers'].set_progress(file_props['type'],
|
self.instances['file_transfers'].set_progress(file_props.type_,
|
||||||
file_props['sid'], file_props['received-len'])
|
file_props.sid, file_props.received_len)
|
||||||
|
|
||||||
def __compare_hashes(self, account, file_props):
|
def __compare_hashes(self, account, file_props):
|
||||||
session = gajim.connections[account].get_jingle_session(jid=None,
|
session = gajim.connections[account].get_jingle_session(jid=None,
|
||||||
sid=file_props['session-sid'])
|
sid=file_props.session_sid)
|
||||||
ft_win = self.instances['file_transfers']
|
ft_win = self.instances['file_transfers']
|
||||||
if not session.file_hash:
|
if not session.file_hash:
|
||||||
# We disn't get the hash, sender probably don't support that
|
# We disn't get the hash, sender probably don't support that
|
||||||
jid = unicode(file_props['sender'])
|
jid = unicode(file_props.sender)
|
||||||
self.popup_ft_result(account, jid, file_props)
|
self.popup_ft_result(account, jid, file_props)
|
||||||
ft_win.set_status(file_props['type'], file_props['sid'], 'ok')
|
ft_win.set_status(file_props, 'ok')
|
||||||
h = Hashes()
|
h = Hashes()
|
||||||
try:
|
try:
|
||||||
file_ = open(file_props['file-name'], 'r')
|
file_ = open(file_props.file_name, 'r')
|
||||||
except:
|
except:
|
||||||
return
|
return
|
||||||
hash_ = h.calculateHash(session.hash_algo, file_)
|
hash_ = h.calculateHash(session.hash_algo, file_)
|
||||||
file_.close()
|
file_.close()
|
||||||
# If the hash we received and the hash of the file are the same,
|
# If the hash we received and the hash of the file are the same,
|
||||||
# then the file is not corrupt
|
# then the file is not corrupt
|
||||||
jid = unicode(file_props['sender'])
|
jid = unicode(file_props.sender)
|
||||||
if session.file_hash == hash_:
|
if session.file_hash == hash_:
|
||||||
self.popup_ft_result(account, jid, file_props)
|
self.popup_ft_result(account, jid, file_props)
|
||||||
ft_win.set_status(file_props['type'], file_props['sid'], 'ok')
|
ft_win.set_status(file_props, 'ok')
|
||||||
else:
|
else:
|
||||||
# wrong hash, we need to get the file again!
|
# wrong hash, we need to get the file again!
|
||||||
file_props['error'] = -10
|
file_props.error = -10
|
||||||
self.popup_ft_result(account, jid, file_props)
|
self.popup_ft_result(account, jid, file_props)
|
||||||
ft_win.set_status(file_props['type'], file_props['sid'],
|
ft_win.set_status(file_props, 'hash_error')
|
||||||
'hash_error')
|
|
||||||
# End jingle session
|
# End jingle session
|
||||||
if session:
|
if session:
|
||||||
session.end_session()
|
session.end_session()
|
||||||
|
|
||||||
def handle_event_file_rcv_completed(self, account, file_props):
|
def handle_event_file_rcv_completed(self, account, file_props):
|
||||||
ft = self.instances['file_transfers']
|
ft = self.instances['file_transfers']
|
||||||
if file_props['error'] == 0:
|
if file_props.error == 0:
|
||||||
ft.set_progress(file_props['type'], file_props['sid'],
|
ft.set_progress(file_props.type_, file_props.sid,
|
||||||
file_props['received-len'])
|
file_props.received_len)
|
||||||
else:
|
else:
|
||||||
ft.set_status(file_props['type'], file_props['sid'], 'stop')
|
ft.set_status(file_props, 'stop')
|
||||||
if 'stalled' in file_props and file_props['stalled'] or \
|
if file_props.stalled or file_props.paused:
|
||||||
'paused' in file_props and file_props['paused']:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if file_props['type'] == 'r': # we receive a file
|
if file_props.type_ == 'r': # we receive a file
|
||||||
# If we have a jingle session id, it is a jingle transfer
|
# If we have a jingle session id, it is a jingle transfer
|
||||||
# we compare hashes
|
# we compare hashes
|
||||||
if 'session-sid' in file_props:
|
if file_props.session_sid:
|
||||||
# Compare hashes in a new thread
|
# Compare hashes in a new thread
|
||||||
self.hashThread = Thread(target=self.__compare_hashes,
|
self.hashThread = Thread(target=self.__compare_hashes,
|
||||||
args=(account, file_props))
|
args=(account, file_props))
|
||||||
self.hashThread.start()
|
self.hashThread.start()
|
||||||
gajim.socks5queue.remove_receiver(file_props['sid'], True, True)
|
gajim.socks5queue.remove_receiver(file_props.sid, True, True)
|
||||||
else: # we send a file
|
else: # we send a file
|
||||||
jid = unicode(file_props['receiver'])
|
jid = unicode(file_props.receiver)
|
||||||
gajim.socks5queue.remove_sender(file_props['sid'], True, True)
|
gajim.socks5queue.remove_sender(file_props.sid, True, True)
|
||||||
self.popup_ft_result(account, jid, file_props)
|
self.popup_ft_result(account, jid, file_props)
|
||||||
|
|
||||||
def popup_ft_result(self, account, jid, file_props):
|
def popup_ft_result(self, account, jid, file_props):
|
||||||
ft = self.instances['file_transfers']
|
ft = self.instances['file_transfers']
|
||||||
if helpers.allow_popup_window(account):
|
if helpers.allow_popup_window(account):
|
||||||
if file_props['error'] == 0:
|
if file_props.error == 0:
|
||||||
if gajim.config.get('notify_on_file_complete'):
|
if gajim.config.get('notify_on_file_complete'):
|
||||||
ft.show_completed(jid, file_props)
|
ft.show_completed(jid, file_props)
|
||||||
elif file_props['error'] == -1:
|
elif file_props.error == -1:
|
||||||
ft.show_stopped(jid, file_props,
|
ft.show_stopped(jid, file_props,
|
||||||
error_msg=_('Remote contact stopped transfer'))
|
error_msg=_('Remote contact stopped transfer'))
|
||||||
elif file_props['error'] == -6:
|
elif file_props.error == -6:
|
||||||
ft.show_stopped(jid, file_props,
|
ft.show_stopped(jid, file_props,
|
||||||
error_msg=_('Error opening file'))
|
error_msg=_('Error opening file'))
|
||||||
elif file_props['error'] == -10:
|
elif file_props.error == -10:
|
||||||
ft.show_hash_error(jid, file_props, account)
|
ft.show_hash_error(jid, file_props, account)
|
||||||
return
|
return
|
||||||
|
|
||||||
msg_type = ''
|
msg_type = ''
|
||||||
event_type = ''
|
event_type = ''
|
||||||
if file_props['error'] == 0 and gajim.config.get(
|
if file_props.error == 0 and gajim.config.get(
|
||||||
'notify_on_file_complete'):
|
'notify_on_file_complete'):
|
||||||
msg_type = 'file-completed'
|
msg_type = 'file-completed'
|
||||||
event_type = _('File Transfer Completed')
|
event_type = _('File Transfer Completed')
|
||||||
elif file_props['error'] in (-1, -6):
|
elif file_props.error in (-1, -6):
|
||||||
msg_type = 'file-stopped'
|
msg_type = 'file-stopped'
|
||||||
event_type = _('File Transfer Stopped')
|
event_type = _('File Transfer Stopped')
|
||||||
elif file_props['error'] == -10:
|
elif file_props.error == -10:
|
||||||
msg_type = 'file-hash-error'
|
msg_type = 'file-hash-error'
|
||||||
event_type = _('File Transfer Failed')
|
event_type = _('File Transfer Failed')
|
||||||
|
|
||||||
|
@ -1017,12 +1015,12 @@ class Interface:
|
||||||
self.add_event(account, jid, msg_type, file_props)
|
self.add_event(account, jid, msg_type, file_props)
|
||||||
|
|
||||||
if file_props is not None:
|
if file_props is not None:
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
# get the name of the sender, as it is in the roster
|
# get the name of the sender, as it is in the roster
|
||||||
sender = unicode(file_props['sender']).split('/')[0]
|
sender = unicode(file_props.sender).split('/')[0]
|
||||||
name = gajim.contacts.get_first_contact_from_jid(account,
|
name = gajim.contacts.get_first_contact_from_jid(account,
|
||||||
sender).get_shown_name()
|
sender).get_shown_name()
|
||||||
filename = os.path.basename(file_props['file-name'])
|
filename = os.path.basename(file_props.file_name)
|
||||||
if event_type == _('File Transfer Completed'):
|
if event_type == _('File Transfer Completed'):
|
||||||
txt = _('You successfully received %(filename)s from '
|
txt = _('You successfully received %(filename)s from '
|
||||||
'%(name)s.') % {'filename': filename, 'name': name}
|
'%(name)s.') % {'filename': filename, 'name': name}
|
||||||
|
@ -1036,14 +1034,14 @@ class Interface:
|
||||||
'failed.') % {'filename': filename, 'name': name}
|
'failed.') % {'filename': filename, 'name': name}
|
||||||
img_name = 'gajim-ft_stopped'
|
img_name = 'gajim-ft_stopped'
|
||||||
else:
|
else:
|
||||||
receiver = file_props['receiver']
|
receiver = file_props.receiver
|
||||||
if hasattr(receiver, 'jid'):
|
if hasattr(receiver, 'jid'):
|
||||||
receiver = receiver.jid
|
receiver = receiver.jid
|
||||||
receiver = receiver.split('/')[0]
|
receiver = receiver.split('/')[0]
|
||||||
# get the name of the contact, as it is in the roster
|
# get the name of the contact, as it is in the roster
|
||||||
name = gajim.contacts.get_first_contact_from_jid(account,
|
name = gajim.contacts.get_first_contact_from_jid(account,
|
||||||
receiver).get_shown_name()
|
receiver).get_shown_name()
|
||||||
filename = os.path.basename(file_props['file-name'])
|
filename = os.path.basename(file_props.file_name)
|
||||||
if event_type == _('File Transfer Completed'):
|
if event_type == _('File Transfer Completed'):
|
||||||
txt = _('You successfully sent %(filename)s to %(name)s.')\
|
txt = _('You successfully sent %(filename)s to %(name)s.')\
|
||||||
% {'filename': filename, 'name': name}
|
% {'filename': filename, 'name': name}
|
||||||
|
@ -1164,17 +1162,10 @@ class Interface:
|
||||||
def handle_event_jingleft_cancel(self, obj):
|
def handle_event_jingleft_cancel(self, obj):
|
||||||
ft = self.instances['file_transfers']
|
ft = self.instances['file_transfers']
|
||||||
file_props = None
|
file_props = None
|
||||||
|
|
||||||
# get the file_props of our session
|
# get the file_props of our session
|
||||||
for sid in obj.conn.files_props:
|
file_props = FilesProp.getFileProp(obj.conn.name, sid)
|
||||||
fp = obj.conn.files_props[sid]
|
ft.set_status(file_props, 'stop')
|
||||||
if fp['session-sid'] == obj.sid:
|
file_props.error = -4 # is it the right error code?
|
||||||
file_props = fp
|
|
||||||
break
|
|
||||||
|
|
||||||
ft.set_status(file_props['type'], file_props['sid'], 'stop')
|
|
||||||
file_props['error'] = -4 # is it the right error code?
|
|
||||||
|
|
||||||
ft.show_stopped(obj.jid, file_props, 'Peer cancelled ' +
|
ft.show_stopped(obj.jid, file_props, 'Peer cancelled ' +
|
||||||
'the transfer')
|
'the transfer')
|
||||||
|
|
||||||
|
|
|
@ -730,23 +730,23 @@ class FileTransfersTooltip(BaseTooltip):
|
||||||
current_row = 1
|
current_row = 1
|
||||||
self.create_window()
|
self.create_window()
|
||||||
properties = []
|
properties = []
|
||||||
name = file_props['name']
|
name = file_props.name
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
file_name = os.path.split(file_props['file-name'])[1]
|
file_name = os.path.split(file_props.file_name)[1]
|
||||||
else:
|
else:
|
||||||
file_name = file_props['name']
|
file_name = file_props.name
|
||||||
properties.append((_('Name: '),
|
properties.append((_('Name: '),
|
||||||
gobject.markup_escape_text(file_name)))
|
gobject.markup_escape_text(file_name)))
|
||||||
if file_props['type'] == 'r':
|
if file_props.type_ == 'r':
|
||||||
type_ = _('Download')
|
type_ = _('Download')
|
||||||
actor = _('Sender: ')
|
actor = _('Sender: ')
|
||||||
sender = unicode(file_props['sender']).split('/')[0]
|
sender = unicode(file_props.sender).split('/')[0]
|
||||||
name = gajim.contacts.get_first_contact_from_jid(
|
name = gajim.contacts.get_first_contact_from_jid(
|
||||||
file_props['tt_account'], sender).get_shown_name()
|
file_props.tt_account, sender).get_shown_name()
|
||||||
else:
|
else:
|
||||||
type_ = _('Upload')
|
type_ = _('Upload')
|
||||||
actor = _('Recipient: ')
|
actor = _('Recipient: ')
|
||||||
receiver = file_props['receiver']
|
receiver = file_props.receiver
|
||||||
if hasattr(receiver, 'name'):
|
if hasattr(receiver, 'name'):
|
||||||
name = receiver.get_shown_name()
|
name = receiver.get_shown_name()
|
||||||
else:
|
else:
|
||||||
|
@ -754,26 +754,24 @@ class FileTransfersTooltip(BaseTooltip):
|
||||||
properties.append((_('Type: '), type_))
|
properties.append((_('Type: '), type_))
|
||||||
properties.append((actor, gobject.markup_escape_text(name)))
|
properties.append((actor, gobject.markup_escape_text(name)))
|
||||||
|
|
||||||
transfered_len = file_props.get('received-len', 0)
|
transfered_len = file_props.received_len
|
||||||
|
if not transfered_len:
|
||||||
|
transfered_len = 0
|
||||||
properties.append((_('Transferred: '), helpers.convert_bytes(transfered_len)))
|
properties.append((_('Transferred: '), helpers.convert_bytes(transfered_len)))
|
||||||
status = ''
|
status = ''
|
||||||
if 'started' not in file_props or not file_props['started']:
|
if file_props.started:
|
||||||
status = _('Not started')
|
status = _('Not started')
|
||||||
elif 'connected' in file_props:
|
if file_props.stopped == True:
|
||||||
if 'stopped' in file_props and \
|
status = _('Stopped')
|
||||||
file_props['stopped'] == True:
|
elif file_props.completed:
|
||||||
status = _('Stopped')
|
status = _('Completed')
|
||||||
elif file_props['completed']:
|
elif file_props.connected == False:
|
||||||
|
if file_props.completed:
|
||||||
status = _('Completed')
|
status = _('Completed')
|
||||||
elif file_props['connected'] == False:
|
|
||||||
if file_props['completed']:
|
|
||||||
status = _('Completed')
|
|
||||||
else:
|
else:
|
||||||
if 'paused' in file_props and \
|
if file_props.paused == True:
|
||||||
file_props['paused'] == True:
|
|
||||||
status = _('?transfer status:Paused')
|
status = _('?transfer status:Paused')
|
||||||
elif 'stalled' in file_props and \
|
elif file_props.stalled == True:
|
||||||
file_props['stalled'] == True:
|
|
||||||
#stalled is not paused. it is like 'frozen' it stopped alone
|
#stalled is not paused. it is like 'frozen' it stopped alone
|
||||||
status = _('Stalled')
|
status = _('Stalled')
|
||||||
else:
|
else:
|
||||||
|
@ -781,10 +779,9 @@ class FileTransfersTooltip(BaseTooltip):
|
||||||
else:
|
else:
|
||||||
status = _('Not started')
|
status = _('Not started')
|
||||||
properties.append((_('Status: '), status))
|
properties.append((_('Status: '), status))
|
||||||
if 'desc' in file_props:
|
file_desc = file_props.desc
|
||||||
file_desc = file_props['desc']
|
properties.append((_('Description: '), gobject.markup_escape_text(
|
||||||
properties.append((_('Description: '), gobject.markup_escape_text(
|
file_desc)))
|
||||||
file_desc)))
|
|
||||||
while properties:
|
while properties:
|
||||||
property_ = properties.pop(0)
|
property_ = properties.pop(0)
|
||||||
current_row += 1
|
current_row += 1
|
||||||
|
|
Loading…
Reference in New Issue