diff options
Diffstat (limited to 'wee_slack.py')
-rw-r--r-- | wee_slack.py | 117 |
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 |