1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 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   
 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   
 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   
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   
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   
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   
152