Advertisement
MegaLoler

BridgeBot v0.1

Apr 30th, 2012
1,321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.67 KB | None | 0 0
  1. # BridgeBot version 0.1
  2. # Attemps to create a seemless interface between multiple chat protocols
  3. # Written and designed by MegaLoler (megaloler9000@gmail.com)
  4. # Written for Python version 2.7
  5.  
  6. # Todo list:
  7. # Make bridged rooms list dynamic
  8. # Deal with already existing nicks
  9. # Prevent connecting to the same place multiple times
  10. # Add colors
  11. # Add quit reasons to IRC
  12. # Find goodies to add yay
  13. # Fix bugs
  14. # Due to a bug, I accidentally spammed Tinychat and got banned.  So I was unable to finish tinychat's functionality.  It was working rather well, but I am sure there is still an unacceptable lack of functionality.
  15. # I'm stuck on chatango because I can't figure out how to make the library connect as temporary users.
  16. # Stopped working on IRC because I got tired
  17. # So basically nothing works except a little bit of Tinychat, which I can't even access :P
  18.  
  19. # Import connection libraries and declare some constants.
  20.  
  21. # MegaLoler's IRC library (http://pastebin.com/d33RgTWY)
  22. import irc
  23.  
  24. # Lumirayz's Chatango library (https://github.com/theholder/ch.py)
  25. import chatango
  26.  
  27. # MegaLoler's Tinychat library (http://pastebin.com/aVJuiLK4)
  28. import tinychat
  29.  
  30. import thread
  31.  
  32. IRC = 0
  33. CHATANGO = 1
  34. TINYCHAT = 2
  35.  
  36. # Configuration
  37.  
  38. botName_IRC = "BridgeBotObserver"
  39. botPass_IRC = None
  40. botName_Chatango = "BridgeBotObserver"
  41. botPass_Chatango = None
  42. botName_Tinychat = "BridgeBotObserver"
  43.  
  44. # A list of the rooms to bridge.  The first entry is the service.  The second entry is the room name.  The third entry is only for IRC connections and is the server name.
  45. bridgedRooms = ()
  46.  
  47. # A User's job is to mock the real user that it represents by relaying their actions to all other connections.
  48.  
  49. class User():
  50.     def __init__(self, nativeConnection, nick, password=None):
  51.         self.nativeConnection = nativeConnection
  52.         self.nick = nick
  53.         self.password = password
  54.         self.connections = []
  55.        
  56.         self.connect()
  57.        
  58.     def _connect(self, room):
  59.         if room.service == IRC:
  60.             self.connections.append(IRCWrapper(self.nick, self.password, room.room, room.server))
  61.         elif room.service == CHATANGO:
  62.             self.connections.append(ChatangoWrapper(self.nick, self.password, room.room))
  63.         elif room.service == TINYCHAT:
  64.             self.connections.append(TinychatWrapper(self.nick, room.room))
  65.    
  66.     # Actions
  67.    
  68.     def connect(self):
  69.         users.append(self)
  70.         for room in rooms:
  71.             if room != self.nativeConnection: self._connect(room)
  72.    
  73.     def quit(self):
  74.         users.remove(self)
  75.         for connection in self.connections: connection.quit()
  76.    
  77.     def say(self, message, color):
  78.         for connection in self.connections: connection.say(message, color)
  79.    
  80.     def setNick(self, nick):
  81.         self.nick = nick
  82.         for connection in self.connections: connection.setNick(nick)
  83.  
  84. # These wrappers are to provide an identical interface for any type of connection.
  85.  
  86. class IRCWrapper():
  87.     def __init__(self, nick, password, room, server, responder=None):
  88.         self.nick = nick
  89.         self.password = password
  90.         self.room = room
  91.         self.server = server
  92.         self.responder = responder
  93.        
  94.         self.connect()
  95.  
  96.     def _listen(self):
  97.         while self.connection.connected:
  98.             self.connection._buffer += self.connection.sock.recv(1024).decode()
  99.             if(self.connection._buffer.find("\r\n")):
  100.                 for msg in self.connection._buffer.split("\r\n")[0:-1]:
  101.                     self.connection.verboseOut("SERVER: " + msg)
  102.                     cmd = self.connection._parse(msg)
  103.                     self.connection.logPretty(cmd)
  104.                     self.connection._handle(cmd)
  105.                     self.handle(cmd)
  106.                 self.connection._buffer = self.connection._buffer.split("\r\n")[-1]
  107.    
  108.     def handle(self, msg):
  109.         if cmd.command == "PRIVMSG":
  110.             if msg.nick.lower() != self.nick.lower() and self.responder == self.responder.getUserByNick(msg.nick).nativeConnection: self.responder.onSay(msg.nick, msg.trailing, None)
  111.    
  112.     # Actions
  113.    
  114.     def connect(self):
  115.         self.connection = irc.IRCServer(self.server)
  116.         if not self.password: self.password = ""
  117.         self.connection.connect(self.nick, self.password, listen=False)
  118.         thread.start_new_thread(self._listen, ())
  119.    
  120.     def quit(self):
  121.         self.connection.disconnect()
  122.    
  123.     def say(self, message, color):
  124.         self.connection.say(message, self.room)
  125.    
  126.     def setNick(self, nick):
  127.         self.nick = nick
  128.         self.connection._sendCommand("nick", [nick])
  129.         self.connection.nick = nick
  130.  
  131. class ChatangoWrapper():
  132.     def __init__(self, nick, password, room, responder=None):
  133.         self.nick = nick
  134.         self.password = password
  135.         self.room = room
  136.         self.responder = responder
  137.        
  138.         self.connect()
  139.    
  140.     class RoomManager(chatango.RoomManager):   
  141.         def onConnect(self, room):
  142.             self.theRoom = room
  143.    
  144.         def onJoin(self, room, user):
  145.             self.responder.onConnect(user.name)
  146.        
  147.         def onLeave(self, room, user):
  148.             self.responder.onQuit(user.name)
  149.            
  150.         def onMessage(self, room, user, message):          
  151.             if user.name.lower() != self.nick.lower() and self.responder == self.responder.getUserByNick(user.name).nativeConnection: self.responder.onSay(user.name, message.body, message.fontColor)
  152.    
  153.     # Actions
  154.    
  155.     def connect(self):
  156.         self.connection = self.RoomManager(self.nick, self.password, False)
  157.         self.connection.joinRoom(self.room)
  158.         self.connection.nick = self.nick
  159.         self.connection.theRoom = None
  160.         self.connection.responder = self.responder
  161.         thread.start_new_thread(self.connection.main, ())
  162.    
  163.     def quit(self):
  164.         self.connection.stop()
  165.         self.connection.theRoom.disconnect()
  166.    
  167.     def say(self, message, color):
  168.         self.connection.message(message)
  169.    
  170.     def setNick(self, nick):
  171.         self.nick = nick
  172.         self.quit()
  173.         self.connect()
  174.  
  175. class TinychatWrapper():
  176.     def __init__(self, nick, room, responder=None):
  177.         self.nick = nick
  178.         self.room = room
  179.         self.responder = responder
  180.        
  181.         self.connect()
  182.    
  183.     class TinychatRoom(tinychat.TinychatRoom):
  184.         def onJoin(self, user):
  185.             if user.nick.find("-") == -1: self.responder.onConnect(user.nick)
  186.        
  187.         def onQuit(self, user):
  188.             self.responder.onQuit(user.nick)
  189.        
  190.         def onMessage(self, user, message):
  191.             if self.responder == self.responder.getUserByNick(user.nick).nativeConnection: self.responder.onSay(user.nick, message.msg, message.color)
  192.        
  193.         def onNickChange(self, new, old, user):
  194.             self.responder.onSetNick(old, new)
  195.    
  196.     # Actions
  197.    
  198.     def connect(self):
  199.         self.connection = self.TinychatRoom(self.room, self.nick)
  200.         self.connection.responder = self.responder
  201.         thread.start_new_thread(self.connection.connect, ())
  202.    
  203.     def quit(self):
  204.         self.connection.disconnect()
  205.    
  206.     def say(self, message, color):
  207.         self.connection.say(message)
  208.    
  209.     def setNick(self, nick):
  210.         self.nick = nick
  211.         self.connection.setNick(nick)
  212.  
  213. # This represents a bridged room.  Specifically, this is the observing connection.  It's job is to create users representing connections and control them based on observations.
  214.  
  215. class Room():
  216.     def __init__(self, service, room, server=None):
  217.         self.service = service
  218.         self.room = room
  219.         self.server = server
  220.        
  221.         rooms.append(self)
  222.        
  223.         if service == IRC:
  224.             self.connection = IRCWrapper(botName_IRC, botPass_IRC, room, server, self)
  225.         elif service == CHATANGO:
  226.             self.connection = ChatangoWrapper(botName_Chatango, botPass_Chatango, room, self)
  227.         elif service == TINYCHAT:
  228.             self.connection = TinychatWrapper(botName_Tinychat, room, self)
  229.  
  230.     def getUserByNick(self, nick, create=True):
  231.         for user in users:
  232.             if user.nick.lower() == nick.lower(): return user
  233.         if create: return User(self, nick)
  234.            
  235.     # Events
  236.    
  237.     def onConnect(self, nick):
  238.         self.getUserByNick(nick)
  239.         print(nick + " has joined.")
  240.    
  241.     def onQuit(self, nick):
  242.         user = self.getUserByNick(nick, False)
  243.         if user:
  244.             user.quit()
  245.             print(nick + " has quit.")
  246.    
  247.     def onSay(self, nick, message, color):
  248.         self.getUserByNick(nick).say(message, color)
  249.         print(nick + ": " + message)
  250.    
  251.     def onSetNick(self, oldNick, newNick):
  252.         user = self.getUserByNick(oldNick, False)
  253.         if user:
  254.             user.setNick(newNick)
  255.             print(oldNick + " is now known as " + newNick + ".")
  256.  
  257. # Initialization
  258.  
  259. rooms = []
  260. users = []
  261.  
  262. # Connect to the listed rooms to bridge.
  263.  
  264. for bridgedRoom in bridgedRooms:
  265.    
  266.     service = bridgedRoom[0]
  267.     room = bridgedRoom[1]
  268.     if service == IRC:
  269.         server = bridgedRoom[2]
  270.     else:
  271.         server = None
  272.     Room(service, room, server)
  273.  
  274. # Welcome the console user and wait.
  275.  
  276. print("")
  277. print("Welcome to BridgeBot!")
  278. print("Attemps to create a seemless interface between multiple chat protocols")
  279. print("Written and designed by MegaLoler (megaloler9000@gmail.com)")
  280. print("Written for Python version 2.7")
  281. print("")
  282. print("IRC library by MegaLoler (http://pastebin.com/d33RgTWY)")
  283. print("Chatango library by Lumirayz (https://github.com/theholder/ch.py)")
  284. print("Tinychat library by MegaLoler (http://pastebin.com/aVJuiLK4)")
  285. print("")
  286. print("Press enter at anytime to quit.")
  287. print("")
  288. raw_input()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement