Preload history into discussion windows (à la mcabber)

- New option load_log defaulting to 200 to indicate the number of lines
  to be loaded
- It’s still very raw, and the format of the message does not match the
  format of the normal room history, for example
- Works in the Private chat, MUC, and Conversation tabs

Thanks to labedz <github@labedz.org> for the original code
This commit is contained in:
mathieui 2012-11-11 16:01:53 +01:00
parent 844392a69a
commit 6781f67e80
6 changed files with 67 additions and 14 deletions

View file

@ -184,6 +184,11 @@ muc_history_length = 50
# in files.
use_log = false
# The number of lines to preload in a chat buffer when it opens
# (the lines are preloaded from the log files)
# 0 or a negative value disable that option
load_log = 200
# If log_dir is not set, logs will be saved in $XDG_DATA_HOME/poezio/logs,
# i.e. in ~/.local/share/poezio/logs/. So, you should specify the directory
# you want to use instead. This directory will be created if it doesn't exist

View file

@ -242,6 +242,10 @@ section of this documentation.
set to 'false' if you dont want to save logs of all the messages
in files.
*load_log*:: 200
The number of line to preload in a chat buffer when it opens. The lines are
loaded from the log files. 0 or a negative value here disable that option.
*log_dir*:: [empty]

View file

@ -63,6 +63,25 @@ class Logger(object):
except IOError:
return None
def get_logs(self, jid, nb=200):
"""
Get the log history for the given jid
"""
if nb <= 0:
return None
directory = os.path.join(DATA_HOME, 'logs')
try:
fd = open(os.path.join(directory, jid), 'r')
except:
return None
else:
if not fd:
return None
logs = fd.readlines()
fd.close()
return logs[-nb:]
def log_message(self, jid, nick, msg):
"""
log the message in the appropriate jid's file

View file

@ -389,8 +389,9 @@ class ChatTab(Tab):
"""
plugin_commands = {}
plugin_keys = {}
def __init__(self):
def __init__(self, jid=''):
Tab.__init__(self)
self.name = jid
self._text_buffer = TextBuffer()
self.remote_wants_chatstates = None # change this to True or False when
# we know that the remote user wants chatstates, or not.
@ -421,6 +422,24 @@ class ChatTab(Tab):
self.update_commands()
self.update_keys()
# Get the logs
log_nb = config.get('load_log', 200)
if isinstance(self, PrivateTab):
logs = logger.get_logs(safeJID(self.get_name()).full.replace('/', '\\'), log_nb)
else:
logs = logger.get_logs(safeJID(self.get_name()).bare, log_nb)
if logs:
for log_line in logs:
log_line = '\x19%s}%s' % (get_theme().COLOR_INFORMATION_TEXT[0], log_line)
self._text_buffer.add_message(
txt=log_line.strip(),
time='',
nickname='',
user='',
str_time=''
)
def last_words_completion(self):
"""
Complete the input with words recently said
@ -617,7 +636,7 @@ class MucTab(ChatTab):
plugin_keys = {}
def __init__(self, jid, nick):
self.joined = False
ChatTab.__init__(self)
ChatTab.__init__(self, jid)
self.own_nick = nick
self.name = jid
self.users = []
@ -1611,7 +1630,7 @@ class PrivateTab(ChatTab):
plugin_commands = {}
plugin_keys = {}
def __init__(self, name, nick):
ChatTab.__init__(self)
ChatTab.__init__(self, name)
self.own_nick = nick
self.name = name
self.text_win = windows.TextWin()
@ -2669,7 +2688,7 @@ class ConversationTab(ChatTab):
additional_informations = {}
message_type = 'chat'
def __init__(self, jid):
ChatTab.__init__(self)
ChatTab.__init__(self, jid)
self.state = 'normal'
self.name = jid # a conversation tab is linked to one specific full jid OR bare jid
self.text_win = windows.TextWin()

View file

@ -35,7 +35,7 @@ class TextBuffer(object):
def add_window(self, win):
self.windows.append(win)
def make_message(self, txt, time, nickname, nick_color, history, user, identifier):
def make_message(self, txt, time, nickname, nick_color, history, user, identifier, str_time=None):
time = time or datetime.now()
if txt.startswith('/me '):
if nick_color:
@ -47,15 +47,17 @@ class TextBuffer(object):
# TODO: display the bg color too.
txt = '\x19%(info_col)s}* \x19%(col)s}%(nick)s \x19%(info_col)s}%(msg)s' % {'info_col':get_theme().COLOR_ME_MESSAGE[0], 'col': color or 5, 'nick': nickname, 'msg': txt[4:]}
nickname = None
msg = Message(txt='%s\x19o'%(txt.replace('\t', ' '),), nick_color=nick_color,
time=time, str_time=time.strftime("%Y-%m-%d %H:%M:%S")\
if history else time.strftime("%H:%M:%S"),\
msg = Message(
txt='%s\x19o'%(txt.replace('\t', ' '),),
nick_color=nick_color,
time=time,
str_time=(time.strftime("%Y-%m-%d %H:%M:%S") if history else time.strftime("%H:%M:%S")) if str_time is None else '',
nickname=nickname, user=user, identifier=identifier)
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):
msg = self.make_message(txt, time, nickname, nick_color, history, user, identifier)
def add_message(self, txt, time=None, nickname=None, nick_color=None, history=None, user=None, highlight=False, identifier=None, str_time=None):
msg = self.make_message(txt, time, nickname, nick_color, history, user, identifier, str_time)
self.messages.append(msg)
while len(self.messages) > self.messages_nb_limit:
self.messages.pop(0)

View file

@ -776,12 +776,14 @@ class TextWin(Win):
if not txt:
return 0
nick = truncate_nick(message.nickname)
offset = 1 + len(message.str_time)
offset = 0
if message.str_time:
offset += 1 + len(message.str_time)
if nick:
offset += wcwidth.wcswidth(nick) + 2 # + nick + spaces length
if get_theme().CHAR_TIME_LEFT:
if get_theme().CHAR_TIME_LEFT and message.str_time:
offset += 1
if get_theme().CHAR_TIME_RIGHT:
if get_theme().CHAR_TIME_RIGHT and message.str_time:
offset += 1
lines = cut_text(txt, self.width-offset)
if self.lock:
@ -832,7 +834,9 @@ class TextWin(Win):
if not line:
self.write_line_separator(y)
else:
self.write_text(y, (3 if line.msg.nickname else 1) + len(line.msg.str_time)+len(truncate_nick(line.msg.nickname) or ''), line.msg.txt[line.start_pos:line.end_pos])
self.write_text(y,
(3 if line.msg.nickname else (1 if line.msg.str_time else 0)) + len(line.msg.str_time)+len(truncate_nick(line.msg.nickname) or ''),
line.msg.txt[line.start_pos:line.end_pos])
if y != self.height-1:
self.addstr('\n')
self._win.attrset(0)