Switch to asyncio and slixmpp
This commit is contained in:
parent
b702c1af45
commit
aa67de2acc
10
README.md
10
README.md
@ -1,10 +1,10 @@
|
||||
# hybridbot
|
||||
|
||||
Hybridbot is a bot that relays messages from a IRC channel to an XMPP MUC and vice versa. First of all, you need to install sleekxmpp and irc.
|
||||
Hybridbot is a bot that relays messages from a IRC channel to an XMPP MUC and vice versa. First of all, you need to install slixmpp and irc.
|
||||
|
||||
su -c "pip install sleekxmpp irc"
|
||||
su -c "pip3 install slixmpp irc"
|
||||
# or
|
||||
su -c "pip install -r requirements.txt"
|
||||
su -c "pip3 install -r requirements.txt"
|
||||
|
||||
It's configuration is simple, you have to create a config file per relay, as this example (remember to change the values):
|
||||
|
||||
@ -32,10 +32,10 @@ The option "owner" is a string that will be printed when issuing the ".help" com
|
||||
|
||||
To execute it, just do:
|
||||
|
||||
python hybridbot.py myconfig.ini
|
||||
python3 hybridbot.py myconfig.ini
|
||||
|
||||
Or if the config file is named "config.ini", just do:
|
||||
|
||||
python hybridbot.py
|
||||
python3 hybridbot.py
|
||||
|
||||
And on the MUC or the IRC channel, you can issue two commands, ".help" and ".users".
|
||||
|
81
hybridbot.py
81
hybridbot.py
@ -1,16 +1,12 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import asyncio
|
||||
import re
|
||||
import signal
|
||||
import sys
|
||||
import time
|
||||
import sleekxmpp
|
||||
if sys.version_info.major >= 3:
|
||||
import slixmpp
|
||||
from configparser import SafeConfigParser
|
||||
else:
|
||||
from ConfigParser import SafeConfigParser
|
||||
from threading import Thread
|
||||
from irc.bot import SingleServerIRCBot
|
||||
|
||||
|
||||
@ -68,7 +64,7 @@ class IRCBot:
|
||||
if nick not in self.inter.get_irc_users():
|
||||
self.inter.append_irc_user(nick)
|
||||
except Exception as e:
|
||||
sys.stderr.write(str(e) + '\n')
|
||||
print(str(e), file=sys.stderr)
|
||||
|
||||
def on_namreply(self, conn, event):
|
||||
for nick in event.arguments[2].split():
|
||||
@ -101,19 +97,16 @@ class IRCBot:
|
||||
self.conn.privmsg(self.chan, prefix + r)
|
||||
|
||||
except Exception as e:
|
||||
sys.stderr.write(str(e) + '\n')
|
||||
print(str(e), file=sys.stderr)
|
||||
|
||||
def start(self):
|
||||
def run(self):
|
||||
self.register_handlers()
|
||||
self.client.start()
|
||||
|
||||
|
||||
class XMPPBot:
|
||||
def __init__(self, opts, inter):
|
||||
if sys.version_info.major < 3:
|
||||
sleekxmpp.util.misc_ops.setdefaultencoding('utf-8')
|
||||
|
||||
self.client = sleekxmpp.ClientXMPP(opts['jid'], opts['passwd'])
|
||||
self.client = slixmpp.ClientXMPP(opts['jid'], opts['passwd'])
|
||||
self.opts = opts
|
||||
self.nick = opts['nick']
|
||||
self.pure_nick = self.nick
|
||||
@ -121,6 +114,8 @@ class XMPPBot:
|
||||
self.inter = inter
|
||||
|
||||
def register_handlers(self):
|
||||
self.client.add_event_handler('failed_all_auth',
|
||||
self.on_failed_all_auth)
|
||||
self.client.add_event_handler('session_start', self.on_session_start)
|
||||
self.client.add_event_handler('session_end', self.on_session_end)
|
||||
self.client.add_event_handler('groupchat_message', self.on_message)
|
||||
@ -128,22 +123,24 @@ class XMPPBot:
|
||||
self.on_presence)
|
||||
|
||||
def connect(self):
|
||||
if not self.client.connect():
|
||||
# sys.stderr.write('could not connect!\n')
|
||||
sys.stderr.write('Could not connect to server, or password ' +
|
||||
'mismatch!\n')
|
||||
sys.exit(1)
|
||||
# sys.stderr.write('connected with %s\n'%con)
|
||||
self.client.connect()
|
||||
|
||||
def join_muc(self):
|
||||
muc_plugin = self.client.plugin['xep_0045']
|
||||
|
||||
muc_plugin.joinMUC(self.muc, self.nick)
|
||||
muc_plugin.join_muc(self.muc, self.nick)
|
||||
|
||||
def on_failed_all_auth(event):
|
||||
# print('could not connect!', file=sys.stderr)
|
||||
print('Could not connect to the server, or password mismatch!',
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
def on_session_start(self, event):
|
||||
# print('connected with %s' %con, file=sys.stderr)
|
||||
print('Connected to XMPP')
|
||||
self.client.get_roster()
|
||||
self.client.send_presence()
|
||||
self.client.get_roster()
|
||||
self.join_muc()
|
||||
|
||||
def on_session_end(self, event):
|
||||
@ -165,7 +162,7 @@ class XMPPBot:
|
||||
if not typ:
|
||||
typ = event['type']
|
||||
if not nick:
|
||||
nick = muc_plugin.getNick(self.muc, event['from'])
|
||||
nick = muc_plugin.get_nick(self.muc, event['from'])
|
||||
|
||||
if typ == 'error':
|
||||
if event['error']['code'] == '409':
|
||||
@ -187,7 +184,7 @@ class XMPPBot:
|
||||
self.inter.append_xmpp_user(nick)
|
||||
|
||||
except Exception as e:
|
||||
sys.stderr.write(str(e) + '\n')
|
||||
print(str(e), file=sys.stderr)
|
||||
|
||||
def send_message(self, msg, prefix=''):
|
||||
try:
|
||||
@ -197,18 +194,19 @@ class XMPPBot:
|
||||
mtype='groupchat')
|
||||
|
||||
except Exception as e:
|
||||
sys.stderr.write(str(e) + '\n')
|
||||
print(str(e), file=sys.stderr)
|
||||
|
||||
def start(self):
|
||||
@asyncio.coroutine
|
||||
def run(self):
|
||||
self.client.register_plugin('xep_0045') # XMPP MUC.
|
||||
self.client.register_plugin('xep_0199') # XMPP Ping.
|
||||
self.register_handlers()
|
||||
self.connect()
|
||||
self.client.process(block=True)
|
||||
|
||||
|
||||
class Intermedia:
|
||||
def __init__(self, shared_opts, irc_chan, xmpp_muc):
|
||||
def __init__(self, loop, shared_opts, irc_chan, xmpp_muc):
|
||||
self.loop = loop
|
||||
self.irc_chan = irc_chan
|
||||
self.xmpp_muc = xmpp_muc
|
||||
self.ircbot = None
|
||||
@ -229,7 +227,7 @@ class Intermedia:
|
||||
|
||||
def to_xmpp(self, msg, prefix=''):
|
||||
if self.xmppbot:
|
||||
self.xmppbot.send_message(msg, prefix)
|
||||
loop.call_soon_threadsafe(self.xmppbot.send_message, msg, prefix)
|
||||
|
||||
def relay_message(self, from_net, nick, body):
|
||||
if not self.ircbot or not self.xmppbot:
|
||||
@ -292,7 +290,7 @@ class Intermedia:
|
||||
prefix=nick_prefix)
|
||||
|
||||
except Exception as e:
|
||||
sys.stderr.write(str(e) + '\n')
|
||||
print(str(e), file=sys.stderr)
|
||||
|
||||
def get_irc_users(self):
|
||||
return self.irc_users
|
||||
@ -324,7 +322,8 @@ if __name__ == '__main__':
|
||||
config.read('config.ini')
|
||||
|
||||
if not config.sections():
|
||||
sys.stderr.write('Error: Configuration file does not exist or is empty.\n')
|
||||
print('Error: Configuration file does not exist or is empty.',
|
||||
file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
shared_opts['prefix'] = config.get('Shared', 'prefix')
|
||||
@ -341,22 +340,14 @@ if __name__ == '__main__':
|
||||
xmpp_opts['nick'] = config.get('XMPP', 'nick')
|
||||
|
||||
signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
while True:
|
||||
inter = Intermedia(shared_opts, irc_opts['chan'], xmpp_opts['muc'])
|
||||
inter = Intermedia(loop, shared_opts, 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()
|
||||
asyncio.async(xmppbot.run())
|
||||
asyncio.async(loop.run_in_executor(None, ircbot.run))
|
||||
loop.run_forever()
|
||||
loop.close()
|
||||
|
@ -1,2 +1,2 @@
|
||||
sleekxmpp>=1.2.0
|
||||
slixmpp
|
||||
irc>=5.0.1
|
||||
|
Loading…
Reference in New Issue
Block a user