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 __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
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
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
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
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
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
151