added timeout for resolving

added proper dispatch signals so contacts get shown
fixed some errors with roster data
This commit is contained in:
Stefan Bethge 2006-06-13 21:19:39 +00:00
parent 40fc5202a5
commit 7da0b4c220
4 changed files with 125 additions and 109 deletions

View File

@ -295,4 +295,45 @@ class ConnectionHandlersZeroconf(ConnectionVcard):
dic[i]['values'] = [dic[i]['options'][0]['values'][0]]
i += 1
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

View File

@ -34,6 +34,8 @@ import signal
if os.name != 'nt':
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
import gobject
from common import helpers
from common import gajim
from common import GnuPG
@ -54,30 +56,26 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
self.name = name
self.zeroconf = zeroconf.Zeroconf(self._on_new_service, self._on_remove_service)
self.connected = 0 # offline
self.connection = None # dummy connection variable
# this property is used to prevent double connections
# self.last_connection = None # last ClientCommon instance
self.connection = None
self.gpg = None
self.is_zeroconf = True
self.status = ''
self.old_show = ''
# increase/decrease default timeout for server responses
self.try_connecting_for_foo_secs = 45
# holds the actual hostname to which we are connected
# self.connected_hostname = None
self.time_to_reconnect = None
self.new_account_info = None
self.bookmarks = []
self.call_resolve_timeout = False
#self.time_to_reconnect = None
#self.new_account_info = None
#self.bookmarks = []
self.on_purpose = False
self.last_io = gajim.idlequeue.current_time()
self.last_sent = []
self.last_history_line = {}
self.password = gajim.config.get_per('accounts', name, 'password')
# self.server_resource = gajim.config.get_per('accounts', name, 'resource')
# if gajim.config.get_per('accounts', self.name, 'keep_alives_enabled'):
# self.keepalives = gajim.config.get_per('accounts', self.name,'keep_alive_every_foo_secs')
# else:
# self.keepalives = 0
#self.last_io = gajim.idlequeue.current_time()
#self.last_sent = []
#self.last_history_line = {}
#we don't need a password
self.password = 'dummy' # gajim.config.get_per('accounts', name, 'password')
self.privacy_rules_supported = False
# Do we continue connection when we get roster (send presence,get vcard...)
self.continue_connect_info = None
@ -91,7 +89,10 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
self.on_connect_failure = None
self.retrycount = 0
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__
def put_event(self, ev):
if gajim.handlers.has_key(ev[0]):
@ -103,20 +104,6 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
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')
signed = self.get_signed_msg(self.status)
@ -131,32 +118,9 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
# make sure previous connection is completely closed
self.last_connection = None
self.connection = None
self.call_resolve_timeout = False
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):
if kill_core and self.connected > 1:
@ -188,24 +152,39 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
self.dispatch('BAD_PASSPHRASE', ())
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):
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))
def _on_remove_service(self,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'):
if self.connection:
return self.connection, ''
self.zeroconf.connect()
self.connection = client_zeroconf.ClientZeroconf(self.zeroconf)
self.roster = self.connection.getRoster()
self.dispatch('ROSTER', self.roster)
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):
self.continue_connect_info = [show, msg, signed]
@ -215,13 +194,13 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
self.connect('',show)
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:
return -1
# 'connect'
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.connect_and_init(show, msg, '')
if show != 'invisible':
@ -231,22 +210,21 @@ class ConnectionZeroconf(ConnectionHandlersZeroconf):
# 'disconnect'
elif show == 'offline' and self.connected:
print "disconnect in change_status"
print "connection_zeroconf.py: disconnect in change_status"
self.connected = 0
self.dispatch('STATUS', 'offline')
self.disconnect()
#self._on_disconnected()
# update status
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')
self.connected = STATUS_LIST.index(show)
if show == 'invisible':
self.zeroconf.remove_announce()
return
if was_invisible:
print "announce after invisible in change_status"
print "connection_zeroconf.py: reannounce after invisible in change_status"
self.zeroconf.announce()
if self.connection:
txt = {}

