Package pyxmpp :: Module iq |
[hide private]

# Source Code for Module pyxmpp.iq

      1  #
      2  # (C) Copyright 2003-2006 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  """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
     32 -class Iq(Stanza):
     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
     81 -    def copy(self):
     82          """Create a deep copy of the iq stanza.
     83
     84          :returntype: `Iq`"""
     85          return Iq(self)
     86
     87 -    def make_error_response(self,cond):
     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
    109 -    def make_result_response(self):
    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
    124 -    def new_query(self,ns_uri,name="query"):
    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
    138 -    def get_query(self):
    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
    153 -    def get_query_ns(self):
    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  # vi: sts=4 et sw=4
    166