1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18  """Iq XMPP stanza handling 
 19   
 20  Normative reference: 
 21    - `RFC 3920 <http://www.ietf.org/rfc/rfc3920.txt>`__ 
 22  """ 
 23   
 24  __revision__="$Id: iq.py 651 2006-08-27 19:26:45Z jajcus $" 
 25  __docformat__="restructuredtext en" 
 26   
 27  import libxml2 
 28   
 29  from pyxmpp.xmlextra import get_node_ns_uri 
 30  from pyxmpp.stanza import Stanza, gen_id 
 31   
 33      """Wraper object for <iq /> stanzas.""" 
 34      stanza_type="iq" 
 35 -    def __init__(self, xmlnode = None, from_jid = None, to_jid = None, stanza_type = None, 
 36              stanza_id = None, error = None, error_cond=None, stream = None): 
  37          """Initialize an `Iq` object. 
 38   
 39          :Parameters: 
 40              - `xmlnode`: XML node to_jid be wrapped into the `Iq` object 
 41                or other Iq object to be copied. If not given then new 
 42                presence stanza is created using following parameters. 
 43              - `from_jid`: sender JID. 
 44              - `to_jid`: recipient JID. 
 45              - `stanza_type`: staza type: one of: "get", "set", "result" or "error". 
 46              - `stanza_id`: stanza id -- value of stanza's "id" attribute. If not 
 47                given, then unique for the session value is generated. 
 48              - `error_cond`: error condition name. Ignored if `stanza_type` is not "error". 
 49          :Types: 
 50              - `xmlnode`: `unicode` or `libxml2.xmlNode` or `Iq` 
 51              - `from_jid`: `JID` 
 52              - `to_jid`: `JID` 
 53              - `stanza_type`: `unicode` 
 54              - `stanza_id`: `unicode` 
 55              - `error_cond`: `unicode`""" 
 56          self.xmlnode=None 
 57          if isinstance(xmlnode,Iq): 
 58              pass 
 59          elif isinstance(xmlnode,Stanza): 
 60              raise TypeError,"Couldn't make Iq from other Stanza" 
 61          elif isinstance(xmlnode,libxml2.xmlNode): 
 62              pass 
 63          elif xmlnode is not None: 
 64              raise TypeError,"Couldn't make Iq from %r" % (type(xmlnode),) 
 65          elif not stanza_type: 
 66              raise ValueError, "type is required for Iq" 
 67          else: 
 68              if not stanza_id and stanza_type in ("get", "set"): 
 69                  stanza_id=gen_id() 
 70   
 71          if not xmlnode and stanza_type not in ("get","set","result","error"): 
 72              raise ValueError, "Invalid Iq type: %r" % (stanza_type,) 
 73   
 74          if xmlnode is None: 
 75              xmlnode="iq" 
 76   
 77          Stanza.__init__(self, xmlnode, from_jid = from_jid, to_jid = to_jid, 
 78              stanza_type = stanza_type, stanza_id = stanza_id, error = error, 
 79              error_cond = error_cond, stream = stream) 
  80   
 82          """Create a deep copy of the iq stanza. 
 83   
 84          :returntype: `Iq`""" 
 85          return Iq(self) 
  86   
 88          """Create error response for the a "get" or "set" iq stanza. 
 89   
 90          :Parameters: 
 91              - `cond`: error condition name, as defined in XMPP specification. 
 92   
 93          :return: new `Iq` object with the same "id" as self, "from" and "to" 
 94              attributes swapped, type="error" and containing <error /> element 
 95              plus payload of `self`. 
 96          :returntype: `Iq`""" 
 97   
 98          if self.get_type() in ("result", "error"): 
 99              raise ValueError, "Errors may not be generated for 'result' and 'error' iq" 
100   
101          iq=Iq(stanza_type="error",from_jid=self.get_to(),to_jid=self.get_from(), 
102              stanza_id=self.get_id(),error_cond=cond) 
103          n=self.get_query() 
104          if n: 
105              n=n.copyNode(1) 
106              iq.xmlnode.children.addPrevSibling(n) 
107          return iq 
 108   
110          """Create result response for the a "get" or "set" iq stanza. 
111   
112          :return: new `Iq` object with the same "id" as self, "from" and "to" 
113              attributes replaced and type="result". 
114          :returntype: `Iq`""" 
115   
116          if self.get_type() not in ("set","get"): 
117              raise ValueError, "Results may only be generated for 'set' or 'get' iq" 
118   
119          iq=Iq(stanza_type="result", from_jid=self.get_to(), 
120                  to_jid=self.get_from(), stanza_id=self.get_id()) 
121   
122          return iq 
 123   
125          """Create new payload element for the stanza. 
126   
127          :Parameters: 
128              - `ns_uri`: namespace URI of the element. 
129              - `name`: element name. 
130          :Types: 
131              - `ns_uri`: `str` 
132              - `name`: `unicode` 
133   
134          :return: the new payload node. 
135          :returntype: `libxml2.xmlNode`""" 
136          return self.set_new_content(ns_uri,name) 
 137   
139          """Get the payload element of the stanza. 
140   
141          :return: the payload element or None if there is no payload. 
142          :returntype: `libxml2.xmlNode`""" 
143          c = self.xmlnode.children 
144          while c: 
145              try: 
146                  if c.ns(): 
147                      return c 
148              except libxml2.treeError: 
149                  pass 
150              c = c.next 
151          return None 
 152   
154          """Get a namespace of the stanza payload. 
155   
156          :return: XML namespace URI of the payload or None if there is no 
157              payload. 
158          :returntype: `str`""" 
159          q=self.get_query() 
160          if q: 
161              return get_node_ns_uri(q) 
162          else: 
163              return None 
  164   
165   
166