Fix message decoding

This commit is contained in:
Némunaire 2012-07-23 18:08:11 +02:00
parent 14a963871f
commit e9ae971621
2 changed files with 52 additions and 44 deletions

View File

@ -16,7 +16,7 @@ class Channel:
self.topic = newtopic self.topic = newtopic
def nick(self, oldnick, newnick): def nick(self, oldnick, newnick):
print ("%s change de nom pour %s" % (oldnick, newnick)) #print ("%s change de nom pour %s" % (oldnick, newnick))
if oldnick in self.people: if oldnick in self.people:
lvl = self.people[oldnick] lvl = self.people[oldnick]
del self.people[oldnick] del self.people[oldnick]
@ -38,23 +38,24 @@ class Channel:
else: else:
self.password = msg.content[1] self.password = msg.content[1]
elif msg.content[0] == "+o": elif msg.content[0] == "+o":
self.people[msg.sender] |= 4 self.people[msg.nick] |= 4
elif msg.content[0] == "-o": elif msg.content[0] == "-o":
self.people[msg.sender] &= ~4 self.people[msg.nick] &= ~4
elif msg.content[0] == "+h": elif msg.content[0] == "+h":
self.people[msg.sender] |= 2 self.people[msg.nick] |= 2
elif msg.content[0] == "-h": elif msg.content[0] == "-h":
self.people[msg.sender] &= ~2 self.people[msg.nick] &= ~2
elif msg.content[0] == "+v": elif msg.content[0] == "+v":
self.people[msg.sender] |= 1 self.people[msg.nick] |= 1
elif msg.content[0] == "-v": elif msg.content[0] == "-v":
self.people[msg.sender] &= ~1 self.people[msg.nick] &= ~1
def parse332(self, msg): def parse332(self, msg):
self.topic = msg.content self.topic = msg.content
def parse353(self, msg): def parse353(self, msg):
for p in msg.content: for p in msg.content:
p = p.decode()
if p[0] == "@": if p[0] == "@":
level = 4 level = 4
elif p[0] == "%": elif p[0] == "%":

View File

