aboutsummaryrefslogtreecommitdiffstats
path: root/slack
diff options
context:
space:
mode:
authorTrygve Aaberge <trygveaa@gmail.com>2024-01-09 20:04:21 +0100
committerTrygve Aaberge <trygveaa@gmail.com>2024-02-18 11:32:55 +0100
commit9e79cdf74f2d04a35332859940e4446e6c979b50 (patch)
treed4b651b60deb65eeb127dd732ba08f3d05264a19 /slack
parent616bb0537859b3d95a29205fdd167ebadac2b9bd (diff)
downloadwee-slack-9e79cdf74f2d04a35332859940e4446e6c979b50.tar.gz
Handle messages without a user field
This can happen in channels shared between workspaces if one of the workspaces are removed. Then messages from users in that workspace will not have a user field anymore, but instead a user_profile field.
Diffstat (limited to 'slack')
-rw-r--r--slack/commands.py4
-rw-r--r--slack/slack_conversation.py9
-rw-r--r--slack/slack_message.py25
-rw-r--r--slack/slack_user.py71
4 files changed, 69 insertions, 40 deletions
diff --git a/slack/commands.py b/slack/commands.py
index 7638b0d..52a1f51 100644
--- a/slack/commands.py
+++ b/slack/commands.py
@@ -17,7 +17,7 @@ from slack.shared import MESSAGE_ID_REGEX_STRING, REACTION_CHANGE_REGEX_STRING,
from slack.slack_buffer import SlackBuffer
from slack.slack_conversation import SlackConversation
from slack.slack_thread import SlackThread
-from slack.slack_user import name_from_user_info_without_spaces
+from slack.slack_user import format_user_nick, name_from_user_info
from slack.slack_workspace import SlackWorkspace
from slack.task import run_async, sleep
from slack.util import get_callback_name, with_color
@@ -608,7 +608,7 @@ async def complete_user_next(
slack_buffer.completion_context = "ACTIVE_COMPLETION"
suffix = nick_suffix() if is_first_word else " "
slack_buffer.completion_values = [
- name_from_user_info_without_spaces(slack_buffer.workspace, user) + suffix
+ format_user_nick(name_from_user_info(slack_buffer.workspace, user)) + suffix
for user in search["results"]
]
slack_buffer.completion_index = 0
diff --git a/slack/slack_conversation.py b/slack/slack_conversation.py
index ee23303..65357a3 100644
--- a/slack/slack_conversation.py
+++ b/slack/slack_conversation.py
@@ -735,10 +735,11 @@ class SlackConversation(SlackBuffer):
nick = await message.nick(colorize=False, only_nick=True)
try:
sender = await message.sender
- if message.subtype in ["channel_leave", "group_leave"]:
- self.nicklist_remove_user(sender)
- else:
- self.nicklist_add_user(sender, nick)
+ if sender is not None:
+ if message.subtype in ["channel_leave", "group_leave"]:
+ self.nicklist_remove_user(sender)
+ else:
+ self.nicklist_add_user(sender, nick)
except Exception as e:
self.nicklist_add_user(None, nick)
if isinstance(e, SlackApiError) and e.response["error"] != "bots_not_found":
diff --git a/slack/slack_message.py b/slack/slack_message.py
index 50eca1c..5d7bb95 100644
--- a/slack/slack_message.py
+++ b/slack/slack_message.py
@@ -19,7 +19,14 @@ from slack.log import print_error
from slack.python_compatibility import removeprefix, removesuffix
from slack.shared import shared
from slack.slack_emoji import get_emoji
-from slack.slack_user import SlackBot, SlackUser, format_bot_nick, nick_color
+from slack.slack_user import (
+ SlackBot,
+ SlackUser,
+ format_bot_nick,
+ format_user_nick,
+ name_from_user_profile,
+ nick_color,
+)
from slack.task import gather
from slack.util import htmlescape, intersperse, unhtmlescape, with_color
@@ -389,10 +396,10 @@ class SlackMessage:
return self._message_json.get("bot_id")
@property
- async def sender(self) -> Union[SlackUser, SlackBot]:
+ async def sender(self) -> Union[SlackUser, SlackBot, None]:
if "user" in self._message_json:
return await self.workspace.users[self._message_json["user"]]
- else:
+ elif "bot_id" in self._message_json:
return await self.workspace.bots[self._message_json["bot_id"]]
@property
@@ -586,13 +593,23 @@ class SlackMessage:
if "user" in self._message_json:
user = await self.workspace.users[self._message_json["user"]]
return user.nick(colorize=colorize, only_nick=only_nick)
+ elif "user_profile" in self._message_json:
+ # TODO: is_external
+ nick = name_from_user_profile(
+ self.workspace,
+ self._message_json["user_profile"],
+ fallback_name=self._message_json["user_profile"]["name"],
+ )
+ return format_user_nick(nick, colorize=colorize, only_nick=only_nick)
else:
username = self._message_json.get("username")
if username:
return format_bot_nick(username, colorize=colorize, only_nick=only_nick)
- else:
+ elif "bot_id" in self._message_json:
bot = await self.workspace.bots[self._message_json["bot_id"]]
return bot.nick(colorize=colorize, only_nick=only_nick)
+ else:
+ return "Unknown"
async def _render_prefix(
self, colorize: bool = True, only_nick: bool = False
diff --git a/slack/slack_user.py b/slack/slack_user.py
index 7e9ddb4..9627af0 100644
--- a/slack/slack_user.py
+++ b/slack/slack_user.py
@@ -1,6 +1,6 @@
from __future__ import annotations
-from typing import TYPE_CHECKING
+from typing import TYPE_CHECKING, Union
import weechat
@@ -11,33 +11,57 @@ from slack.util import with_color
if TYPE_CHECKING:
from slack_api.slack_bots_info import SlackBotInfo
+ from slack_api.slack_conversations_history import SlackMessageUserProfile
from slack_api.slack_usergroups_info import SlackUsergroupInfo
- from slack_api.slack_users_info import SlackUserInfo
+ from slack_api.slack_users_info import SlackProfile, SlackUserInfo
from slack.slack_workspace import SlackWorkspace
-def nick_color(nick: str) -> str:
+def nick_color(nick: str, is_self: bool = False) -> str:
+ if is_self:
+ return weechat.config_string(weechat.config_get("weechat.color.chat_nick_self"))
+
return weechat.info_get("nick_color_name", nick)
# TODO: Probably need to do some mapping here based on the existing users, in case some has been changed to avoid duplicate names
-def _name_from_user_info(workspace: SlackWorkspace, info: SlackUserInfo) -> str:
- display_name = info["profile"].get("display_name")
+def name_from_user_profile(
+ workspace: SlackWorkspace,
+ profile: Union[SlackProfile, SlackMessageUserProfile],
+ fallback_name: str,
+) -> str:
+ display_name = profile.get("display_name")
if display_name and not workspace.config.use_real_names:
return display_name
- return info["profile"].get("display_name") or info.get("real_name") or info["name"]
+ return profile.get("display_name") or profile.get("real_name") or fallback_name
-def name_from_user_info_without_spaces(
- workspace: SlackWorkspace, info: SlackUserInfo
-) -> str:
- return _name_from_user_info(workspace, info).replace(
- " ", shared.config.look.replace_space_in_nicks_with.value
+def name_from_user_info(workspace: SlackWorkspace, info: SlackUserInfo) -> str:
+ return name_from_user_profile(
+ workspace, info["profile"], info.get("real_name") or info["name"]
)
+def format_user_nick(
+ nick: str,
+ colorize: bool = False,
+ only_nick: bool = False,
+ is_external: bool = False,
+ is_self: bool = False,
+) -> str:
+ nick = nick.replace(" ", shared.config.look.replace_space_in_nicks_with.value)
+
+ if colorize:
+ nick = with_color(nick_color(nick, is_self), nick)
+
+ if not only_nick and is_external:
+ nick += shared.config.look.external_user_suffix.value
+
+ return nick
+
+
def format_bot_nick(nick: str, colorize: bool = False, only_nick: bool = False) -> str:
nick = nick.replace(" ", shared.config.look.replace_space_in_nicks_with.value)
@@ -45,7 +69,7 @@ def format_bot_nick(nick: str, colorize: bool = False, only_nick: bool = False)
nick = with_color(nick_color(nick), nick)
if not only_nick:
- nick = nick + shared.config.look.bot_user_suffix.value
+ nick += shared.config.look.bot_user_suffix.value
return nick
@@ -88,26 +112,13 @@ class SlackUser:
return get_emoji(status_emoji.strip(":"))
def nick(self, colorize: bool = False, only_nick: bool = False) -> str:
- nick = self._name_without_spaces()
-
- if colorize:
- nick = with_color(self.nick_color(), nick)
-
- if not only_nick and self.is_external:
- nick += shared.config.look.external_user_suffix.value
-
- return nick
-
- def _name_without_spaces(self) -> str:
- return name_from_user_info_without_spaces(self.workspace, self._info)
+ nick = name_from_user_info(self.workspace, self._info)
+ return format_user_nick(
+ nick, colorize, only_nick, self.is_external, self.is_self
+ )
def nick_color(self) -> str:
- if self.is_self:
- return weechat.config_string(
- weechat.config_get("weechat.color.chat_nick_self")
- )
-
- return nick_color(self._name_without_spaces())
+ return nick_color(self.nick(colorize=False, only_nick=True), self.is_self)
def update_info_json(self, info_json: SlackUserInfo):
self._info.update(info_json) # pyright: ignore [reportGeneralTypeIssues]