* added a method to load roster from DB
* now we load roster from DB when we receive an iq result for the roster without any query * added a "force" argument to NonBlockingRoster.getRoster(), to force the return of the instance
This commit is contained in:
parent
f2e214a033
commit
d347b79c38
|
@ -65,6 +65,7 @@ VCARD_PUBLISHED = 'vcard_published'
|
|||
VCARD_ARRIVED = 'vcard_arrived'
|
||||
AGENT_REMOVED = 'agent_removed'
|
||||
METACONTACTS_ARRIVED = 'metacontacts_arrived'
|
||||
ROSTER_ARRIVED = 'roster_arrived'
|
||||
PRIVACY_ARRIVED = 'privacy_arrived'
|
||||
PEP_CONFIG = 'pep_config'
|
||||
HAS_IDLE = True
|
||||
|
@ -1166,7 +1167,16 @@ class ConnectionVcard:
|
|||
# We can now continue connection by requesting the roster
|
||||
version = gajim.config.get_per('accounts', self.name,
|
||||
'roster_version')
|
||||
self.connection.initRoster(version=version)
|
||||
iq_id = self.connection.initRoster(version=version)
|
||||
self.awaiting_answers[iq_id] = (ROSTER_ARRIVED, )
|
||||
elif self.awaiting_answers[id_][0] == ROSTER_ARRIVED:
|
||||
if iq_obj.getType() == 'result':
|
||||
if not iq_obj.getTag('query'):
|
||||
account_jid = gajim.get_jid_from_account(self.name)
|
||||
roster_data = gajim.logger.get_roster(account_jid)
|
||||
roster = self.connection.getRoster(force=True)
|
||||
roster.setRaw(roster_data)
|
||||
self._getRoster()
|
||||
elif self.awaiting_answers[id_][0] == PRIVACY_ARRIVED:
|
||||
if iq_obj.getType() != 'error':
|
||||
self.privacy_rules_supported = True
|
||||
|
@ -2418,7 +2428,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
self.connection.send(result)
|
||||
raise common.xmpp.NodeProcessed
|
||||
|
||||
def _getRosterCB(self, con, iq_obj):
|
||||
def _getRoster(self):
|
||||
log.debug('getRosterCB')
|
||||
if not self.connection:
|
||||
return
|
||||
|
@ -2441,6 +2451,7 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
gajim.proxy65_manager.resolve(proxy, self.connection, our_jid)
|
||||
|
||||
def _on_roster_set(self, roster):
|
||||
roster_version = roster.version
|
||||
raw_roster = roster.getRaw()
|
||||
roster = {}
|
||||
our_jid = helpers.parse_jid(gajim.get_jid_from_account(self.name))
|
||||
|
@ -2480,6 +2491,8 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
self.discoverInfo(jid)
|
||||
|
||||
self.dispatch('ROSTER', roster)
|
||||
gajim.logger.replace_roster(self.name, roster_version, roster)
|
||||
print raw_roster
|
||||
|
||||
def _send_first_presence(self, signed = ''):
|
||||
show = self.continue_connect_info[0]
|
||||
|
@ -2621,8 +2634,6 @@ class ConnectionHandlers(ConnectionVcard, ConnectionBytestream, ConnectionDisco,
|
|||
common.xmpp.NS_MUC_OWNER)
|
||||
con.RegisterHandler('iq', self._MucAdminCB, 'result',
|
||||
common.xmpp.NS_MUC_ADMIN)
|
||||
con.RegisterHandler('iq', self._getRosterCB, 'result',
|
||||
common.xmpp.NS_ROSTER)
|
||||
con.RegisterHandler('iq', self._PrivateCB, 'result',
|
||||
common.xmpp.NS_PRIVATE)
|
||||
con.RegisterHandler('iq', self._HttpAuthCB, 'get',
|
||||
|
|
|
@ -339,6 +339,7 @@ class Logger:
|
|||
return 'mrim'
|
||||
|
||||
def convert_human_subscription_values_to_db_api_values(self, sub):
|
||||
'''converts from string style to constant ints for db'''
|
||||
if sub == 'none':
|
||||
return constants.SUBSCRIPTION_NONE
|
||||
if sub == 'to':
|
||||
|
@ -348,6 +349,17 @@ class Logger:
|
|||
if sub == 'both':
|
||||
return constants.SUBSCRIPTION_BOTH
|
||||
|
||||
def convert_db_api_values_to_human_subscription_values(self, sub):
|
||||
'''converts from constant ints for db to string style'''
|
||||
if sub == constants.SUBSCRIPTION_NONE:
|
||||
return 'none'
|
||||
if sub == constants.SUBSCRIPTION_TO:
|
||||
return 'to'
|
||||
if sub == constants.SUBSCRIPTION_FROM:
|
||||
return 'from'
|
||||
if sub == constants.SUBSCRIPTION_BOTH:
|
||||
return 'both'
|
||||
|
||||
def commit_to_db(self, values, write_unread = False):
|
||||
sql = 'INSERT INTO logs (jid_id, contact_name, time, kind, show, message, subject) VALUES (?, ?, ?, ?, ?, ?, ?)'
|
||||
try:
|
||||
|
@ -816,7 +828,30 @@ class Logger:
|
|||
except sqlite.OperationalError, e:
|
||||
print >> sys.stderr, str(e)
|
||||
|
||||
def replace_roster(self, account_name, roster_version, roster):
|
||||
''' Replace current roster in DB by a new one.
|
||||
accout_name is the name of the account to change
|
||||
roster_version is the version of the new roster
|
||||
roster is the new version '''
|
||||
gajim.config.set_per('accounts', account_name, 'roster_version', '')
|
||||
account_jid = gajim.get_jid_from_account(account_name)
|
||||
account_jid_id = self.get_jid_id(account_jid)
|
||||
|
||||
# Delete old roster
|
||||
sql = 'DELETE FROM roster_entry WHERE account_jid_id = %d' % (
|
||||
account_jid_id)
|
||||
sql = 'DELETE FROM roster_group WHERE account_jid_id = %d' % (
|
||||
account_jid_id)
|
||||
|
||||
# Fill roster tables with the new roster
|
||||
for jid in roster:
|
||||
self.add_or_update_contact(account_jid, jid, roster[jid]['name'],
|
||||
roster[jid]['subscription'], roster[jid]['groups'])
|
||||
gajim.config.set_per('accounts', account_name, 'roster_version',
|
||||
roster_version)
|
||||
|
||||
def del_contact(self, account_jid, jid):
|
||||
''' Remove jid from account_jid roster. '''
|
||||
try:
|
||||
account_jid_id = self.get_jid_id(account_jid)
|
||||
jid_id = self.get_jid_id(jid)
|
||||
|
@ -826,6 +861,7 @@ class Logger:
|
|||
self.simple_commit(sql)
|
||||
|
||||
def add_or_update_contact(self, account_jid, jid, name, sub, groups):
|
||||
''' Add or update a contact from account_jid roster. '''
|
||||
if sub == 'remove':
|
||||
self.del_contact(account_jid, jid)
|
||||
return
|
||||
|
@ -836,11 +872,11 @@ class Logger:
|
|||
except exceptions.PysqliteOperationalError, e:
|
||||
raise exceptions.PysqliteOperationalError(str(e))
|
||||
|
||||
# update groups information
|
||||
# first we delete all previous groups information
|
||||
# Update groups information
|
||||
# First we delete all previous groups information
|
||||
sql = 'DELETE FROM roster_group WHERE account_jid_id = %d AND jid_id = %d' % (account_jid_id, jid_id)
|
||||
self.cur.execute(sql)
|
||||
# then we add all new groups information
|
||||
# Then we add all new groups information
|
||||
for group in groups:
|
||||
sql = 'INSERT INTO roster_group VALUES("%d", "%d", "%s")' % (
|
||||
account_jid_id, jid_id, group)
|
||||
|
@ -851,4 +887,29 @@ class Logger:
|
|||
self.convert_human_subscription_values_to_db_api_values(sub))
|
||||
self.simple_commit(sql)
|
||||
|
||||
def get_roster(self, account_jid):
|
||||
''' Return the accound_jid roster in NonBlockingRoster format. '''
|
||||
data = {}
|
||||
account_jid_id = self.get_jid_id(account_jid)
|
||||
|
||||
# First we fill data with roster_entry informations
|
||||
self.cur.execute('SELECT j.jid, re.jid_id, re.name, re.subscription FROM roster_entry re, jids j WHERE re.account_jid_id="%(account_jid_id)s" AND j.jid_id=re.jid_id' % {'account_jid_id': account_jid_id})
|
||||
for jid, jid_id, name, subscription in self.cur:
|
||||
data[jid] = {}
|
||||
data[jid]['name'] = name
|
||||
data[jid]['subscription'] = self.convert_db_api_values_to_human_subscription_values(subscription)
|
||||
data[jid]['groups'] = []
|
||||
data[jid]['resources'] = {}
|
||||
data[jid]['ask'] = None
|
||||
data[jid]['id'] = jid_id
|
||||
|
||||
# Then we add group for roster entries
|
||||
for jid in data:
|
||||
self.cur.execute('SELECT group_name FROM roster_group WHERE account_jid_id="%(account_jid_id)s" AND jid_id="%(jid_id)s"' % {'account_jid_id': account_jid_id, 'jid_id': data[jid]['id']})
|
||||
for (group_name,) in self.cur:
|
||||
data[jid]['groups'].append(group_name)
|
||||
del data[jid]['id']
|
||||
|
||||
return data
|
||||
|
||||
# vim: se ts=3:
|
||||
|
|
|
@ -506,13 +506,13 @@ class NonBlockingClient:
|
|||
def initRoster(self, version=''):
|
||||
''' Plug in the roster. '''
|
||||
if not self.__dict__.has_key('NonBlockingRoster'):
|
||||
roster_nb.NonBlockingRoster.get_instance(version=version).PlugIn(self)
|
||||
return roster_nb.NonBlockingRoster.get_instance(version=version).PlugIn(self)
|
||||
|
||||
def getRoster(self, on_ready=None):
|
||||
def getRoster(self, on_ready=None, force=False):
|
||||
''' Return the Roster instance, previously plugging it in and
|
||||
requesting roster from server if needed. '''
|
||||
if self.__dict__.has_key('NonBlockingRoster'):
|
||||
return self.NonBlockingRoster.getRoster(on_ready)
|
||||
return self.NonBlockingRoster.getRoster(on_ready, force)
|
||||
return None
|
||||
|
||||
def sendPresence(self, jid=None, typ=None, requestRoster=0):
|
||||
|
|
|
@ -52,8 +52,11 @@ class NonBlockingRoster(PlugIn):
|
|||
|
||||
iq = Iq('get',NS_ROSTER)
|
||||
iq.setTagAttr('query', 'ver', self.version)
|
||||
id_ = self._owner.getAnID()
|
||||
iq.setID(id_)
|
||||
self._owner.send(iq)
|
||||
log.info('Roster requested from server')
|
||||
return id_
|
||||
|
||||
def RosterIqHandler(self,dis,stanza):
|
||||
''' Subscription tracker. Used internally for setting items state in
|
||||
|
@ -64,6 +67,9 @@ class NonBlockingRoster(PlugIn):
|
|||
return
|
||||
query = stanza.getTag('query')
|
||||
if query:
|
||||
self.version = stanza.getTagAttr('query', 'ver')
|
||||
if self.version is None:
|
||||
self.version = ''
|
||||
for item in query.getTags('item'):
|
||||
jid=item.getAttr('jid')
|
||||
if item.getAttr('subscription')=='remove':
|
||||
|
@ -192,6 +198,11 @@ class NonBlockingRoster(PlugIn):
|
|||
def getRaw(self):
|
||||
'''Returns the internal data representation of the roster.'''
|
||||
return self._data
|
||||
def setRaw(self, data):
|
||||
'''Returns the internal data representation of the roster.'''
|
||||
self._data = data
|
||||
self._data[self._owner.User+'@'+self._owner.Server]={'resources':{},'name':None,'ask':None,'subscription':None,'groups':None,}
|
||||
self.set=1
|
||||
# copypasted methods for roster.py from constructor to here
|
||||
|
||||
|
||||
|
@ -203,7 +214,7 @@ class NonBlockingRoster(PlugIn):
|
|||
self._owner.RegisterHandler('iq', self.RosterIqHandler, 'set', NS_ROSTER)
|
||||
self._owner.RegisterHandler('presence', self.PresenceHandler)
|
||||
if request:
|
||||
self.Request()
|
||||
return self.Request()
|
||||
|
||||
def _on_roster_set(self, data):
|
||||
if data:
|
||||
|
@ -216,16 +227,18 @@ class NonBlockingRoster(PlugIn):
|
|||
self.on_ready = None
|
||||
return True
|
||||
|
||||
def getRoster(self, on_ready=None):
|
||||
def getRoster(self, on_ready=None, force=False):
|
||||
''' Requests roster from server if neccessary and returns self. '''
|
||||
return_self = True
|
||||
if not self.set:
|
||||
self.on_ready = on_ready
|
||||
self._owner.onreceive(self._on_roster_set)
|
||||
return
|
||||
if on_ready:
|
||||
return_self = False
|
||||
elif on_ready:
|
||||
on_ready(self)
|
||||
on_ready = None
|
||||
else:
|
||||
return_self = False
|
||||
if return_self or force:
|
||||
return self
|
||||
return None
|
||||
|
||||
# vim: se ts=3:
|
||||
|
|
Loading…
Reference in New Issue