#!/usr/bin/env python # -*- coding: utf-8 -*- import sys import time import re import sleekxmpp from irc.bot import SingleServerIRCBot from irc.bot import Channel from threading import Thread if sys.version_info >= (3, 0): from configparser import SafeConfigParser else: from ConfigParser import SafeConfigParser class IRCBot(SingleServerIRCBot): def __init__(self, opts, inter): SingleServerIRCBot.__init__(self, [(opts['server'], opts['port'])], opts['nick'], opts['nick']) self.opts = opts self.nick = opts['nick'] self.owner = opts['owner'] self.inter = inter def _on_join(self, c, e): nick = e.source.nick if nick not in self.inter.get_irc_users(): self.inter.append_irc_user(nick) def _on_namreply(self, c, e): for nick in e.arguments[2].split(): if nick != c.get_nickname(): self.inter.append_irc_user(nick) def _on_part(self, c, e): nick = e.source.nick if nick in self.inter.get_irc_users(): self.inter.remove_irc_user(nick) def on_nicknameinuse(self, c, e): self.nick = c.get_nickname() + '_' c.nick(self.nick) def on_welcome(self, c, e): print('Connected to IRC') c.join(self.opts['chan']) def on_pubmsg(self, c, e): nick = e.source.split('!')[0] body = ''.join(e.arguments) self.inter.relay_message('irc', nick, body) def on_action(self, c, e): nick = e.source.split('!')[0] body = '/me ' + ''.join(e.arguments) self.inter.relay_message('irc', nick, body) class XMPPBot(sleekxmpp.ClientXMPP): def __init__(self, opts, inter): if sys.version_info < (3, 0): sleekxmpp.util.misc_ops.setdefaultencoding('utf8') self.jabber = sleekxmpp.ClientXMPP(opts['jid'], opts['passwd']) self.opts = opts self.nick = opts['nick'] self.owner = opts['owner'] self.inter = inter def register_handlers(self): self.jabber.add_event_handler('session_start', self.session_start) self.jabber.add_event_handler('groupchat_message', self.xmpp_message) self.jabber.add_event_handler('muc::%s::presence' % self.opts['muc'], self.xmpp_presence) def session_start(self, event): self.jabber.get_roster() self.jabber.send_presence() self.jabber.plugin['xep_0045'].joinMUC(self.opts['muc'], self.nick, wait=True) def xmpp_message(self, event): body = event['body'] nick = event['mucnick'] self.inter.relay_message('xmpp', nick, body) def xmpp_presence(self, event): try: type = event['muc']['type'] nick = event['muc']['nick'] if type == 'unavailable': if nick in self.inter.get_xmpp_users(): self.inter.remove_xmpp_user(n) else: if nick not in self.inter.get_xmpp_users(): self.inter.append_xmpp_user(nick) except Exception as e: print(e) def start(self): self.jabber.register_plugin('xep_0045') # XMPP MUC. self.jabber.register_plugin('xep_0199') # XMPP Ping. if self.jabber.connect(): # sys.stderr.write('connected with %s\n'%con) print('Connected to XMPP') self.register_handlers() self.jabber.process(block=True) else: # sys.stderr.write('could not connect!\n') sys.stderr.write('Could not connect to server, or password ' 'mismatch!\n') sys.exit(1) class Intermedia: def __init__(self, irc_chan, xmpp_muc): self.irc_chan = irc_chan self.xmpp_muc = xmpp_muc self.ircbot = None self.xmppbot = None self.irc_users = [] self.xmpp_users = [] def set_bots(self, ircbot, xmppbot): self.ircbot = ircbot self.xmppbot = xmppbot def to_irc(self, msg): buffer = 460 if self.ircbot: try: for i in range(0, len(msg), buffer): self.ircbot.connection.privmsg(self.irc_chan, msg[i:i + buffer]) except: pass def to_xmpp(self, msg): if self.xmppbot: try: self.xmppbot.jabber.send_message(mto=self.xmpp_muc, mbody=msg, mtype='groupchat') except: pass def relay_message(self, from_net, nick, body): if not self.ircbot or not self.xmppbot: return if from_net != 'irc' and from_net != 'xmpp': return if from_net == 'irc' and nick == self.ircbot.nick or \ from_net == 'xmpp' and nick == self.xmppbot.nick: return if not body or len(body) <= 0: return try: msg = body.replace('\r\n', '\n').replace('\r', '\n').split('\n') if from_net == 'irc': owner = self.ircbot.owner elif from_net == 'xmpp': owner = self.xmppbot.owner if msg and len(msg) > 0: if len(msg) == 1 and msg[0] == '.users': irc_users = ', '.join(self.get_irc_users()) xmpp_users = ', '.join(self.get_xmpp_users()) if irc_users: irc_users = '[ IRC Users ] ' + irc_users if xmpp_users: xmpp_users = '[ XMPP Users ] ' + xmpp_users if from_net == 'irc': for answer in [xmpp_users]: self.to_irc(answer) elif from_net == 'xmpp': for answer in [irc_users]: self.to_xmpp(answer) elif len(msg) == 1 and msg[0] == '.help': answer = 'The only command I have is \'.users\''+ \ '. Also, my owner is ' + owner + '.' if from_net == 'irc': self.to_irc(answer) elif from_net == 'xmpp': self.to_xmpp(answer) else: prefix = '[' + nick + '] ' prefix_me = '***' + nick + ' ' if (not re.match('^/me .+$', msg[0])): msg[0] = prefix + msg[0] else: msg[0] = prefix_me + re.split('^/me ', msg[0])[1] if from_net == 'irc': self.to_xmpp('\n'.join(msg)) elif from_net == 'xmpp': self.to_irc(msg[0]) # Separately as with a standard prefix, always. for m in msg[1:]: time.sleep(0.5) self.to_irc(prefix + m) except Exception as e: print(e) def get_irc_users(self): return self.irc_users def append_irc_user(self, user): if user != self.ircbot.nick: self.irc_users.append(user) def remove_irc_user(self, user): self.irc_users.remove(user) def get_xmpp_users(self): return self.xmpp_users def append_xmpp_user(self, user): if user != self.xmppbot.nick: self.xmpp_users.append(user) def remove_xmpp_user(self, user): self.xmpp_users.remove(user) if __name__ == '__main__': parser = SafeConfigParser() xmpp_opts = {} irc_opts = {} if len(sys.argv) > 1: parser.read(sys.argv[1]) else: parser.read('config.ini') irc_opts['chan'] = parser.get('IRC', 'channel') irc_opts['nick'] = parser.get('IRC', 'nick') irc_opts['server'] = parser.get('IRC', 'server') irc_opts['port'] = int(parser.get('IRC', 'port')) irc_opts['owner'] = parser.get('IRC', 'owner') xmpp_opts['jid'] = parser.get('XMPP', 'jid') xmpp_opts['passwd'] = parser.get('XMPP', 'password') xmpp_opts['muc'] = parser.get('XMPP', 'muc') xmpp_opts['nick'] = parser.get('XMPP', 'nick') xmpp_opts['owner'] = irc_opts['owner'] try: inter = Intermedia(irc_opts['chan'], xmpp_opts['muc']) ircbot = IRCBot(irc_opts, inter) xmppbot = XMPPBot(xmpp_opts, inter) inter.set_bots(ircbot, xmppbot) irc_thread = Thread(target=ircbot.start, args=()) xmpp_thread = Thread(target=xmppbot.start, args=()) irc_thread.daemon = True xmpp_thread.daemon = True irc_thread.start() time.sleep(1) xmpp_thread.start() irc_thread.join() xmpp_thread.join() except (KeyboardInterrupt, SystemExit): print('Exit')