hybridbot/hybridbot.py

288 lines
8.8 KiB
Python
Raw Normal View History

2016-07-28 18:25:38 +00:00
#!/usr/bin/env python
2016-07-25 18:01:51 +00:00
# -*- coding: utf-8 -*-
import sys
import time
2016-07-30 10:11:20 +00:00
import re
2016-07-28 18:14:33 +00:00
import sleekxmpp
2016-07-30 14:47:11 +00:00
from irc.bot import SingleServerIRCBot
from irc.bot import Channel
2016-07-25 18:01:51 +00:00
from threading import Thread
2016-07-28 18:25:38 +00:00
if sys.version_info >= (3, 0):
from configparser import SafeConfigParser
else:
from ConfigParser import SafeConfigParser
2016-07-25 18:01:51 +00:00
class IRCBot(SingleServerIRCBot):
def __init__(self, opts, inter):
2016-08-01 12:44:08 +00:00
SingleServerIRCBot.__init__(self, [(opts['server'], opts['port'])],
opts['nick'], opts['nick'])
self.opts = opts
self.nick = opts['nick']
self.owner = opts['owner']
2016-08-01 12:44:08 +00:00
self.inter = inter
2016-07-25 18:01:51 +00:00
def _on_join(self, c, e):
2016-07-30 14:47:11 +00:00
nick = e.source.nick
2016-07-25 18:01:51 +00:00
if nick not in self.inter.get_irc_users():
self.inter.append_irc_user(nick)
2016-07-25 18:01:51 +00:00
def _on_namreply(self, c, e):
2016-07-30 14:47:11 +00:00
for nick in e.arguments[2].split():
2016-07-25 18:01:51 +00:00
if nick != c.get_nickname():
self.inter.append_irc_user(nick)
2016-07-25 18:01:51 +00:00
def _on_part(self, c, e):
2016-07-30 14:47:11 +00:00
nick = e.source.nick
2016-07-25 18:01:51 +00:00
if nick in self.inter.get_irc_users():
self.inter.remove_irc_user(nick)
2016-07-25 18:01:51 +00:00
def on_nicknameinuse(self, c, e):
2016-08-01 12:44:08 +00:00
self.nick = c.get_nickname() + '_'
c.nick(self.nick)
2016-07-25 18:01:51 +00:00
def on_welcome(self, c, e):
2016-07-28 18:25:38 +00:00
print('Connected to IRC')
2016-08-01 12:44:08 +00:00
c.join(self.opts['chan'])
2016-07-25 18:01:51 +00:00
def on_pubmsg(self, c, e):
2016-08-01 12:44:08 +00:00
nick = e.source.split('!')[0]
body = ''.join(e.arguments)
2016-07-25 18:01:51 +00:00
self.inter.relay_message('irc', nick, body)
2016-07-25 18:01:51 +00:00
2016-07-30 10:11:20 +00:00
def on_action(self, c, e):
2016-08-01 12:44:08 +00:00
nick = e.source.split('!')[0]
body = '/me ' + ''.join(e.arguments)
2016-07-30 10:11:20 +00:00
self.inter.relay_message('irc', nick, body)
2016-07-30 10:11:20 +00:00
2016-07-25 18:01:51 +00:00
2016-07-28 18:14:33 +00:00
class XMPPBot(sleekxmpp.ClientXMPP):
def __init__(self, opts, inter):
2016-07-28 18:14:33 +00:00
if sys.version_info < (3, 0):
sleekxmpp.util.misc_ops.setdefaultencoding('utf8')
2016-08-01 12:44:08 +00:00
self.jabber = sleekxmpp.ClientXMPP(opts['jid'], opts['passwd'])
self.opts = opts
self.nick = opts['nick']
self.owner = opts['owner']
2016-08-01 12:44:08 +00:00
self.inter = inter
2016-07-25 18:01:51 +00:00
def register_handlers(self):
2016-07-28 18:14:33 +00:00
self.jabber.add_event_handler('session_start', self.session_start)
self.jabber.add_event_handler('groupchat_message', self.xmpp_message)
2016-08-01 12:44:08 +00:00
self.jabber.add_event_handler('muc::%s::presence' % self.opts['muc'],
2016-07-28 18:14:33 +00:00
self.xmpp_presence)
def session_start(self, event):
self.jabber.get_roster()
self.jabber.send_presence()
2016-08-01 12:44:08 +00:00
self.jabber.plugin['xep_0045'].joinMUC(self.opts['muc'],
self.nick,
2016-07-28 18:14:33 +00:00
wait=True)
def xmpp_message(self, event):
body = event['body']
nick = event['mucnick']
2016-07-25 18:01:51 +00:00
self.inter.relay_message('xmpp', nick, body)
2016-07-25 18:01:51 +00:00
2016-07-28 18:14:33 +00:00
def xmpp_presence(self, event):
2016-07-25 18:01:51 +00:00
try:
2016-07-28 18:14:33 +00:00
type = event['muc']['type']
nick = event['muc']['nick']
2016-07-25 18:01:51 +00:00
if type == 'unavailable':
if nick in self.inter.get_xmpp_users():
self.inter.remove_xmpp_user(n)
2016-07-25 18:01:51 +00:00
else:
if nick not in self.inter.get_xmpp_users():
self.inter.append_xmpp_user(nick)
2016-07-25 18:01:51 +00:00
except Exception as e:
2016-07-28 18:25:38 +00:00
print(e)
2016-07-25 18:01:51 +00:00
2016-07-28 18:14:33 +00:00
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)
2016-07-28 18:25:38 +00:00
print('Connected to XMPP')
2016-07-28 18:14:33 +00:00
self.register_handlers()
self.jabber.process(block=True)
else:
# sys.stderr.write('could not connect!\n')
2016-07-25 18:01:51 +00:00
sys.stderr.write('Could not connect to server, or password '
2016-07-28 18:14:33 +00:00
'mismatch!\n')
2016-07-25 18:01:51 +00:00
sys.exit(1)
class Intermedia:
2016-08-01 12:44:08 +00:00
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 = []
2016-08-01 12:44:08 +00:00
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):
2016-08-01 12:44:08 +00:00
if self.xmppbot:
try:
self.xmppbot.jabber.send_message(mto=self.xmpp_muc, mbody=msg,
mtype='groupchat')
except:
pass
2016-07-25 18:01:51 +00:00
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)
2016-07-25 18:01:51 +00:00
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__':
2016-07-25 18:01:51 +00:00
parser = SafeConfigParser()
2016-08-01 12:44:08 +00:00
xmpp_opts = {}
irc_opts = {}
2016-07-25 18:01:51 +00:00
if len(sys.argv) > 1:
parser.read(sys.argv[1])
else:
parser.read('config.ini')
2016-08-01 12:44:08 +00:00
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')
2016-07-25 18:01:51 +00:00
2016-08-01 12:44:08 +00:00
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']
2016-07-25 18:01:51 +00:00
try:
2016-08-01 12:44:08 +00:00
inter = Intermedia(irc_opts['chan'], xmpp_opts['muc'])
ircbot = IRCBot(irc_opts, inter)
xmppbot = XMPPBot(xmpp_opts, inter)
2016-08-01 12:44:08 +00:00
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()
2016-07-25 18:01:51 +00:00
time.sleep(1)
2016-08-01 12:44:08 +00:00
xmpp_thread.start()
irc_thread.join()
xmpp_thread.join()
2016-07-28 18:14:33 +00:00
except (KeyboardInterrupt, SystemExit):
2016-07-28 18:25:38 +00:00
print('Exit')