Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import rtmp_protocol
- import httplib
- from xml.dom.minidom import parseString
- import thread
- import time
- import random
- import socket
- # Tinychat Library by MegaLoler
- # Changes:
- # Added youtube and soundcloud control commands
- # Incorporated some console commands for when running the script directly
- # Brief Todo:
- # Unban command
- # Fix bug where all messages received in rooms the same name as your username appear to be PMs
- # Ability to tell whether users are moderators or not
- # Figure out more things to add :P
- DEBUG = False
- def httpRequest(server, resource, body="", headers={}, method="GET"):
- connection = httplib.HTTPConnection(server)
- connection.request(method, resource, body, headers)
- response = connection.getresponse()
- headers = response.getheaders()
- data = response.read()
- connection.close()
- return (headers, data)
- class TinychatMessage():
- def __init__(self, msg, nick, user=None, recipient=None, color=None, pm=False):
- self.msg = msg
- self.nick = nick
- self.user = user
- self.recipient = recipient
- self.color = color
- self.pm = pm
- def printFormatted(self):
- if self.pm:
- pm = "(PM) "
- else:
- pm = ""
- print(pm + self.recipient + ": " + self.nick + ": " + self.msg)
- class TinychatUser():
- def __init__(self, nick, id=None, color=None, lastMsg=None):
- self.nick = nick
- self.id = id
- self.color = color
- self.lastMsg = lastMsg
- TINYCHAT_COLORS = ["#7db257", "#a78901", "#9d5bb5", "#5c1a7a", "#c53332", "#821615", "#a08f23", "#487d21", "#c356a3", "#1d82eb", "#919104", "#a990", "#b9807f", "#7bb224", "#1965b6", "#32a5d9"]
- class TinychatRoom():
- # Manages a single room connection
- def __init__(self, room, nick=None, passwd=None):
- self.room = room
- self.tcUrl = self._getTcUrl()
- parts = self.tcUrl.split("/")
- server = parts[2].split(":")
- self.server = server[0]
- self.port = int(server[1])
- self.app = parts[3]
- self.url = "http://tinychat.com/" + room
- self.connected = False
- self.queue = []
- self.color = TINYCHAT_COLORS[random.randint(0, len(TINYCHAT_COLORS) - 1)]
- self.nick = nick
- self.passwd = passwd
- if self.nick == "": self.nick = None
- if self.passwd == "": self.passwd = None
- self.topic = None
- self.users = {}
- self.echo = __name__ == "__main__"
- self.stack = False
- def connect(self):
- if not self.connected:
- self.connection = rtmp_protocol.RtmpClient(self.server, self.port, self.tcUrl, self.url, '', self.app)
- if self.nick:
- n = self.nick.lower()
- else:
- n = ""
- self.connection.connect([self.room, self._getAutoOp(), u'show', u'tinychat', n])
- self.connected = True
- self._listen()
- def disconnect(self):
- if self.connected:
- self.connected = False
- try:
- self.connection.socket.shutdown(socket.SHUT_RDWR)
- except:
- pass
- self.onDisconnect()
- def poll(self):
- q = self.queue
- self.queue = []
- return q
- # Commands
- def say(self, msg):
- if len(msg) > 152: return
- self._sendCommand("privmsg", [u"" + self._encodeMessage(msg), u"" + self.color + ",en"])
- def pm(self, msg, recipient):
- if len(msg) > 152: return
- self._sendCommand("privmsg", [u"" + self._encodeMessage("/msg " + recipient + " " + msg), u"" + self.color + ",en", u"n" + self._getUser(recipient).id + "-" + recipient])
- def setNick(self, nick=None):
- if not nick: nick = self.nick
- self.nick = nick
- self._sendCommand("nick", [u"" + nick])
- def cycleColor(self):
- try:
- i = TINYCHAT_COLORS.index(self.color)
- except:
- i = TINYCHAT_COLORS[random.randint(0, len(TINYCHAT_COLORS) - 1)]
- i = (i + 1) % len(TINYCHAT_COLORS)
- self.color = TINYCHAT_COLORS[i]
- def ban(self, nick):
- self._sendCommand("kick", [u"" + nick, self._getUser(nick).id])
- def playYoutube(self, video):
- self.say("/mbs youTube " + str(video) + " 0")
- def stopYoutube(self):
- self.say("/mbc youTube")
- def playSoundcloud(self, track):
- self.say("/mbs soundCloud " + str(track) + " 0")
- def stopSoundcloud(self):
- self.say("/mbc soundCloud")
- # Events
- def onMessage(self, user, message):
- if self.echo: message.printFormatted()
- def onPM(self, user, message):
- if self.echo: message.printFormatted()
- def onQuit(self, user):
- if self.echo: print(self.room + ": " + user.nick + " left the room.")
- def onBan(self, user):
- if self.echo: print(self.room + ": " + user.nick + " was banned.")
- def onJoin(self, user):
- if self.echo: print(self.room + ": " + user.nick + " entered the room.")
- def onRegister(self, user):
- if self.echo: print("You have connected to " + self.room + ".")
- def onNickChange(self, new, old, user):
- if self.echo: print(self.room + ": " + old + " changed nickname to " + new + ".")
- def onTopic(self, topic):
- if self.echo: print(self.room + ": Topic set to \"" + topic + "\".")
- def onUserList(self, users):
- pass
- def onDisconnect(self):
- if self.echo: print("You have disconnected from " + self.room + ".")
- # Helper methods
- def _listen(self):
- while self.connected:
- try:
- msg = self.connection.reader.next()
- if DEBUG: print("SERVER: " + str(msg))
- if msg['msg'] == rtmp_protocol.DataTypes.COMMAND:
- pars = msg['command']
- cmd = pars[0].encode("ascii", "ignore").lower()
- if len(pars) > 3:
- pars = pars[3:]
- else:
- pars = []
- for i in range(len(pars)):
- if type(pars[i]) == str: pars[i] = pars[i].encode("ascii", "ignore")
- if cmd == "privmsg":
- recipient = pars[0]
- message = pars[1]
- color = pars[2].lower().split(",")[0]
- nick = pars[3]
- if recipient[0] == "#":
- recipient = "^".join(recipient.split("^")[1:])
- else:
- recipient = "-".join(recipient.split("-")[1:])
- user = self._getUser(nick)
- message = TinychatMessage(self._decodeMessage(message), nick, user, recipient, color)
- user.lastMsg = message
- user.color = color
- if self.stack: self.queue.append(message)
- if recipient.lower() == self.nick.lower():
- message.pm = True
- if message.msg.startswith("/msg ") and len(message.msg.split(" ")) >= 2: message.msg = " ".join(message.msg.split(" ")[2:])
- self.onPM(user, message)
- else:
- self.onMessage(user, message)
- elif cmd == "registered":
- if self.nick: self.setNick()
- user = self._getUser(pars[0])
- user.id = pars[1]
- self.onRegister(user)
- elif cmd == "topic":
- self.topic = pars[0]
- self.onTopic(self.topic)
- elif cmd == "nick":
- user = self._getUser(pars[0])
- old = user.nick
- user.nick = pars[1]
- if old.lower() in self.users.keys():
- del self.users[old.lower()]
- self.users[user.nick.lower()] = user
- self.onNickChange(user.nick, old, user)
- elif cmd == "quit":
- user = self.users[pars[0].lower()]
- del self.users[pars[0].lower()]
- self.onQuit(user)
- elif cmd == "kick":
- self.onBan(user = self.users[pars[1].lower()])
- elif cmd == "join":
- user = self._getUser(pars[1])
- user.id = pars[0]
- self.onJoin(user)
- elif cmd == "joins":
- for i in range((len(pars) - 1) / 2):
- user = self._getUser(pars[i*2 + 2])
- user.id = pars[i*2 + 1]
- elif cmd == "joinsdone":
- self.onUserList(self.users)
- except:
- self.disconnect()
- def _getUser(self, nick):
- if not nick.lower() in self.users.keys(): self.users[nick.lower()] = TinychatUser(nick)
- return self.users[nick.lower()]
- def _decodeMessage(self, msg):
- chars = msg.split(",")
- msg = ""
- for i in chars:
- msg += chr(int(i))
- return msg
- def _encodeMessage(self, msg):
- msg2 = []
- for i in msg:
- msg2.append(str(ord(i)))
- return ",".join(msg2)
- def _sendCommand(self, cmd, pars=[]):
- msg = {"msg": rtmp_protocol.DataTypes.COMMAND, "command": [u"" + cmd, 0, None] + pars}
- if DEBUG: print("CLIENT: " + str(msg))
- self.connection.writer.write(msg)
- self.connection.writer.flush()
- def _getTcUrl(self):
- return parseString(httpRequest("tinychat.com", "/api/find.room/" + self.room)[1]).getElementsByTagName("response")[0].getAttribute("rtmp")
- def _getAutoOp(self):
- if self.nick and self.passwd:
- headers = httpRequest("tinychat.com", "/login", "form_sent=1&referer=&next=&username=" + self.nick + "&password=" + self.passwd + "&passwordfake=Password&remember=1", {"Content-Type": "application/x-www-form-urlencoded"}, "POST")[0]
- cookies = []
- for header in headers:
- if header[0].lower() == "set-cookie":
- parts = header[1].split(", ")
- for i in range(len(parts)):
- part = parts[i]
- part2 = part.split(";")[0]
- if "=" in part2:
- if "," in part2:
- part2 = part2.split(", ")[1]
- cookies.append(part2)
- break
- if len(cookies) > 0:
- html = httpRequest("tinychat.com", "/" + self.room, "", {"Content-Type": "application/x-www-form-urlencoded", "Cookie": "; ".join(cookies)})[1]
- if ", autoop: \"" in html:
- return html.split(", autoop: \"")[1].split("\"")[0]
- return u"none"
- if __name__ == "__main__":
- room = TinychatRoom(raw_input("Enter room name: "), raw_input("Enter username (optional): "), raw_input("Enter password (optional): "))
- thread.start_new_thread(room.connect, ())
- while not room.connected: time.sleep(1)
- while room.connected:
- msg = raw_input()
- if len(msg) > 0:
- if msg[0] == "/":
- msg = msg[1:]
- if len(msg) > 0:
- parts = msg.split(" ")
- if len(parts) == 1:
- cmd = parts[0]
- pars = []
- par = ""
- else:
- cmd = parts[0]
- pars = parts[1:]
- par = " ".join(parts[1:])
- if cmd.lower() == "say":
- room.say(par)
- elif cmd.lower() == "pm":
- if len(pars) > 1:
- room.pm(" ".join(pars[1:]), pars[0])
- else:
- print("Please supply the recipient's nick as well as the message to send")
- elif cmd.lower() == "nick":
- room.setNick(par)
- elif cmd.lower() == "color":
- room.cycleColor()
- elif cmd.lower() == "ban":
- room.ban(par)
- elif cmd.lower() == "quit":
- room.disconnect()
- elif cmd.lower() == "playyoutube":
- room.playYoutube(par)
- elif cmd.lower() == "stopyoutube":
- room.stopYoutube()
- elif cmd.lower() == "playsoundcloud":
- room.playSoundcloud(par)
- elif cmd.lower() == "stopsoundcloud":
- room.stopSoundcloud()
- else:
- room.say(msg)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement