Package pyxmpp :: Module presence
[hide private]

Source Code for Module pyxmpp.presence

  1  # 
  2  # (C) Copyright 2003-2010 Jacek Konieczny <jajcus@jajcus.net> 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU Lesser General Public License Version 
  6  # 2.1 as published by the Free Software Foundation. 
  7  # 
  8  # This program is distributed in the hope that it will be useful, 
  9  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 10  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 11  # GNU Lesser General Public License for more details. 
 12  # 
 13  # You should have received a copy of the GNU Lesser General Public 
 14  # License along with this program; if not, write to the Free Software 
 15  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 16  # 
 17   
 18  """Presence XMPP stanza handling 
 19   
 20  Normative reference: 
 21    - `RFC 3920 <http://www.ietf.org/rfc/rfc3920.txt>`__ 
 22  """ 
 23   
 24  __docformat__="restructuredtext en" 
 25   
 26  import libxml2 
 27   
 28  from pyxmpp.utils import to_utf8,from_utf8 
 29  from pyxmpp.stanza import Stanza 
 30  from pyxmpp.xmlextra import common_ns 
 31   
 32  presence_types=("available","unavailable","probe","subscribe","unsubscribe","subscribed", 
 33          "unsubscribed","invisible","error") 
 34   
 35  accept_responses={ 
 36          "subscribe": "subscribed", 
 37          "subscribed": "subscribe", 
 38          "unsubscribe": "unsubscribed", 
 39          "unsubscribed": "unsubscribe", 
 40          } 
 41   
 42  deny_responses={ 
 43          "subscribe": "unsubscribed", 
 44          "subscribed": "unsubscribe", 
 45          "unsubscribe": "subscribed", 
 46          "unsubscribed": "subscribe", 
 47          } 
 48   
