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