mirror of
https://github.com/correl/SleekXMPP.git
synced 2024-11-27 19:19:54 +00:00
Merge branch 'xep_0085' into develop
This commit is contained in:
commit
109af1b1b6
3 changed files with 148 additions and 1 deletions
|
@ -17,4 +17,4 @@
|
|||
along with SleekXMPP; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
__all__ = ['xep_0004', 'xep_0030', 'xep_0045', 'xep_0050', 'xep_0078', 'xep_0092', 'xep_0199', 'gmail_notify', 'xep_0060']
|
||||
__all__ = ['xep_0004', 'xep_0030', 'xep_0045', 'xep_0050', 'xep_0078', 'xep_0085', 'xep_0092', 'xep_0199', 'gmail_notify', 'xep_0060']
|
||||
|
|
100
sleekxmpp/plugins/xep_0085.py
Normal file
100
sleekxmpp/plugins/xep_0085.py
Normal file
|
@ -0,0 +1,100 @@
|
|||
"""
|
||||
SleekXMPP: The Sleek XMPP Library
|
||||
Copyright (C) 2010 Nathanael C. Fritz, Lance J.T. Stout
|
||||
This file is part of SleekXMPP.
|
||||
|
||||
See the file license.txt for copying permissio
|
||||
"""
|
||||
|
||||
import logging
|
||||
from . import base
|
||||
from .. xmlstream.handler.callback import Callback
|
||||
from .. xmlstream.matcher.xpath import MatchXPath
|
||||
from .. xmlstream.stanzabase import ElementBase, ET, JID
|
||||
from .. stanza.message import Message
|
||||
|
||||
|
||||
class ChatState(ElementBase):
|
||||
namespace = 'http://jabber.org/protocol/chatstates'
|
||||
plugin_attrib = 'chat_state'
|
||||
interface = set(('state',))
|
||||
states = set(('active', 'composing', 'gone', 'inactive', 'paused'))
|
||||
|
||||
def active(self):
|
||||
self.setState('active')
|
||||
|
||||
def composing(self):
|
||||
self.setState('composing')
|
||||
|
||||
def gone(self):
|
||||
self.setState('gone')
|
||||
|
||||
def inactive(self):
|
||||
self.setState('inactive')
|
||||
|
||||
def paused(self):
|
||||
self.setState('paused')
|
||||
|
||||
def setState(self, state):
|
||||
if state in self.states:
|
||||
self.name = state
|
||||
self.xml.tag = state
|
||||
self.xml.attrib['xmlns'] = self.namespace
|
||||
|
||||
def getState(self):
|
||||
return self.name
|
||||
|
||||
# In order to match the various chat state elements,
|
||||
# we need one stanza object per state, even though
|
||||
# they are all the same except for the initial name
|
||||
# value. Do not depend on the type of the chat state
|
||||
# stanza object for the actual state.
|
||||
|
||||
class Active(ChatState):
|
||||
name = 'active'
|
||||
class Composing(ChatState):
|
||||
name = 'composing'
|
||||
class Gone(ChatState):
|
||||
name = 'gone'
|
||||
class Inactive(ChatState):
|
||||
name = 'inactive'
|
||||
class Paused(ChatState):
|
||||
name = 'paused'
|
||||
|
||||
|
||||
class xep_0085(base.base_plugin):
|
||||
"""
|
||||
XEP-0085 Chat State Notifications
|
||||
"""
|
||||
|
||||
def plugin_init(self):
|
||||
self.xep = '0085'
|
||||
self.description = 'Chat State Notifications'
|
||||
|
||||
handlers = [('Active Chat State', 'active'),
|
||||
('Composing Chat State', 'composing'),
|
||||
('Gone Chat State', 'gone'),
|
||||
('Inactive Chat State', 'inactive'),
|
||||
('Paused Chat State', 'paused')]
|
||||
for handler in handlers:
|
||||
self.xmpp.registerHandler(
|
||||
Callback(handler[0],
|
||||
MatchXPath("{%s}message/{%s}%s" % (self.xmpp.default_ns,
|
||||
ChatState.namespace,
|
||||
handler[1])),
|
||||
self._handleChatState))
|
||||
|
||||
self.xmpp.stanzaPlugin(Message, Active)
|
||||
self.xmpp.stanzaPlugin(Message, Composing)
|
||||
self.xmpp.stanzaPlugin(Message, Gone)
|
||||
self.xmpp.stanzaPlugin(Message, Inactive)
|
||||
self.xmpp.stanzaPlugin(Message, Paused)
|
||||
|
||||
def post_init(self):
|
||||
base.base_plugin.post_init(self)
|
||||
self.xmpp.plugin['xep_0030'].add_feature('http://jabber.org/protocol/chatstates')
|
||||
|
||||
def _handleChatState(self, msg):
|
||||
state = msg['chat_state'].name
|
||||
logging.debug("Chat State: %s, %s" % (state, msg['from'].jid))
|
||||
self.xmpp.event('chatstate_%s' % state, msg)
|
47
tests/test_chatstates.py
Normal file
47
tests/test_chatstates.py
Normal file
|
@ -0,0 +1,47 @@
|
|||
import unittest
|
||||
from xml.etree import cElementTree as ET
|
||||
from sleekxmpp.xmlstream.matcher.stanzapath import StanzaPath
|
||||
from . import xmlcompare
|
||||
|
||||
import sleekxmpp.plugins.xep_0085 as cs
|
||||
|
||||
def stanzaPlugin(stanza, plugin):
|
||||
stanza.plugin_attrib_map[plugin.plugin_attrib] = plugin
|
||||
stanza.plugin_tag_map["{%s}%s" % (plugin.namespace, plugin.name)] = plugin
|
||||
|
||||
class testchatstates(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.cs = cs
|
||||
stanzaPlugin(self.cs.Message, self.cs.Active)
|
||||
stanzaPlugin(self.cs.Message, self.cs.Composing)
|
||||
stanzaPlugin(self.cs.Message, self.cs.Gone)
|
||||
stanzaPlugin(self.cs.Message, self.cs.Inactive)
|
||||
stanzaPlugin(self.cs.Message, self.cs.Paused)
|
||||
|
||||
def try2Methods(self, xmlstring, msg):
|
||||
msg2 = self.cs.Message(None, self.cs.ET.fromstring(xmlstring))
|
||||
self.failUnless(xmlstring == str(msg) == str(msg2),
|
||||
"Two methods for creating stanza don't match")
|
||||
|
||||
def testCreateChatState(self):
|
||||
"""Testing creating chat states."""
|
||||
xmlstring = """<message><%s xmlns="http://jabber.org/protocol/chatstates" /></message>"""
|
||||
|
||||
msg = self.cs.Message()
|
||||
msg['chat_state'].active()
|
||||
self.try2Methods(xmlstring % 'active', msg)
|
||||
|
||||
msg['chat_state'].composing()
|
||||
self.try2Methods(xmlstring % 'composing', msg)
|
||||
|
||||
msg['chat_state'].gone()
|
||||
self.try2Methods(xmlstring % 'gone', msg)
|
||||
|
||||
msg['chat_state'].inactive()
|
||||
self.try2Methods(xmlstring % 'inactive', msg)
|
||||
|
||||
msg['chat_state'].paused()
|
||||
self.try2Methods(xmlstring % 'paused', msg)
|
||||
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(testchatstates)
|
Loading…
Reference in a new issue