diff options
-rw-r--r-- | slack/config.py | 16 | ||||
-rw-r--r-- | slack/slack_conversation.py | 13 | ||||
-rw-r--r-- | slack/slack_message.py | 83 | ||||
-rw-r--r-- | typings/slack_api/slack_conversations_history.pyi | 19 | ||||
-rw-r--r-- | typings/slack_rtm/slack_rtm_message.pyi | 12 |
5 files changed, 125 insertions, 18 deletions
diff --git a/slack/config.py b/slack/config.py index 723d4d3..7527190 100644 --- a/slack/config.py +++ b/slack/config.py @@ -43,6 +43,22 @@ class SlackConfigSectionColor: WeeChatColor("yellow"), ) + self.message_join = WeeChatOption( + self._section, + "message_join", + "color for text in join messages", + WeeChatColor("green"), + parent_option="irc.color.message_join", + ) + + self.message_quit = WeeChatOption( + self._section, + "message_quit", + "color for text in part messages", + WeeChatColor("red"), + parent_option="irc.color.message_quit", + ) + self.reaction_suffix = WeeChatOption( self._section, "reaction_suffix", diff --git a/slack/slack_conversation.py b/slack/slack_conversation.py index 8de3a26..3b06a4d 100644 --- a/slack/slack_conversation.py +++ b/slack/slack_conversation.py @@ -100,20 +100,29 @@ class SlackConversation: else: return self._info["name"] - def name_prefix(self, name_type: Literal["full_name", "short_name"]) -> str: + def name_prefix( + self, + name_type: Literal["full_name", "short_name", "short_name_without_padding"], + ) -> str: if self._info["is_im"] is True: if name_type == "short_name": return " " else: return "" elif self._info["is_mpim"]: - if name_type == "short_name": + if name_type == "short_name" or name_type == "short_name_without_padding": return "@" else: return "" else: return "#" + async def name_with_prefix( + self, + name_type: Literal["full_name", "short_name", "short_name_without_padding"], + ) -> str: + return f"{self.name_prefix(name_type)}{await self.name()}" + @contextmanager def loading(self): self.is_loading = True diff --git a/slack/slack_message.py b/slack/slack_message.py index 376695c..a2220f3 100644 --- a/slack/slack_message.py +++ b/slack/slack_message.py @@ -4,8 +4,10 @@ import re from enum import Enum from typing import TYPE_CHECKING, List, Match, Optional +import weechat + from slack.log import print_exception_once -from slack.python_compatibility import removeprefix +from slack.python_compatibility import removeprefix, removesuffix from slack.shared import shared from slack.slack_user import format_bot_nick from slack.task import gather @@ -74,8 +76,13 @@ class SlackMessage: return MessagePriority.MESSAGE async def tags(self, backlog: bool = False) -> str: - nick = await self._prefix(colorize=False, only_nick=True) - tags = ["slack_privmsg", f"slack_ts_{self.ts}", f"nick_{nick}"] + nick = await self._nick(colorize=False, only_nick=True) + tags = [f"slack_ts_{self.ts}", f"nick_{nick}"] + + if self.sender_user_id: + tags.append(f"slack_user_id_{self.sender_user_id}") + if self.sender_bot_id: + tags.append(f"slack_bot_id_{self.sender_bot_id}") if self.sender_user_id: user_or_bot = await self.workspace.users[self.sender_user_id] @@ -84,20 +91,24 @@ class SlackMessage: else: user_or_bot = None - if user_or_bot and shared.weechat_version >= 0x04000000: - tags.append(f"prefix_nick_{user_or_bot.nick_color()}") - - if self.is_bot_message: - tags.append("bot_message") - if self.sender_user_id: - tags.append(f"slack_user_id_{self.sender_user_id}") - if self.sender_bot_id: - tags.append(f"slack_bot_id_{self.sender_bot_id}") + if self._message_json.get("subtype") in ["channel_join", "group_join"]: + tags.append("slack_join") + log_tags = ["log4"] + elif self._message_json.get("subtype") in ["channel_leave", "group_leave"]: + tags.append("slack_part") + log_tags = ["log4"] + else: + tags.append("slack_privmsg") + if self.is_bot_message: + tags.append("bot_message") + if user_or_bot and shared.weechat_version >= 0x04000000: + tags.append(f"prefix_nick_{user_or_bot.nick_color()}") + log_tags = ["notify_message", "log1"] if backlog: tags += ["no_highlight", "notify_none", "logger_backlog", "no_log"] else: - tags += ["notify_message", "log1"] + tags += log_tags return ",".join(tags) @@ -106,12 +117,12 @@ class SlackMessage: return self._rendered prefix_coro = self._prefix() - message_coro = self._unfurl_refs(self._message_json["text"]) + message_coro = self._render_message() prefix, message = await gather(prefix_coro, message_coro) self._rendered = f"{prefix}\t{message}" return self._rendered - async def _prefix(self, colorize: bool = True, only_nick: bool = False) -> str: + async def _nick(self, colorize: bool = True, only_nick: bool = False) -> str: if ( "subtype" in self._message_json and self._message_json["subtype"] == "bot_message" @@ -126,6 +137,46 @@ class SlackMessage: user = await self.workspace.users[self._message_json["user"]] return user.nick(colorize=colorize, only_nick=only_nick) + async def _prefix(self, colorize: bool = True, only_nick: bool = False) -> str: + if self._message_json.get("subtype") in ["channel_join", "group_join"]: + return removesuffix(weechat.prefix("join"), "\t") + elif self._message_json.get("subtype") in ["channel_leave", "group_leave"]: + return removesuffix(weechat.prefix("quit"), "\t") + else: + return await self._nick(colorize=colorize, only_nick=only_nick) + + async def _render_message(self) -> str: + if self._message_json.get("subtype") in [ + "channel_join", + "group_join", + "channel_leave", + "group_leave", + ]: + is_join = self._message_json.get("subtype") in [ + "channel_join", + "group_join", + ] + text_action = ( + f"{with_color(shared.config.color.message_join.value, 'has joined')}" + if is_join + else f"{with_color(shared.config.color.message_quit.value, 'has left')}" + ) + conversation_name = await self.conversation.name_with_prefix( + "short_name_without_padding" + ) + text_conversation_name = f"{with_color('chat_channel', conversation_name)}" + + inviter_id = self._message_json.get("inviter") + if is_join and inviter_id: + inviter_user = await self.workspace.users[inviter_id] + inviter_text = f" by invitation from {inviter_user.nick(colorize=True)}" + else: + inviter_text = "" + + return f"{await self._nick()} {text_action} {text_conversation_name}{inviter_text}" + else: + return await self._unfurl_refs(self._message_json["text"]) + def _item_prefix(self, item_id: str): if item_id.startswith("#") or item_id.startswith("@"): return item_id[0] @@ -144,7 +195,7 @@ class SlackMessage: removeprefix(item_id, "#") ] color = shared.config.color.channel_mention_color.value - name = conversation.name_prefix("short_name") + await conversation.name() + name = await conversation.name_with_prefix("short_name_without_padding") return (color, name) elif item_id.startswith("@"): user = await self.workspace.users[removeprefix(item_id, "@")] diff --git a/typings/slack_api/slack_conversations_history.pyi b/typings/slack_api/slack_conversations_history.pyi index 04a48e1..809e7c6 100644 --- a/typings/slack_api/slack_conversations_history.pyi +++ b/typings/slack_api/slack_conversations_history.pyi @@ -161,6 +161,23 @@ class SlackMessageSubtypeBotAdd(SlackMessageCommon): class SlackMessageSubtypeBotAddFinal(SlackMessageSubtypeBotAdd): pass +class SlackMessageSubtypeChannelJoin(SlackMessageCommon): + subtype: Literal["channel_join", "group_join"] + user: str + inviter: NotRequired[str] + +@final +class SlackMessageSubtypeChannelJoinFinal(SlackMessageSubtypeChannelJoin): + pass + +class SlackMessageSubtypeChannelLeave(SlackMessageCommon): + subtype: Literal["channel_leave", "group_leave"] + user: str + +@final +class SlackMessageSubtypeChannelLeaveFinal(SlackMessageSubtypeChannelLeave): + pass + SlackMessage = ( SlackMessageStandardFinal | SlackMessageThreadParentNotSubscribedFinal @@ -169,6 +186,8 @@ SlackMessage = ( | SlackMessageSubtypeBotMessageFinal | SlackMessageSubtypeBotRemoveFinal | SlackMessageSubtypeBotAddFinal + | SlackMessageSubtypeChannelJoinFinal + | SlackMessageSubtypeChannelLeaveFinal | SlackMessageRtm ) diff --git a/typings/slack_rtm/slack_rtm_message.pyi b/typings/slack_rtm/slack_rtm_message.pyi index 7eb50f1..1e0c105 100644 --- a/typings/slack_rtm/slack_rtm_message.pyi +++ b/typings/slack_rtm/slack_rtm_message.pyi @@ -4,6 +4,8 @@ from slack_api.slack_conversations_history import ( SlackMessageSubtypeBotAdd, SlackMessageSubtypeBotMessage, SlackMessageSubtypeBotRemove, + SlackMessageSubtypeChannelJoin, + SlackMessageSubtypeChannelLeave, SlackMessageThreadParentNotSubscribed, SlackMessageThreadParentSubscribed, SlackMessageWithFiles, @@ -46,6 +48,14 @@ class SlackMessageSubtypeBotAddRtm(SlackMessageSubtypeBotAdd): channel: str @final +class SlackMessageSubtypeChannelJoinRtm(SlackMessageSubtypeChannelJoin): + channel: str + +@final +class SlackMessageSubtypeChannelLeaveRtm(SlackMessageSubtypeChannelLeave): + channel: str + +@final class SlackMessageChanged(TypedDict): type: Literal["message"] subtype: Literal["message_changed"] @@ -93,6 +103,8 @@ SlackMessageRtm = ( | SlackMessageSubtypeBotMessageRtm | SlackMessageSubtypeBotRemoveRtm | SlackMessageSubtypeBotAddRtm + | SlackMessageSubtypeChannelJoinRtm + | SlackMessageSubtypeChannelLeaveRtm ) SlackRtmMessage = ( |