Source code for botlib.xmpp

# mad/xmpp.py
#
#

""" XMPP bot class. """

from .bot import Bot
from .event import Event
from .utils import stripped

import logging
import time
import os

[docs]def init(event): bot = XMPP() try: bot.start() except UnboundLocalError: logging.error("# missing sleekxmpp") return return bot
[docs]class XMPP(Bot): cc = ""
[docs] def announce(self, txt): for channel in self.channels: self.say(channel, txt)
[docs] def connect(self, user="", pw=""): fn = os.path.expanduser("~/.sleekpass") pww = "" f = open(fn, "r") pww = f.read() f.close() self._connect(user or self.cfg.user, pw or pww)
[docs] def connected(self, data): self._connected.ready()
[docs] def disconnected(self, data): self._connected.clear() pass
[docs] def event(self): e = self._queue.get() if e: e.btype = self.type return e
[docs] def exception(self, data): self._error = data
[docs] def failedauth(self, data): logging.error("# failed auth %s" % data)
[docs] def failure(self, data): logging.error("# failure %s" % data) self._error = data
[docs] def invalid_cert(self, data): logging.debug("# invalid cert")
[docs] def iqed(self, data): logging.warn("# Iq %s:%s %s" % (self.cfg.server, self.cfg.port, data))
[docs] def messaged(self, data): from .space import kernel logging.debug("< %s" % data) m = Event() m.update(data) if m.type == "error": logging.error("^ %s" % m.error) return m.cc = "" m["from"] = str(m["from"]) if self.cfg.user in m["from"]: logging.debug("! ignore %s %s" % (m.type, m["from"])) return m.origin = m["from"] m.btype = self.type m.server = self.cfg.server m.channel = m.origin m.to = m.origin m.element = "message" m.txt = m["body"] if '<delay xmlns="urn:xmpp:delay"' in str(data): logging.debug("! ignore %s" % m.origin) return logging.info("< %s %s" % (stripped(m.origin), m.txt)) kernel.put(m)
[docs] def pinged(self, event): self._connected.ready()
[docs] def presenced(self, data): from .space import kernel logging.debug("< %s" % data) o = Event() o.cc = "" o.update(data) o.id = self.id() o.origin = o["from"] if "txt" not in o: o.txt = "" o.element = "presence" username = stripped(o.origin) if o.type == 'subscribe': pres = Event({'to': o["from"], 'type': 'subscribed'}) self.client.send_presence(dict(pres)) pres = Event({'to': o["from"], 'type': 'subscribe'}) self.client.send_presence(dict(pres)) elif o.type == "unavailable" and username != self.cfg.username and username in self.channels: self.channels.remove(username) elif o.origin != self.cfg.user and username != self.cfg.username and username not in self.channels: self.channels.append(username) o.txt = o.type logging.info("< presence %s" % stripped(o.origin)) kernel.put(o)
[docs] def register(self, key, value): self.client.add_event_handler(key, value)
[docs] def resume(self): pass
[docs] def say(self, jid, txt): txt = str(txt) self.client.send_message(jid, txt) logging.info("%s %s" % (stripped(jid), txt))
[docs] def session_start(self, data): self.client.send_presence()
[docs] def start(self, *args, **kwargs): self.launch(self.sleek) try: self.connect() except FileNotFoundError: print("# no ~/.sleekpass file found.") return super().start(*args, **kwargs)
[docs] def stop(self): self._connected.ready() self._queue.put(None) if "client" in self and self.client: self.client.disconnect() super().stop()
[docs] def sleek(self): self._connected.wait() if "client" in self and self.client: self.client.process(block=True)
[docs] def _connect(self, user, pw): self.makeclient(user, pw) self.client.reconnect_max_attempts = 2 logging.warn("# connect %s" % self.cfg.user) if self.cfg.openfire: self.client.connect((self.cfg.server, self.cfg.port), use_ssl=True) else: self.client.connect((self.cfg.server, self.cfg.port)) if self.cfg.noresolver: self.client.configure_dns(None) self.register_fd(self.client.socket)
[docs] def makeclient(self, jid, password): try: import sleekxmpp.clientxmpp import sleekxmpp except ImportError: logging.warn("sleekxmpp is not installed") self.client = sleekxmpp.clientxmpp.ClientXMPP(jid, password) self.register("session_start", self.session_start) self.register("message", self.messaged) self.register("iq", self.iqed) self.register("ssl_invalid_cert", self.invalid_cert) self.register('disconnected', self.disconnected) self.register('connected', self.connected) self.register('presence_available', self.presenced) self.register('presence_dnd', self.presenced) self.register('presence_xa', self.presenced) self.register('presence_chat', self.presenced) self.register('presence_away', self.presenced) self.register('presence_unavailable', self.presenced) self.register('presence_subscribe', self.presenced) self.register('presence_subscribed', self.presenced) self.register('presence_unsubscribe', self.presenced) self.register('presence_unsubscribed', self.presenced) self.register('groupchat_message', self.messaged) self.register('groupchat_presence', self.presenced) self.register('groupchat_subject', self.presenced) self.register('failed_auth', self.failedauth) self.client.exception = self.exception self.client.use_signals()