From 29d775e6756e7d8028438942ca2d34d1c39c559f Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Thu, 16 Jun 2011 16:03:31 -0700 Subject: Integrate roster with BaseXMPP. Last sent stanzas are saved regardless of if the roster is used directly or self.send_presence --- sleekxmpp/roster/item.py | 57 ++++++++++++++++++++++++++++++++++------------ sleekxmpp/roster/multi.py | 27 +++++++++++++++++++++- sleekxmpp/roster/single.py | 54 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 116 insertions(+), 22 deletions(-) (limited to 'sleekxmpp/roster') diff --git a/sleekxmpp/roster/item.py b/sleekxmpp/roster/item.py index eb115a4a..72baf694 100644 --- a/sleekxmpp/roster/item.py +++ b/sleekxmpp/roster/item.py @@ -105,23 +105,25 @@ class RosterItem(object): """ def __init__(self, xmpp, jid, owner=None, - state=None, db=None): + state=None, db=None, roster=None): """ Create a new roster item. Arguments: - xmpp -- The main SleekXMPP instance. - jid -- The item's JID. - owner -- The roster owner's JID. Defaults - so self.xmpp.boundjid.bare. - state -- A dictionary of initial state values. - db -- An optional interface to an external datastore. + xmpp -- The main SleekXMPP instance. + jid -- The item's JID. + owner -- The roster owner's JID. Defaults + so self.xmpp.boundjid.bare. + state -- A dictionary of initial state values. + db -- An optional interface to an external datastore. + roster -- The roster object containing this entry. """ self.xmpp = xmpp self.jid = jid self.owner = owner or self.xmpp.boundjid.bare self.last_status = None self.resources = {} + self.roster = roster self.db = db self._state = state or { 'from': False, @@ -290,19 +292,46 @@ class RosterItem(object): p['from'] = self.owner p.send() - def send_presence(self, ptype='available', status=None): - p = self.xmpp.Presence() - p['to'] = self.jid - p['type'] = ptype - p['status'] = status + def send_presence(self, ptype=None, pshow=None, pstatus=None, + ppriority=None, pnick=None): + """ + Create, initialize, and send a Presence stanza. + + Arguments: + pshow -- The presence's show value. + pstatus -- The presence's status message. + ppriority -- This connections' priority. + ptype -- The type of presence, such as 'subscribe'. + pnick -- Optional nickname of the presence's sender. + """ + p = self.xmpp.make_presence(pshow=pshow, + pstatus=pstatus, + ppriority=ppriority, + ptype=ptype, + pnick=pnick, + pto=self.jid) if self.xmpp.is_component: p['from'] = self.owner - self.last_status = p + if p['type'] in p.showtypes or p['type'] == 'available': + self.last_status = p p.send() + if not self.xmpp.sentpresence: + self.xmpp.event('sent_presence') + self.xmpp.sentpresence = True + def send_last_presence(self): if self.last_status is None: - self.send_presence() + pres = self.roster.last_status + if pres is None: + self.send_presence() + else: + pres['to'] = self.jid + if self.xmpp.is_component: + pres['from'] = self.owner + else: + del pres['from'] + pres.send() else: self.last_status.send() diff --git a/sleekxmpp/roster/multi.py b/sleekxmpp/roster/multi.py index cd4a5195..e9f3389e 100644 --- a/sleekxmpp/roster/multi.py +++ b/sleekxmpp/roster/multi.py @@ -34,7 +34,8 @@ class Roster(object): Defaults to True. Methods: - add -- Create a new roster node for a JID. + add -- Create a new roster node for a JID. + send_presence -- Shortcut for sending a presence stanza. """ def __init__(self, xmpp, db=None): @@ -113,3 +114,27 @@ class Roster(object): """ for node in self: self[node].reset() + + def send_presence(self, pshow=None, pstatus=None, ppriority=None, + pto=None, pfrom=None, ptype=None, pnick=None): + """ + Create, initialize, and send a Presence stanza. + + Forwards the send request to the appropriate roster to + perform the actual sending. + + Arguments: + pshow -- The presence's show value. + pstatus -- The presence's status message. + ppriority -- This connections' priority. + pto -- The recipient of a directed presence. + ptype -- The type of presence, such as 'subscribe'. + pfrom -- The sender of the presence. + pnick -- Optional nickname of the presence's sender. + """ + self[pfrom].send_presence(ptype=ptype, + pshow=pshow, + pstatus=pstatus, + ppriority=ppriority, + pnick=pnick, + pto=pto) diff --git a/sleekxmpp/roster/single.py b/sleekxmpp/roster/single.py index 6ce44e8f..6833563f 100644 --- a/sleekxmpp/roster/single.py +++ b/sleekxmpp/roster/single.py @@ -29,14 +29,17 @@ class RosterNode(object): are created after automatically authrorizing a subscription request. Defaults to True + last_status -- The last sent presence status that was broadcast + to all contact JIDs. Methods: - add -- Add a JID to the roster. - update -- Update a JID's subscription information. - subscribe -- Subscribe to a JID. - unsubscribe -- Unsubscribe from a JID. - remove -- Remove a JID from the roster. - presence -- Return presence information for a JID's resources. + add -- Add a JID to the roster. + update -- Update a JID's subscription information. + subscribe -- Subscribe to a JID. + unsubscribe -- Unsubscribe from a JID. + remove -- Remove a JID from the roster. + presence -- Return presence information for a JID's resources. + send_presence -- Shortcut for sending a presence stanza. """ def __init__(self, xmpp, jid, db=None): @@ -53,6 +56,7 @@ class RosterNode(object): self.db = db self.auto_authorize = True self.auto_subscribe = True + self.last_status = None self._jids = {} if self.db: @@ -135,7 +139,8 @@ class RosterNode(object): 'whitelisted': whitelisted, 'subscription': 'none'} self._jids[jid] = RosterItem(self.xmpp, jid, self.jid, - state=state, db=self.db) + state=state, db=self.db, + roster=self) if save: self._jids[jid].save() @@ -220,3 +225,38 @@ class RosterNode(object): """ for jid in self: self[jid].reset() + + def send_presence(self, ptype=None, pshow=None, pstatus=None, + ppriority=None, pnick=None, pto=None): + """ + Create, initialize, and send a Presence stanza. + + If no recipient is specified, send the presence immediately. + Otherwise, forward the send request to the recipient's roster + entry for processing. + + Arguments: + pshow -- The presence's show value. + pstatus -- The presence's status message. + ppriority -- This connections' priority. + pto -- The recipient of a directed presence. + ptype -- The type of presence, such as 'subscribe'. + """ + if pto: + self[pto].send_presence(ptype, pshow, pstatus, + ppriority, pnick) + else: + p = self.xmpp.make_presence(pshow=pshow, + pstatus=pstatus, + ppriority=ppriority, + ptype=ptype, + pnick=pnick) + if self.xmpp.is_component: + p['from'] = self.jid + if p['type'] in p.showtypes or p['type'] == 'available': + self.last_status = p + p.send() + + if not self.xmpp.sentpresence: + self.xmpp.event('sent_presence') + self.xmpp.sentpresence = True -- cgit v1.2.3