Package pyxmpp :: Module message |
[hide private]

# Source Code for Module pyxmpp.message

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