From 36d2b432b9888d9cb0f7b5fdabd083261e49e2be Mon Sep 17 00:00:00 2001 From: Uriziel Date: Sat, 19 Apr 2014 11:30:28 +0200 Subject: [PATCH] Removed IRC Bot support (Faulty and obsolete) --- syncplay/ircBot.py | 190 --------------------------------------------- syncplay/server.py | 185 +++++++------------------------------------ syncplayServer.py | 6 +- 3 files changed, 33 insertions(+), 348 deletions(-) delete mode 100644 syncplay/ircBot.py diff --git a/syncplay/ircBot.py b/syncplay/ircBot.py deleted file mode 100644 index 04ff260..0000000 --- a/syncplay/ircBot.py +++ /dev/null @@ -1,190 +0,0 @@ -from twisted.words.protocols import irc -from twisted.internet import reactor, protocol -from syncplay import utils - -class ColorCode(object): - NORMAL = chr(15) - BOLD = chr(2) - RED = chr(3) + "5" - BLUE = chr(3) + "12" - -''' -@author Uriziel -@author HarHar -''' -class Bot(object): - def __init__(self, server='irc.rizon.net', port=6667, nick='SyncBot', channel='', functions=[]): - ''' - functions - dict of functions that can be used from the bot: - functions = { - "pause": lambda setBy, state: None, - "getRooms": lambda: ["",], - "setRoomPosition": lambda setBy, seconds 0: None, - "getRoomPosition": lambda room: 0, - "getRoomUsers": lambda room: [{"nick": "", "file": "", "duration": 0},], - "isRoomPaused": lambda room: True, - } - ''' - self.factory = BotFactory(self, channel.encode("ascii", "replace"), nick.encode("ascii", "replace")) - self.proto = None - self.server = server - self.port = port - self._functions = functions - - def start(self): - reactor.connectTCP(self.server, self.port, self.factory) - - def registerProto(self, proto): - self.proto = proto - - def takeAction(self, action, user): - if(action == "help" or action == "h"): - v = (ColorCode.BOLD, ColorCode.NORMAL) - return "{}Available commands:{} !rooms / !roominfo [room] / !playpause (or aliases: !r, !ri [room], !p).".format(*v) - elif(action == "rooms" or action == "r"): - return self.__listRooms() - elif(action.startswith("roominfo") or action.startswith("ri")): - return self.__getRoomInfo(action) - elif(action == "playpause" or action == "p"): - return self.__playpause(user) - else: - return "{}Error!{} Unknown command".format(ColorCode.RED, ColorCode.NORMAL) - - def sp_joined(self, who, room): - msg ="{}<{}>{} has joined the room: `{}`".format(ColorCode.BOLD, who, ColorCode.NORMAL, room) - self._sendChanMessage(msg) - - def sp_left(self, who, room): - msg ="{}<{}>{} has left the room: `{}`".format(ColorCode.BOLD, who, ColorCode.NORMAL, room) - self._sendChanMessage(msg) - - def sp_unpaused(self, who, room): - msg ="{}<{}>{} has unpaused (in room `{}`)".format(ColorCode.BOLD, who, ColorCode.NORMAL, room) - self._sendChanMessage(msg) - - def sp_paused(self, who, room): - msg ="{}<{}>{} has paused (in room `{}`)".format(ColorCode.BOLD, who, ColorCode.NORMAL, room) - self._sendChanMessage(msg) - - def sp_fileplaying(self, who, filename, room): - if filename: - msg ="{}<{}>{} is playing {} (in room `{}`)".format(ColorCode.BOLD, who, ColorCode.NORMAL, filename, room) - self._sendChanMessage(msg) - - def sp_seek(self, who, fromTime, toTime, room): - v = (ColorCode.BOLD, who, ColorCode.NORMAL, utils.formatTime(fromTime), utils.formatTime(toTime), room,) - msg ="{}<{}>{} has jumped from {} to {} (in room `{}`)".format(*v) - self._sendChanMessage(msg) - - def __playpause(self, user): - rooms = self._functions["getRooms"]() - for room in rooms: - users = self._functions["getRoomUsers"](room) - for u in users: - if u['nick'] == user: - paused = self._functions["isRoomPaused"](room) - self._functions["pause"](user, not (paused)) - return "<{}> {} the room: `{}`".format(ColorCode.BOLD, user, ColorCode.NORMAL, "paused" if paused else "unpaused", room) - return "{}Error!{} Your nick was not found on the server.".format(ColorCode.RED, ColorCode.NORMAL) - - def __listRooms(self): - rooms = self._functions["getRooms"]() - if(len(rooms) >= 3): - v = ("`, `".join(rooms[:-1]), rooms[-1]) - return "Currently the Syncplay server hosts viewing sessions as follows: `{}` and ultimately `{}`.".format(*v) - elif(len(rooms) == 2): - return "Currently the Syncplay server hosts viewing sessions as follows: `{}` and `{}`.".format(rooms[0], rooms[1]) - elif(len(rooms) == 1): - return "Currently the Syncplay server hosts one viewing session called `{}`".format(rooms[0]) - else: - return "{}Notice:{} No rooms have been found on server".format(ColorCode.BLUE, ColorCode.NORMAL) - - def __getListOfFiles(self, users): - files = [] - for u in users: - if [u["file"], u["duration"]] not in files: - files.append([u["file"], u["duration"]]) - return files - - def __getUserlist(self, room): - users = self._functions["getRoomUsers"](room) - position = self._functions["getRoomPosition"](room) - paused = "Paused" if self._functions["isRoomPaused"](room) else "Playing" - files = self.__getListOfFiles(users) - message = "" - for f in files: - if (f[0] == None): - message += "No file:\n" - else: - v = ( - ColorCode.BOLD, paused, ColorCode.NORMAL, - utils.formatTime(position), - utils.formatTime(f[1]), f[0] - ) - message += "{}<{}>{} [{}/{}] {}\n".format(*v) - u = [u['nick'] for u in users if f[0] == u['file'] and f[1] == u['duration']] - if (len(u) > 1): - message += "Played by: <{}> and <{}>.\n".format(">, <".join(u[:-1]), u[-1]) - else: - message += "Played by {} alone.\n".format(u[0]) - return message - - def __getRoomInfo(self, action): - if(action.startswith("rooms")): - room = action.replace("rooms", "", 1) - else: - room = action.replace("ri", "", 1) - room = room.strip() - if('' == room): - return "{}Usage:{} !roominfo [room]".format(ColorCode.BLUE, ColorCode.NORMAL) - rooms = self._functions["getRooms"]() - if(not room in rooms): - return "{}Error!{} Room does not exists.".format(ColorCode.RED, ColorCode.NORMAL) - message = self.__getUserlist(room) - return message - - def _sendChanMessage(self, msg): - if(self.proto): - self.proto.sendChanMessage(msg) - -class BotProto(irc.IRCClient): - def __init__(self, bot, nickname): - self.nickname = nickname - self.bot = bot - self.bot.registerProto(self) - - def signedOn(self): - self.join(self.factory.channel) - - def joined(self, channel): - self.msg(channel, "Syncplay IRC Bot - I'm all fired up!") - - def privmsg(self, user, channel, msg): - user = user.split('!', 1)[0] - isActionMessage = channel == self.nickname or msg.startswith(self.nickname + ":") or msg.startswith("!") or msg.startswith(".") - if isActionMessage: - action = msg.replace(self.nickname + ":", "") - action = msg.lstrip(".!") - reply = self.bot.takeAction(action.lower(), user) - for line in reply.splitlines(): - self.msg(channel, line) - - def sendChanMessage(self, msg): - self.msg(self.factory.channel, msg) - -class BotFactory(protocol.ClientFactory): - def __init__(self, bot, channel, nickname): - self.channel = channel - self.nickname = nickname - self.bot = bot - - def buildProtocol(self, addr): - p = BotProto(self.bot, self.nickname) - p.factory = self - return p - - def clientConnectionLost(self, connector, reason): - connector.connect() - - def clientConnectionFailed(self, connector, reason): - print "IRC Bot connection failed, please check your configuration" diff --git a/syncplay/server.py b/syncplay/server.py index a136281..c8f96a6 100644 --- a/syncplay/server.py +++ b/syncplay/server.py @@ -1,4 +1,4 @@ -#coding:utf8 +# coding:utf8 import hashlib from twisted.internet import task, reactor from twisted.internet.protocol import Factory @@ -11,11 +11,10 @@ from syncplay.messages import getMessage import codecs import os from string import Template -from ircBot import Bot as IRCBot import argparse class SyncFactory(Factory): - def __init__(self, password = '', motdFilePath = None, httpReplyFilePath= None, ircConfig = None, ircVerbose = False): + def __init__(self, password='', motdFilePath=None, httpReplyFilePath=None): print getMessage("en", "welcome-server-notification").format(syncplay.version) if(password): password = hashlib.md5(password).hexdigest() @@ -25,56 +24,10 @@ class SyncFactory(Factory): self._rooms = {} self._roomStates = {} self._roomUpdate = threading.RLock() - self.ircVerbose = ircVerbose - ircConnectionData = self.readIrcConfig(ircConfig) - if(ircConnectionData): - self.setupIRCBot(ircConnectionData) - - def readIrcConfig(self, ircConfig): - if(ircConfig and os.path.isfile(ircConfig)): - cfg = codecs.open(ircConfig, "r", "utf-8-sig").read() - cfg = cfg.splitlines() - ircConnectionData = { - "server": "", - "port": "", - "nick": "", - "channel": "" - } - for line in cfg: - if("irc.server: " in line): - ircConnectionData['server'] = line.split(": ")[1] - elif("irc.serverPort: " in line): - ircConnectionData['port'] = int(line.split(": ")[1]) - elif("irc.botName: " in line): - ircConnectionData['nick'] = line.split(": ")[1] - elif("irc.channel: " in line): - ircConnectionData['channel'] = line.split(": ")[1] - return ircConnectionData - - def setupIRCBot(self, ircConnectionData): - botFunctions = { - "pause": self.ircPauseRoom, - "getRooms": self.getRooms, - "setRoomPosition": self.ircSetRoomPosition, - "getRoomPosition": self.getRoomPosition, - "getRoomUsers": self.getRoomUsernames, - "isRoomPaused": self.isRoomPaused, - } - try: - self.ircBot = IRCBot( - ircConnectionData['server'], - ircConnectionData['port'], - ircConnectionData['nick'], - ircConnectionData['channel'], - botFunctions, - ) - self.ircBot.start() - except: - print "IRC Bot could not be started, please check your configuration" def buildProtocol(self, addr): - return SyncServerProtocol(self) - + return SyncServerProtocol(self) + def _createRoomIfDoesntExist(self, roomName): if (not self._rooms.has_key(roomName)): with self._roomUpdate: @@ -90,25 +43,23 @@ class SyncFactory(Factory): allnames = [] for room in self._rooms.itervalues(): for watcher in room.itervalues(): - allnames.append(watcher.name.lower()) + allnames.append(watcher.name.lower()) while username.lower() in allnames: username += '_' self._createRoomIfDoesntExist(roomName) watcher = Watcher(self, watcherProtocol, username, roomName) with self._roomUpdate: - self._rooms[roomName][watcherProtocol] = watcher + self._rooms[roomName][watcherProtocol] = watcher reactor.callLater(0.1, watcher.scheduleSendState) l = lambda w: w.sendUserSetting(username, roomName, None, {"joined": True}) self.broadcast(watcherProtocol, l) - if(self.ircVerbose): - self.ircBot.sp_joined(username, roomName) def getWatcher(self, watcherProtocol): for room in self._rooms.itervalues(): if(room.has_key(watcherProtocol)): return room[watcherProtocol] - def getAllWatchers(self, watcherProtocol): #TODO: Optimize me + def getAllWatchers(self, watcherProtocol): # TODO: Optimize me watchers = {} for room in self._rooms.itervalues(): for watcher in room.itervalues(): @@ -127,7 +78,7 @@ class SyncFactory(Factory): with self._roomUpdate: self._rooms.pop(room) self._roomStates.pop(room) - + def getRoomPausedAndPosition(self, room): position = self._roomStates[room]["position"] paused = self._roomStates[room]["paused"] @@ -139,7 +90,7 @@ class SyncFactory(Factory): def getMotd(self, userIp, username, room, clientVersion): oldClient = False if constants.WARN_OLD_CLIENTS: - if int(clientVersion.replace(".","")) < int(constants.RECENT_CLIENT_THRESHOLD.replace(".","")): + if int(clientVersion.replace(".", "")) < int(constants.RECENT_CLIENT_THRESHOLD.replace(".", "")): oldClient = True if(self._motdFilePath and os.path.isfile(self._motdFilePath)): tmpl = codecs.open(self._motdFilePath, "r", "utf-8-sig").read() @@ -147,10 +98,10 @@ class SyncFactory(Factory): try: motd = Template(tmpl).substitute(args) if oldClient: - motdwarning = getMessage("en","new-syncplay-available-motd-message").format(clientVersion) + motdwarning = getMessage("en", "new-syncplay-available-motd-message").format(clientVersion) motd = "{}\n{}".format(motdwarning, motd) return motd if len(motd) < constants.SERVER_MAX_TEMPLATE_LENGTH else getMessage("en", "server-messed-up-motd-too-long").format(constants.SERVER_MAX_TEMPLATE_LENGTH, len(motd)) - except ValueError: + except ValueError: return getMessage("en", "server-messed-up-motd-unescaped-placeholders") elif oldClient: return getMessage("en", "new-syncplay-available-motd-message").format(clientVersion) @@ -164,7 +115,7 @@ class SyncFactory(Factory): else: return getMessage("en", "server-default-http-reply") - def sendState(self, watcherProtocol, doSeek = False, forcedUpdate = False): + def sendState(self, watcherProtocol, doSeek=False, forcedUpdate=False): watcher = self.getWatcher(watcherProtocol) if(not watcher): return @@ -180,7 +131,7 @@ class SyncFactory(Factory): def __shouldServerForceUpdateOnRoom(self, pauseChanged, doSeek): return doSeek or pauseChanged - + def __updatePausedState(self, paused, watcher): watcher.paused = paused if(self._roomStates[watcher.room]["paused"] <> paused): @@ -188,7 +139,7 @@ class SyncFactory(Factory): self._roomStates[watcher.room]["paused"] = paused self._roomStates[watcher.room]["lastUpdate"] = time.time() return True - + def __updatePositionState(self, position, doSeek, watcher): watcher.position = position if (doSeek): @@ -198,18 +149,8 @@ class SyncFactory(Factory): else: setter = min(self._rooms[watcher.room].values()) self._roomStates[watcher.room]["position"] = setter.position - self._roomStates[watcher.room]["setBy"] = setter.name + self._roomStates[watcher.room]["setBy"] = setter.name self._roomStates[watcher.room]["lastUpdate"] = setter.lastUpdate - - - def __notifyIrcBot(self, position, paused, doSeek, watcher, oldPosition, pauseChanged): - if (self.ircVerbose): - if (paused and pauseChanged): - self.ircBot.sp_paused(watcher.name, watcher.room) - elif (not paused and pauseChanged): - self.ircBot.sp_unpaused(watcher.name, watcher.room) - if (doSeek and position): - self.ircBot.sp_seek(watcher.name, oldPosition, position, watcher.room) def updateWatcherState(self, watcherProtocol, position, paused, doSeek, messageAge): watcher = self.getWatcher(watcherProtocol) @@ -227,7 +168,6 @@ class SyncFactory(Factory): self.__updatePositionState(position, doSeek or pauseChanged, watcher) forceUpdate = self.__shouldServerForceUpdateOnRoom(pauseChanged, doSeek) if(forceUpdate): - self.__notifyIrcBot(position, paused, doSeek, watcher, oldPosition, pauseChanged) l = lambda w: self.sendState(w, doSeek, forceUpdate) self.broadcastRoom(watcher.watcherProtocol, l) @@ -240,15 +180,13 @@ class SyncFactory(Factory): self._removeWatcherFromTheRoom(watcherProtocol) watcher.deactivate() self._deleteRoomIfEmpty(watcher.room) - if(self.ircVerbose): - self.ircBot.sp_left(watcher.name, watcher.room) - + def watcherGetUsername(self, watcherProtocol): return self.getWatcher(watcherProtocol).name - + def watcherGetRoom(self, watcherProtocol): return self.getWatcher(watcherProtocol).room - + def watcherSetRoom(self, watcherProtocol, room): watcher = self._removeWatcherFromTheRoom(watcherProtocol) if(not watcher): @@ -263,7 +201,7 @@ class SyncFactory(Factory): self.sendState(watcherProtocol, True) l = lambda w: w.sendUserSetting(watcher.name, watcher.room, None, None) self.broadcast(watcherProtocol, l) - + def watcherSetFile(self, watcherProtocol, file_): watcher = self.getWatcher(watcherProtocol) if(not watcher): @@ -271,92 +209,31 @@ class SyncFactory(Factory): watcher.file = file_ l = lambda w: w.sendUserSetting(watcher.name, watcher.room, watcher.file, None) self.broadcast(watcherProtocol, l) - if(self.ircVerbose): - self.ircBot.sp_fileplaying(watcher.name, watcher.file['name'], watcher.room) - + def broadcastRoom(self, sender, what): room = self._rooms[self.watcherGetRoom(sender)] if(room): with self._roomUpdate: for receiver in room: what(receiver) - + def broadcast(self, sender, what): with self._roomUpdate: for room in self._rooms.itervalues(): for receiver in room: what(receiver) - - def _findUserByUsername(self, username): - with self._roomUpdate: - for room in self._rooms.itervalues(): - for user in room.itervalues(): - if user.name == username: - return user - - def ircPauseRoom(self, setBy, paused): - user = self._findUserByUsername(setBy) - if(user): - with self._roomUpdate: - if(self._roomStates[user.room]['paused'] != paused): - self._roomStates[user.room]['paused'] = paused - self._roomStates[user.room]['setBy'] = "IRC: " + setBy - if(paused): - self.ircBot.sp_paused("IRC: " + user.name, user.room) - elif(not paused): - self.ircBot.sp_unpaused("IRC: " + user.name, user.room) - l = lambda w: self.sendState(w, False, 0, True) - self.broadcastRoom(user.watcherProtocol, l) - - - def getRooms(self): - return self._rooms.keys() - - def getRoomPosition(self, room): - with self._roomUpdate: - if room in self._roomStates: - return self._roomStates[room]["position"] - - def ircSetRoomPosition(self, setBy, time): - user = self._findUserByUsername(setBy) - if(user): - with self._roomUpdate: - oldPosition = self._roomStates[user.room]['paused'] - if(oldPosition - time > 1): - self._roomStates[user.room]['paused'] = time - self._roomStates[user.room]['setBy'] = "IRC: " + setBy - self.ircBot.sp_seek(user.name, oldPosition, time, user.room) - l = lambda w: self.sendState(w, True, 0, True) - self.broadcastRoom(user.watcherProtocol, l) - - - def getRoomUsernames(self, room): - l = [] - with self._roomUpdate: - if room in self._rooms: - for user in self._rooms[room].itervalues(): - if(user.file): - l.append({'nick': user.name, 'file': user.file['name'], "duration": user.file['duration']}) - else: - l.append({'nick': user.name, 'file': None, "duration": None}) - return l - - def isRoomPaused(self, room): - with self._roomUpdate: - if room in self._roomStates: - return self._roomStates[room]["paused"] - + class SyncIsolatedFactory(SyncFactory): def broadcast(self, sender, what): self.broadcastRoom(sender, what) - + def getAllWatchers(self, watcherProtocol): room = self.getWatcher(watcherProtocol).room if(self._rooms.has_key(room)): return self._rooms[room] else: return {} - + def watcherSetRoom(self, watcherProtocol, room): watcher = self.getWatcher(watcherProtocol) oldRoom = watcher.room @@ -387,23 +264,23 @@ class Watcher(object): def getRoomPosition(self): _, position = self.factory.getRoomPausedAndPosition(self.room) return position - + def scheduleSendState(self): self._sendStateTimer = task.LoopingCall(self.sendState) self._sendStateTimer.start(constants.SERVER_STATE_INTERVAL, True) def sendState(self): self.factory.sendState(self.watcherProtocol) - + def resetStateTimer(self): if(self._sendStateTimer): self._sendStateTimer.stop() - self._sendStateTimer.start(constants.SERVER_STATE_INTERVAL) - + self._sendStateTimer.start(constants.SERVER_STATE_INTERVAL) + def deactivate(self): if(self._sendStateTimer): self._sendStateTimer.stop() - + class ConfigurationGetter(object): def getConfiguration(self): self._prepareArgParser() @@ -411,7 +288,7 @@ class ConfigurationGetter(object): if(self._args.port == None): self._args.port = constants.DEFAULT_PORT return self._args - + def _prepareArgParser(self): self._argparser = argparse.ArgumentParser(description=getMessage("en", "server-argument-description"), epilog=getMessage("en", "server-argument-epilog")) @@ -420,5 +297,3 @@ class ConfigurationGetter(object): self._argparser.add_argument('--isolate-rooms', action='store_true', help=getMessage("en", "server-isolate-room-argument")) self._argparser.add_argument('--motd-file', metavar='file', type=str, nargs='?', help=getMessage("en", "server-motd-argument")) self._argparser.add_argument('--http-reply-file', metavar='file', type=str, nargs='?', help=getMessage("en", "server-http-reply-argument")) - self._argparser.add_argument('--irc-verbose', action='store_true', help=getMessage("en", "server-irc-verbose")) - self._argparser.add_argument('--irc-config-file', metavar='file', type=str, nargs='?', help=getMessage("en", "server-irc-config")) diff --git a/syncplayServer.py b/syncplayServer.py index ccdb88e..d74aa16 100755 --- a/syncplayServer.py +++ b/syncplayServer.py @@ -8,12 +8,12 @@ import site from twisted.internet import reactor from syncplay.server import SyncFactory, SyncIsolatedFactory, ConfigurationGetter - + argsGetter = ConfigurationGetter() args = argsGetter.getConfiguration() if(not args.isolate_rooms): - reactor.listenTCP(int(args.port), SyncFactory(args.password, args.motd_file, args.http_reply_file, args.irc_config_file, args.irc_verbose)) + reactor.listenTCP(int(args.port), SyncFactory(args.password, args.motd_file, args.http_reply_file)) else: - reactor.listenTCP(int(args.port), SyncIsolatedFactory(args.password, args.motd_file, args.http_reply_file, args.irc_config_file, args.irc_verbose)) + reactor.listenTCP(int(args.port), SyncIsolatedFactory(args.password, args.motd_file, args.http_reply_file)) reactor.run()