diff --git a/bot.py b/bot.py index 36ef80d..2ac55b1 100644 --- a/bot.py +++ b/bot.py @@ -116,7 +116,7 @@ class Bot: logger.error("DCC: unable to connect to %s:%d", ip, port) return _ctcp_response(msg.sender, "ERRMSG unable to connect to %s:%d" % (ip, port)) - self.ctcp_capabilities["ACTION"] = lambda srv, msg: print ("ACTION receive: %s" % msg.content) + self.ctcp_capabilities["ACTION"] = lambda srv, msg: print ("ACTION receive: %s" % msg.text) self.ctcp_capabilities["CLIENTINFO"] = _ctcp_clientinfo self.ctcp_capabilities["DCC"] = _ctcp_dcc self.ctcp_capabilities["FINGER"] = lambda srv, msg: _ctcp_response( @@ -298,8 +298,8 @@ class Bot: def add_modules_path(self, path): """Add a path to the modules_path array, used by module loader""" # The path must end by / char - if path[len(path)-1] != "/": - path = path + "/" + if path[-1] != "/": + path += "/" if path not in self.modules_paths: self.modules_paths.append(path) @@ -444,9 +444,9 @@ class Bot: def treat_pre(self, msg, srv): """Treat a message before all other treatment""" # Treat all messages starting with 'nemubot:' as distinct commands - if msg.cmd == "PRIVMSG" and msg.content.find("%s:"%srv.nick) == 0: + if msg.cmd == "PRIVMSG" and msg.text.find("%s:"%srv.nick) == 0: # Remove the bot name - msg.content = msg.content[len(srv.nick)+1:].strip() + msg.text = msg.text[len(srv.nick)+1:].strip() msg.parse_content() msg.private = True @@ -487,30 +487,28 @@ class Bot: def treat_prvmsg_ask(self, msg, srv): # Treat ping if re.match("^ *(m[' ]?entends?[ -]+tu|h?ear me|do you copy|ping)", - msg.content, re.I) is not None: + msg.text, re.I) is not None: return response.Response(msg.sender, message="pong", - channel=msg.channel, nick=msg.nick) + channel=msg.receivers, nick=msg.nick) # Ask hooks else: return self.treat_ask(msg, srv) def treat_prvmsg(self, msg, srv): - msg.is_owner = msg.nick == srv.owner - # First, treat CTCP - if msg.ctcp: + if msg.is_ctcp: if msg.cmds[0] in self.ctcp_capabilities: return self.ctcp_capabilities[msg.cmds[0]](srv, msg) else: return _ctcp_response(msg.sender, "ERRMSG Unknown or unimplemented CTCP request") # Owner commands - if len(msg.content) > 1 and msg.content[0] == '`' and msg.nick == srv.owner: + if len(msg.text) > 1 and msg.text[0] == '`' and msg.nick == srv.owner: #TODO: owner commands pass - elif len(msg.content) > 1 and msg.content[0] == '!': + elif len(msg.text) > 1 and msg.text[0] == '!': # Remove the ! msg.cmds[0] = msg.cmds[0][1:] @@ -518,21 +516,21 @@ class Bot: return _help_msg(msg.sender, self.modules, msg.cmds) elif msg.cmds[0] == "more": - if msg.channel == srv.nick: + if msg.receivers == srv.nick: if msg.sender in srv.moremessages: return srv.moremessages[msg.sender] else: - if msg.channel in srv.moremessages: - return srv.moremessages[msg.channel] + if msg.receivers in srv.moremessages: + return srv.moremessages[msg.receivers] elif msg.cmds[0] == "next": ret = None - if msg.channel == srv.nick: + if msg.receivers == srv.nick: if msg.sender in srv.moremessages: ret = srv.moremessages[msg.sender] else: - if msg.channel in srv.moremessages: - ret = srv.moremessages[msg.channel] + if msg.receivers in srv.moremessages: + ret = srv.moremessages[msg.receivers] if ret is not None: ret.pop() return ret @@ -569,7 +567,7 @@ class Bot: if msg.cmds[0] in cmd_hook: (hks, lvl, store, bot) = cmd_hook[msg.cmds[0]] for h in hks: - if h.is_matching(msg.cmds[0], channel=msg.channel, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.channel].people): + if h.is_matching(msg.cmds[0], channel=msg.receivers, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.receivers].people): res = h.run(msg, strcmp=msg.cmds[0]) if res is not None and res != False: treated.append(res) @@ -578,7 +576,7 @@ class Bot: # Then, treat regexp based hook cmd_rgxp = self.create_cache("cmd_rgxp") for hook, lvl, store, bot in cmd_rgxp: - if hook.is_matching(msg.cmds[0], msg.channel, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.channel].people): + if hook.is_matching(msg.cmds[0], msg.receivers, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.receivers].people): res = hook.run(msg) if res is not None and res != False: treated.append(res) @@ -602,11 +600,11 @@ class Bot: # First, treat simple hook ask_hook = self.create_cache("ask_hook") - if msg.content in ask_hook: - hks, lvl, store, bot = ask_hook[msg.content] + if msg.text in ask_hook: + hks, lvl, store, bot = ask_hook[msg.text] for h in hks: - if h.is_matching(msg.content, channel=msg.channel, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.channel].people): - res = h.run(msg, strcmp=msg.content) + if h.is_matching(msg.text, channel=msg.receivers, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.receivers].people): + res = h.run(msg, strcmp=msg.text) if res is not None and res != False: treated.append(res) self.check_rest_times(store, h) @@ -614,8 +612,8 @@ class Bot: # Then, treat regexp based hook ask_rgxp = self.create_cache("ask_rgxp") for hook, lvl, store, bot in ask_rgxp: - if hook.is_matching(msg.content, channel=msg.channel, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.channel].people): - res = hook.run(msg, strcmp=msg.content) + if hook.is_matching(msg.text, channel=msg.receivers, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.receivers].people): + res = hook.run(msg, strcmp=msg.text) if res is not None and res != False: treated.append(res) self.check_rest_times(store, hook) @@ -638,11 +636,11 @@ class Bot: # First, treat simple hook msg_hook = self.create_cache("msg_hook") - if msg.content in msg_hook: - hks, lvl, store, bot = msg_hook[msg.content] + if msg.text in msg_hook: + hks, lvl, store, bot = msg_hook[msg.text] for h in hks: - if h.is_matching(msg.content, channel=msg.channel, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.channel].people): - res = h.run(msg, strcmp=msg.content) + if h.is_matching(msg.text, channel=msg.receivers, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.receivers].people): + res = h.run(msg, strcmp=msg.text) if res is not None and res != False: treated.append(res) self.check_rest_times(store, h) @@ -650,8 +648,8 @@ class Bot: # Then, treat regexp based hook msg_rgxp = self.create_cache("msg_rgxp") for hook, lvl, store, bot in msg_rgxp: - if hook.is_matching(msg.content, channel=msg.channel, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.channel].people): - res = hook.run(msg, strcmp=msg.content) + if hook.is_matching(msg.text, channel=msg.receivers, server=srv) and (msg.private or lvl == 0 or bot.nick not in srv.channels[msg.receivers].people): + res = hook.run(msg, strcmp=msg.text) if res is not None and res != False: treated.append(res) self.check_rest_times(store, hook) diff --git a/channel.py b/channel.py index c6266e8..fb570a2 100644 --- a/channel.py +++ b/channel.py @@ -36,11 +36,11 @@ class Channel: elif cmd == "JOIN": self.join(msg.nick) elif cmd == "NICK": - self.nick(msg.nick, msg.content) + self.nick(msg.nick, msg.text) elif cmd == "PART" or cmd == "QUIT": self.part(msg.nick) elif cmd == "TOPIC": - self.topic = self.content + self.topic = self.text def join(self, nick, level = 0): """Someone join the channel""" @@ -67,31 +67,31 @@ class Channel: del self.people[nick] def mode(self, msg): - if msg.content[0] == "-k": + if msg.text[0] == "-k": self.password = "" - elif msg.content[0] == "+k": - if len(msg.content) > 1: - self.password = ' '.join(msg.content[1:])[1:] + elif msg.text[0] == "+k": + if len(msg.text) > 1: + self.password = ' '.join(msg.text[1:])[1:] else: - self.password = msg.content[1] - elif msg.content[0] == "+o": + self.password = msg.text[1] + elif msg.text[0] == "+o": self.people[msg.nick] |= 4 - elif msg.content[0] == "-o": + elif msg.text[0] == "-o": self.people[msg.nick] &= ~4 - elif msg.content[0] == "+h": + elif msg.text[0] == "+h": self.people[msg.nick] |= 2 - elif msg.content[0] == "-h": + elif msg.text[0] == "-h": self.people[msg.nick] &= ~2 - elif msg.content[0] == "+v": + elif msg.text[0] == "+v": self.people[msg.nick] |= 1 - elif msg.content[0] == "-v": + elif msg.text[0] == "-v": self.people[msg.nick] &= ~1 def parse332(self, msg): - self.topic = msg.content + self.topic = msg.text def parse353(self, msg): - for p in msg.content: + for p in msg.text: p = p.decode() if p[0] == "@": level = 4 diff --git a/consumer.py b/consumer.py index 3839e72..9ad8304 100644 --- a/consumer.py +++ b/consumer.py @@ -32,7 +32,9 @@ import server logger = logging.getLogger("nemubot.consumer") class MessageConsumer: + """Store a message before treating""" + def __init__(self, srv, raw, time, prvt, data): self.srv = srv self.raw = raw @@ -44,10 +46,10 @@ class MessageConsumer: def treat_in(self, context, msg): """Treat the input message""" if msg.cmd == "PING": - self.srv.send_pong(msg.content) - else: - # TODO: Manage credits - if msg.channel is None or self.srv.accepted_channel(msg.channel): + self.srv.send_pong(msg.params[0]) + elif hasattr(msg, "receivers"): + msg.receivers = [ receiver for receiver in msg.receivers if self.srv.accepted_channel(receiver) ] + if msg.receivers: # All messages context.treat_pre(msg, self.srv) @@ -86,7 +88,7 @@ class MessageConsumer: msg.server = self.srv.id if msg.cmd == "PRIVMSG": msg.is_owner = (msg.nick == self.srv.owner) - msg.private = msg.private or msg.channel == self.srv.nick + msg.private = msg.private or (len(msg.receivers) == 1 and msg.receivers[0] == self.srv.nick) res = self.treat_in(context, msg) except: logger.exception("Error occurred during the processing of the message: %s", self.raw) diff --git a/exception.py b/exception.py index 7acfaf8..aae19c9 100644 --- a/exception.py +++ b/exception.py @@ -26,4 +26,4 @@ class IRCException(Exception): self.personnal = personnal def fill_response(self, msg): - return Response(msg.sender, self.message, channel=msg.channel, nick=(msg.nick if self.personnal else None)) + return Response(msg.sender, self.message, channel=msg.receivers, nick=(msg.nick if self.personnal else None)) diff --git a/message.py b/message.py index af4785f..c5bef6b 100644 --- a/message.py +++ b/message.py @@ -22,99 +22,107 @@ import shlex import time from response import Response -import xmlparser -filename = "" +mgx = re.compile(b'''^(?:@(?P[^ ]+)\ )? + (?::(?P + (?P[a-zA-Z][^!@ ]*) + (?: !(?P[^@ ]+))? + (?:@(?P[^ ]+))? + )\ )? + (?P(?:[a-zA-Z]+|[0-9]{3})) + (?P(?:\ [^:][^ ]*)*)(?:\ :(?P.*))? + $''', re.X) class Message: - def __init__ (self, line, timestamp, private=False): - self.raw = line - self.time = timestamp - self.channel = None - self.content = b'' - self.ctcp = False - line = line.rstrip() #remove trailing 'rn' - - words = line.split(b' ') - if words[0][0] == 58: #58 is : in ASCII table - self.sender = words[0][1:].decode() - self.cmd = words[1].decode() - else: - self.cmd = words[0].decode() - self.sender = None - - if self.cmd == 'PING': - self.content = words[1] - elif self.sender is not None: - self.nick = (self.sender.split('!'))[0] - if self.nick != self.sender: - self.realname = (self.sender.split('!'))[1] - else: - self.realname = self.nick - self.sender = self.nick + "!" + self.realname - - if len(words) > 2: - self.channel = self.pickWords(words[2:]).decode() - - if self.cmd == 'PRIVMSG': - # Check for CTCP request - self.ctcp = len(words[3]) > 1 and (words[3][0] == 0x01 or words[3][1] == 0x01) - self.content = self.pickWords(words[3:]) - # If CTCP, remove 0x01 - if self.ctcp: - self.content = self.content[1:len(self.content)-1] - elif self.cmd == '353' and len(words) > 3: - for i in range(2, len(words)): - if words[i][0] == 58: - self.content = words[i:] - #Remove the first : - self.content[0] = self.content[0][1:] - self.channel = words[i-1].decode() - break - elif self.cmd == 'NICK': - self.content = self.pickWords(words[2:]) - elif self.cmd == 'MODE': - self.content = words[3:] - elif self.cmd == '332': - self.channel = words[3] - self.content = self.pickWords(words[4:]) - else: - self.content = self.pickWords(words[3:]) - else: - if self.cmd == 'PRIVMSG': - self.channel = words[2].decode() - self.content = b' '.join(words[3:]) - self.decode() - if self.cmd == 'PRIVMSG': - self.parse_content() + def __init__ (self, raw_line, timestamp, private=False): + self.raw = raw_line self.private = private + self.tags = { 'time': timestamp } + self.params = list() + + p = mgx.match(raw_line.rstrip()) + + # Parse tags if exists: @aaa=bbb;ccc;example.com/ddd=eee + if p.group("tags"): + for tgs in self.decode(p.group("tags")).split(';'): + tag = tgs.split('=') + if len(tag) > 1: + self.add_tag(tag[0], tag[1]) + else: + self.add_tag(tag[0]) + + # Parse prefix if exists: :nick!user@host.com + self.prefix = self.decode(p.group("prefix")) + self.nick = self.decode(p.group("nick")) + self.user = self.decode(p.group("user")) + self.host = self.decode(p.group("host")) + + # Parse command + self.cmd = self.decode(p.group("command")) + + # Parse params + if p.group("params"): + for param in p.group("params").strip().split(b' '): + self.params.append(param) + + if p.group("trailing"): + self.params.append(p.group("trailing")) + + # Special commands + if self.cmd == 'PRIVMSG': + self.receivers = self.decode(self.params[0]).split(',') + + # If CTCP, remove 0x01 + if len(self.params[1]) > 1 and (self.params[1][0] == 0x01 or self.params[1][1] == 0x01): + self.is_ctcp = True + self.text = self.decode(self.params[1][1:len(self.params[1])-1]) + else: + self.is_ctcp = False + self.text = self.decode(self.params[1]) + + # Split content by words + self.parse_content() + + elif self.cmd == '353': # RPL_NAMREPLY + self.receivers = [ self.decode(self.params[0]) ] + self.nicks = self.decode(self.params[1]).split(" ") + + elif self.cmd == '332': + self.receivers = [ self.decode(self.params[0]) ] + self.topic = self.decode(self.params[1]).split(" ") + + else: + for i in range(0, len(self.params)-1): + self.params[i] = self.decode(self.params[i]) + + + # TODO: here for legacy content + @property + def sender(self): + return self.prefix + @property + def channel(self): + return self.receivers[0] + def parse_content(self): """Parse or reparse the message content""" # Split content by words try: - self.cmds = shlex.split(self.content) + self.cmds = shlex.split(self.text) except ValueError: - self.cmds = self.content.split(' ') + self.cmds = self.text.split(' ') - def pickWords(self, words): - """Parse last argument of a line: can be a single word or a sentence starting with :""" - if len(words) > 0 and len(words[0]) > 0: - if words[0][0] == 58: - return b' '.join(words[0:])[1:] - else: - return words[0] - else: - return b'' - def decode(self): + def decode(self, s): """Decode the content string usign a specific encoding""" - if isinstance(self.content, bytes): + if isinstance(s, bytes): try: - self.content = self.content.decode() + s = s.decode() except UnicodeDecodeError: #TODO: use encoding from config file - self.content = self.content.decode('utf-8', 'replace') + s = s.decode('utf-8', 'replace') + return s ############################## # # diff --git a/modules/alias.py b/modules/alias.py index 6eb8501..a9621fb 100644 --- a/modules/alias.py +++ b/modules/alias.py @@ -157,7 +157,7 @@ def treat_alias(msg, hooks_cache): and msg.cmds[0][0] == "!" and msg.cmds[0][1:] in DATAS.getNode("aliases").index and msg.cmds[0][1:] not in hooks_cache("cmd_hook")): - msg.content = msg.content.replace(msg.cmds[0], + msg.text = msg.text.replace(msg.cmds[0], DATAS.getNode("aliases").index[msg.cmds[0][1:]]["origin"], 1) msg.parse_content() @@ -166,7 +166,7 @@ def treat_alias(msg, hooks_cache): return True else: - msg.content = replace_variables(msg.content, msg) + msg.text = replace_variables(msg.text, msg) msg.parse_content() return False return False @@ -174,8 +174,8 @@ def treat_alias(msg, hooks_cache): @hook("ask_default") def parseask(msg): global ALIAS - if re.match(".*(set|cr[ée]{2}|nouvel(le)?) alias.*", msg.content) is not None: - result = re.match(".*alias !?([^ ]+) (pour|=|:) (.+)$", msg.content) + if re.match(".*(set|cr[ée]{2}|nouvel(le)?) alias.*", msg.text) is not None: + result = re.match(".*alias !?([^ ]+) (pour|=|:) (.+)$", msg.text) if result.group(1) in DATAS.getNode("aliases").index or result.group(3).find("alias") >= 0: return Response(msg.sender, "Cet alias est déjà défini.") else: diff --git a/modules/birthday.py b/modules/birthday.py index 1473091..2ae5b9e 100644 --- a/modules/birthday.py +++ b/modules/birthday.py @@ -84,7 +84,7 @@ def cmd_age(msg): @hook("ask_default") def parseask(msg): - res = re.match(r"^(\S+)\s*('s|suis|est|is|was|were)?\s+(birthday|geburtstag|née? |nee? le|born on).*$", msg.content, re.I) + res = re.match(r"^(\S+)\s*('s|suis|est|is|was|were)?\s+(birthday|geburtstag|née? |nee? le|born on).*$", msg.text, re.I) if res is not None: try: extDate = msg.extractDate() diff --git a/modules/events.py b/modules/events.py index e14b3d2..0026b85 100644 --- a/modules/events.py +++ b/modules/events.py @@ -188,14 +188,14 @@ RGXP_ask = re.compile(r"^.*((create|new)\s+(a|an|a\s*new|an\s*other)?\s*(events? @hook("ask_default") def parseask(msg): - if RGXP_ask.match(msg.content) is not None: - name = re.match("^.*!([^ \"'@!]+).*$", msg.content) + if RGXP_ask.match(msg.text) is not None: + name = re.match("^.*!([^ \"'@!]+).*$", msg.text) if name is None: raise IRCException("il faut que tu attribues une commande à l'événement.") if name.group(1) in DATAS.index: raise IRCException("un événement portant ce nom existe déjà.") - texts = re.match("^[^\"]*(avant|après|apres|before|after)?[^\"]*\"([^\"]+)\"[^\"]*((avant|après|apres|before|after)?.*\"([^\"]+)\".*)?$", msg.content, re.I) + texts = re.match("^[^\"]*(avant|après|apres|before|after)?[^\"]*\"([^\"]+)\"[^\"]*((avant|après|apres|before|after)?.*\"([^\"]+)\".*)?$", msg.text, re.I) if texts is not None and texts.group(3) is not None: extDate = msg.extractDate() if extDate is None or extDate == "": diff --git a/modules/reddit.py b/modules/reddit.py index 7789540..82bed8a 100644 --- a/modules/reddit.py +++ b/modules/reddit.py @@ -59,7 +59,7 @@ def parselisten(msg): global LAST_SUBS try: - urls = re.findall("www.reddit.com(/\w/\w+/?)", msg.content) + urls = re.findall("www.reddit.com(/\w/\w+/?)", msg.text) for url in urls: if msg.channel not in LAST_SUBS: LAST_SUBS[msg.channel] = list() diff --git a/modules/sms.py b/modules/sms.py index 48e9da2..8db48ef 100644 --- a/modules/sms.py +++ b/modules/sms.py @@ -78,11 +78,11 @@ apikey_ask = re.compile(r"(clef|key|password|mot de passe?)\s+(?:est|is)?\s+(?P< @hook("ask_default") def parseask(msg): - if msg.content.find("Free") >= 0 and ( - msg.content.find("API") >= 0 or msg.content.find("api") >= 0) and ( - msg.content.find("SMS") >= 0 or msg.content.find("sms") >= 0): - resuser = apiuser_ask.search(msg.content) - reskey = apikey_ask.search(msg.content) + if msg.text.find("Free") >= 0 and ( + msg.text.find("API") >= 0 or msg.text.find("api") >= 0) and ( + msg.text.find("SMS") >= 0 or msg.text.find("sms") >= 0): + resuser = apiuser_ask.search(msg.text) + reskey = apikey_ask.search(msg.text) if resuser is not None and reskey is not None: apiuser = resuser.group("user") apikey = reskey.group("key") diff --git a/modules/weather.py b/modules/weather.py index dab0509..dfcb583 100644 --- a/modules/weather.py +++ b/modules/weather.py @@ -212,7 +212,7 @@ gps_ask = re.compile(r"^\s*(?P.*\w)\s*(?:(?:se|est)\s+(?:trouve|situ[ée]* @hook("ask_default") def parseask(msg): - res = gps_ask.match(msg.content) + res = gps_ask.match(msg.text) if res is not None: city_name = res.group("city").lower() gps_lat = res.group("lat").replace(",", ".") diff --git a/modules/ycc.py b/modules/ycc.py index d653ccb..9ea0d15 100644 --- a/modules/ycc.py +++ b/modules/ycc.py @@ -55,7 +55,7 @@ def cmd_ycc(msg): def parselisten(msg): global LAST_URLS try: - urls = re.findall("([a-zA-Z0-9+.-]+:(?://)?[^ ]+)", msg.content) + urls = re.findall("([a-zA-Z0-9+.-]+:(?://)?[^ ]+)", msg.text) for url in urls: o = urlparse(url) if o.scheme != "": diff --git a/response.py b/response.py index 3df4fc1..4533c86 100644 --- a/response.py +++ b/response.py @@ -32,7 +32,7 @@ class Response: self.server = server self.messages = list() self.alone = True - self.ctcp = ctcp + self.is_ctcp = ctcp if message is not None: self.append_message(message, shown_first_count=shown_first_count) self.elt = 0 # Next element to display @@ -106,12 +106,18 @@ class Response: if len(self.rawtitle) <= 0: self.rawtitle = None + def treat_ctcp(self, content): + if self.is_ctcp: + return "\x01" + content + "\x01" + else: + return content + def get_message(self): if self.alone and len(self.messages) > 1: self.alone = False if self.empty: - return self.nomore + return self.treat_ctcp(self.nomore) msg = "" if self.channel is not None and self.nick is not None: @@ -132,35 +138,35 @@ class Response: if len(msg) + len(e) > 430: msg += "[…]" self.alone = False - return msg + return self.treat_ctcp(msg) else: msg += e + ", " self.elt += 1 self.pop() - return msg[:len(msg)-2] + return self.treat_ctcp(msg[:len(msg)-2]) else: if len(elts) <= 432: self.pop() if self.count is not None: - return msg + elts + (self.count % len(self.messages)) + return self.treat_ctcp(msg + elts + (self.count % len(self.messages))) else: - return msg + elts + return self.treat_ctcp(msg + elts) else: words = elts.split(' ') if len(words[0]) > 432 - len(msg): self.elt += 432 - len(msg) - return msg + elts[:self.elt] + "[…]" + return self.treat_ctcp(msg + elts[:self.elt] + "[…]") for w in words: if len(msg) + len(w) > 431: msg += "[…]" self.alone = False - return msg + return self.treat_ctcp(msg) else: msg += w + " " self.elt += len(w) + 1 self.pop() - return msg + return self.treat_ctcp(msg) diff --git a/server/IRC.py b/server/IRC.py index f42ecc6..16bcabd 100644 --- a/server/IRC.py +++ b/server/IRC.py @@ -120,21 +120,16 @@ class IRCServer(server.Server): self.channels[chan].treat(msg.cmd, msg) def evt_channel(self, msg, srv): - if msg.channel is not None: - if msg.channel in self.channels: - self.channels[msg.channel].treat(msg.cmd, msg) + if msg.receivers is not None: + for receiver in msg.receivers: + if receiver in self.channels: + self.channels[receiver].treat(msg.cmd, msg) def accepted_channel(self, chan, sender=None): """Return True if the channel (or the user) is authorized""" - if self.allow_all: - return True - elif self.listen_nick: - return (chan in self.channels and (sender is None or sender in - self.channels[chan].people) - ) or chan == self.nick - else: - return chan in self.channels and (sender is None or sender - in self.channels[chan].people) + return (self.allow_all or + (chan in self.channels and (sender is None or sender in self.channels[chan].people)) or + (self.listen_nick and chan == self.nick)) def join(self, chan, password=None, force=False): """Join a channel""" @@ -255,7 +250,7 @@ class IRCServer(server.Server): """Send a message without checks or format""" #TODO: add something for post message treatment here if channel == self.nick: - self.logger.warn("Nemubot talks to himself: %s", msg, stack_info=True) + self.logger.warn("Nemubot talks to himself: %s", line, stack_info=True) if line is not None and channel is not None: if self.s is None: self.logger.warn("Attempt to send message on a non connected server: %s: %s", self.id, line, stack_info=True) diff --git a/server/__init__.py b/server/__init__.py index a1ac635..8fffe1d 100644 --- a/server/__init__.py +++ b/server/__init__.py @@ -73,22 +73,20 @@ class Server(threading.Thread): def send_response(self, res, origin): """Analyse a Response and send it""" - # TODO: how to send a CTCP message to a different person - if res.ctcp: - self.send_ctcp(res.sender, res.get_message()) + if type(res.channel) != list: + res.channel = [ res.channel ] - elif res.channel is not None and res.channel != self.nick: - self.send_msg(res.channel, res.get_message()) + for channel in res.channel: + if channel != self.nick: + self.send_msg(channel, res.get_message()) + else: + channel = res.sender + self.send_msg_usr(channel, res.get_message(), "NOTICE" if res.is_ctcp else "PRIVMSG") if not res.alone: if hasattr(self, "send_bot"): self.send_bot("NOMORE %s" % res.channel) - self.moremessages[res.channel] = res - elif res.sender is not None: - self.send_msg_usr(res.sender, res.get_message()) - - if not res.alone: - self.moremessages[res.sender] = res + self.moremessages[channel] = res def send_ctcp(self, to, msg, cmd="NOTICE", endl="\r\n"): """Send a message as CTCP response"""