# zbot/drivers/xmpp.py
#
#
""" XMPP bot build on sleekxmpp. """
## IMPORTS
from zbot.utils import error, stripped, attributes, subelements
from zbot import Bot, Object, handle_loop
import collections
import threading
import _thread
import logging
import getpass
import types
import time
import sys
import os
import re
## XMPPBot
[docs]class XMPPBot(Bot):
def __init__(self, *args, **kwargs):
import sleekxmpp
from sleekxmpp import clientxmpp
Bot.__init__(self, *args, **kwargs)
self.port = self.port or 5222
self.xmpp = clientxmpp.ClientXMPP(self.user, getpass.getpass())
self.xmpp.add_event_handler("session_start", self.session_start)
self.xmpp.add_event_handler("message", self.handle_message)
self.xmpp.add_event_handler('disconnected', self.handle_disconnected)
self.xmpp.add_event_handler('connected', self.handle_connected)
self.xmpp.add_event_handler('presence_available', self.handle_presence)
self.xmpp.add_event_handler('presence_dnd', self.handle_presence)
self.xmpp.add_event_handler('presence_xa', self.handle_presence)
self.xmpp.add_event_handler('presence_chat', self.handle_presence)
self.xmpp.add_event_handler('presence_away', self.handle_presence)
self.xmpp.add_event_handler('presence_unavailable', self.handle_presence)
self.xmpp.add_event_handler('presence_subscribe', self.handle_presence)
self.xmpp.add_event_handler('presence_subscribed', self.handle_presence)
self.xmpp.add_event_handler('presence_unsubscribe', self.handle_presence)
self.xmpp.add_event_handler('presence_unsubscribed', self.handle_presence)
self.xmpp.add_event_handler('groupchat_message', self.handle_message)
self.xmpp.add_event_handler('groupchat_presence', self.handle_presence)
self.xmpp.add_event_handler('groupchat_subject', self.handle_presence)
self.xmpp.add_event_handler('failed_auth', self.handle_failedauth)
self.xmpp.exception = self.exception
self.xmpp.use_signals()
if self.openfire:
import ssl
self.xmpp.ssl_version = ssl.PROTOCOL_SSLv3
self._connected = threading.Event()
def _raw(self, txt): self.xmpp.send_raw(txt)
[docs] def connect(self): self.xmpp.connect((self.server, self.port), use_ssl=self.openfire)
[docs] def session_start(self, event): self.xmpp.send_presence()
[docs] def exception(self, ex): logging.error(str(ex))
[docs] def handle_failedauth(self, error, *args): logging.warn(error)
[docs] def handle_failure(self, ex, *args, **kwargs): logging.info(str(ex))
[docs] def handle_disconnected(self, *args, **kwargs): self._connected.clear() ; logging.error("disconnected")
[docs] def handle_connected(self, *args, **kwargs): self._connected.set() ; logging.warn("connected!")
[docs] def loop(self, *args, **kwargs): self.xmpp.process(block=True)
[docs] def say(self, *args, **kwargs): self.xmpp.send_message(args[0], args[1])
[docs] def get_one(self, *args, **kwargs): return
[docs] def handle_message(self, data, *args, **kwargs):
if '<delay xmlns="urn:xmpp:delay"' in str(data): logging.debug("ignoring delayed message") ; return
logging.warn("< %s" % data)
m = Object(**data)
if m.type == "error": logging.warn("error %s" % m.make_json()) ; return
m.origin = stripped(str(m["from"]))
m.channel = m.origin
m.to = m.origin
m.element = "message"
try: m.txt = m["body"]
except KeyError: pass
m._target = self
self.put(m)
[docs] def handle_presence(self, data, *args, **kwargs):
logging.info("< %s" % data)
p = Object(**data)
if "from" in p and p["from"]:
p.origin = stripped(str(p["from"]))
p.to = p.origin
else: p.origin = "" ; p.to = ""
p.element = "presence"
if p.type == 'subscribe':
pres = Object({'to': p["from"], 'type': 'subscribed'})
self.send(pres)
pres = Object({'to': p["from"], 'type': 'subscribe'})
self.send(pres)
p.no_dispatch = True
p._target = self
self.put(p)