@ -33,18 +33,20 @@ class Message:
self.srv = srv self.srv = srv
self.time = datetime.now () self.time = datetime.now ()
self.channel = None self.channel = None
self.content = b''
self.ctcp = False
line = line.rstrip() #remove trailing 'rn' line = line.rstrip() #remove trailing 'rn'
words = line.split(b' ') words = line.split(b' ')
if words[0][0] == 58: #58 is : in ASCII table if words[0][0] == 58: #58 is : in ASCII table
self.sender = words[0][1:].decode() self.sender = words[0][1:].decode()
self.cmd = words[1] self.cmd = words[1].decode()
else: else:
self.cmd = words[0] self.cmd = words[0].decode()
self.sender = None self.sender = None
if self.cmd == b'PING': if self.cmd == 'PING':
self.content = words[1].decode() self.content = words[1]
elif self.sender is not None: elif self.sender is not None:
self.nick = (self.sender.split('!'))[0] self.nick = (self.sender.split('!'))[0]
if self.nick != self.sender: if self.nick != self.sender:
@ -54,51 +56,56 @@ class Message:
self.sender = self.nick + "!" + self.realname self.sender = self.nick + "!" + self.realname
if len(words) > 2: if len(words) > 2:
self.channel = words[2].decode() self.channel = self.pickWords(words[2:]).decode()
if self.cmd == b'PRIVMSG': if self.cmd == 'PRIVMSG':
#Check for CTCP request #Check for CTCP request
self.ctcp = len(words[3]) > 1 and (words[3][0] == 0x01 or words[3][1] == 0x01) self.ctcp = len(words[3]) > 1 and (words[3][0] == 0x01 or words[3][1] == 0x01)
self.content = words[3] self.content = b' '.join(words[3:])
self.decode()
if self.content[0] == ':':
self.content = (b' '.join(words[3:])[1:])
self.decode()
elif self.cmd == '353' and len(words) > 3: elif self.cmd == '353' and len(words) > 3:
for i in range(2, len(words)): for i in range(2, len(words)):
if words[i][0] == ":": if words[i][0] == 58:
self.content = words[i:] self.content = words[i:]
#Remove the first : #Remove the first :
self.content[0] = self.content[0][1:] self.content[0] = self.content[0][1:]
self.channel = words[i-1] self.channel = words[i-1].decode()
break break
elif self.cmd == 'NICK':
self.content = self.pickWords(words[2:])
elif self.cmd == 'MODE': elif self.cmd == 'MODE':
self.content = words[3:] self.content = words[3:]
elif self.cmd == 'JOIN' and self.channel[0] == ":":
self.channel = self.channel[1:]
elif self.cmd == 'TOPIC' and self.channel[0] == ":":
self.content = ' '.join(words[3:])[1:]
elif self.cmd == '332': elif self.cmd == '332':
self.channel = words[3] self.channel = words[3]
self.content = ' '.join(words[4:])[1:] self.content = self.pickWords(words[4:])
else: else:
# print (line) print (line)
self.content = ' '.join(words[3:]) self.content = self.pickWords(words[3:])
else: else:
print (line) print (line)
if self.cmd == 'PRIVMSG': if self.cmd == 'PRIVMSG':
self.channel = words[2] self.channel = words[2].decode()
self.content = words[3] self.content = b' '.join(words[3:])
if self.content[0] == ':': self.decode()
self.content = ' '.join(words[3:])[1:]
self.private = private or (self.channel is not None and self.channel == self.srv.nick) self.private = private or (self.channel is not None and self.channel == self.srv.nick)
def pickWords(self, words):
"""Parse last argument of a line: can be a single word or a sentence starting with :"""
if len(words) > 0:
if words[0][0] == 58:
return b' '.join(words[0:])[1:]
else:
return words[0]
else:
return ""
def decode(self): def decode(self):
try: """Decode the content string usign a specific encoding"""
self.content = self.content.decode() if isinstance(self.content, bytes):
except UnicodeDecodeError: try:
#TODO: use encoding from config file self.content = self.content.decode()
self.content = self.content.decode('utf-8', 'replace') except UnicodeDecodeError:
#TODO: use encoding from config file
self.content = self.content.decode('utf-8', 'replace')
@property @property
def is_owner(self): def is_owner(self):
@ -139,11 +146,11 @@ class Message:
return self.srv.accepted_channel(self.channel) return self.srv.accepted_channel(self.channel)
def treat(self, mods): def treat(self, mods):
if self.cmd == b"PING": if self.cmd == "PING":
self.pong () self.pong ()
elif self.cmd == b"PRIVMSG" and self.ctcp: elif self.cmd == "PRIVMSG" and self.ctcp:
self.parsectcp () self.parsectcp ()
elif self.cmd == b"PRIVMSG" and self.authorize(): elif self.cmd == "PRIVMSG" and self.authorize():
self.parsemsg (mods) self.parsemsg (mods)
elif self.channel in self.srv.channels: elif self.channel in self.srv.channels:
if self.cmd == "353": if self.cmd == "353":
@ -153,17 +160,17 @@ class Message:
elif self.cmd == "MODE": elif self.cmd == "MODE":
self.srv.channels[self.channel].mode(self) self.srv.channels[self.channel].mode(self)
elif self.cmd == "JOIN": elif self.cmd == "JOIN":
self.srv.channels[self.channel].join(self.sender) self.srv.channels[self.channel].join(self.nick)
elif self.cmd == "PART": elif self.cmd == "PART":
self.srv.channels[self.channel].part(self.sender) self.srv.channels[self.channel].part(self.nick)
elif self.cmd == "TOPIC": elif self.cmd == "TOPIC":
self.srv.channels[self.channel].chtopic(self.content) self.srv.channels[self.channel].chtopic(self.content)
elif self.cmd == "NICK": elif self.cmd == "NICK":
for chn in self.srv.channels.keys(): for chn in self.srv.channels.keys():
self.srv.channels[chn].nick(self.sender, self.content) self.srv.channels[chn].nick(self.nick, self.content)
elif self.cmd == "QUIT": elif self.cmd == "QUIT":
for chn in self.srv.channels.keys(): for chn in self.srv.channels.keys():
self.srv.channels[chn].part(self.sender) self.srv.channels[chn].part(self.nick)
def pong (self): def pong (self):
@ -256,7 +263,7 @@ class Message:
print (CREDITS[c].to_string()) print (CREDITS[c].to_string())
#Messages stating with ! #Messages stating with !
elif self.content[0] == '!' and len(self.content[0]) > 1: elif self.content[0] == '!' and len(self.content) > 1:
self.mods = mods self.mods = mods
try: try:
self.cmd = shlex.split(self.content[1:]) self.cmd = shlex.split(self.content[1:])