def modeChanged(self, user, channel, set, modes, args): message = IRCMessage('MODE', user, self.getChannel(channel), u'', self) if not message.Channel: # Setting a usermode for mode, arg in zip(modes, args): if set: self.userModes[mode] = arg else: del self.userModes[mode] else: # Setting a chanmode for mode, arg in zip(modes, args): if mode in ServerInfo.Statuses: # Setting a status mode if set: if arg not in self.channels[channel].Ranks: self.channels[channel].Ranks[arg] = mode else: self.channels[channel].Ranks[arg] = self.channels[channel].Ranks[arg] + mode else: self.channels[channel].Ranks[arg] = self.channels[channel].Rank[arg].replace(mode, '') else: # Setting a normal chanmode if set: self.channels[channel].Modes[mode] = arg else: del self.channels[channel].Modes[mode] message.ModeArgs = [arg for arg in args if arg is not None] message.Modes = modes message.ModeOperator = '+' if set else '-' message.ReplyTo = message.ReplyTo if message.Channel else '' self.handleMessage(message)
def POST(self, name=None): data = web.data() jsonData = json.loads(data) message = IRCMessage(jsonData) if message.MessageString is not None: message.MessageString = message.MessageString.encode('ascii', 'xmlcharrefreplace') #print message.__dict__ print ( '%s <%s> %s' % (message.ReplyTo, message.User.Name, message.MessageString) ) responses = [] for (name, func) in functions.items(): try: response = func.GetResponse(message) if response is None: continue if hasattr(response, '__iter__'): for r in response: responses.append( r.__dict__ ) else: responses.append( response.__dict__ ) except Exception: msg = IRCResponse(ResponseType.Say, ("Python Execution Error in '%s': %s" % (name, str( sys.exc_info() ))), message.ReplyTo) responses.append( msg.__dict__ ) return json.dumps(responses)
def sendMsg(self, to_nick, format, *args): #sends a message to a nick as this client #eventually, will use the client's preferred notification method, for now it's PRIVMSGs #Network.sendMsg(IRCMessage(":", self.nick, "PRIVMSG", to_nick, format % args)) if (isinstance(format, types.StringTypes)): text = format % args else: text = format for line in IRCMessage.wrapText(text): Network.sendMsg( IRCMessage(":", self.nick, "PRIVMSG", to_nick, line))
def execute(self, message): """ @type message: IRCMessage """ # split on unescaped | chain = re.split(r'(?<!\\)\|', message.Parameters) response = None extraVars = {} for link in chain: link = link.strip() link = re.sub(r'\\\|', r'|', link) if response is not None: if hasattr(response, '__iter__'): return IRCResponse(ResponseType.Say, u"Chain Error: segment before '{}' returned a list".format(link), message.ReplyTo) link = link.replace('$output', response.Response) # replace $output with output of previous command extraVars.update(response.ExtraVars) for var, value in extraVars.iteritems(): link = re.sub(r'\$\b{}\b'.format(re.escape(var)), '{}'.format(value), link) else: # replace $output with empty string if previous command had no output # (or this is the first command in the chain, but for some reason has $output as a param) link = link.replace('$output', '') link = link.replace('$sender', message.User.Name) if message.Channel is not None: link = link.replace('$channel', message.Channel.Name) else: link = link.replace('$channel', message.User.Name) # build a new message out of this 'link' in the chain inputMessage = IRCMessage(message.Type, message.User.String, message.Channel, self.bot.commandChar + link.lstrip(), self.bot) inputMessage.chained = True # might be used at some point to tell commands they're being called from Chain if inputMessage.Command.lower() in self.bot.moduleHandler.mappedTriggers: response = self.bot.moduleHandler.mappedTriggers[inputMessage.Command.lower()].execute(inputMessage) else: return IRCResponse(ResponseType.Say, "'{0}' is not a recognized command trigger".format(inputMessage.Command), message.ReplyTo) if response.Response is not None: # limit response length (chains can get pretty large) response.Response = list(StringUtils.splitUTF8(response.Response.encode('utf-8'), 700))[0] response.Response = unicode(response.Response, 'utf-8') return response
def _aliasedMessage(self, message): if message.Command.lower() not in self.aliases: return alias = self.aliases[message.Command.lower()] newMsg = u"{0}{1}".format(self.bot.commandChar, ' '.join(alias)) newMsg = newMsg.replace("$sender", message.User.Name) if message.Channel is not None: newMsg = newMsg.replace("$channel", message.Channel.Name) else: newMsg = newMsg.replace("$channel", message.User.Name) paramList = [ self._mangleReplacementPoints(param) for param in message.ParameterList ] # if the alias contains numbered param replacement points, replace them if re.search(r'\$[0-9]+', newMsg): newMsg = newMsg.replace("$0", u" ".join(paramList)) for i, param in enumerate(paramList): if newMsg.find(u"${}+".format(i + 1)) != -1: newMsg = newMsg.replace(u"${}+".format(i + 1), u" ".join(paramList[i:])) else: newMsg = newMsg.replace(u"${}".format(i + 1), param) # if there are no numbered replacement points, append the full parameter list instead else: newMsg += u" {}".format(u" ".join(paramList)) newMsg = self._unmangleReplacementPoints(newMsg) return IRCMessage(message.Type, message.User.String, message.Channel, newMsg, self.bot)
def execute(self, message): """ @type message: IRCMessage """ # TODO: maybe do this in the command handler? # map triggers to commands so we can call them via dict lookup mappedTriggers = {} for command in self.bot.moduleHandler.commands.values(): for trigger in command.triggers: mappedTriggers[trigger] = command # split on unescaped | chain = re.split(r'(?<!\\)\|', message.Parameters) # rebuild the user string... TODO: this should probably be part of the User class if message.User.User is not None: userString = '{0}!{1}@{2}'.format(message.User.Name, message.User.User, message.User.Hostmask) else: userString = message.User.Name response = None for link in chain: if response is not None: link = link.replace('%output%', response.Response) # replace %output% with output of previous command else: # replace %output% with empty string if previous command had no output # (or this is the first command in the chain, but for some reason has %output% as a param) link = link.replace('%output%', '') # build a new message out of this 'link' in the chain inputMessage = IRCMessage(message.Type, userString, message.Channel, self.bot.commandChar + link.lstrip(), self.bot) inputMessage.chained = True # might be used at some point to tell commands they're being called from Chain if inputMessage.Command.lower() in mappedTriggers: response = mappedTriggers[inputMessage.Command.lower()].execute(inputMessage) else: return IRCResponse(ResponseType.Say, "'{0}' is not a recognized command trigger".format(inputMessage.Command), message.ReplyTo) if response.Response is not None: # limit response length (chains can get pretty large) response.Response = list(StringUtils.splitUTF8(response.Response.encode('utf-8'), 700))[0] response.Response = unicode(response.Response, 'utf-8') return response
def topicUpdated(self, user, channel, newTopic): self.channels[channel].Topic = newTopic self.channels[channel].TopicSetBy = user message = IRCMessage('TOPIC', user, self.getChannel(channel), newTopic, self) self.handleMessage(message)
def irc_KICK(self, prefix, params): kickMessage = u'' if len(params) > 2: kickMessage = u', message: ' + u' '.join(params[2:]) channel = self.channels[params[0]] message = IRCMessage('KICK', prefix, channel, kickMessage, self) message.Kickee = params[1] if message.Kickee == self.nickname: del self.channels[message.ReplyTo] else: del channel.Users[message.Kickee] if message.Kickee in channel.Ranks: del channel.Ranks[message.Kickee] self.handleMessage(message)
def irc_KICK(self, prefix, params): kickMessage = u'' if len(params) > 2: kickMessage = u', message: ' + u' '.join(params[2:]) channel = self.channels[params[0]] message = IRCMessage('KICK', prefix, channel, kickMessage, self) message.Kickee = params[1] if message.Kickee == self.nickname: del self.channels[message.ReplyTo] else: del channel.Users[message.Kickee] if message.Kickee in channel.Ranks: del channel.Ranks[message.Kickee] self.handleMessage(message)
def sendMsg(self, to_nick, format, *args): #sends a message to a nick as this client #eventually, will use the client's preferred notification method, for now it's PRIVMSGs #Network.sendMsg(IRCMessage(":", self.nick, "PRIVMSG", to_nick, format % args)) if(isinstance(format, types.StringTypes)): text=format % args else: text=format for line in IRCMessage.wrapText(text): Network.sendMsg(IRCMessage(":", self.nick, "PRIVMSG", to_nick, line))
def introduce(self): svr = Server.getLinkedServer() msg = None if (svr.protoctl["NICKv2"]): if (svr.protoctl["CLK"]): #NICKv2 and CLK if (svr.protoctl["NICKIP"]): #NICKv2 and CLK and NICKIP msg = IRCMessage(None, None, "nick", self.nick, self.hopcount, self.timestamp, self.username, self.hostname, self.server, self.servicestamp, self.usermodes, self.virtualhost, self.cloakedhost, self.nickipaddr, self.realname) else: #NICKv2 and CLK msg = IRCMessage(None, None, "nick", self.nick, self.hopcount, self.timestamp, self.username, self.hostname, self.server, self.servicestamp, self.usermodes, self.virtualhost, self.cloakedhost, self.realname) else: #NICKv2 but not CLK if (svr.protoctl["NICKIP"]): #NICKv2 and NICKIP msg = IRCMessage(None, None, "nick", self.nick, self.hopcount, self.timestamp, self.username, self.hostname, self.server, self.servicestamp, self.usermodes, self.virtualhost, self.nickipaddr, self.realname) else: #nickv2, no clk, no nickip msg = IRCMessage(None, None, "nick", self.nick, self.hopcount, self.timestamp, self.username, self.hostname, self.server, self.servicestamp, self.usermodes, self.virtualhost, self.realname) else: #normal msg = IRCMessage(None, None, "nick", self.nick, self.hopcount, self.timestamp, self.username, self.hostname, self.server, self.servicestamp, self.realname) Network.sendMsg(msg)
def sendf(*args): args = list(args) if (args[0][0] in (":", "@")): src_type = args[0][0] source = args.pop(0)[1:] else: #if(Server.getLinkedServer().protoctl["NS"]): # src_type="@" # source=config.get("Server/Numeric") #else: src_type = ":" source = config.get("Server/Name") return sendMsg(IRCMessage(src_type, source, *args))
def irc_QUIT(self, prefix, params): quitMessage = u'' if len(params) > 0: quitMessage = u', message: ' + u' '.join(params[0:]) for key in self.channels: channel = self.channels[key] message = IRCMessage('QUIT', prefix, channel, quitMessage, self) if message.User.Name in channel.Users: del channel.Users[message.User.Name] if message.User.Name in channel.Ranks: del channel.Ranks[message.User.Name] self.handleMessage(message)
def irc_PART(self, prefix, params): partMessage = u'' if len(params) > 1: partMessage = u', message: ' + u' '.join(params[1:]) channel = self.channels[params[0]] message = IRCMessage('PART', prefix, channel, partMessage, self) if message.User.Name == self.nickname: del self.channels[message.ReplyTo] else: del channel.Users[message.User.Name] if message.User.Name in channel.Ranks: del channel.Ranks[message.User.Name] self.handleMessage(message)
def irc_JOIN(self, prefix, params): if params[0] in self.channels: channel = self.channels[params[0]] else: channel = IRCChannel(params[0]) message = IRCMessage('JOIN', prefix, channel, u'', self) if message.User.Name == self.nickname: self.channels[message.ReplyTo] = channel self.sendLine('WHO ' + message.ReplyTo) self.sendLine('MODE ' + message.ReplyTo) else: channel.Users[message.User.Name] = message.User self.handleMessage(message)
def irc_NICK(self, prefix, params): userArray = prefix.split('!') oldnick = userArray[0] newnick = params[0] for key in self.channels: channel = self.channels[key] for userKey in channel.Users: user = channel.Users[userKey] if userKey == oldnick: channel.Users[newnick] = IRCUser('{0}!{1}@{2}'.format( newnick, user.User, user.Hostmask)) del channel.Users[oldnick] if oldnick in channel.Ranks: channel.Ranks[newnick] = channel.Ranks[oldnick] del channel.Ranks[oldnick] message = IRCMessage('NICK', prefix, channel, newnick, self) self.handleMessage(message)
def execute(self, message): """ @type message: IRCMessage """ if len(message.ParameterList) < 2: return IRCResponse(ResponseType.Say, self.help, message.ReplyTo) command = message.ParameterList[1].lower() delay = timeparse(message.ParameterList[0]) delayDelta = datetime.timedelta(seconds=delay) delayString = StringUtils.deltaTimeToString(delayDelta, 's') params = message.ParameterList[2:] commandString = u'{}{} {}'.format(self.bot.commandChar, command, u' '.join(params)) commandString = commandString.replace('$delayString', delayString) commandString = commandString.replace('$delay', str(delay)) newMessage = IRCMessage(message.Type, message.User.String, message.Channel, commandString, self.bot) moduleHandler = self.bot.moduleHandler if command in moduleHandler.mappedTriggers: d = task.deferLater(reactor, delay, moduleHandler.mappedTriggers[command].execute, newMessage) d.addCallback(self.bot.sendResponse) return IRCResponse(ResponseType.Say, "OK, I'll execute that in {}".format(delayString), message.ReplyTo, {'delay': delay, 'delayString': delayString}) else: if 'Alias' not in moduleHandler.commands: return IRCResponse(ResponseType.Say, "'{}' is not a recognized command".format(command), message.ReplyTo) if command not in moduleHandler.commands['Alias'].aliases: return IRCResponse(ResponseType.Say, "'{}' is not a recognized command or alias".format(command), message.ReplyTo) d = task.deferLater(reactor, delay, moduleHandler.commands['Alias'].execute, newMessage) d.addCallback(self.bot.sendResponse) return IRCResponse(ResponseType.Say, "OK, I'll execute that in {}".format(delayString), message.ReplyTo)
def modeChanged(self, user, channel, set, modes, args): message = IRCMessage('MODE', user, self.getChannel(channel), u'', self) if not message.Channel: # Setting a usermode for mode, arg in zip(modes, args): if set: self.userModes[mode] = arg else: del self.userModes[mode] else: # Setting a chanmode for mode, arg in zip(modes, args): if mode in ServerInfo.Statuses: # Setting a status mode if set: if arg not in self.channels[channel].Ranks: self.channels[channel].Ranks[arg] = mode else: self.channels[channel].Ranks[ arg] = self.channels[channel].Ranks[arg] + mode else: self.channels[channel].Ranks[arg] = self.channels[ channel].Rank[arg].replace(mode, '') else: # Setting a normal chanmode if set: self.channels[channel].Modes[mode] = arg else: del self.channels[channel].Modes[mode] message.ModeArgs = [arg for arg in args if arg is not None] message.Modes = modes message.ModeOperator = '+' if set else '-' message.ReplyTo = message.ReplyTo if message.Channel else '' self.handleMessage(message)
def noticed(self, user, channel, msg): chan = self.getChannel(channel) message = IRCMessage('NOTICE', user, chan, msg, self) self.handleMessage(message)
def introduce(self): Network.sendMsg( IRCMessage(":", config.get("Server/Name"), "server", self.name, self.hopcount + 1, self.description)) Network.sendMsg(IRCMessage(":", self.name, "EOS"))
def remove(self, reason="Removed"): del self.pseudoclients[self.name] del self.pseudoclients_bynick[self.nick.lower()] Client.removeClient(self) Network.sendMsg(IRCMessage(":", self.nick, "QUIT", reason))
def execute(self, message): """ @type message: IRCMessage """ subString = self._mangleEscapes(message.Parameters) try: segments = list(self._parseSubcommandTree(subString)) except UnbalancedBracesException as e: red = assembleFormattedText(A.fg.lightRed['']) normal = assembleFormattedText(A.normal['']) error = subString[:e.column] + red + subString[ e.column] + normal + subString[e.column + 1:] error = self._unmangleEscapes(error, False) return [ IRCResponse(ResponseType.Say, u"Sub Error: {}".format(e.message), message.ReplyTo), IRCResponse(ResponseType.Say, error, message.ReplyTo) ] prevLevel = -1 responseStack = [] extraVars = {} metadata = {} for segment in segments: (level, command, start, end) = segment # We've finished executing subcommands at the previous depth, # so replace subcommands with their output at the current depth if level < prevLevel: command = self._substituteResponses(command, responseStack, level, extraVars, start) # Build a new message out of this segment inputMessage = IRCMessage(message.Type, message.User.String, message.Channel, self.bot.commandChar + command.lstrip(), self.bot, metadata=metadata) # Execute the constructed message if inputMessage.Command.lower( ) in self.bot.moduleHandler.mappedTriggers: response = self.bot.moduleHandler.mappedTriggers[ inputMessage.Command.lower()].execute(inputMessage) """@type : IRCResponse""" else: return IRCResponse( ResponseType.Say, u"'{}' is not a recognized command trigger".format( inputMessage.Command), message.ReplyTo) # Push the response onto the stack responseStack.append((level, response.Response, start, end)) # Update the extraVars dict extraVars.update(response.ExtraVars) metadata = self._recursiveMerge(metadata, response.Metadata) prevLevel = level responseString = self._substituteResponses(subString, responseStack, -1, extraVars, -1) responseString = self._unmangleEscapes(responseString) return IRCResponse(ResponseType.Say, responseString, message.ReplyTo, extraVars=extraVars, metadata=metadata)
def privmsg(self, user, channel, msg): chan = self.getChannel(channel) message = IRCMessage('PRIVMSG', user, chan, msg, self) self.handleMessage(message)
def action(self, user, channel, msg): chan = self.getChannel(channel) message = IRCMessage('ACTION', user, chan, msg, self) self.handleMessage(message)