Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mrDoctorWho/xmpppy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'xmpp/roster.py')
-rw-r--r--xmpp/roster.py564
1 files changed, 282 insertions, 282 deletions
diff --git a/xmpp/roster.py b/xmpp/roster.py
index b91000e..5d4209a 100644
--- a/xmpp/roster.py
+++ b/xmpp/roster.py
@@ -1,282 +1,282 @@
-## roster.py
-##
-## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
-##
-## This program is free software; you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## This program is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-
-# $Id: roster.py, v1.21 2013/10/21 alkorgun Exp $
-
-"""
-Simple roster implementation. Can be used though for different tasks like
-mass-renaming of contacts.
-"""
-
-from .plugin import PlugIn
-from .protocol import *
-
-class Roster(PlugIn):
- """
- Defines a plenty of methods that will allow you to manage roster.
- Also automatically track presences from remote JIDs taking into
- account that every JID can have multiple resources connected. Does not
- currently support "error" presences.
- You can also use mapping interface for access to the internal representation of
- contacts in roster.
- """
- def __init__(self):
- """
- Init internal variables.
- """
- PlugIn.__init__(self)
- self.DBG_LINE = "roster"
- self._data = {}
- self.set = None
- self._exported_methods = [self.getRoster]
-
- def plugin(self, owner, request=1):
- """
- Register presence and subscription trackers in the owner's dispatcher.
- Also request roster from server if the "request" argument is set.
- Used internally.
- """
- self._owner.RegisterHandler("iq", self.RosterIqHandler, "result", NS_ROSTER)
- self._owner.RegisterHandler("iq", self.RosterIqHandler, "set", NS_ROSTER)
- self._owner.RegisterHandler("presence", self.PresenceHandler)
- if request:
- self.Request()
-
- def Request(self, force=0):
- """
- Request roster from server if it were not yet requested
- (or if the "force" argument is set).
- """
- if self.set is None:
- self.set = 0
- elif not force:
- return None
- self._owner.send(Iq("get", NS_ROSTER))
- self.DEBUG("Roster requested from server", "start")
-
- def getRoster(self):
- """
- Requests roster from server if neccessary and returns self.
- """
- if not self.set:
- self.Request()
- while not self.set:
- self._owner.Process(10)
- return self
-
- def RosterIqHandler(self, dis, stanza):
- """
- Subscription tracker. Used internally for setting items state in
- internal roster representation.
- """
- if not stanza or not stanza.getTag("query"):
- raise NodeProcessed()
- for item in stanza.getTag("query").getTags("item"):
- jid = item.getAttr("jid")
- if item.getAttr("subscription") == "remove":
- if jid in self._data:
- del self._data[jid]
- raise NodeProcessed() # a MUST
- self.DEBUG("Setting roster item %s..." % jid, "ok")
- if jid not in self._data:
- self._data[jid] = {}
- self._data[jid]["name"] = item.getAttr("name")
- self._data[jid]["ask"] = item.getAttr("ask")
- self._data[jid]["subscription"] = item.getAttr("subscription")
- self._data[jid]["groups"] = []
- if "resources" not in self._data[jid]:
- self._data[jid]["resources"] = {}
- for group in item.getTags("group"):
- self._data[jid]["groups"].append(group.getData())
- self._data["@".join((self._owner.User, self._owner.Server))] = {"resources": {}, "name": None, "ask": None, "subscription": None, "groups": None, }
- self.set = 1
- raise NodeProcessed() # a MUST. Otherwise you'll get back an <iq type='error'/>
-
- def PresenceHandler(self, dis, pres):
- """
- Presence tracker. Used internally for setting items' resources state in
- internal roster representation.
- """
- jid = JID(pres.getFrom())
- if jid.getStripped() not in self._data:
- self._data[jid.getStripped()] = {"name": None, "ask": None, "subscription": "none", "groups": ["Not in roster"], "resources": {}}
- item = self._data[jid.getStripped()]
- typ = pres.getType()
- if not typ:
- self.DEBUG("Setting roster item %s for resource %s..." % (jid.getStripped(), jid.getResource()), "ok")
- item["resources"][jid.getResource()] = res = {"show": None, "status": None, "priority": "0", "timestamp": None}
- if pres.getTag("show"):
- res["show"] = pres.getShow()
- if pres.getTag("status"):
- res["status"] = pres.getStatus()
- if pres.getTag("priority"):
- res["priority"] = pres.getPriority()
- if not pres.getTimestamp():
- pres.setTimestamp()
- res["timestamp"] = pres.getTimestamp()
- elif typ == "unavailable" and jid.getResource() in item["resources"]:
- del item["resources"][jid.getResource()]
- # Need to handle type="error" also
-
- def _getItemData(self, jid, dataname):
- """
- Return specific jid's representation in internal format. Used internally.
- """
- jid = jid[:(jid + "/").find("/")]
- return self._data[jid][dataname]
-
- def _getResourceData(self, jid, dataname):
- """
- Return specific jid's resource representation in internal format. Used internally.
- """
- if jid.find("/") + 1:
- jid, resource = jid.split("/", 1)
- if resource in self._data[jid]["resources"]:
- return self._data[jid]["resources"][resource][dataname]
- elif self._data[jid]["resources"].keys():
- lastpri = -129
- for r in self._data[jid]["resources"].keys():
- if int(self._data[jid]["resources"][r]["priority"]) > lastpri:
- resource, lastpri = r, int(self._data[jid]["resources"][r]["priority"])
- return self._data[jid]["resources"][resource][dataname]
-
- def delItem(self, jid):
- """
- Delete contact "jid" from roster.
- """
- self._owner.send(Iq("set", NS_ROSTER, payload=[Node("item", {"jid": jid, "subscription": "remove"})]))
-
- def getAsk(self, jid):
- """
- Returns "ask" value of contact "jid".
- """
- return self._getItemData(jid, "ask")
-
- def getGroups(self, jid):
- """
- Returns groups list that contact "jid" belongs to.
- """
- return self._getItemData(jid, "groups")
-
- def getName(self, jid):
- """
- Returns name of contact "jid".
- """
- return self._getItemData(jid, "name")
-
- def getPriority(self, jid):
- """
- Returns priority of contact "jid". "jid" should be a full (not bare) JID.
- """
- return self._getResourceData(jid, "priority")
-
- def getRawRoster(self):
- """
- Returns roster representation in internal format.
- """
- return self._data
-
- def getRawItem(self, jid):
- """
- Returns roster item "jid" representation in internal format.
- """
- return self._data[jid[:(jid + "/").find("/")]]
-
- def getShow(self, jid):
- """
- Returns "show" value of contact "jid". "jid" should be a full (not bare) JID.
- """
- return self._getResourceData(jid, "show")
-
- def getStatus(self, jid):
- """
- Returns "status" value of contact "jid". "jid" should be a full (not bare) JID.
- """
- return self._getResourceData(jid, "status")
-
- def getSubscription(self, jid):
- """
- Returns "subscription" value of contact "jid".
- """
- return self._getItemData(jid, "subscription")
-
- def getResources(self, jid):
- """
- Returns list of connected resources of contact "jid".
- """
- return self._data[jid[:(jid + "/").find("/")]]["resources"].keys()
-
- def setItem(self, jid, name=None, groups=[]):
- """
- Creates/renames contact "jid" and sets the groups list that it now belongs to.
- """
- iq = Iq("set", NS_ROSTER)
- query = iq.getTag("query")
- attrs = {"jid": jid}
- if name:
- attrs["name"] = name
- item = query.setTag("item", attrs)
- for group in groups:
- item.addChild(node=Node("group", payload=[group]))
- self._owner.send(iq)
-
- def getItems(self):
- """
- Return list of all [bare] JIDs that the roster is currently tracks.
- """
- return self._data.keys()
-
- def keys(self):
- """
- Same as getItems. Provided for the sake of dictionary interface.
- """
- return self._data.keys()
-
- def __getitem__(self, item):
- """
- Get the contact in the internal format. Raises KeyError if JID "item" is not in roster.
- """
- return self._data[item]
-
- def getItem(self, item):
- """
- Get the contact in the internal format (or None if JID "item" is not in roster).
- """
- if item in self._data:
- return self._data[item]
-
- def Subscribe(self, jid):
- """
- Send subscription request to JID "jid".
- """
- self._owner.send(Presence(jid, "subscribe"))
-
- def Unsubscribe(self, jid):
- """
- Ask for removing our subscription for JID "jid".
- """
- self._owner.send(Presence(jid, "unsubscribe"))
-
- def Authorize(self, jid):
- """
- Authorise JID "jid". Works only if these JID requested auth previously.
- """
- self._owner.send(Presence(jid, "subscribed"))
-
- def Unauthorize(self, jid):
- """
- Unauthorise JID "jid". Use for declining authorisation request
- or for removing existing authorization.
- """
- self._owner.send(Presence(jid, "unsubscribed"))
+## roster.py
+##
+## Copyright (C) 2003-2005 Alexey "Snake" Nezhdanov
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+
+# $Id: roster.py, v1.21 2013/10/21 alkorgun Exp $
+
+"""
+Simple roster implementation. Can be used though for different tasks like
+mass-renaming of contacts.
+"""
+
+from .plugin import PlugIn
+from .protocol import *
+
+class Roster(PlugIn):
+ """
+ Defines a plenty of methods that will allow you to manage roster.
+ Also automatically track presences from remote JIDs taking into
+ account that every JID can have multiple resources connected. Does not
+ currently support "error" presences.
+ You can also use mapping interface for access to the internal representation of
+ contacts in roster.
+ """
+ def __init__(self):
+ """
+ Init internal variables.
+ """
+ PlugIn.__init__(self)
+ self.DBG_LINE = "roster"
+ self._data = {}
+ self.set = None
+ self._exported_methods = [self.getRoster]
+
+ def plugin(self, owner, request=1):
+ """
+ Register presence and subscription trackers in the owner's dispatcher.
+ Also request roster from server if the "request" argument is set.
+ Used internally.
+ """
+ self._owner.RegisterHandler("iq", self.RosterIqHandler, "result", NS_ROSTER)
+ self._owner.RegisterHandler("iq", self.RosterIqHandler, "set", NS_ROSTER)
+ self._owner.RegisterHandler("presence", self.PresenceHandler)
+ if request:
+ self.Request()
+
+ def Request(self, force=0):
+ """
+ Request roster from server if it were not yet requested
+ (or if the "force" argument is set).
+ """
+ if self.set is None:
+ self.set = 0
+ elif not force:
+ return None
+ self._owner.send(Iq("get", NS_ROSTER))
+ self.DEBUG("Roster requested from server", "start")
+
+ def getRoster(self):
+ """
+ Requests roster from server if neccessary and returns self.
+ """
+ if not self.set:
+ self.Request()
+ while not self.set:
+ self._owner.Process(10)
+ return self
+
+ def RosterIqHandler(self, dis, stanza):
+ """
+ Subscription tracker. Used internally for setting items state in
+ internal roster representation.
+ """
+ if not stanza or not stanza.getTag("query"):
+ raise NodeProcessed()
+ for item in stanza.getTag("query").getTags("item"):
+ jid = item.getAttr("jid")
+ if item.getAttr("subscription") == "remove":
+ if jid in self._data:
+ del self._data[jid]
+ raise NodeProcessed() # a MUST
+ self.DEBUG("Setting roster item %s..." % jid, "ok")
+ if jid not in self._data:
+ self._data[jid] = {}
+ self._data[jid]["name"] = item.getAttr("name")
+ self._data[jid]["ask"] = item.getAttr("ask")
+ self._data[jid]["subscription"] = item.getAttr("subscription")
+ self._data[jid]["groups"] = []
+ if "resources" not in self._data[jid]:
+ self._data[jid]["resources"] = {}
+ for group in item.getTags("group"):
+ self._data[jid]["groups"].append(group.getData())
+ self._data["@".join((self._owner.User, self._owner.Server))] = {"resources": {}, "name": None, "ask": None, "subscription": None, "groups": None, }
+ self.set = 1
+ raise NodeProcessed() # a MUST. Otherwise you'll get back an <iq type='error'/>
+
+ def PresenceHandler(self, dis, pres):
+ """
+ Presence tracker. Used internally for setting items' resources state in
+ internal roster representation.
+ """
+ jid = JID(pres.getFrom())
+ if jid.getStripped() not in self._data:
+ self._data[jid.getStripped()] = {"name": None, "ask": None, "subscription": "none", "groups": ["Not in roster"], "resources": {}}
+ item = self._data[jid.getStripped()]
+ typ = pres.getType()
+ if not typ:
+ self.DEBUG("Setting roster item %s for resource %s..." % (jid.getStripped(), jid.getResource()), "ok")
+ item["resources"][jid.getResource()] = res = {"show": None, "status": None, "priority": "0", "timestamp": None}
+ if pres.getTag("show"):
+ res["show"] = pres.getShow()
+ if pres.getTag("status"):
+ res["status"] = pres.getStatus()
+ if pres.getTag("priority"):
+ res["priority"] = pres.getPriority()
+ if not pres.getTimestamp():
+ pres.setTimestamp()
+ res["timestamp"] = pres.getTimestamp()
+ elif typ == "unavailable" and jid.getResource() in item["resources"]:
+ del item["resources"][jid.getResource()]
+ # Need to handle type="error" also
+
+ def _getItemData(self, jid, dataname):
+ """
+ Return specific jid's representation in internal format. Used internally.
+ """
+ jid = jid[:(jid + "/").find("/")]
+ return self._data[jid][dataname]
+
+ def _getResourceData(self, jid, dataname):
+ """
+ Return specific jid's resource representation in internal format. Used internally.
+ """
+ if jid.find("/") + 1:
+ jid, resource = jid.split("/", 1)
+ if resource in self._data[jid]["resources"]:
+ return self._data[jid]["resources"][resource][dataname]
+ elif self._data[jid]["resources"].keys():
+ lastpri = -129
+ for r in self._data[jid]["resources"].keys():
+ if int(self._data[jid]["resources"][r]["priority"]) > lastpri:
+ resource, lastpri = r, int(self._data[jid]["resources"][r]["priority"])
+ return self._data[jid]["resources"][resource][dataname]
+
+ def delItem(self, jid):
+ """
+ Delete contact "jid" from roster.
+ """
+ self._owner.send(Iq("set", NS_ROSTER, payload=[Node("item", {"jid": jid, "subscription": "remove"})]))
+
+ def getAsk(self, jid):
+ """
+ Returns "ask" value of contact "jid".
+ """
+ return self._getItemData(jid, "ask")
+
+ def getGroups(self, jid):
+ """
+ Returns groups list that contact "jid" belongs to.
+ """
+ return self._getItemData(jid, "groups")
+
+ def getName(self, jid):
+ """
+ Returns name of contact "jid".
+ """
+ return self._getItemData(jid, "name")
+
+ def getPriority(self, jid):
+ """
+ Returns priority of contact "jid". "jid" should be a full (not bare) JID.
+ """
+ return self._getResourceData(jid, "priority")
+
+ def getRawRoster(self):
+ """
+ Returns roster representation in internal format.
+ """
+ return self._data
+
+ def getRawItem(self, jid):
+ """
+ Returns roster item "jid" representation in internal format.
+ """
+ return self._data[jid[:(jid + "/").find("/")]]
+
+ def getShow(self, jid):
+ """
+ Returns "show" value of contact "jid". "jid" should be a full (not bare) JID.
+ """
+ return self._getResourceData(jid, "show")
+
+ def getStatus(self, jid):
+ """
+ Returns "status" value of contact "jid". "jid" should be a full (not bare) JID.
+ """
+ return self._getResourceData(jid, "status")
+
+ def getSubscription(self, jid):
+ """
+ Returns "subscription" value of contact "jid".
+ """
+ return self._getItemData(jid, "subscription")
+
+ def getResources(self, jid):
+ """
+ Returns list of connected resources of contact "jid".
+ """
+ return self._data[jid[:(jid + "/").find("/")]]["resources"].keys()
+
+ def setItem(self, jid, name=None, groups=[]):
+ """
+ Creates/renames contact "jid" and sets the groups list that it now belongs to.
+ """
+ iq = Iq("set", NS_ROSTER)
+ query = iq.getTag("query")
+ attrs = {"jid": jid}
+ if name:
+ attrs["name"] = name
+ item = query.setTag("item", attrs)
+ for group in groups:
+ item.addChild(node=Node("group", payload=[group]))
+ self._owner.send(iq)
+
+ def getItems(self):
+ """
+ Return list of all [bare] JIDs that the roster is currently tracks.
+ """
+ return self._data.keys()
+
+ def keys(self):
+ """
+ Same as getItems. Provided for the sake of dictionary interface.
+ """
+ return self._data.keys()
+
+ def __getitem__(self, item):
+ """
+ Get the contact in the internal format. Raises KeyError if JID "item" is not in roster.
+ """
+ return self._data[item]
+
+ def getItem(self, item):
+ """
+ Get the contact in the internal format (or None if JID "item" is not in roster).
+ """
+ if item in self._data:
+ return self._data[item]
+
+ def Subscribe(self, jid):
+ """
+ Send subscription request to JID "jid".
+ """
+ self._owner.send(Presence(jid, "subscribe"))
+
+ def Unsubscribe(self, jid):
+ """
+ Ask for removing our subscription for JID "jid".
+ """
+ self._owner.send(Presence(jid, "unsubscribe"))
+
+ def Authorize(self, jid):
+ """
+ Authorise JID "jid". Works only if these JID requested auth previously.
+ """
+ self._owner.send(Presence(jid, "subscribed"))
+
+ def Unauthorize(self, jid):
+ """
+ Unauthorise JID "jid". Use for declining authorisation request
+ or for removing existing authorization.
+ """
+ self._owner.send(Presence(jid, "unsubscribed"))