49 -class Presence(Stanza):
50 """Wraper object for <presence /> stanzas.""" 51 stanza_type="presence"
52 - def __init__(self, xmlnode = None, from_jid = None, to_jid = None, stanza_type = None, 53 stanza_id = None, show = None, status = None, priority = 0, 54 error = None, error_cond = None, stream = None):
55 """Initialize a `Presence` object. 56 57 :Parameters: 58 - `xmlnode`: XML node to_jid be wrapped into the `Presence` object 59 or other Presence object to be copied. If not given then new 60 presence stanza is created using following parameters. 61 - `from_jid`: sender JID. 62 - `to_jid`: recipient JID. 63 - `stanza_type`: staza type: one of: None, "available", "unavailable", 64 "subscribe", "subscribed", "unsubscribe", "unsubscribed" or 65 "error". "available" is automaticaly changed to_jid None. 66 - `stanza_id`: stanza id -- value of stanza's "id" attribute 67 - `show`: "show" field of presence stanza. One of: None, "away", 68 "xa", "dnd", "chat". 69 - `status`: descriptive text for the presence stanza. 70 - `priority`: presence priority. 71 - `error_cond`: error condition name. Ignored if `stanza_type` is not "error" 72 :Types: 73 - `xmlnode`: `unicode` or `libxml2.xmlNode` or `Stanza` 74 - `from_jid`: `JID` 75 - `to_jid`: `JID` 76 - `stanza_type`: `unicode` 77 - `stanza_id`: `unicode` 78 - `show`: `unicode` 79 - `status`: `unicode` 80 - `priority`: `unicode` 81 - `error_cond`: `unicode`""" 82 self.xmlnode=None 83 if isinstance(xmlnode,Presence): 84 pass 85 elif isinstance(xmlnode,Stanza): 86 raise TypeError,"Couldn't make Presence from other Stanza" 87 elif isinstance(xmlnode,libxml2.xmlNode): 88 pass 89 elif xmlnode is not None: 90 raise TypeError,"Couldn't make Presence from %r" % (type(xmlnode),) 91 92 if stanza_type and stanza_type not in presence_types: 93 raise ValueError, "Invalid presence type: %r" % (type,) 94 95 if stanza_type=="available": 96 stanza_type=None 97 98 if xmlnode is None: 99 xmlnode="presence" 100 101 Stanza.__init__(self, xmlnode, from_jid = from_jid, to_jid = to_jid, stanza_type = stanza_type, 102 stanza_id = stanza_id, error = error, error_cond = error_cond, stream = stream) 103 104 if show: 105 self.xmlnode.newTextChild(common_ns,"show",to_utf8(show)) 106 if status: 107 self.xmlnode.newTextChild(common_ns,"status",to_utf8(status)) 108 if priority and priority!=0: 109 self.xmlnode.newTextChild(common_ns,"priority",to_utf8(unicode(priority)))
110
111 - def copy(self):
112 """Create a deep copy of the presence stanza. 113 114 :returntype: `Presence`""" 115 return Presence(self)
116
117 - def set_status(self,status):
118 """Change presence status description. 119 120 :Parameters: 121 - `status`: descriptive text for the presence stanza. 122 :Types: 123 - `status`: `unicode`""" 124 n=self.xpath_eval("ns:status") 125 if not status: 126 if n: 127 n[0].unlinkNode() 128 n[0].freeNode() 129 else: 130 return 131 if n: 132 n[0].setContent(to_utf8(status)) 133 else: 134 self.xmlnode.newTextChild(common_ns,"status",to_utf8(status))
135
136 - def get_status(self):
137 """Get presence status description. 138 139 :return: value of stanza's <status/> field. 140 :returntype: `unicode`""" 141 n=self.xpath_eval("ns:status") 142 if n: 143 return from_utf8(n[0].getContent()) 144 else: 145 return None
146
147 - def get_show(self):
148 """Get presence "show" field. 149 150 :return: value of stanza's <show/> field. 151 :returntype: `unicode`""" 152 n=self.xpath_eval("ns:show") 153 if n: 154 return from_utf8(n[0].getContent()) 155 else: 156 return None
157
158 - def set_show(self,show):
159 """Change presence "show" field. 160 161 :Parameters: 162 - `show`: new value for the "show" field of presence stanza. One 163 of: None, "away", "xa", "dnd", "chat". 164 :Types: 165 - `show`: `unicode`""" 166 n=self.xpath_eval("ns:show") 167 if not show: 168 if n: 169 n[0].unlinkNode() 170 n[0].freeNode() 171 else: 172 return 173 if n: 174 n[0].setContent(to_utf8(show)) 175 else: 176 self.xmlnode.newTextChild(common_ns,"show",to_utf8(show))
177
178 - def get_priority(self):
179 """Get presence priority. 180 181 :return: value of stanza's priority. 0 if the stanza doesn't contain 182 <priority/> element. 183 :returntype: `int`""" 184 n=self.xpath_eval("ns:priority") 185 if not n: 186 return 0 187 try: 188 prio=int(n[0].getContent()) 189 except ValueError: 190 return 0 191 return prio
192
193 - def set_priority(self,priority):
194 """Change presence priority. 195 196 :Parameters: 197 - `priority`: new presence priority. 198 :Types: 199 - `priority`: `int`""" 200 n=self.xpath_eval("ns:priority") 201 if not priority: 202 if n: 203 n[0].unlinkNode() 204 n[0].freeNode() 205 else: 206 return 207 priority=int(priority) 208 if priority<-128 or priority>127: 209 raise ValueError, "Bad priority value" 210 priority=str(priority) 211 if n: 212 n[0].setContent(priority) 213 else: 214 self.xmlnode.newTextChild(common_ns,"priority",priority)
215
216 - def make_accept_response(self):
217 """Create "accept" response for the "subscribe"/"subscribed"/"unsubscribe"/"unsubscribed" 218 presence stanza. 219 220 :return: new stanza. 221 :returntype: `Presence`""" 222 223 if self.get_type() not in ("subscribe","subscribed","unsubscribe","unsubscribed"): 224 raise ValueError, ("Results may only be generated for 'subscribe'," 225 "'subscribed','unsubscribe' or 'unsubscribed' presence") 226 227 pr=Presence(stanza_type=accept_responses[self.get_type()], 228 from_jid=self.get_to(),to_jid=self.get_from(),stanza_id=self.get_id()) 229 return pr
230
231 - def make_deny_response(self):
232 """Create "deny" response for the "subscribe"/"subscribed"/"unsubscribe"/"unsubscribed" 233 presence stanza. 234 235 :return: new presence stanza. 236 :returntype: `Presence`""" 237 if self.get_type() not in ("subscribe","subscribed","unsubscribe","unsubscribed"): 238 raise ValueError, ("Results may only be generated for 'subscribe'," 239 "'subscribed','unsubscribe' or 'unsubscribed' presence") 240 241 pr=Presence(stanza_type=deny_responses[self.get_type()], 242 from_jid=self.get_to(),to_jid=self.get_from(),stanza_id=self.get_id()) 243 return pr
244
245 - def make_error_response(self,cond):
246 """Create error response for the any non-error presence stanza. 247 248 :Parameters: 249 - `cond`: error condition name, as defined in XMPP specification. 250 :Types: 251 - `cond`: `unicode` 252 253 :return: new presence stanza. 254 :returntype: `Presence`""" 255 256 if self.get_type() == "error": 257 raise ValueError, "Errors may not be generated in response to errors" 258 259 p=Presence(stanza_type="error",from_jid=self.get_to(),to_jid=self.get_from(), 260 stanza_id=self.get_id(),error_cond=cond) 261 262 if self.xmlnode.children: 263 n=self.xmlnode.children 264 while n: 265 p.xmlnode.children.addPrevSibling(n.copyNode(1)) 266 n=n.next 267 return p
268 269 # vi: sts=4 et sw=4 270