259 lines
7.1 KiB
Python
259 lines
7.1 KiB
Python
|
#!/usr/bin/env python2
|
||
|
# -*- coding: utf-8 -*-
|
||
|
|
||
|
import sys
|
||
|
sys.path.append('lib')
|
||
|
import time
|
||
|
import xmpp
|
||
|
from ircbot import SingleServerIRCBot
|
||
|
from ircbot import Channel
|
||
|
from irclib import nm_to_n
|
||
|
from threading import Thread
|
||
|
from ConfigParser import SafeConfigParser
|
||
|
|
||
|
|
||
|
class IRCBot(SingleServerIRCBot):
|
||
|
def __init__(self, channel, nickname, server, port, chanmuc):
|
||
|
SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
|
||
|
self.channel = channel
|
||
|
self.nickname = nickname
|
||
|
self.chanmuc = chanmuc
|
||
|
|
||
|
def _on_join(self, c, e):
|
||
|
nick = nm_to_n(e.source())
|
||
|
|
||
|
if nick not in self.chanmuc.chan_users():
|
||
|
self.chanmuc.chan_add_user(nick)
|
||
|
|
||
|
def _on_namreply(self, c, e):
|
||
|
bot = c.get_nickname()
|
||
|
|
||
|
for nick in e.arguments()[2].split():
|
||
|
if nick != c.get_nickname():
|
||
|
self.chanmuc.chan_add_user(nick)
|
||
|
|
||
|
def _on_part(self, c, e):
|
||
|
nick = nm_to_n(e.source())
|
||
|
|
||
|
if nick in self.chanmuc.chan_users():
|
||
|
self.chanmuc.chan_remove_user(nick)
|
||
|
|
||
|
def on_nicknameinuse(self, c, e):
|
||
|
self.nickname = c.get_nickname() + "_"
|
||
|
c.nick(self.nickname)
|
||
|
|
||
|
def on_welcome(self, c, e):
|
||
|
print "Connected to IRC"
|
||
|
c.join(self.channel)
|
||
|
|
||
|
def on_pubmsg(self, c, e):
|
||
|
from_nick = nm_to_n(e.source())
|
||
|
|
||
|
if str(e.arguments()[0]) == ".users":
|
||
|
users = self.chanmuc.muc_users()
|
||
|
users = ', '.join(users)
|
||
|
m = "[ XMPP Users ] " + users
|
||
|
|
||
|
buffer = 460
|
||
|
for i in range(0, len(m), buffer):
|
||
|
inter.irc(m[i:i + buffer].encode('latin-1', 'replace'))
|
||
|
|
||
|
else:
|
||
|
message = "[" + from_nick + "] " + ''.join(e.arguments())
|
||
|
m = xmpp.protocol.Message(to=muc, body=message, typ='groupchat')
|
||
|
|
||
|
try:
|
||
|
inter.xmpp(m)
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
|
||
|
class XMPPBot:
|
||
|
def __init__(self, jabber, remotejid, chanmuc, lines):
|
||
|
self.jabber = jabber
|
||
|
self.remotejid = remotejid
|
||
|
self.chanmuc = chanmuc
|
||
|
self.lines = lines
|
||
|
self.counter = 0
|
||
|
|
||
|
def register_handlers(self):
|
||
|
self.jabber.RegisterHandler('message', self.xmpp_message)
|
||
|
self.jabber.RegisterHandler('presence', self.xmpp_presence)
|
||
|
|
||
|
def xmpp_message(self, con, event):
|
||
|
try:
|
||
|
type = event.getType()
|
||
|
text = event.getBody()
|
||
|
fromjid = event.getFrom().getStripped()
|
||
|
|
||
|
if type in ['message', 'groupchat', None] and \
|
||
|
fromjid == self.remotejid:
|
||
|
n = event.getFrom().getResource()
|
||
|
|
||
|
if text and n != m_nick:
|
||
|
m = text.replace("\r", "")
|
||
|
m = m.replace("\n", "")
|
||
|
if m == '.users':
|
||
|
users = self.chanmuc.chan_users()
|
||
|
users = ', '.join(users)
|
||
|
|
||
|
if users:
|
||
|
users = "[ IRC Users ] " + users
|
||
|
|
||
|
m = xmpp.protocol.Message(to=muc, body=users,
|
||
|
typ='groupchat')
|
||
|
inter.xmpp(m)
|
||
|
|
||
|
else:
|
||
|
if self.counter >= self.lines:
|
||
|
m = "[" + n + "] " + m
|
||
|
|
||
|
buffer = 460
|
||
|
for i in range(0, len(m), buffer):
|
||
|
inter.irc(m[i:i + buffer].encode('latin-1',
|
||
|
'replace'))
|
||
|
|
||
|
else:
|
||
|
m = ""
|
||
|
|
||
|
self.counter += 1
|
||
|
|
||
|
except Exception as e:
|
||
|
print e
|
||
|
pass
|
||
|
|
||
|
def xmpp_presence(self, con, event):
|
||
|
try:
|
||
|
type = event.getType()
|
||
|
n = event.getFrom().getResource()
|
||
|
|
||
|
if type == "unavailable":
|
||
|
if n in self.chanmuc.muc_users():
|
||
|
self.chanmuc.muc_remove_user(n)
|
||
|
|
||
|
else:
|
||
|
if n not in self.chanmuc.muc_users():
|
||
|
self.chanmuc.muc_add_user(n.decode())
|
||
|
except Exception as e:
|
||
|
print e
|
||
|
pass
|
||
|
|
||
|
def stdio_message(self, message):
|
||
|
m = xmpp.protocol.Message(to=self.remotejid, body=message, typ='chat')
|
||
|
self.jabber.send(m)
|
||
|
pass
|
||
|
|
||
|
def xmpp_connect(self):
|
||
|
con = self.jabber.connect()
|
||
|
|
||
|
if not con:
|
||
|
sys.stderr.write('could not connect!\n')
|
||
|
return False
|
||
|
|
||
|
# sys.stderr.write('connected with %s\n'%con)
|
||
|
auth = self.jabber.auth(jid.getNode(), password,
|
||
|
resource=jid.getResource())
|
||
|
|
||
|
if not auth:
|
||
|
sys.stderr.write('could not authenticate!\n')
|
||
|
return False
|
||
|
print "Connected to XMPP"
|
||
|
# sys.stderr.write('authenticated using %s\n'%auth)
|
||
|
self.register_handlers()
|
||
|
|
||
|
return con
|
||
|
|
||
|
def DisconnectHandler(self):
|
||
|
reconnectAndReauth(self)
|
||
|
|
||
|
def start(self, cl):
|
||
|
if not self.xmpp_connect():
|
||
|
sys.stderr.write('Could not connect to server, or password '
|
||
|
'mismatch!\n')
|
||
|
sys.exit(1)
|
||
|
|
||
|
cl.send(xmpp.Presence(to="%s/%s" % (muc, m_nick)))
|
||
|
|
||
|
while cl.Process(1):
|
||
|
pass
|
||
|
|
||
|
cl.disconnect()
|
||
|
|
||
|
|
||
|
class ChannelAndMuc:
|
||
|
def __init__(self):
|
||
|
self.m_users = []
|
||
|
self.c_users = []
|
||
|
|
||
|
def muc_add_user(self, user):
|
||
|
self.m_users.append(user)
|
||
|
|
||
|
def muc_remove_user(self, user):
|
||
|
self.m_users.remove(user)
|
||
|
|
||
|
def chan_add_user(self, user):
|
||
|
self.c_users.append(user)
|
||
|
|
||
|
def chan_remove_user(self, user):
|
||
|
self.c_users.remove(user)
|
||
|
|
||
|
def muc_users(self):
|
||
|
return self.m_users
|
||
|
|
||
|
def chan_users(self):
|
||
|
return self.c_users
|
||
|
|
||
|
|
||
|
class Intermedia:
|
||
|
def xmpp(self, m):
|
||
|
try:
|
||
|
xmppbot.jabber.send(m)
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
def irc(self, m):
|
||
|
try:
|
||
|
ircb0t.connection.privmsg(channel, m)
|
||
|
except:
|
||
|
pass
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
|
||
|
global xmppbot, ircb0t, muc, channel, inter, jid, password, m_nick
|
||
|
|
||
|
parser = SafeConfigParser()
|
||
|
|
||
|
if len(sys.argv) > 1:
|
||
|
parser.read(sys.argv[1])
|
||
|
else:
|
||
|
parser.read('config.ini')
|
||
|
|
||
|
jid = parser.get('XMPP', 'jid')
|
||
|
password = parser.get('XMPP', 'password')
|
||
|
jid = xmpp.protocol.JID(jid)
|
||
|
cl = xmpp.Client(jid.getDomain(), debug=[])
|
||
|
muc = parser.get('XMPP', 'muc')
|
||
|
m_nick = parser.get('XMPP', 'nick')
|
||
|
lines = int(parser.get('XMPP', 'lines'))
|
||
|
|
||
|
channel = str(parser.get('IRC', 'channel'))
|
||
|
i_nick = parser.get('IRC', 'nick')
|
||
|
server = parser.get('IRC', 'server')
|
||
|
port = int(parser.get('IRC', 'port'))
|
||
|
|
||
|
chanmuc = ChannelAndMuc()
|
||
|
|
||
|
try:
|
||
|
ircb0t = IRCBot(channel, i_nick, server, port, chanmuc)
|
||
|
xmppbot = XMPPBot(cl, muc, chanmuc, lines)
|
||
|
inter = Intermedia()
|
||
|
z = Thread(target=ircb0t.start, args=())
|
||
|
w = Thread(target=xmppbot.start, args=(cl,))
|
||
|
z.start()
|
||
|
time.sleep(1)
|
||
|
w.start()
|
||
|
z.join()
|
||
|
w.join()
|
||
|
except KeyboardInterrupt:
|
||
|
print "Exit"
|