Source code for zot.bots.xmpp

# zot/bots/xmpp.py
#
#

""" basic package for the program. """

__copyright__ = "Copyright 2015, B.H.J Thate"

## IMPORTS


from zot.defines import BLA, GREEN, ENDC, pfc
from zot.runtime import kernel, fleet, cfg
from zot.object import Object
from zot.defaults import cfg_xmpp
from zot.utils import stripped
from zot.bot import BOT

import threading
import logging
import getpass
import queue
import time
import html

## XMPP

[docs]class XMPP(BOT): """ XMPP bot. """ cc = "" def __init__(zelf, *args, **kwargs): import sleekxmpp from sleekxmpp import clientxmpp BOT.__init__(zelf, *args, **kwargs) if "port" not in zelf: zelf.port = 5222 zelf._queue = queue.Queue() zelf.xmpp = clientxmpp.ClientXMPP(zelf.user, getpass.getpass()) zelf.xmpp.add_event_handler("session_start", zelf.session_start) zelf.xmpp.add_event_handler("message", zelf.handle_message) zelf.xmpp.add_event_handler('disconnected', zelf.handle_disconnected) zelf.xmpp.add_event_handler('connected', zelf.handle_connected) zelf.xmpp.add_event_handler('presence_available', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_dnd', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_xa', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_chat', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_away', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_unavailable', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_subscribe', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_subscribed', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_unsubscribe', zelf.handle_presence) zelf.xmpp.add_event_handler('presence_unsubscribed', zelf.handle_presence) zelf.xmpp.add_event_handler('groupchat_message', zelf.handle_message) zelf.xmpp.add_event_handler('groupchat_presence', zelf.handle_presence) zelf.xmpp.add_event_handler('groupchat_subject', zelf.handle_presence) zelf.xmpp.add_event_handler('failed_auth', zelf.handle_failedauth) zelf.xmpp.exception = zelf.exception zelf.xmpp.use_signals() zelf.openfire = cfg.openfire if zelf.openfire: logging.warn("! XMPP/enable openfire") import ssl zelf.xmpp.ssl_version = ssl.PROTOCOL_SSLv3 zelf._connected = threading.Event() zelf.channels = [] def _raw(zelf, *args, **kwargs): logging.debug("> XMPP/raw %s" % args[0]) zelf.xmpp.send_raw(args[0])
[docs] def start(zelf, *args, **kwargs): zelf.connect() BOT.start(zelf, *args, **kwargs)
[docs] def connect(zelf): logging.error("! XMPP/connecting %s" % zelf.server) try: zelf.xmpp.connect((zelf.server, zelf.port), use_ssl=zelf.openfire) except: zelf.xmpp.connect((zelf.server, zelf.port))
[docs] def session_start(zelf, event): zelf.xmpp.send_presence() zelf.ready() logging.error("! XMPP/session established %s" % zelf.user)
[docs] def exception(zelf, ex): zelf._status = ex logging.error("! XMPP/error %s"% str(ex))
[docs] def announce(zelf, *args, **kwargs): zelf.wait() for channel in zelf.channels: zelf.say(channel, args[0])
[docs] def handle_failedauth(zelf, error, *args, **kwargs): zelf._error = error ; logging.error("! XMPP/auth %s" % str(error))
[docs] def handle_failure(zelf, error, *args, **kwargs): zelf._error = error ; logging.error("! XMPP/failure %s" % str(error))
[docs] def handle_disconnected(zelf, *args, **kwargs): zelf._connected.clear() zelf._status = "disconnected" logging.error("! XMPP/disconnected %s" % zelf.user)
[docs] def handle_connected(zelf, *args, **kwargs): zelf._status = "running" zelf._connected.set() logging.error("! XMPP/connected %s" % zelf.user)
[docs] def loop(zelf, *args, **kwargs): zelf.xmpp.process(block=True)
[docs] def say(zelf, *args, **kwargs): to = args[0] txt = args[1] zelf.xmpp.send_message(to, txt) logging.info("> XMPP/message %s" % to)
[docs] def event(zelf, *args, **kwargs): event = zelf._queue.get() event.cc = zelf.cc return event
[docs] def handle_message(zelf, data, *args, **kwargs): logging.debug("< XMPP/raw %s" % data) m = Object(**data) if m.type == "error": logging.error(m.error) ; return m["from"] = str(m["from"]) m.origin = m["from"] m.channel = m.origin m.to = m.origin m.element = "message" m.txt = m["body"] m._target = zelf if '<delay xmlns="urn:xmpp:delay"' in str(data): logging.warn("! XMPP/ignore %s %s" % (m.type, m.origin)) return logging.warn("! XMPP/%s %s" % (m.type, m.origin)) zelf._queue.put(m)
[docs] def handle_presence(zelf, data, *args, **kwargs): logging.debug("< XMPP/raw %s" % data) o = Object(data) o["from"] = str(o["from"]) o.origin = o["from"] o.element = "presence" if o.type == 'subscribe': pres = Object({'to': o["from"], 'type': 'subscribed'}) o.xmpp.send_presence(pres) pres = Object({'to': o["from"], 'type': 'subscribe'}) o.xmpp.send_presence(pres) elif o.type == "unavailable": if o.origin in zelf.channels: zelf.channels.remove(o.origin) else: if o.origin != zelf.user and o.origin not in zelf.channels: zelf.channels.append(o.origin) o.no_dispatch = True o._target = zelf logging.warn("! XMPP/%s %s" % (o.type, o.origin)) zelf._queue.put(o)
[docs] def exit(zelf, *args, **kwargs): zelf.xmpp.disconnect() Bot.exit(zelf) zelf._queue.put(None)
[docs]def init(*args, **kwargs): cfg = Object().last("cfg", "xmpp") if not cfg: cfg = cfg_xmpp ; cfg.save() bot = XMPP(**cfg) fleet.append(bot) kernel.put(bot.loop) kernel.put(bot.start)