summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sleekxmpp/stanza/message.py188
-rw-r--r--tests/test_messagestanzas.py73
2 files changed, 171 insertions, 90 deletions
diff --git a/sleekxmpp/stanza/message.py b/sleekxmpp/stanza/message.py
index 75ecc232..560e1d47 100644
--- a/sleekxmpp/stanza/message.py
+++ b/sleekxmpp/stanza/message.py
@@ -5,59 +5,139 @@
See the file LICENSE for copying permission.
"""
-from .. xmlstream.stanzabase import StanzaBase
-from xml.etree import cElementTree as ET
-from . error import Error
-from . rootstanza import RootStanza
+
+from sleekxmpp.stanza import Error
+from sleekxmpp.stanza.rootstanza import RootStanza
+from sleekxmpp.xmlstream.stanzabase import StanzaBase, ET
+
class Message(RootStanza):
- interfaces = set(('type', 'to', 'from', 'id', 'body', 'subject', 'mucroom', 'mucnick'))
- types = set((None, 'normal', 'chat', 'headline', 'error', 'groupchat'))
- sub_interfaces = set(('body', 'subject'))
- name = 'message'
- plugin_attrib = name
- namespace = 'jabber:client'
-
- def getType(self):
- return self.xml.attrib.get('type', 'normal')
-
- def chat(self):
- self['type'] = 'chat'
- return self
-
- def normal(self):
- self['type'] = 'normal'
- return self
-
- def reply(self, body=None):
- StanzaBase.reply(self)
- if self['type'] == 'groupchat':
- self['to'] = self['to'].bare
- del self['id']
- if body is not None:
- self['body'] = body
- return self
-
- def getMucroom(self):
- if self['type'] == 'groupchat':
- return self['from'].bare
- else:
- return ''
-
- def setMucroom(self, value):
- pass
-
- def delMucroom(self):
- pass
-
- def getMucnick(self):
- if self['type'] == 'groupchat':
- return self['from'].resource
- else:
- return ''
-
- def setMucnick(self, value):
- pass
-
- def delMucnick(self):
- pass
+
+ """
+ XMPP's <message> stanzas are a "push" mechanism to send information
+ to other XMPP entities without requiring a response.
+
+ Chat clients will typically use <message> stanzas that have a type
+ of either "chat" or "groupchat".
+
+ When handling a message event, be sure to check if the message is
+ an error response.
+
+ Example <message> stanzas:
+ <message to="user1@example.com" from="user2@example.com">
+ <body>Hi!</body>
+ </message>
+
+ <message type="groupchat" to="room@conference.example.com">
+ <body>Hi everyone!</body>
+ </message>
+
+ Stanza Interface:
+ body -- The main contents of the message.
+ subject -- An optional description of the message's contents.
+ mucroom -- (Read-only) The name of the MUC room that sent the message.
+ mucnick -- (Read-only) The MUC nickname of message's sender.
+
+ Attributes:
+ types -- May be one of: normal, chat, headline, groupchat, or error.
+
+ Methods:
+ chat -- Set the message type to 'chat'.
+ normal -- Set the message type to 'normal'.
+ reply -- Overrides StanzaBase.reply
+ getType -- Overrides StanzaBase interface
+ getMucroom -- Return the name of the MUC room of the message.
+ setMucroom -- Dummy method to prevent assignment.
+ delMucroom -- Dummy method to prevent deletion.
+ getMucnick -- Return the MUC nickname of the message's sender.
+ setMucnick -- Dummy method to prevent assignment.
+ delMucnick -- Dummy method to prevent deletion.
+ """
+
+ namespace = 'jabber:client'
+ name = 'message'
+ interfaces = set(('type', 'to', 'from', 'id', 'body', 'subject',
+ 'mucroom', 'mucnick'))
+ sub_interfaces = set(('body', 'subject'))
+ plugin_attrib = name
+ types = set((None, 'normal', 'chat', 'headline', 'error', 'groupchat'))
+
+ def getType(self):
+ """
+ Return the message type.
+
+ Overrides default stanza interface behavior.
+
+ Returns 'normal' if no type attribute is present.
+ """
+ return self._getAttr('type', 'normal')
+
+ def chat(self):
+ """Set the message type to 'chat'."""
+ self['type'] = 'chat'
+ return self
+
+ def normal(self):
+ """Set the message type to 'chat'."""
+ self['type'] = 'normal'
+ return self
+
+ def reply(self, body=None):
+ """
+ Create a message reply.
+
+ Overrides StanzaBase.reply.
+
+ Sets proper 'to' attribute if the message is from a MUC, and
+ adds a message body if one is given.
+
+ Arguments:
+ body -- Optional text content for the message.
+ """
+ StanzaBase.reply(self)
+ if self['type'] == 'groupchat':
+ self['to'] = self['to'].bare
+
+ del self['id']
+
+ if body is not None:
+ self['body'] = body
+ return self
+
+ def getMucroom(self):
+ """
+ Return the name of the MUC room where the message originated.
+
+ Read-only stanza interface.
+ """
+ if self['type'] == 'groupchat':
+ return self['from'].bare
+ else:
+ return ''
+
+ def getMucnick(self):
+ """
+ Return the nickname of the MUC user that sent the message.
+
+ Read-only stanza interface.
+ """
+ if self['type'] == 'groupchat':
+ return self['from'].resource
+ else:
+ return ''
+
+ def setMucroom(self, value):
+ """Dummy method to prevent modification."""
+ pass
+
+ def delMucroom(self):
+ """Dummy method to prevent deletion."""
+ pass
+
+ def setMucnick(self, value):
+ """Dummy method to prevent modification."""
+ pass
+
+ def delMucnick(self):
+ """Dummy method to prevent deletion."""
+ pass
diff --git a/tests/test_messagestanzas.py b/tests/test_messagestanzas.py
index c83b59a7..f55211db 100644
--- a/tests/test_messagestanzas.py
+++ b/tests/test_messagestanzas.py
@@ -2,44 +2,45 @@ from sleektest import *
from sleekxmpp.stanza.message import Message
from sleekxmpp.stanza.htmlim import HTMLIM
+
class TestMessageStanzas(SleekTest):
- def setUp(self):
- registerStanzaPlugin(Message, HTMLIM)
-
- def testGroupchatReplyRegression(self):
- "Regression groupchat reply should be to barejid"
- msg = self.Message()
- msg['to'] = 'me@myserver.tld'
- msg['from'] = 'room@someservice.someserver.tld/somenick'
- msg['type'] = 'groupchat'
- msg['body'] = "this is a message"
- msg.reply()
- self.failUnless(str(msg['to']) == 'room@someservice.someserver.tld')
+ def setUp(self):
+ registerStanzaPlugin(Message, HTMLIM)
+
+ def testGroupchatReplyRegression(self):
+ "Regression groupchat reply should be to barejid"
+ msg = self.Message()
+ msg['to'] = 'me@myserver.tld'
+ msg['from'] = 'room@someservice.someserver.tld/somenick'
+ msg['type'] = 'groupchat'
+ msg['body'] = "this is a message"
+ msg.reply()
+ self.failUnless(str(msg['to']) == 'room@someservice.someserver.tld')
+
+ def testAttribProperty(self):
+ "Test attrib property returning self"
+ msg = self.Message()
+ msg.attrib.attrib.attrib['to'] = 'usr@server.tld'
+ self.failUnless(str(msg['to']) == 'usr@server.tld')
- def testAttribProperty(self):
- "Test attrib property returning self"
- msg = self.Message()
- msg.attrib.attrib.attrib['to'] = 'usr@server.tld'
- self.failUnless(str(msg['to']) == 'usr@server.tld')
-
- def testHTMLPlugin(self):
- "Test message/html/html stanza"
- msg = self.Message()
- msg['to'] = "fritzy@netflint.net/sleekxmpp"
- msg['body'] = "this is the plaintext message"
- msg['type'] = 'chat'
- p = ET.Element('{http://www.w3.org/1999/xhtml}p')
- p.text = "This is the htmlim message"
- msg['html']['html'] = p
- self.checkMessage(msg, """
- <message to="fritzy@netflint.net/sleekxmpp" type="chat">
- <body>this is the plaintext message</body>
- <html xmlns="http://jabber.org/protocol/xhtml-im">
- <body xmlns="http://www.w3.org/1999/xhtml">
- <p>This is the htmlim message</p>
- </body>
- </html>
- </message>""")
+ def testHTMLPlugin(self):
+ "Test message/html/html stanza"
+ msg = self.Message()
+ msg['to'] = "fritzy@netflint.net/sleekxmpp"
+ msg['body'] = "this is the plaintext message"
+ msg['type'] = 'chat'
+ p = ET.Element('{http://www.w3.org/1999/xhtml}p')
+ p.text = "This is the htmlim message"
+ msg['html']['html'] = p
+ self.checkMessage(msg, """
+ <message to="fritzy@netflint.net/sleekxmpp" type="chat">
+ <body>this is the plaintext message</body>
+ <html xmlns="http://jabber.org/protocol/xhtml-im">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <p>This is the htmlim message</p>
+ </body>
+ </html>
+ </message>""")
suite = unittest.TestLoader().loadTestsFromTestCase(TestMessageStanzas)