Commit 58d66ad0 authored by Link Mauve's avatar Link Mauve

Replace the namedtuple Message with a slotted class and merge TextBuffer.make_message in it.

parent 41f6604e
......@@ -17,9 +17,77 @@ from datetime import datetime
from config import config
from theming import get_theme, dump_tuple
message_fields = ('txt nick_color time str_time nickname user identifier'
' highlight me old_message revisions jid ack')
Message = collections.namedtuple('Message', message_fields)
class Message:
__slots__ = ('txt', 'nick_color', 'time', 'str_time', 'nickname', 'user',
'identifier', 'highlight', 'me', 'old_message', 'revisions',
'jid', 'ack')
def __init__(self, txt, time, nickname, nick_color, history, user,
identifier, str_time=None, highlight=False,
old_message=None, revisions=0, jid=None, ack=0):
"""
Create a new Message object with parameters, check for /me messages,
and delayed messages
"""
time = time or datetime.now()
if txt.startswith('/me '):
me = True
txt = '\x19%s}%s\x19o' % (dump_tuple(get_theme().COLOR_ME_MESSAGE),
txt[4:])
else:
me = False
if history:
txt = txt.replace('\x19o', '\x19o\x19%s}' %
dump_tuple(get_theme().COLOR_LOG_MSG))
str_time = time.strftime("%Y-%m-%d %H:%M:%S")
else:
if str_time is None:
str_time = time.strftime("%H:%M:%S")
else:
str_time = ''
self.txt = txt.replace('\t', ' ') + '\x19o'
self.nick_color = nick_color
self.time = time
self.str_time = str_time
self.nickname = nickname
self.user = user
self.identifier = identifier
self.highlight = highlight
self.me = me
self.old_message = old_message
self.revisions = revisions
self.jid = jid
self.ack = ack
def _other_elems(self):
"Helper for the repr_message function"
acc = ['Message(']
fields = list(self.__slots__)
fields.remove('old_message')
for field in fields:
acc.append('%s=%s' % (field, repr(getattr(self, field))))
return ', '.join(acc) + ', old_message='
def __repr__(self):
"""
repr() for the Message class, for debug purposes, since the default
repr() is recursive, so it can stack overflow given too many revisions
of a message
"""
init = self._other_elems()
acc = [init]
next_message = self.old_message
rev = 1
while next_message is not None:
acc.append(next_message._other_elems())
next_message = next_message.old_message
rev += 1
acc.append('None')
while rev:
acc.append(')')
rev -= 1
return ''.join(acc)
class CorrectionError(Exception):
pass
......@@ -27,38 +95,6 @@ class CorrectionError(Exception):
class AckError(Exception):
pass
def other_elems(self):
"Helper for the repr_message function"
acc = ['Message(']
fields = message_fields.split()
fields.remove('old_message')
for field in fields:
acc.append('%s=%s' % (field, repr(getattr(self, field))))
return ', '.join(acc) + ', old_message='
def repr_message(self):
"""
repr() for the Message class, for debug purposes, since the default
repr() is recursive, so it can stack overflow given too many revisions
of a message
"""
init = other_elems(self)
acc = [init]
next_message = self.old_message
rev = 1
while next_message:
acc.append(other_elems(next_message))
next_message = next_message.old_message
rev += 1
acc.append('None')
while rev:
acc.append(')')
rev -= 1
return ''.join(acc)
Message.__repr__ = repr_message
Message.__str__ = repr_message
class TextBuffer(object):
"""
This class just keep trace of messages, in a list with various
......@@ -83,58 +119,15 @@ class TextBuffer(object):
def last_message(self):
return self.messages[-1] if self.messages else None
@staticmethod
def make_message(txt, time, nickname, nick_color, history, user,
identifier, str_time=None, highlight=False,
old_message=None, revisions=0, jid=None, ack=0):
"""
Create a new Message object with parameters, check for /me messages,
and delayed messages
"""
time = time or datetime.now()
if txt.startswith('/me '):
me = True
txt = '\x19%s}%s' % (dump_tuple(get_theme().COLOR_ME_MESSAGE),
txt[4:])
else:
me = False
if history:
txt = txt.replace('\x19o', '\x19o\x19%s}' %
dump_tuple(get_theme().COLOR_LOG_MSG))
str_time = time.strftime("%Y-%m-%d %H:%M:%S")
else:
if str_time is None:
str_time = time.strftime("%H:%M:%S")
else:
str_time = ''
msg = Message(
txt='%s\x19o'%(txt.replace('\t', ' '),),
nick_color=nick_color,
time=time,
str_time=str_time,
nickname=nickname,
user=user,
identifier=identifier,
highlight=highlight,
me=me,
old_message=old_message,
revisions=revisions,
jid=jid,
ack=ack)
log.debug('Set message %s with %s.', identifier, msg)
return msg
def add_message(self, txt, time=None, nickname=None,
nick_color=None, history=None, user=None, highlight=False,
identifier=None, str_time=None, jid=None, ack=0):
"""
Create a message and add it to the text buffer
"""
msg = self.make_message(txt, time, nickname, nick_color, history,
user, identifier, str_time=str_time,
highlight=highlight, jid=jid, ack=ack)
msg = Message(txt, time, nickname, nick_color, history, user,
identifier, str_time=str_time, highlight=highlight,
jid=jid, ack=ack)
self.messages.append(msg)
while len(self.messages) > self.messages_nb_limit:
......@@ -187,13 +180,10 @@ class TextBuffer(object):
raise AckError('Wrong JID for message id %s (was %s, expected %s)' %
(old_id, msg.jid, jid))
new_msg = list(msg)
new_msg[12] = value
msg.ack = value
if append:
new_msg[0] = new_msg[0] + append
new_msg = Message(*new_msg)
self.messages[i] = new_msg
return new_msg
msg.txt += append
return msg
def modify_message(self, txt, old_id, new_id, highlight=False,
time=None, user=None, jid=None):
......@@ -224,12 +214,10 @@ class TextBuffer(object):
if not time:
time = msg.time
message = self.make_message(txt, time, msg.nickname,
msg.nick_color, None, msg.user,
new_id, highlight=highlight,
old_message=msg,
revisions=msg.revisions + 1,
jid=jid)
message = Message(txt, time, msg.nickname, msg.nick_color, None,
msg.user, new_id, highlight=highlight,
old_message=msg, revisions=msg.revisions + 1,
jid=jid)
self.messages[i] = message
log.debug('Replacing message %s with %s.', old_id, new_id)
return message
......
......@@ -26,7 +26,7 @@ format_chars = '\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18'
# different colors allowed in the input
allowed_color_digits = ('0', '1', '2', '3', '4', '5', '6', '7')
# msg is a reference to the corresponding Message tuple. text_start and
# msg is a reference to the corresponding Message object. text_start and
# text_end are the position delimiting the text in this line.
class Line:
__slots__ = ('msg', 'start_pos', 'end_pos', 'prepend')
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment