Add a concept of "history gap"
This commit is contained in:
parent
ea438438f2
commit
7e29abf2e6
1 changed files with 82 additions and 1 deletions
|
@ -19,9 +19,15 @@ from typing import (
|
|||
Tuple,
|
||||
Union,
|
||||
)
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from poezio.config import config
|
||||
from poezio.ui.types import Message, BaseMessage
|
||||
from poezio.ui.types import (
|
||||
BaseMessage,
|
||||
Message,
|
||||
MucOwnJoinMessage,
|
||||
MucOwnLeaveMessage,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from poezio.windows.text_win import TextWin
|
||||
|
@ -35,6 +41,15 @@ class AckError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
@dataclass
|
||||
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:
|
||||
"""
|
||||
This class just keep trace of messages, in a list with various
|
||||
|
@ -58,6 +73,72 @@ class TextBuffer:
|
|||
def add_window(self, win) -> None:
|
||||
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)
|
||||
break
|
||||
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
|
||||
else:
|
||||
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
|
||||
break
|
||||
first_timestamp = datetime.now()
|
||||
if join is None:
|
||||
join_msg = None
|
||||
else:
|
||||
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
|
||||
break
|
||||
return HistoryGap(
|
||||
leave_message=leave_msg,
|
||||
join_message=join_msg,
|
||||
last_timestamp_before_leave=last_timestamp,
|
||||
first_timestamp_after_join=first_timestamp,
|
||||
)
|
||||
|
||||
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
|
||||
return
|
||||
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
|
||||
window.rebuild_everything(self)
|
||||
|
||||
@property
|
||||
def last_message(self) -> Optional[BaseMessage]:
|
||||
return self.messages[-1] if self.messages else None
|
||||
|
|
Loading…
Reference in a new issue