aboutsummaryrefslogtreecommitdiffstats
path: root/wee_slack.py
diff options
context:
space:
mode:
Diffstat (limited to 'wee_slack.py')
-rw-r--r--wee_slack.py117
1 files changed, 103 insertions, 14 deletions
diff --git a/wee_slack.py b/wee_slack.py
index 9262e7f..f6448ce 100644
--- a/wee_slack.py
+++ b/wee_slack.py
@@ -72,6 +72,13 @@ SLACK_API_TRANSLATOR = {
"mark": "groups.mark",
"info": "groups.info"
},
+ "shared": {
+ "history": "conversations.history",
+ "join": "conversations.join",
+ "leave": "conversations.leave",
+ "mark": "channels.mark",
+ "info": "conversations.info",
+ },
"thread": {
"history": None,
"join": None,
@@ -122,6 +129,7 @@ def utf8_decode(f):
NICK_GROUP_HERE = "0|Here"
NICK_GROUP_AWAY = "1|Away"
+NICK_GROUP_EXTERNAL = "2|External"
sslopt_ca_certs = {}
if hasattr(ssl, "get_default_verify_paths") and callable(ssl.get_default_verify_paths):
@@ -981,6 +989,7 @@ class SlackTeam(object):
except:
self.channels = channels
self.users = users
+ self.external_users = {}
self.bots = bots
self.team_hash = SlackTeam.generate_team_hash(self.nick, self.subdomain)
self.name = self.domain
@@ -1071,6 +1080,12 @@ class SlackTeam(object):
def get_username_map(self):
return {v.name: k for k, v in self.users.iteritems()}
+ def get_user(self, user_id):
+ if user_id in self.users:
+ return self.users[user_id]
+ elif user_id in self.external_users:
+ return self.external_users[user_id]
+
def get_team_hash(self):
return self.team_hash
@@ -1248,6 +1263,8 @@ class SlackChannel(object):
prepend = ">"
elif self.type == "group":
prepend = config.group_name_prefix
+ elif self.type == "shared":
+ prepend = config.shared_name_prefix
else:
prepend = "#"
select = {
@@ -1552,7 +1569,7 @@ class SlackChannel(object):
def update_nicklist(self, user=None):
if not self.channel_buffer:
return
- if self.type not in ["channel", "group", "mpim"]:
+ if self.type not in ["channel", "group", "mpim", "shared"]:
return
w.buffer_set(self.channel_buffer, "nicklist", "1")
# create nicklists for the current channel if they don't exist
@@ -1564,16 +1581,25 @@ class SlackChannel(object):
if not afk:
afk = w.nicklist_add_group(self.channel_buffer, '', NICK_GROUP_AWAY, "weechat.color.nicklist_group", 1)
+ # Add External nicklist group only for shared channels
+ if self.type == 'shared':
+ external = w.nicklist_search_group(self.channel_buffer, '', NICK_GROUP_EXTERNAL)
+ if not external:
+ external = w.nicklist_add_group(self.channel_buffer, '', NICK_GROUP_EXTERNAL, 'weechat.color.nicklist_group', 2)
+
if user and len(self.members) < 1000:
- user = self.team.users[user]
- if user.deleted:
+ user = self.team.get_user(user)
+ # External users that have left shared channels won't exist
+ if not user or user.deleted:
return
nick = w.nicklist_search_nick(self.channel_buffer, "", user.name)
# since this is a change just remove it regardless of where it is
w.nicklist_remove_nick(self.channel_buffer, nick)
# now add it back in to whichever..
nick_group = afk
- if self.team.is_user_present(user.identifier):
+ if user.is_external:
+ nick_group = external
+ elif self.team.is_user_present(user.identifier):
nick_group = here
if user.identifier in self.members:
w.nicklist_add_nick(self.channel_buffer, nick_group, user.name, user.color_name, "", "", 1)
@@ -1583,11 +1609,13 @@ class SlackChannel(object):
if len(self.members) < 1000:
try:
for user in self.members:
- user = self.team.users[user]
+ user = self.team.get_user(user)
if user.deleted:
continue
nick_group = afk
- if self.team.is_user_present(user.identifier):
+ if user.is_external:
+ nick_group = external
+ elif self.team.is_user_present(user.identifier):
nick_group = here
w.nicklist_add_nick(self.channel_buffer, nick_group, user.name, user.color_name, "", "", 1)
except Exception as e:
@@ -1770,6 +1798,30 @@ class SlackMPDMChannel(SlackChannel):
pass
+class SlackSharedChannel(SlackChannel):
+ def __init__(self, eventrouter, **kwargs):
+ super(SlackSharedChannel, self).__init__(eventrouter, **kwargs)
+ self.type = 'shared'
+
+ def set_related_server(self, team):
+ super(SlackSharedChannel, self).set_related_server(team)
+ # Fetch members here (after the team is known) since they aren't
+ # included in rtm.start
+ s = SlackRequest(team.token, 'conversations.members', {'channel': self.identifier}, team_hash=team.team_hash, channel_identifier=self.identifier)
+ self.eventrouter.receive(s)
+
+ def get_history(self, slow_queue=False):
+ # Get info for external users in the channel
+ all_users = set(self.team.users.keys()) | set(self.team.external_users.keys())
+ for user in self.members - all_users:
+ s = SlackRequest(self.team.token, 'users.info', {'user': user}, team_hash=self.team.team_hash, channel_identifier=self.identifier)
+ self.eventrouter.receive(s)
+ super(SlackSharedChannel, self).get_history(slow_queue)
+
+ def set_name(self, slack_name):
+ self.name = config.shared_name_prefix + slack_name
+
+
class SlackThreadChannel(object):
"""
A thread channel is a virtual channel. We don't inherit from
@@ -1923,6 +1975,7 @@ class SlackUser(object):
# the rest we can just learn from slack
self.identifier = kwargs["id"]
self.profile = {} # in case it's not in kwargs
+ self.is_external = False
for key, value in kwargs.items():
setattr(self, key, value)
@@ -2020,10 +2073,13 @@ class SlackMessage(object):
if 'user' in self.message_json:
if self.message_json['user'] == self.team.myidentifier:
u = self.team.users[self.team.myidentifier]
- elif self.message_json['user'] in self.team.users:
- u = self.team.users[self.message_json['user']]
+ else:
+ u = self.team.get_user(self.message_json['user'])
name = "{}".format(u.formatted_name())
name_plain = "{}".format(u.formatted_name(enable_color=False))
+ if u.is_external:
+ name += config.external_user_suffix
+ name_plain += config.external_user_suffix
elif 'username' in self.message_json:
u = self.message_json["username"]
if self.message_json.get("subtype") == "bot_message":
@@ -2163,7 +2219,10 @@ def handle_rtmstart(login_data, eventrouter):
channels = {}
for item in login_data["channels"]:
- channels[item["id"]] = SlackChannel(eventrouter, **item)
+ if item["is_shared"]:
+ channels[item["id"]] = SlackSharedChannel(eventrouter, **item)
+ else:
+ channels[item["id"]] = SlackChannel(eventrouter, **item)
for item in login_data["ims"]:
channels[item["id"]] = SlackDMChannel(eventrouter, users, **item)
@@ -2260,6 +2319,10 @@ def handle_mpimhistory(message_json, eventrouter, **kwargs):
handle_history(message_json, eventrouter, **kwargs)
+def handle_conversationshistory(message_json, eventrouter, **kwargs):
+ handle_history(message_json, eventrouter, **kwargs)
+
+
def handle_history(message_json, eventrouter, **kwargs):
request_metadata = pickle.loads(message_json["wee_slack_request_metadata"])
kwargs['team'] = eventrouter.teams[request_metadata.team_hash]
@@ -2276,6 +2339,23 @@ def handle_history(message_json, eventrouter, **kwargs):
process_message(message, eventrouter, **kwargs)
+def handle_conversationsmembers(members_json, eventrouter, **kwargs):
+ request_metadata = pickle.loads(members_json['wee_slack_request_metadata'])
+ team = eventrouter.teams[request_metadata.team_hash]
+ channel = team.channels[request_metadata.channel_identifier]
+ channel.members = set(members_json['members'])
+
+
+def handle_usersinfo(user_json, eventrouter, **kwargs):
+ request_metadata = pickle.loads(user_json['wee_slack_request_metadata'])
+ team = eventrouter.teams[request_metadata.team_hash]
+ channel = team.channels[request_metadata.channel_identifier]
+ user_info = user_json['user']
+ user_info.update(is_external=True, deleted=False)
+ team.external_users[user_info['id']] = SlackUser(**user_info)
+ channel.update_nicklist(user_info['id'])
+
+
###### New/converted process_ and subprocess_ methods
def process_hello(message_json, eventrouter, **kwargs):
kwargs['team'].subscribe_users_presence()
@@ -2834,11 +2914,12 @@ def resolve_ref(ref):
e = EVENTROUTER
if ref.startswith('@U') or ref.startswith('@W'):
for t in e.teams.keys():
- if ref[1:] in e.teams[t].users:
- # try:
- return "@{}".format(e.teams[t].users[ref[1:]].name)
- # except:
- # dbg("NAME: {}".format(ref))
+ user = e.teams[t].get_user(ref[1:])
+ if user:
+ name = '@{}'.format(user.name)
+ if user.is_external:
+ name += config.external_user_suffix
+ return name
elif ref.startswith('#C'):
for t in e.teams.keys():
if ref[1:] in e.teams[t].channels:
@@ -3666,6 +3747,9 @@ class PluginConfig(object):
'distracting_channels': Setting(
default='',
desc='List of channels to hide.'),
+ 'external_user_suffix': Setting(
+ default='*',
+ desc='The suffix appended to nicks to indicate external users.'),
'group_name_prefix': Setting(
default='&',
desc='The prefix of buffer names for groups (private channels).'),
@@ -3697,6 +3781,9 @@ class PluginConfig(object):
' will be used instead of the actual name of the slack (in buffer'
' names, logging, etc). E.g `work:no_fun_allowed` would make your'
' work slack show up as `no_fun_allowed` rather than `work.slack.com`.'),
+ 'shared_name_prefix': Setting(
+ default='%',
+ desc='The prefix of buffer names for shared channels.'),
'short_buffer_names': Setting(
default='false',
desc='Use `foo.#channel` rather than `foo.slack.com.#channel` as the'
@@ -3796,10 +3883,12 @@ class PluginConfig(object):
return w.config_get_plugin(key) == default
get_debug_level = get_int
+ get_external_user_suffix = get_string
get_group_name_prefix = get_string
get_map_underline_to = get_string
get_render_bold_as = get_string
get_render_italic_as = get_string
+ get_shared_name_prefix = get_string
get_slack_timeout = get_int
get_thread_suffix_color = get_string
get_unfurl_auto_link_display = get_string