c66a4d4097
- update most of the examples with slixmpp - change the help channels pointed out in the doc - add a page listing differences from slixmpp and how to use asyncio nicely with slixmpp - fix some in-code rst documentation
188 lines
5.4 KiB
Python
188 lines
5.4 KiB
Python
"""
|
|
Slixmpp: The Slick XMPP Library
|
|
Copyright (C) 2010 Nathanael C. Fritz
|
|
This file is part of Slixmpp.
|
|
|
|
See the file LICENSE for copying permission.
|
|
"""
|
|
|
|
from slixmpp.stanza.rootstanza import RootStanza
|
|
from slixmpp.xmlstream import StanzaBase, ET
|
|
|
|
|
|
class Message(RootStanza):
|
|
|
|
"""
|
|
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:
|
|
|
|
.. code-block:: xml
|
|
|
|
<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.
|
|
"""
|
|
|
|
name = 'message'
|
|
namespace = 'jabber:client'
|
|
plugin_attrib = name
|
|
interfaces = set(['type', 'to', 'from', 'id', 'body', 'subject',
|
|
'thread', 'parent_thread', 'mucroom', 'mucnick'])
|
|
sub_interfaces = set(['body', 'subject', 'thread'])
|
|
lang_interfaces = sub_interfaces
|
|
types = set(['normal', 'chat', 'headline', 'error', 'groupchat'])
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
"""
|
|
Initialize a new <message /> stanza with an optional 'id' value.
|
|
|
|
Overrides StanzaBase.__init__.
|
|
"""
|
|
StanzaBase.__init__(self, *args, **kwargs)
|
|
if self['id'] == '':
|
|
if self.stream is not None and self.stream.use_message_ids:
|
|
self['id'] = self.stream.new_id()
|
|
|
|
def get_type(self):
|
|
"""
|
|
Return the message type.
|
|
|
|
Overrides default stanza interface behavior.
|
|
|
|
Returns 'normal' if no type attribute is present.
|
|
|
|
:rtype: str
|
|
"""
|
|
return self._get_attr('type', 'normal')
|
|
|
|
def get_parent_thread(self):
|
|
"""Return the message thread's parent thread.
|
|
|
|
:rtype: str
|
|
"""
|
|
thread = self.xml.find('{%s}thread' % self.namespace)
|
|
if thread is not None:
|
|
return thread.attrib.get('parent', '')
|
|
return ''
|
|
|
|
def set_parent_thread(self, value):
|
|
"""Add or change the message thread's parent thread.
|
|
|
|
:param str value: identifier of the thread"""
|
|
thread = self.xml.find('{%s}thread' % self.namespace)
|
|
if value:
|
|
if thread is None:
|
|
thread = ET.Element('{%s}thread' % self.namespace)
|
|
self.xml.append(thread)
|
|
thread.attrib['parent'] = value
|
|
else:
|
|
if thread is not None and 'parent' in thread.attrib:
|
|
del thread.attrib['parent']
|
|
|
|
def del_parent_thread(self):
|
|
"""Delete the message thread's parent reference."""
|
|
thread = self.xml.find('{%s}thread' % self.namespace)
|
|
if thread is not None and 'parent' in thread.attrib:
|
|
del thread.attrib['parent']
|
|
|
|
def chat(self):
|
|
"""Set the message type to 'chat'."""
|
|
self['type'] = 'chat'
|
|
return self
|
|
|
|
def normal(self):
|
|
"""Set the message type to 'normal'."""
|
|
self['type'] = 'normal'
|
|
return self
|
|
|
|
def reply(self, body=None, clear=True):
|
|
"""
|
|
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.
|
|
|
|
:param str body: Optional text content for the message.
|
|
:param bool clear: Indicates if existing content should be removed
|
|
before replying. Defaults to True.
|
|
|
|
:rtype: :class:`~.Message`
|
|
"""
|
|
new_message = StanzaBase.reply(self, clear)
|
|
|
|
if self['type'] == 'groupchat':
|
|
new_message['to'] = new_message['to'].bare
|
|
|
|
new_message['thread'] = self['thread']
|
|
new_message['parent_thread'] = self['parent_thread']
|
|
|
|
del new_message['id']
|
|
|
|
if body is not None:
|
|
new_message['body'] = body
|
|
return new_message
|
|
|
|
def get_mucroom(self):
|
|
"""
|
|
Return the name of the MUC room where the message originated.
|
|
|
|
Read-only stanza interface.
|
|
|
|
:rtype: str
|
|
"""
|
|
if self['type'] == 'groupchat':
|
|
return self['from'].bare
|
|
else:
|
|
return ''
|
|
|
|
def get_mucnick(self):
|
|
"""
|
|
Return the nickname of the MUC user that sent the message.
|
|
|
|
Read-only stanza interface.
|
|
|
|
:rtype: str
|
|
"""
|
|
if self['type'] == 'groupchat':
|
|
return self['from'].resource
|
|
else:
|
|
return ''
|
|
|
|
def set_mucroom(self, value):
|
|
"""Dummy method to prevent modification."""
|
|
pass
|
|
|
|
def del_mucroom(self):
|
|
"""Dummy method to prevent deletion."""
|
|
pass
|
|
|
|
def set_mucnick(self, value):
|
|
"""Dummy method to prevent modification."""
|
|
pass
|
|
|
|
def del_mucnick(self):
|
|
"""Dummy method to prevent deletion."""
|
|
pass
|