View File

@ -6,17 +6,12 @@ class Roster:
self.zeroconf = zeroconf # our zeroconf instance
def getRoster(self):
print 'getRoster in Roster'
self._data = self.zeroconf.get_contacts()
print 'roster_zeroconf.py: getRoster'
self._data = self.zeroconf.get_contacts().copy()
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 = ''):
print 'setItem %s in Roster' % jid
print 'roster_zeroconf.py: setItem %s' % jid
(service_jid, domain, interface, protocol, host, address, port, txt) \
= self.zeroconf.get_contact(jid)
@ -29,67 +24,66 @@ class Roster:
self._data[jid]['address'] = address
self._data[jid]['host'] = host
self._data[jid]['port'] = port
self._data[jid]['txt'] = txt
txt_dict = self.zeroconf.txt_array_to_dict(txt)
if txt_dict.has_key('status'):
status = txt_dict['status']
else:
status = ''
if status == 'avail': status = 'online'
self._data[jid]['txt_dict'] = txt_dict
self._data[jid]['status'] = status
self._data[jid]['show'] = status
print self._data[jid]
# print self._data[jid]
def delItem(self, jid):
print 'delItem %s in Roster' % jid
print 'roster_zeroconf.py: delItem %s' % jid
if self._data.has_key(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):
print '__getitem__ in Roster'
print 'roster_zeroconf.py: __getitem__'
return self._data[jid]
def getItems(self):
print 'getItems in Roster'
# Return list of all [bare] JIDs that the roster is currently tracks.
print 'roster_zeroconf.py: getItems'
# Return list of all [bare] JIDs that the roster currently tracks.
return self._data.keys()
def keys(self):
print 'keys in Roster'
print 'roster_zeroconf.py: keys'
return self._data.keys()
def getRaw(self):
print 'getRaw in Roster'
print 'roster_zeroconf.py: getRaw'
return self._data
def getResources(self, jid):
print 'getResources(%s) in Roster' % jid
print 'roster_zeroconf.py: getResources(%s)' % jid
return {}
def getGroups(self, jid):
print 'roster_zeroconf.py: getGroups(%s)' % jid
return self._data[jid]['groups']
def getStatus(self, jid):
print 'getStatus %s in Roster' % jid
txt = self._data[jid]['txt']
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 == '':
return 'online'
else:
return status
print 'roster_zeroconf.py: getStatus %s' % jid
return self._data[jid]['status']
def getShow(self, jid):
print 'getShow in Roster'
print 'roster_zeroconf.py: getShow'
return getStatus(jid)
def getPriority(jid):
return 5
def getSubscription(self,jid):
print 'getSubscription in Roster'
print 'roster_zeroconf.py: getSubscription'
return 'both'
def Subscribe(self,jid):

View File

@ -18,7 +18,9 @@ class Zeroconf:
self.domain = None # specific domain to browse
self.stype = '_presence._tcp'
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.new_serviceCB = new_serviceCB
@ -35,10 +37,11 @@ class Zeroconf:
print "Error:", str(err)
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)
#synchronous resolving
self.server.ResolveService( int(interface), int(protocol), name, stype, \
if name != self.name:
print "Found service '%s' in domain '%s' on %i.%i." % (name, domain, interface, protocol)
#synchronous resolving
self.server.ResolveService( int(interface), int(protocol), name, stype, \
domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), \
reply_handler=self.service_resolved_callback, error_handler=self.print_error_callback)
@ -186,21 +189,21 @@ class Zeroconf:
def disconnect(self):
self.remove_announce()
# refresh data manually - really ok or too much traffic?
def resolve_all(self):
for val in self.contacts.values():
#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),\
reply_handler=self.service_resolved_all_callback, error_handler=self.print_error_callback)
print "zeroconf.py: resolve_all"
def get_contacts(self):
self.resolve_all()
return self.contacts
def get_contact(self, jid):
return self.contacts[jid]
if self.contacts.has_key(jid):
return self.contacts[jid]
def update_txt(self, txt):
# update only given keys