summaryrefslogtreecommitdiff
path: root/poezio/tabs/muctab.py
diff options
context:
space:
mode:
Diffstat (limited to 'poezio/tabs/muctab.py')
-rw-r--r--poezio/tabs/muctab.py213
1 files changed, 108 insertions, 105 deletions
diff --git a/poezio/tabs/muctab.py b/poezio/tabs/muctab.py
index 73359610..f0c055b1 100644
--- a/poezio/tabs/muctab.py
+++ b/poezio/tabs/muctab.py
@@ -40,6 +40,7 @@ from poezio.roster import roster
from poezio.theming import get_theme, dump_tuple
from poezio.user import User
from poezio.core.structs import Completion, Status
+from poezio.ui.types import BaseMessage, Message, InfoMessage, StatusMessage
log = logging.getLogger(__name__)
@@ -75,6 +76,8 @@ class MucTab(ChatTab):
self.users = [] # type: List[User]
# private conversations
self.privates = [] # type: List[Tab]
+ # Used to check if we are still receiving muc history
+ self.last_message_was_history = None # type: Optional[bool]
self.topic = ''
self.topic_from = ''
# Self ping event, so we can cancel it when we leave the room
@@ -197,8 +200,7 @@ class MucTab(ChatTab):
'color_spec': spec_col,
'nick': self.own_nick,
}
-
- self.add_message(msg, typ=2)
+ self.add_message(InfoMessage(msg), typ=2)
self.disconnect()
muc.leave_groupchat(self.core.xmpp, self.jid.bare, self.own_nick,
message)
@@ -301,7 +303,7 @@ class MucTab(ChatTab):
'role': user.role or 'None',
'status': '\n%s' % user.status if user.status else ''
}
- self.add_message(info, typ=0)
+ self.add_message(InfoMessage(info), typ=0)
return True
def change_topic(self, topic: str):
@@ -327,9 +329,13 @@ class MucTab(ChatTab):
else:
user_string = ''
- self._text_buffer.add_message(
- "\x19%s}The subject of the room is: \x19%s}%s %s" %
- (info_text, norm_text, self.topic, user_string))
+ self.add_message(
+ InfoMessage(
+ "The subject of the room is: \x19%s}%s %s" %
+ (norm_text, self.topic, user_string),
+ ),
+ typ=0,
+ )
@refresh_wrapper.always
def recolor(self, random_colors=False):
@@ -558,28 +564,32 @@ class MucTab(ChatTab):
'nick_col': color,
'info_col': info_col,
}
- self.add_message(enable_message, typ=2)
+ self.add_message(InfoMessage(enable_message), typ=2)
self.core.enable_private_tabs(self.jid.bare, enable_message)
if '201' in status_codes:
self.add_message(
- '\x19%(info_col)s}Info: The room '
- 'has been created' % {'info_col': info_col},
- typ=0)
+ InfoMessage('Info: The room has been created'),
+ typ=0
+ )
if '170' in status_codes:
self.add_message(
- '\x19%(warn_col)s}Warning:\x19%(info_col)s}'
- ' This room is publicly logged' % {
- 'info_col': info_col,
- 'warn_col': warn_col
- },
+ InfoMessage(
+ '\x19%(warn_col)s}Warning:\x19%(info_col)s}'
+ ' This room is publicly logged' % {
+ 'info_col': info_col,
+ 'warn_col': warn_col
+ },
+ ),
typ=0)
if '100' in status_codes:
self.add_message(
- '\x19%(warn_col)s}Warning:\x19%(info_col)s}'
- ' This room is not anonymous.' % {
- 'info_col': info_col,
- 'warn_col': warn_col
- },
+ InfoMessage(
+ '\x19%(warn_col)s}Warning:\x19%(info_col)s}'
+ ' This room is not anonymous.' % {
+ 'info_col': info_col,
+ 'warn_col': warn_col
+ },
+ ),
typ=0)
def handle_presence_joined(self, presence, status_codes):
@@ -635,18 +645,20 @@ class MucTab(ChatTab):
def on_non_member_kicked(self):
"""We have been kicked because the MUC is members-only"""
self.add_message(
- '\x19%(info_col)s}You have been kicked because you '
- 'are not a member and the room is now members-only.' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
+ InfoMessage(
+ 'You have been kicked because you '
+ 'are not a member and the room is now members-only.'
+ ),
typ=2)
self.disconnect()
def on_muc_shutdown(self):
"""We have been kicked because the MUC service is shutting down"""
self.add_message(
- '\x19%(info_col)s}You have been kicked because the'
- ' MUC service is shutting down.' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
+ InfoMessage(
+ 'You have been kicked because the'
+ ' MUC service is shutting down.'
+ ),
typ=2)
self.disconnect()
@@ -693,7 +705,7 @@ class MucTab(ChatTab):
'jid_color': dump_tuple(theme.COLOR_MUC_JID),
'color_spec': spec_col,
}
- self.add_message(msg, typ=2)
+ self.add_message(InfoMessage(msg), typ=2)
self.core.on_user_rejoined_private_conversation(self.jid.bare, from_nick)
def on_user_nick_change(self, presence, user, from_nick, from_room):
@@ -723,14 +735,16 @@ class MucTab(ChatTab):
old_color = color = 3
info_col = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
self.add_message(
- '\x19%(old_color)s}%(old)s\x19%(info_col)s} is'
- ' now known as \x19%(color)s}%(new)s' % {
- 'old': from_nick,
- 'new': new_nick,
- 'color': color,
- 'old_color': old_color,
- 'info_col': info_col
- },
+ InfoMessage(
+ '\x19%(old_color)s}%(old)s\x19%(info_col)s} is'
+ ' now known as \x19%(color)s}%(new)s' % {
+ 'old': from_nick,
+ 'new': new_nick,
+ 'color': color,
+ 'old_color': old_color,
+ 'info_col': info_col
+ },
+ ),
typ=2)
# rename the private tabs if needed
self.core.rename_private_tabs(self.jid.bare, from_nick, user)
@@ -814,7 +828,7 @@ class MucTab(ChatTab):
'reason': reason.text,
'info_col': info_col
}
- self.add_message(kick_msg, typ=2)
+ self.add_message(InfoMessage(kick_msg), typ=2)
def on_user_kicked(self, presence, user, from_nick):
"""
@@ -892,7 +906,7 @@ class MucTab(ChatTab):
'reason': reason.text,
'info_col': info_col
}
- self.add_message(kick_msg, typ=2)
+ self.add_message(InfoMessage(kick_msg), typ=2)
def on_user_leave_groupchat(self,
user: User,
@@ -957,7 +971,7 @@ class MucTab(ChatTab):
}
if status:
leave_msg += ' (\x19o%s\x19%s})' % (status, info_col)
- self.add_message(leave_msg, typ=2)
+ self.add_message(InfoMessage(leave_msg), typ=2)
self.core.on_user_left_private_conversation(from_room, user, status)
def on_user_change_status(self, user, from_nick, from_room, affiliation,
@@ -1016,7 +1030,7 @@ class MucTab(ChatTab):
or show != user.show or status != user.status)) or (
affiliation != user.affiliation or role != user.role):
# display the message in the room
- self._text_buffer.add_message(msg)
+ self.add_message(InfoMessage(msg))
self.core.on_user_changed_status_in_private(
'%s/%s' % (from_room, from_nick), Status(show, status))
self.users.remove(user)
@@ -1042,13 +1056,15 @@ class MucTab(ChatTab):
"""
return self.topic.replace('\n', '|')
- def log_message(self, txt, nickname, time=None, typ=1):
+ def log_message(self, msg: Message, typ=1):
"""
Log the messages in the archives, if it needs
to be
"""
- if time is None and self.joined: # don't log the history messages
- if not logger.log_message(self.jid.bare, nickname, txt, typ=typ):
+ if not isinstance(msg, Message):
+ return
+ if not msg.history and self.joined: # don't log the history messages
+ if not logger.log_message(self.jid.bare, msg.nickname, msg.txt, typ=typ):
self.core.information('Unable to write in the log file',
'Error')
@@ -1061,65 +1077,37 @@ class MucTab(ChatTab):
return user
return None
- def add_message(self, txt, time=None, nickname=None, **kwargs):
+ def add_message(self, msg: BaseMessage, typ=1):
"""
Note that user can be None even if nickname is not None. It happens
when we receive an history message said by someone who is not
in the room anymore
Return True if the message highlighted us. False otherwise.
"""
-
# reset self-ping interval
if self.self_ping_event:
self.enable_self_ping_event()
-
- self.log_message(txt, nickname, time=time, typ=kwargs.get('typ', 1))
- args = dict()
- for key, value in kwargs.items():
- if key not in ('typ', 'forced_user'):
- args[key] = value
- if nickname is not None:
- user = self.get_user_by_name(nickname)
- else:
- user = None
-
- if user:
- user.set_last_talked(datetime.now())
- args['user'] = user
- if not user and kwargs.get('forced_user'):
- args['user'] = kwargs['forced_user']
-
- if (not time and nickname and nickname != self.own_nick
- and self.state != 'current'):
- if (self.state != 'highlight'
- and config.get_by_tabname('notify_messages', self.jid.bare)):
+ super().add_message(msg, typ=typ)
+ if not isinstance(msg, Message):
+ return
+ if msg.user:
+ msg.user.set_last_talked(msg.time)
+ if config.get_by_tabname('notify_messages', self.jid.bare) and self.state != 'current':
+ if msg.nickname != self.own_nick and not msg.history:
self.state = 'message'
- if time and not txt.startswith('/me'):
- txt = '\x19%(info_col)s}%(txt)s' % {
- 'txt': txt,
- 'info_col': dump_tuple(get_theme().COLOR_LOG_MSG)
- }
- elif not nickname:
- txt = '\x19%(info_col)s}%(txt)s' % {
- 'txt': txt,
- 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
- }
- elif not kwargs.get('highlight'): # TODO
- args['highlight'] = self.do_highlight(txt, time, nickname)
- time = time or datetime.now()
- self._text_buffer.add_message(txt, time, nickname, **args)
- return args.get('highlight', False)
+ msg.highlight = self.do_highlight(msg.txt, msg.nickname, msg.delayed)
+ return msg.highlight
def modify_message(self,
txt,
old_id,
new_id,
time=None,
+ delayed: bool = False,
nickname=None,
user=None,
jid=None):
- self.log_message(txt, nickname, time=time, typ=1)
- highlight = self.do_highlight(txt, time, nickname, corrected=True)
+ highlight = self.do_highlight(txt, nickname, delayed, corrected=True)
message = self._text_buffer.modify_message(
txt,
old_id,
@@ -1129,6 +1117,7 @@ class MucTab(ChatTab):
user=user,
jid=jid)
if message:
+ self.log_message(message, typ=1)
self.text_win.modify_message(message.identifier, message)
return highlight
return False
@@ -1192,9 +1181,11 @@ class MucTab(ChatTab):
def on_self_ping_failed(self, iq):
if not self.lagged:
self.lagged = True
- info_text = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
self._text_buffer.add_message(
- "\x19%s}MUC service not responding." % info_text)
+ InfoMessage(
+ "MUC service not responding."
+ ),
+ )
self._state = 'disconnected'
self.core.refresh_window()
self.enable_self_ping_event()
@@ -1202,9 +1193,9 @@ class MucTab(ChatTab):
def reset_lag(self):
if self.lagged:
self.lagged = False
- info_text = dump_tuple(get_theme().COLOR_INFORMATION_TEXT)
- self._text_buffer.add_message(
- "\x19%s}MUC service is responding again." % info_text)
+ self.add_message(
+ InfoMessage("MUC service is responding again.")
+ )
if self != self.core.tabs.current_tab:
self._state = 'joined'
else:
@@ -1323,28 +1314,38 @@ class MucTab(ChatTab):
def build_highlight_regex(self, nickname):
return re.compile(r"(^|\W)" + re.escape(nickname) + r"(\W|$)", re.I)
- def is_highlight(self, txt, time, nickname, own_nick, highlight_on,
- corrected=False):
+ def is_highlight(self, txt: str, nick: str, highlight_on: List[str],
+ delayed, corrected: bool = False):
+ """
+ Highlight algorithm for MUC tabs
+ """
+
highlighted = False
- if (not time or corrected) and nickname and nickname != own_nick:
- if self.build_highlight_regex(own_nick).search(txt):
+ if not delayed and not corrected:
+ if self.build_highlight_regex(nick).search(txt):
highlighted = True
else:
- highlight_words = highlight_on.split(':')
- for word in highlight_words:
+ for word in highlight_on:
if word and word.lower() in txt.lower():
highlighted = True
break
return highlighted
- def do_highlight(self, txt, time, nickname, corrected=False):
+ def do_highlight(self, txt, nickname, delayed, corrected=False):
"""
Set the tab color and returns the nick color
"""
own_nick = self.own_nick
- highlight_on = config.get_by_tabname('highlight_on', self.general_jid)
- highlighted = self.is_highlight(txt, time, nickname, own_nick,
- highlight_on, corrected)
+ highlight_on = config.get_by_tabname(
+ 'highlight_on',
+ self.general_jid,
+ ).split(':')
+
+ # Don't highlight on info message or our own messages
+ if not nickname or nickname == own_nick:
+ return False
+
+ highlighted = self.is_highlight(txt, own_nick, highlight_on, delayed, corrected)
if highlighted and self.joined:
if self.state != 'current':
self.state = 'highlight'
@@ -1551,7 +1552,7 @@ class MucTab(ChatTab):
buff.append('\n')
message = ' '.join(buff)
- self._text_buffer.add_message(message)
+ self.add_message(InfoMessage(message), typ=0)
self.text_win.refresh()
self.input.refresh()
@@ -1650,16 +1651,18 @@ class MucTab(ChatTab):
if all_errors:
self.add_message(
- 'Can\'t access affiliations',
- highlight=True,
- nickname='Error',
- nick_color=theme.COLOR_ERROR_MSG,
+ Message(
+ 'Can\'t access affiliations',
+ highlight=True,
+ nickname='Error',
+ nick_color=theme.COLOR_ERROR_MSG,
+ ),
typ=2,
)
self.core.refresh_window()
return None
- self._text_buffer.add_message('Affiliations')
+ self._text_buffer.add_message(InfoMessage('Affiliations'))
for iq in iqs:
if isinstance(iq, (IqError, IqTimeout)):
continue
@@ -1672,12 +1675,12 @@ class MucTab(ChatTab):
affiliation = items[0].get('affiliation')
aff_char = aff_colors[affiliation]
self._text_buffer.add_message(
- ' %s%s' % (aff_char, affiliation.capitalize()),
+ InfoMessage(' %s%s' % (aff_char, affiliation.capitalize())),
)
items = map(lambda i: i.get('jid'), items)
for ajid in sorted(items):
- self._text_buffer.add_message(' %s' % ajid)
+ self._text_buffer.add_message(InfoMessage(' %s' % ajid))
self.core.refresh_window()
return None