aboutsummaryrefslogtreecommitdiffstats
path: root/slack
diff options
context:
space:
mode:
authorTrygve Aaberge <trygveaa@gmail.com>2023-10-21 23:31:00 +0200
committerTrygve Aaberge <trygveaa@gmail.com>2024-02-18 11:32:54 +0100
commitcfbe97d9a476eb543498ad13547a023ace23dd17 (patch)
treee5ae9178adf185897fb82a78522182cecda32a05 /slack
parent9e99c1d54eec2ab49a1a6a749bec1def8d182927 (diff)
downloadwee-slack-cfbe97d9a476eb543498ad13547a023ace23dd17.tar.gz
Make conversations.name not async
This means a lot of methods don't have to be async. It's especially useful for the next commit adding conversations completions.
Diffstat (limited to 'slack')
-rw-r--r--slack/slack_buffer.py8
-rw-r--r--slack/slack_conversation.py85
-rw-r--r--slack/slack_message.py2
-rw-r--r--slack/slack_thread.py4
-rw-r--r--slack/slack_workspace.py25
5 files changed, 73 insertions, 51 deletions
diff --git a/slack/slack_buffer.py b/slack/slack_buffer.py
index addd2be..108221c 100644
--- a/slack/slack_buffer.py
+++ b/slack/slack_buffer.py
@@ -221,7 +221,7 @@ class SlackBuffer(ABC):
raise NotImplementedError()
@abstractmethod
- async def get_name_and_buffer_props(self) -> Tuple[str, Dict[str, str]]:
+ def get_name_and_buffer_props(self) -> Tuple[str, Dict[str, str]]:
raise NotImplementedError()
async def buffer_switched_to(self) -> None:
@@ -236,7 +236,7 @@ class SlackBuffer(ABC):
weechat.buffer_set(self.buffer_pointer, "display", "1")
return
- name, buffer_props = await self.get_name_and_buffer_props()
+ name, buffer_props = self.get_name_and_buffer_props()
full_name = self.get_full_name(name)
buffer_props["highlight_tags"] = (
@@ -272,8 +272,8 @@ class SlackBuffer(ABC):
if switch:
await self.buffer_switched_to()
- async def update_buffer_props(self) -> None:
- name, buffer_props = await self.get_name_and_buffer_props()
+ def update_buffer_props(self) -> None:
+ name, buffer_props = self.get_name_and_buffer_props()
buffer_props["name"] = self.get_full_name(name)
for key, value in buffer_props.items():
weechat.buffer_set(self.buffer_pointer, key, value)
diff --git a/slack/slack_conversation.py b/slack/slack_conversation.py
index a7a6928..22dd8f8 100644
--- a/slack/slack_conversation.py
+++ b/slack/slack_conversation.py
@@ -50,7 +50,7 @@ if TYPE_CHECKING:
def update_buffer_props():
for workspace in shared.workspaces.values():
for conversation in workspace.open_conversations.values():
- run_async(conversation.update_buffer_props())
+ conversation.update_buffer_props()
def invalidate_nicklists():
@@ -114,7 +114,7 @@ class SlackConversationMessageHashes(Dict[SlackTs, str]):
if other_message:
run_async(self._conversation.rerender_message(other_message))
if other_message.thread_buffer is not None:
- run_async(other_message.thread_buffer.update_buffer_props())
+ other_message.thread_buffer.update_buffer_props()
for reply in other_message.replies.values():
run_async(self._conversation.rerender_message(reply))
@@ -128,15 +128,25 @@ class SlackConversationMessageHashes(Dict[SlackTs, str]):
class SlackConversation(SlackBuffer):
+ __create_key = object()
+
def __init__(
self,
+ create_key: object,
workspace: SlackWorkspace,
info: SlackConversationsInfo,
):
+ if create_key is not self.__create_key:
+ raise SlackError(
+ workspace,
+ "SlackConversation must be created with SlackConversation.create or SlackConversation.create_from_info",
+ )
super().__init__()
self._workspace = workspace
self._info = info
self._members: Optional[List[str]] = None
+ self._im_user: Optional[SlackUser] = None
+ self._mpim_users: Optional[List[SlackUser]] = None
self._messages: OrderedDict[SlackTs, SlackMessage] = OrderedDict()
self._nicklist: Dict[Union[SlackUser, SlackBot], str] = {}
self.nicklist_needs_refresh = True
@@ -145,7 +155,27 @@ class SlackConversation(SlackBuffer):
@classmethod
async def create(cls, workspace: SlackWorkspace, conversation_id: str):
info_response = await workspace.api.fetch_conversations_info(conversation_id)
- return cls(workspace, info_response["channel"])
+ return await cls.create_from_info(workspace, info_response["channel"])
+
+ @classmethod
+ async def create_from_info(
+ cls, workspace: SlackWorkspace, info: SlackConversationsInfo
+ ):
+ conversation = cls(cls.__create_key, workspace, info)
+
+ if info["is_im"] is True:
+ conversation._im_user = await workspace.users[info["user"]]
+ elif conversation.type == "mpim":
+ members = await conversation.load_members(load_all=True)
+ conversation._mpim_users = await gather(
+ *(
+ workspace.users[user_id]
+ for user_id in members
+ if user_id != workspace.my_user.id
+ )
+ )
+
+ return conversation
def __repr__(self):
return f"{self.__class__.__name__}({self.workspace}, {self.id})"
@@ -209,30 +239,22 @@ class SlackConversation(SlackBuffer):
if self.type == "im":
return self._info.get("user")
- async def sort_key(self) -> str:
+ def sort_key(self) -> str:
type_sort_key = {
"channel": 0,
"private": 1,
"mpim": 2,
"im": 3,
}[self.type]
- name = await self.name()
- return f"{type_sort_key}{name}".lower()
-
- async def name(self) -> str:
- if self._info["is_im"] is True:
- im_user = await self.workspace.users[self._info["user"]]
- return im_user.nick()
- elif self._info["is_mpim"] is True:
- members = await self.load_members(load_all=True)
- member_users = await gather(
- *(
- self.workspace.users[user_id]
- for user_id in members
- if user_id != self.workspace.my_user.id
- )
- )
- return ",".join(sorted(user.nick() for user in member_users))
+ return f"{type_sort_key}{self.name()}".lower()
+
+ def name(self) -> str:
+ if self._im_user is not None:
+ return self._im_user.nick()
+ elif self._info["is_im"] is True:
+ raise SlackError(self.workspace, "IM conversation without _im_user set")
+ elif self._mpim_users is not None:
+ return ",".join(sorted(user.nick() for user in self._mpim_users))
else:
return self._info["name"]
@@ -255,11 +277,11 @@ class SlackConversation(SlackBuffer):
else:
return "#"
- async def name_with_prefix(
+ 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()}"
+ return f"{self.name_prefix(name_type)}{self.name()}"
def should_open(self):
if "is_open" in self._info:
@@ -269,23 +291,22 @@ class SlackConversation(SlackBuffer):
return True
return False
- async def buffer_title(self) -> str:
+ def buffer_title(self) -> str:
# TODO: unfurl and apply styles
topic = unhtmlescape(self._info.get("topic", {}).get("value", ""))
- if self.im_user_id:
- user = await self.workspace.users[self.im_user_id]
- status = f"{user.status_emoji} {user.status_text}".strip()
+ if self._im_user:
+ status = f"{self._im_user.status_emoji} {self._im_user.status_text}".strip()
return " | ".join(part for part in [status, topic] if part)
return topic
- async def set_topic(self, title: str):
+ def set_topic(self, title: str):
if "topic" not in self._info:
self._info["topic"] = {"value": "", "creator": "", "last_set": 0}
self._info["topic"]["value"] = title
- await self.update_buffer_props()
+ self.update_buffer_props()
- async def get_name_and_buffer_props(self) -> Tuple[str, Dict[str, str]]:
- name_without_prefix = await self.name()
+ def get_name_and_buffer_props(self) -> Tuple[str, Dict[str, str]]:
+ name_without_prefix = self.name()
name = f"{self.name_prefix('full_name')}{name_without_prefix}"
short_name = self.name_prefix("short_name") + name_without_prefix
if self.muted:
@@ -295,7 +316,7 @@ class SlackConversation(SlackBuffer):
return name, {
"short_name": short_name,
- "title": await self.buffer_title(),
+ "title": self.buffer_title(),
"input_multiline": "1",
"nicklist": "0" if self.type == "im" else "1",
"nicklist_display_groups": "0",
diff --git a/slack/slack_message.py b/slack/slack_message.py
index 6d5b39e..18d3d3a 100644
--- a/slack/slack_message.py
+++ b/slack/slack_message.py
@@ -187,7 +187,7 @@ class PendingMessageItem:
if self.item_type == "conversation":
try:
conversation = await self.message.workspace.conversations[self.item_id]
- name = await conversation.name_with_prefix("short_name_without_padding")
+ name = conversation.name_with_prefix("short_name_without_padding")
except (SlackApiError, SlackError) as e:
if (
isinstance(e, SlackApiError)
diff --git a/slack/slack_thread.py b/slack/slack_thread.py
index 3a96789..38f0ac2 100644
--- a/slack/slack_thread.py
+++ b/slack/slack_thread.py
@@ -47,8 +47,8 @@ class SlackThread(SlackBuffer):
def last_read(self) -> Optional[SlackTs]:
return self.parent.last_read
- async def get_name_and_buffer_props(self) -> Tuple[str, Dict[str, str]]:
- conversation_name = await self.parent.conversation.name_with_prefix("full_name")
+ def get_name_and_buffer_props(self) -> Tuple[str, Dict[str, str]]:
+ conversation_name = self.parent.conversation.name_with_prefix("full_name")
name = f"{conversation_name}.${self.parent.hash}"
short_name = f" ${self.parent.hash}"
diff --git a/slack/slack_workspace.py b/slack/slack_workspace.py
index fc3f65a..350a3ca 100644
--- a/slack/slack_workspace.py
+++ b/slack/slack_workspace.py
@@ -88,7 +88,7 @@ class SlackItem(
item = items_info.get(item_id)
if item is None:
raise SlackError(self.workspace, "item_not_found")
- return self._create_item_from_info(item)
+ return await self._create_item_from_info(item)
else:
return await self._item_class.create(self.workspace, item_id)
@@ -99,7 +99,7 @@ class SlackItem(
raise NotImplementedError()
@abstractmethod
- def _create_item_from_info(self, item_info: SlackItemInfo) -> SlackItemClass:
+ async def _create_item_from_info(self, item_info: SlackItemInfo) -> SlackItemClass:
raise NotImplementedError()
@@ -120,10 +120,10 @@ class SlackConversations(SlackItem[SlackConversation, SlackConversationsInfo]):
response["channel"]["id"]: response["channel"] for response in responses
}
- def _create_item_from_info(
+ async def _create_item_from_info(
self, item_info: SlackConversationsInfo
) -> SlackConversation:
- return self._item_class(self.workspace, item_info)
+ return await self._item_class.create_from_info(self.workspace, item_info)
class SlackUsers(SlackItem[SlackUser, SlackUserInfo]):
@@ -136,7 +136,7 @@ class SlackUsers(SlackItem[SlackUser, SlackUserInfo]):
response = await self.workspace.api.fetch_users_info(item_ids)
return {info["id"]: info for info in response["users"]}
- def _create_item_from_info(self, item_info: SlackUserInfo) -> SlackUser:
+ async def _create_item_from_info(self, item_info: SlackUserInfo) -> SlackUser:
return self._item_class(self.workspace, item_info)
@@ -150,7 +150,7 @@ class SlackBots(SlackItem[SlackBot, SlackBotInfo]):
response = await self.workspace.api.fetch_bots_info(item_ids)
return {info["id"]: info for info in response["bots"]}
- def _create_item_from_info(self, item_info: SlackBotInfo) -> SlackBot:
+ async def _create_item_from_info(self, item_info: SlackBotInfo) -> SlackBot:
return self._item_class(self.workspace, item_info)
@@ -166,7 +166,9 @@ class SlackUsergroups(SlackItem[SlackUsergroup, SlackUsergroupInfo]):
)
return {info["id"]: info for info in response["results"]}
- def _create_item_from_info(self, item_info: SlackUsergroupInfo) -> SlackUsergroup:
+ async def _create_item_from_info(
+ self, item_info: SlackUsergroupInfo
+ ) -> SlackUsergroup:
return self._item_class(self.workspace, item_info)
@@ -283,8 +285,7 @@ class SlackWorkspace:
if not history["messages"]:
return
- sort_key = await conversation.sort_key()
- return sort_key, conversation
+ return conversation.sort_key(), conversation
async def _connect_ws(self, url: str):
proxy = Proxy()
@@ -348,14 +349,14 @@ class SlackWorkspace:
for channel_id in changed_channels:
channel = self.open_conversations.get(channel_id)
if channel:
- await channel.update_buffer_props()
+ channel.update_buffer_props()
return
elif data["type"] == "user_status_changed":
user = await self.users[data["user"]["id"]]
user.update_info_json(data["user"])
for conversation in self.open_conversations.values():
if conversation.im_user_id == user.id:
- await conversation.update_buffer_props()
+ conversation.update_buffer_props()
return
elif data["type"] == "channel_joined" or data["type"] == "group_joined":
channel_id = data["channel"]["id"]
@@ -413,7 +414,7 @@ class SlackWorkspace:
await channel.change_message(data)
else:
if "subtype" in data and data["subtype"] == "channel_topic":
- await channel.set_topic(data["topic"])
+ channel.set_topic(data["topic"])
message = SlackMessage(channel, data)
await channel.add_new_message(message)