Commit 7e29abf2 authored by mathieui's avatar mathieui

Add a concept of "history gap"

parent ea438438
...@@ -19,9 +19,15 @@ from typing import ( ...@@ -19,9 +19,15 @@ from typing import (
Tuple, Tuple,
Union, Union,
) )
from dataclasses import dataclass
from datetime import datetime from datetime import datetime
from poezio.config import config from poezio.config import config
from poezio.ui.types import Message, BaseMessage from poezio.ui.types import (
from import TextWin from import TextWin
...@@ -35,6 +41,15 @@ class AckError(Exception): ...@@ -35,6 +41,15 @@ class AckError(Exception):
pass pass
class HistoryGap:
"""Class representing a period of non-presence inside a MUC"""
leave_message: Optional[MucOwnLeaveMessage]
join_message: Optional[MucOwnJoinMessage]
last_timestamp_before_leave: Optional[datetime]
first_timestamp_after_join: Optional[datetime]
class TextBuffer: class TextBuffer:
""" """
This class just keep trace of messages, in a list with various This class just keep trace of messages, in a list with various
...@@ -58,6 +73,72 @@ class TextBuffer: ...@@ -58,6 +73,72 @@ class TextBuffer:
def add_window(self, win) -> None: def add_window(self, win) -> None:
self._windows.append(win) self._windows.append(win)
def find_last_gap_muc(self) -> Optional[HistoryGap]:
"""Find the last known history gap contained in buffer"""
leave, join = None, None
for i, item in enumerate(reversed(self.messages)):
if isinstance(item, MucOwnLeaveMessage):
leave = (i, item)
if isinstance(item, MucOwnJoinMessage):
join = (i, item)
if join and leave: # Skip if we find a message in the interval
real_leave = len(self.messages) - leave[0] - 1
real_join = len(self.messages) - join[0] - 1
for i in range(real_leave, real_join, 1):
if isinstance(self.messages[i], Message):
return None
elif not (join or leave):
return None
if leave is None:
last_timestamp, leave_msg = None, None
last_timestamp = None
leave_msg = leave[1]
for i in range(len(self.messages) - leave[0] - 1, 0, -1):
if isinstance(self.messages[i], Message):
last_timestamp = self.messages[i].time
first_timestamp =
if join is None:
join_msg = None
join_msg = join[1]
for i in range(len(self.messages) - join[0], len(self.messages)):
msg = self.messages[i]
if isinstance(msg, Message) and msg.time < first_timestamp:
first_timestamp = msg.time
return HistoryGap(
def get_gap_index(self, gap: HistoryGap) -> Optional[int]:
"""Find the first index to insert into inside a gap"""
if gap.leave_message is None:
return 0
for i, msg in enumerate(self.messages):
if msg is gap.leave_message:
return i + 1
return None
def add_history_messages(self, messages: List[Message], gap: Optional[HistoryGap] = None) -> None:
"""Insert history messages at their correct place """
index = 0
if gap is not None:
index = self.get_gap_index(gap)
if index is None: # Not sure what happened, abort
for message in messages:
self.messages.insert(index, message)
index += 1
log.debug('inserted message: %s', message)
for window in self._windows: # make the associated windows
@property @property
def last_message(self) -> Optional[BaseMessage]: def last_message(self) -> Optional[BaseMessage]:
return self.messages[-1] if self.messages else None return self.messages[-1] if self.messages else None
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