added timeout for resolving
added proper dispatch signals so contacts get shown fixed some errors with roster data
This commit is contained in:
parent
40fc5202a5
commit
7da0b4c220
|
@ -296,3 +296,44 @@ class ConnectionHandlersZeroconf(ConnectionVcard):
|
||||||
i += 1
|
i += 1
|
||||||
return dic
|
return dic
|
||||||
|
|
||||||
|
def remove_transfers_for_contact(self, contact):
|
||||||
|
''' stop all active transfer for contact '''
|
||||||
|
'''for file_props in self.files_props.values():
|
||||||
|
if self.is_transfer_stoped(file_props):
|
||||||
|
continue
|
||||||
|
receiver_jid = unicode(file_props['receiver']).split('/')[0]
|
||||||
|
if contact.jid == receiver_jid:
|
||||||
|
file_props['error'] = -5
|
||||||
|
self.remove_transfer(file_props)
|
||||||
|
self.dispatch('FILE_REQUEST_ERROR', (contact.jid, file_props))
|
||||||
|
sender_jid = unicode(file_props['sender']).split('/')[0]
|
||||||
|
if contact.jid == sender_jid:
|
||||||
|
file_props['error'] = -3
|
||||||
|
self.remove_transfer(file_props)
|
||||||
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_all_transfers(self):
|
||||||
|
''' stops and removes all active connections from the socks5 pool '''
|
||||||
|
'''
|
||||||
|
for file_props in self.files_props.values():
|
||||||
|
self.remove_transfer(file_props, remove_from_list = False)
|
||||||
|
del(self.files_props)
|
||||||
|
self.files_props = {}
|
||||||
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_transfer(self, file_props, remove_from_list = True):
|
||||||
|
'''
|
||||||
|
if file_props is None:
|
||||||
|
return
|
||||||
|
self.disconnect_transfer(file_props)
|
||||||
|
sid = file_props['sid']
|
||||||
|
gajim.socks5queue.remove_file_props(self.name, sid)
|
||||||
|
|
||||||
|
if remove_from_list:
|
||||||
|
if self.files_props.has_key('sid'):
|
||||||
|
del(self.files_props['sid'])
|
||||||
|
'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,8 @@ import signal
|
||||||
if os.name != 'nt':
|
if os.name != 'nt':
|
||||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||||
|
|
||||||
|
import gobject
|
||||||
|
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common import gajim
|
from common import gajim
|
||||||
from common import GnuPG
|
from common import GnuPG
|
||||||
|
@ -54,30 +56,26 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.zeroconf = zeroconf.Zeroconf(self._on_new_service, self._on_remove_service)
|
self.zeroconf = zeroconf.Zeroconf(self._on_new_service, self._on_remove_service)
|
||||||
self.connected = 0 # offline
|
self.connected = 0 # offline
|
||||||
self.connection = None # dummy connection variable
|
self.connection = None
|
||||||
# this property is used to prevent double connections
|
|
||||||
# self.last_connection = None # last ClientCommon instance
|
|
||||||
self.gpg = None
|
self.gpg = None
|
||||||
self.is_zeroconf = True
|
self.is_zeroconf = True
|
||||||
self.status = ''
|
self.status = ''
|
||||||
self.old_show = ''
|
self.old_show = ''
|
||||||
# increase/decrease default timeout for server responses
|
|
||||||
self.try_connecting_for_foo_secs = 45
|
self.call_resolve_timeout = False
|
||||||
# holds the actual hostname to which we are connected
|
|
||||||
# self.connected_hostname = None
|
#self.time_to_reconnect = None
|
||||||
self.time_to_reconnect = None
|
#self.new_account_info = None
|
||||||
self.new_account_info = None
|
#self.bookmarks = []
|
||||||
self.bookmarks = []
|
|
||||||
self.on_purpose = False
|
self.on_purpose = False
|
||||||
self.last_io = gajim.idlequeue.current_time()
|
#self.last_io = gajim.idlequeue.current_time()
|
||||||
self.last_sent = []
|
#self.last_sent = []
|
||||||
self.last_history_line = {}
|
#self.last_history_line = {}
|
||||||
self.password = gajim.config.get_per('accounts', name, 'password')
|
|
||||||
# self.server_resource = gajim.config.get_per('accounts', name, 'resource')
|
#we don't need a password
|
||||||
# if gajim.config.get_per('accounts', self.name, 'keep_alives_enabled'):
|
self.password = 'dummy' # gajim.config.get_per('accounts', name, 'password')
|
||||||
# self.keepalives = gajim.config.get_per('accounts', self.name,'keep_alive_every_foo_secs')
|
|
||||||
# else:
|
|
||||||
# self.keepalives = 0
|
|
||||||
self.privacy_rules_supported = False
|
self.privacy_rules_supported = False
|
||||||
# Do we continue connection when we get roster (send presence,get vcard...)
|
# Do we continue connection when we get roster (send presence,get vcard...)
|
||||||
self.continue_connect_info = None
|
self.continue_connect_info = None
|
||||||
|
@ -92,6 +90,9 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.retrycount = 0
|
self.retrycount = 0
|
||||||
self.jids_for_auto_auth = [] # list of jid to auto-authorize
|
self.jids_for_auto_auth = [] # list of jid to auto-authorize
|
||||||
|
|
||||||
|
gajim.config.set_per('accounts', name, 'name', self.zeroconf.username)
|
||||||
|
gajim.config.set_per('accounts', name, 'hostname', self.zeroconf.host)
|
||||||
|
|
||||||
# END __init__
|
# END __init__
|
||||||
def put_event(self, ev):
|
def put_event(self, ev):
|
||||||
if gajim.handlers.has_key(ev[0]):
|
if gajim.handlers.has_key(ev[0]):
|
||||||
|
@ -103,20 +104,6 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
|
|
||||||
|
|
||||||
def _reconnect(self):
|
def _reconnect(self):
|
||||||
'''# Do not try to reco while we are already trying
|
|
||||||
self.time_to_reconnect = None
|
|
||||||
if self.connected < 2: #connection failed
|
|
||||||
gajim.log.debug('reconnect')
|
|
||||||
self.retrycount += 1
|
|
||||||
signed = self.get_signed_msg(self.status)
|
|
||||||
self.on_connect_auth = self._init_roster
|
|
||||||
self.connect_and_init(self.old_show, self.status, signed)
|
|
||||||
else:
|
|
||||||
# reconnect succeeded
|
|
||||||
self.time_to_reconnect = None
|
|
||||||
self.retrycount = 0
|
|
||||||
'''
|
|
||||||
|
|
||||||
gajim.log.debug('reconnect')
|
gajim.log.debug('reconnect')
|
||||||
|
|
||||||
signed = self.get_signed_msg(self.status)
|
signed = self.get_signed_msg(self.status)
|
||||||
|
@ -131,32 +118,9 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
# make sure previous connection is completely closed
|
# make sure previous connection is completely closed
|
||||||
self.last_connection = None
|
self.last_connection = None
|
||||||
self.connection = None
|
self.connection = None
|
||||||
|
self.call_resolve_timeout = False
|
||||||
self.zeroconf.disconnect()
|
self.zeroconf.disconnect()
|
||||||
|
|
||||||
def select_next_host(self, hosts):
|
|
||||||
hosts_best_prio = []
|
|
||||||
best_prio = 65535
|
|
||||||
sum_weight = 0
|
|
||||||
for h in hosts:
|
|
||||||
if h['prio'] < best_prio:
|
|
||||||
hosts_best_prio = [h]
|
|
||||||
best_prio = h['prio']
|
|
||||||
sum_weight = h['weight']
|
|
||||||
elif h['prio'] == best_prio:
|
|
||||||
hosts_best_prio.append(h)
|
|
||||||
sum_weight += h['weight']
|
|
||||||
if len(hosts_best_prio) == 1:
|
|
||||||
return hosts_best_prio[0]
|
|
||||||
r = random.randint(0, sum_weight)
|
|
||||||
min_w = sum_weight
|
|
||||||
# We return the one for which has the minimum weight and weight >= r
|
|
||||||
for h in hosts_best_prio:
|
|
||||||
if h['weight'] >= r:
|
|
||||||
if h['weight'] <= min_w:
|
|
||||||
min_w = h['weight']
|
|
||||||
return h
|
|
||||||
|
|
||||||
|
|
||||||
def quit(self, kill_core):
|
def quit(self, kill_core):
|
||||||
|
|
||||||
if kill_core and self.connected > 1:
|
if kill_core and self.connected > 1:
|
||||||
|
@ -188,14 +152,25 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.dispatch('BAD_PASSPHRASE', ())
|
self.dispatch('BAD_PASSPHRASE', ())
|
||||||
return signed
|
return signed
|
||||||
|
|
||||||
|
def _on_resolve_timeout(self):
|
||||||
|
if self.connected:
|
||||||
|
self.zeroconf.resolve_all()
|
||||||
|
return self.call_resolve_timeout
|
||||||
|
|
||||||
|
# callbacks called from zeroconf
|
||||||
def _on_new_service(self,jid):
|
def _on_new_service(self,jid):
|
||||||
self.roster.setItem(jid)
|
self.roster.setItem(jid)
|
||||||
#self.dispatch('ROSTER', self.roster)
|
self.dispatch('ROSTER_INFO', (jid, jid, 'both', 'no', self.roster.getGroups(jid)))
|
||||||
self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid), '', 'Gajim', 0, None, 0))
|
self.dispatch('NOTIFY', (jid, self.roster.getStatus(jid), '', 'Gajim', 0, None, 0))
|
||||||
|
|
||||||
|
|
||||||
def _on_remove_service(self,jid):
|
def _on_remove_service(self,jid):
|
||||||
self.roster.delItem(jid)
|
self.roster.delItem(jid)
|
||||||
#self.dispatch('NOTIFY', self, )
|
# 'NOTIFY' (account, (jid, status, status message, resource, priority,
|
||||||
|
# keyID, timestamp))
|
||||||
|
self.dispatch('NOTIFY', (jid, 'offline', '', 'Gajim', 0
|
||||||
|
, None, 0))
|
||||||
|
|
||||||
|
|
||||||
def connect(self, data = None, show = 'online'):
|
def connect(self, data = None, show = 'online'):
|
||||||
if self.connection:
|
if self.connection:
|
||||||
|
@ -207,6 +182,10 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.dispatch('ROSTER', self.roster)
|
self.dispatch('ROSTER', self.roster)
|
||||||
self.connected = STATUS_LIST.index(show)
|
self.connected = STATUS_LIST.index(show)
|
||||||
|
|
||||||
|
# refresh all contacts data all 10 seconds
|
||||||
|
self.call_timeout = True
|
||||||
|
gobject.timeout_add(10000, self._on_resolve_timeout)
|
||||||
|
|
||||||
def connect_and_init(self, show, msg, signed):
|
def connect_and_init(self, show, msg, signed):
|
||||||
self.continue_connect_info = [show, msg, signed]
|
self.continue_connect_info = [show, msg, signed]
|
||||||
|
|
||||||
|
@ -215,13 +194,13 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
self.connect('',show)
|
self.connect('',show)
|
||||||
|
|
||||||
def change_status(self, show, msg, sync = False, auto = False):
|
def change_status(self, show, msg, sync = False, auto = False):
|
||||||
print "change_status: show: %s msg: %s" % (show, msg)
|
print "connection_zeroconf.py: show: %s msg: %s in change_status" % (show, msg)
|
||||||
if not show in STATUS_LIST:
|
if not show in STATUS_LIST:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
# 'connect'
|
# 'connect'
|
||||||
if show != 'offline' and not self.connected:
|
if show != 'offline' and not self.connected:
|
||||||
print "connect in change_status"
|
print "connection_zeroconf.py: connect in change_status"
|
||||||
self.on_purpose = False
|
self.on_purpose = False
|
||||||
self.connect_and_init(show, msg, '')
|
self.connect_and_init(show, msg, '')
|
||||||
if show != 'invisible':
|
if show != 'invisible':
|
||||||
|
@ -231,22 +210,21 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
|
||||||
|
|
||||||
# 'disconnect'
|
# 'disconnect'
|
||||||
elif show == 'offline' and self.connected:
|
elif show == 'offline' and self.connected:
|
||||||
print "disconnect in change_status"
|
print "connection_zeroconf.py: disconnect in change_status"
|
||||||
self.connected = 0
|
self.connected = 0
|
||||||
self.dispatch('STATUS', 'offline')
|
self.dispatch('STATUS', 'offline')
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
#self._on_disconnected()
|
|
||||||
|
|
||||||
# update status
|
# update status
|
||||||
elif show != 'offline' and self.connected:
|
elif show != 'offline' and self.connected:
|
||||||
print "update in change_status"
|
print "connection_zeroconf.py: update in change_status"
|
||||||
was_invisible = self.connected == STATUS_LIST.index('invisible')
|
was_invisible = self.connected == STATUS_LIST.index('invisible')
|
||||||
self.connected = STATUS_LIST.index(show)
|
self.connected = STATUS_LIST.index(show)
|
||||||
if show == 'invisible':
|
if show == 'invisible':
|
||||||
self.zeroconf.remove_announce()
|
self.zeroconf.remove_announce()
|
||||||
return
|
return
|
||||||
if was_invisible:
|
if was_invisible:
|
||||||
print "announce after invisible in change_status"
|
print "connection_zeroconf.py: reannounce after invisible in change_status"
|
||||||
self.zeroconf.announce()
|
self.zeroconf.announce()
|
||||||
if self.connection:
|
if self.connection:
|
||||||
txt = {}
|
txt = {}
|
||||||
|
|
|
@ -6,17 +6,12 @@ class Roster:
|
||||||
self.zeroconf = zeroconf # our zeroconf instance
|
self.zeroconf = zeroconf # our zeroconf instance
|
||||||
|
|
||||||
def getRoster(self):
|
def getRoster(self):
|
||||||
print 'getRoster in Roster'
|
print 'roster_zeroconf.py: getRoster'
|
||||||
self._data = self.zeroconf.get_contacts()
|
self._data = self.zeroconf.get_contacts().copy()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def getItem(self, jid):
|
|
||||||
print 'getItem(%s) in Roster' % jid
|
|
||||||
if self._data.has_key(jid):
|
|
||||||
return self._data[jid]
|
|
||||||
|
|
||||||
def setItem(self, jid, name = '', groups = ''):
|
def setItem(self, jid, name = '', groups = ''):
|
||||||
print 'setItem %s in Roster' % jid
|
print 'roster_zeroconf.py: setItem %s' % jid
|
||||||
(service_jid, domain, interface, protocol, host, address, port, txt) \
|
(service_jid, domain, interface, protocol, host, address, port, txt) \
|
||||||
= self.zeroconf.get_contact(jid)
|
= self.zeroconf.get_contact(jid)
|
||||||
|
|
||||||
|
@ -29,67 +24,66 @@ class Roster:
|
||||||
self._data[jid]['address'] = address
|
self._data[jid]['address'] = address
|
||||||
self._data[jid]['host'] = host
|
self._data[jid]['host'] = host
|
||||||
self._data[jid]['port'] = port
|
self._data[jid]['port'] = port
|
||||||
self._data[jid]['txt'] = txt
|
|
||||||
txt_dict = self.zeroconf.txt_array_to_dict(txt)
|
txt_dict = self.zeroconf.txt_array_to_dict(txt)
|
||||||
if txt_dict.has_key('status'):
|
if txt_dict.has_key('status'):
|
||||||
status = txt_dict['status']
|
status = txt_dict['status']
|
||||||
else:
|
else:
|
||||||
status = ''
|
status = ''
|
||||||
if status == 'avail': status = 'online'
|
if status == 'avail': status = 'online'
|
||||||
|
self._data[jid]['txt_dict'] = txt_dict
|
||||||
self._data[jid]['status'] = status
|
self._data[jid]['status'] = status
|
||||||
self._data[jid]['show'] = status
|
self._data[jid]['show'] = status
|
||||||
print self._data[jid]
|
|
||||||
|
# print self._data[jid]
|
||||||
|
|
||||||
def delItem(self, jid):
|
def delItem(self, jid):
|
||||||
print 'delItem %s in Roster' % jid
|
print 'roster_zeroconf.py: delItem %s' % jid
|
||||||
if self._data.has_key(jid):
|
if self._data.has_key(jid):
|
||||||
del self._data[jid]
|
del self._data[jid]
|
||||||
|
|
||||||
|
def getItem(self, jid):
|
||||||
|
print 'roster_zeroconf.py: getItem: %s' % jid
|
||||||
|
if self._data.has_key(jid):
|
||||||
|
return self._data[jid]
|
||||||
|
|
||||||
def __getitem__(self,jid):
|
def __getitem__(self,jid):
|
||||||
print '__getitem__ in Roster'
|
print 'roster_zeroconf.py: __getitem__'
|
||||||
return self._data[jid]
|
return self._data[jid]
|
||||||
|
|
||||||
def getItems(self):
|
def getItems(self):
|
||||||
print 'getItems in Roster'
|
print 'roster_zeroconf.py: getItems'
|
||||||
# Return list of all [bare] JIDs that the roster is currently tracks.
|
# Return list of all [bare] JIDs that the roster currently tracks.
|
||||||
return self._data.keys()
|
return self._data.keys()
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
print 'keys in Roster'
|
print 'roster_zeroconf.py: keys'
|
||||||
return self._data.keys()
|
return self._data.keys()
|
||||||
|
|
||||||
def getRaw(self):
|
def getRaw(self):
|
||||||
print 'getRaw in Roster'
|
print 'roster_zeroconf.py: getRaw'
|
||||||
return self._data
|
return self._data
|
||||||
|
|
||||||
def getResources(self, jid):
|
def getResources(self, jid):
|
||||||
print 'getResources(%s) in Roster' % jid
|
print 'roster_zeroconf.py: getResources(%s)' % jid
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def getStatus(self, jid):
|
def getGroups(self, jid):
|
||||||
print 'getStatus %s in Roster' % jid
|
print 'roster_zeroconf.py: getGroups(%s)' % jid
|
||||||
txt = self._data[jid]['txt']
|
return self._data[jid]['groups']
|
||||||
txt_dict = self.zeroconf.txt_array_to_dict(txt)
|
|
||||||
if txt_dict.has_key('status'):
|
|
||||||
status = txt_dict['status']
|
|
||||||
else:
|
|
||||||
status = ''
|
|
||||||
|
|
||||||
if status == 'avail' or status == '':
|
def getStatus(self, jid):
|
||||||
return 'online'
|
print 'roster_zeroconf.py: getStatus %s' % jid
|
||||||
else:
|
return self._data[jid]['status']
|
||||||
return status
|
|
||||||
|
|
||||||
def getShow(self, jid):
|
def getShow(self, jid):
|
||||||
print 'getShow in Roster'
|
print 'roster_zeroconf.py: getShow'
|
||||||
return getStatus(jid)
|
return getStatus(jid)
|
||||||
|
|
||||||
|
|
||||||
def getPriority(jid):
|
def getPriority(jid):
|
||||||
return 5
|
return 5
|
||||||
|
|
||||||
def getSubscription(self,jid):
|
def getSubscription(self,jid):
|
||||||
print 'getSubscription in Roster'
|
print 'roster_zeroconf.py: getSubscription'
|
||||||
return 'both'
|
return 'both'
|
||||||
|
|
||||||
def Subscribe(self,jid):
|
def Subscribe(self,jid):
|
||||||
|
|
|
@ -18,7 +18,9 @@ class Zeroconf:
|
||||||
self.domain = None # specific domain to browse
|
self.domain = None # specific domain to browse
|
||||||
self.stype = '_presence._tcp'
|
self.stype = '_presence._tcp'
|
||||||
self.port = 5298 # listening port that gets announced
|
self.port = 5298 # listening port that gets announced
|
||||||
self.name = getpass.getuser()+'@'+socket.gethostname() # service name
|
self.username = getpass.getuser()
|
||||||
|
self.host = socket.gethostname()
|
||||||
|
self.name = self.username+'@'+ self.host # service name
|
||||||
self.txt = {} # service data
|
self.txt = {} # service data
|
||||||
|
|
||||||
self.new_serviceCB = new_serviceCB
|
self.new_serviceCB = new_serviceCB
|
||||||
|
@ -35,10 +37,11 @@ class Zeroconf:
|
||||||
print "Error:", str(err)
|
print "Error:", str(err)
|
||||||
|
|
||||||
def new_service_callback(self, interface, protocol, name, stype, domain, flags):
|
def new_service_callback(self, interface, protocol, name, stype, domain, flags):
|
||||||
print "Found service '%s' in domain '%s' on %i.%i." % (name, domain, interface, protocol)
|
if name != self.name:
|
||||||
|
print "Found service '%s' in domain '%s' on %i.%i." % (name, domain, interface, protocol)
|
||||||
|
|
||||||
#synchronous resolving
|
#synchronous resolving
|
||||||
self.server.ResolveService( int(interface), int(protocol), name, stype, \
|
self.server.ResolveService( int(interface), int(protocol), name, stype, \
|
||||||
domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), \
|
domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), \
|
||||||
reply_handler=self.service_resolved_callback, error_handler=self.print_error_callback)
|
reply_handler=self.service_resolved_callback, error_handler=self.print_error_callback)
|
||||||
|
|
||||||
|
@ -186,21 +189,21 @@ class Zeroconf:
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
self.remove_announce()
|
self.remove_announce()
|
||||||
|
|
||||||
|
|
||||||
# refresh data manually - really ok or too much traffic?
|
# refresh data manually - really ok or too much traffic?
|
||||||
def resolve_all(self):
|
def resolve_all(self):
|
||||||
for val in self.contacts.values():
|
for val in self.contacts.values():
|
||||||
#val:(name, domain, interface, protocol, host, address, port, txt)
|
#val:(name, domain, interface, protocol, host, address, port, txt)
|
||||||
self.server.ResolveService( int(val[2]), int(val[3]), val[0], \
|
self.server.ResolveService(int(val[2]), int(val[3]), val[0], \
|
||||||
self.stype, val[1], avahi.PROTO_UNSPEC, dbus.UInt32(0),\
|
self.stype, val[1], avahi.PROTO_UNSPEC, dbus.UInt32(0),\
|
||||||
reply_handler=self.service_resolved_all_callback, error_handler=self.print_error_callback)
|
reply_handler=self.service_resolved_all_callback, error_handler=self.print_error_callback)
|
||||||
|
print "zeroconf.py: resolve_all"
|
||||||
|
|
||||||
def get_contacts(self):
|
def get_contacts(self):
|
||||||
self.resolve_all()
|
|
||||||
return self.contacts
|
return self.contacts
|
||||||
|
|
||||||
def get_contact(self, jid):
|
def get_contact(self, jid):
|
||||||
return self.contacts[jid]
|
if self.contacts.has_key(jid):
|
||||||
|
return self.contacts[jid]
|
||||||
|
|
||||||
def update_txt(self, txt):
|
def update_txt(self, txt):
|
||||||
# update only given keys
|
# update only given keys
|
||||||
|
|
Loading…
Reference in New Issue