pyxmpp.message

Package pyxmpp :: Module message |
[hide private]

# Source Code for Module pyxmpp.message

      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  """Message 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  from pyxmpp.stanza import Stanza
     28  from pyxmpp.utils import to_utf8,from_utf8
     29  from pyxmpp.xmlextra import common_ns
     30
     31  message_types=("normal","chat","headline","error","groupchat")
     32
     33 -class Message(Stanza):
     34      """Wraper object for <message /> stanzas."""
     35      stanza_type="message"
     36 -    def __init__(self, xmlnode = None, from_jid = None, to_jid = None, stanza_type = None, stanza_id = None,
     37              subject = None, body = None, thread = None, error = None, error_cond = None, stream = None):
     38          """Initialize a `Message` object.
     39
     40          :Parameters:
     41              - `xmlnode`: XML node to_jid be wrapped into the `Message` object
     42                or other Message object to be copied. If not given then new
     43                presence stanza is created using following parameters.
     44              - `from_jid`: sender JID.
     45              - `to_jid`: recipient JID.
     46              - `stanza_type`: staza type: one of: "get", "set", "result" or "error".
     47              - `stanza_id`: stanza id -- value of stanza's "id" attribute. If not
     48                given, then unique for the session value is generated.
     49              - `subject`: message subject,
     50              - `body`: message body.
     51              - `thread`: message thread id.
     52              - `error_cond`: error condition name. Ignored if `stanza_type` is not "error".
     53          :Types:
     54              - `xmlnode`: `unicode` or `libxml2.xmlNode` or `Stanza`
     55              - `from_jid`: `JID`
     56              - `to_jid`: `JID`
     57              - `stanza_type`: `unicode`
     58              - `stanza_id`: `unicode`
     59              - `subject`: `unicode`
     60              - `body`: `unicode`
     61              - `thread`: `unicode`
     62              - `error_cond`: `unicode`"""
     63
     64          self.xmlnode=None
     65          if isinstance(xmlnode,Message):
     66              pass
     67          elif isinstance(xmlnode,Stanza):
     68              raise TypeError, "Couldn't make Message from other Stanza"
     69          elif isinstance(xmlnode,libxml2.xmlNode):
     70              pass
     71          elif xmlnode is not None:
     72              raise TypeError, "Couldn't make Message from %r" % (type(xmlnode),)
     73
     74          if xmlnode is None:
     75              xmlnode="message"
     76
     77          Stanza.__init__(self, xmlnode, from_jid = from_jid, to_jid = to_jid, stanza_type = stanza_type,
     78                  stanza_id = stanza_id, error = error, error_cond = error_cond, stream = stream)
     79
     80          if subject is not None:
     81              self.xmlnode.newTextChild(common_ns,"subject",to_utf8(subject))
     82          if body is not None:
     83              self.xmlnode.newTextChild(common_ns,"body",to_utf8(body))
     84          if thread is not None:
     85              self.xmlnode.newTextChild(common_ns,"thread",to_utf8(thread))
     86
     87 -    def get_subject(self):
     88          """Get the message subject.
     89
     90          :return: the message subject or `None` if there is no subject.
     91          :returntype: `unicode`"""
     92          n=self.xpath_eval("ns:subject")
     93          if n:
     94              return from_utf8(n[0].getContent())
     95          else:
     96              return None
     97
     98 -    def get_thread(self):
     99          """Get the thread-id subject.
    100
    101          :return: the thread-id or `None` if there is no thread-id.
    102          :returntype: `unicode`"""
    103          n=self.xpath_eval("ns:thread")
    104          if n:
    105              return from_utf8(n[0].getContent())
    106          else:
    107              return None
    108
    109 -    def copy(self):
    110          """Create a deep copy of the message stanza.
    111
    112          :returntype: `Message`"""
    113          return Message(self)
    114
    115 -    def get_body(self):
    116          """Get the body of the message.
    117
    118          :return: the body of the message or `None` if there is no body.
    119          :returntype: `unicode`"""
    120          n=self.xpath_eval("ns:body")
    121          if n:
    122              return from_utf8(n[0].getContent())
    123          else:
    124              return None
    125
    126 -    def make_error_response(self,cond):
    127          """Create error response for any non-error message stanza.
    128
    129          :Parameters:
    130              - `cond`: error condition name, as defined in XMPP specification.
    131
    132          :return: new message stanza with the same "id" as self, "from" and
    133              "to" attributes swapped, type="error" and containing <error />
    134              element plus payload of `self`.
    135          :returntype: `unicode`"""
    136
    137          if self.get_type() == "error":
    138              raise ValueError, "Errors may not be generated in response to errors"
    139
    140          m=Message(stanza_type="error",from_jid=self.get_to(),to_jid=self.get_from(),
    141              stanza_id=self.get_id(),error_cond=cond)
    142
    143          if self.xmlnode.children:
    144              n=self.xmlnode.children
    145              while n:
    146                  m.xmlnode.children.addPrevSibling(n.copyNode(1))
    147                  n=n.next
    148          return m
    149
    150  # vi: sts=4 et sw=4
    151