aboutsummaryrefslogtreecommitdiffstats
path: root/wee_slack.py
diff options
context:
space:
mode:
authorNana Amfo <nanaus13@yahoo.com>2019-04-08 06:03:35 -0500
committerTrygve Aaberge <trygveaa@gmail.com>2019-04-08 13:03:35 +0200
commit7d919f3897deb322f13428127b1ba91731917f4c (patch)
tree942f9995cb32d70f4891135ff01082e51d1403e2 /wee_slack.py
parentc605e587a6ee17029b8f072351de8b81a473dce5 (diff)
downloadwee-slack-7d919f3897deb322f13428127b1ba91731917f4c.tar.gz
Add @user-groups support (#680)
Add @user-groups with tab-completion. @user-groups will be unfurl into format <!subteam^{ID}|handle> message before sending message via linktext method.
Diffstat (limited to 'wee_slack.py')
-rw-r--r--wee_slack.py130
1 files changed, 122 insertions, 8 deletions
diff --git a/wee_slack.py b/wee_slack.py
index c1e683b..9f1fe6f 100644
--- a/wee_slack.py
+++ b/wee_slack.py
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
+
from __future__ import unicode_literals
from collections import OrderedDict
@@ -278,6 +279,7 @@ class EventRouter(object):
self.slow_queue = []
self.slow_queue_timer = 0
self.teams = {}
+ self.subteams = {}
self.context = {}
self.weechat_controller = WeechatController(self)
self.previous_buffer = ""
@@ -560,6 +562,8 @@ class EventRouter(object):
kwargs["user"] = self.teams[team].users[j["user"]]
if "channel" in j:
kwargs["channel"] = self.teams[team].channels[j["channel"]]
+ if "subteam" in j:
+ kwargs["subteam"] = self.teams[team].subteams[j["subteam"]]
except:
dbg("metadata failure")
@@ -774,7 +778,6 @@ def input_text_for_buffer_cb(data, modifier, current_buffer, string):
return ""
return string
-
@utf8_decode
def buffer_switch_callback(signal, sig_type, data):
"""
@@ -927,6 +930,20 @@ def emoji_completion_cb(data, completion_item, current_buffer, completion):
w.hook_completion_list_add(completion, ":" + e + ":", 0, w.WEECHAT_LIST_POS_SORT)
return w.WEECHAT_RC_OK
+@utf8_decode
+def usergroups_completion_cb(data, completion_item, current_buffer, completion):
+ """
+ Adds all @-prefixed usergroups to completion list
+ """
+
+ current_channel = EVENTROUTER.weechat_controller.buffers.get(current_buffer, None)
+
+ if current_channel is None:
+ return w.WEECHAT_RC_OK
+ for subteam in current_channel.team.subteams.values():
+ w.hook_completion_list_add(completion, "@" + subteam.handle, 1, w.WEECHAT_LIST_POS_SORT)
+ return w.WEECHAT_RC_OK
+
@utf8_decode
def complete_next_cb(data, current_buffer, command):
@@ -1031,6 +1048,24 @@ class SlackRequest(object):
def retry_ready(self):
return (self.start_time + (self.tries**2)) < time.time()
+class SlackSubteam(object):
+ """
+ Represents a slack group or subteam
+ """
+ def __init__(self, originating_team_id, **kwargs):
+ self.handle = kwargs.get('handle', None)
+ self.identifier = kwargs['id']
+ self.name = kwargs.get('name', None)
+ self.description = kwargs.get('description', None)
+ self.team_id = originating_team_id
+
+
+ def __repr__(self):
+ return "Name:{} Identifier:{}".format(self.name, self.identifier)
+
+ def __eq__(self, compare_str):
+ return compare_str == self.subteam_id
+
class SlackTeam(object):
"""
@@ -1038,7 +1073,7 @@ class SlackTeam(object):
Team object under which users and channels live.. Does lots.
"""
- def __init__(self, eventrouter, token, websocket_url, team_info, nick, myidentifier, users, bots, channels, **kwargs):
+ def __init__(self, eventrouter, token, websocket_url, team_info, subteams, nick, myidentifier, users, bots, channels, **kwargs):
self.identifier = team_info["id"]
self.ws_url = websocket_url
self.connected = False
@@ -1049,6 +1084,7 @@ class SlackTeam(object):
self.eventrouter = eventrouter
self.token = token
self.team = self
+ self.subteams = subteams
self.subdomain = team_info["domain"]
self.domain = self.subdomain + ".slack.com"
self.preferred_name = self.domain
@@ -1072,7 +1108,7 @@ class SlackTeam(object):
for c in self.channels.keys():
channels[c].set_related_server(self)
channels[c].check_should_open()
- # self.channel_set_related_server(c)
+ # self.channel_set_related_server(c)
# Last step is to make sure my nickname is the set color
self.users[self.myidentifier].force_color(w.config_string(w.config_get('weechat.color.chat_nick_self')))
# This highlight step must happen after we have set related server
@@ -1084,10 +1120,7 @@ class SlackTeam(object):
return "domain={} nick={}".format(self.subdomain, self.nick)
def __eq__(self, compare_str):
- if compare_str == self.token or compare_str == self.domain or compare_str == self.subdomain:
- return True
- else:
- return False
+ return compare_str == self.token or compare_str == self.domain or compare_str == self.subdomain
@property
def members(self):
@@ -1103,6 +1136,9 @@ class SlackTeam(object):
self.channels[channel["id"]] = channel
channel.set_related_server(self)
+ def generate_usergroup_map(self):
+ return { s.handle: s.identifier for s in self.subteams.values()}
+
# def connect_request_generate(self):
# return SlackRequest(self.token, 'rtm.start', {})
@@ -2410,6 +2446,10 @@ def handle_rtmstart(login_data, eventrouter):
for item in login_data["bots"]:
bots[item["id"]] = SlackBot(login_data['team']['id'], **item)
+ subteams = {}
+ for item in login_data["subteams"]["all"]:
+ subteams[item['id']] = SlackSubteam(login_data['team']['id'], **item)
+
channels = {}
for item in login_data["channels"]:
if item["is_shared"]:
@@ -2431,6 +2471,7 @@ def handle_rtmstart(login_data, eventrouter):
metadata.token,
login_data['url'],
login_data["team"],
+ subteams,
login_data["self"]["name"],
login_data["self"]["id"],
users,
@@ -2541,7 +2582,15 @@ def handle_usersinfo(user_json, eventrouter, **kwargs):
channel.slack_name = user.name
channel.set_topic(create_user_status_string(user.profile))
+def handle_usergroupsuserslist(users_json, eventrouter, **kwargs):
+ request_metadata = pickle.loads(users_json['wee_slack_request_metadata'])
+ team = eventrouter.teams[request_metadata.team_hash]
+ user_identifers = users_json['users']
+ team.buffer_prnt("Users:")
+ for user_identifier in user_identifers:
+ user = team.users[user_identifier]
+ team.buffer_prnt(" {:<25}({})".format(user.name, user.presence))
###### New/converted process_ and subprocess_ methods
def process_hello(message_json, eventrouter, **kwargs):
@@ -2649,6 +2698,27 @@ def process_message(message_json, eventrouter, store=True, download=True, **kwar
if download:
download_files(message_json, **kwargs)
+def process_subteam_created(subteam_json, eventrouter, **kwargs):
+ team = kwargs['team']
+ subteam_json_info = subteam_json['subteam']
+ subteam = SlackSubteam(team.identifier, **subteam_json_info)
+ team.subteams[subteam_json_info['id']] = subteam
+
+def process_subteam_updated(subteam_json, eventrouter, **kwargs):
+ team = kwargs['team']
+ usergroups = team.generate_usergroup_map()
+ new_subteam_info = subteam_json['subteam']
+
+ current_subteam_info = team.subteams[new_subteam_info.get('id')]
+
+ if config.notify_usergroup_handle_updated and current_subteam_info.handle != new_subteam_info['handle']:
+ usergroups[new_subteam_info['handle']] = new_subteam_info.get('id')
+ template = 'User group @{old_handle} has updated its handle to @{new_handle} in team {team}'
+ message = template.format(old_handle=current_subteam_info.handle, new_handle=new_subteam_info['handle'],
+ team=team.preferred_name)
+ team.buffer_prnt(message, message=True)
+
+ team.subteams[new_subteam_info.get('id')] = SlackSubteam(team.identifier, **new_subteam_info)
def download_files(message_json, **kwargs):
team = kwargs["team"]
@@ -2955,6 +3025,7 @@ def linkify_text(message, team):
# function is only called on message send..
usernames = team.get_username_map()
channels = team.get_channel_map()
+ usergroups = team.generate_usergroup_map()
message = (message
# Replace IRC formatting chars with Slack formatting chars.
.replace('\x02', '*')
@@ -2973,6 +3044,8 @@ def linkify_text(message, team):
named = targets.groups()
if named[1] in ["group", "channel", "here"]:
message[item[0]] = "<!{}>{}".format(named[1], named[2])
+ elif named[1] in list(usergroups.viewkeys()):
+ message[item[0]] = "<!subteam^{}|@{}>{}".format(usergroups[named[1]], named[1], named[2])
else:
try:
if usernames[named[1]]:
@@ -3000,6 +3073,7 @@ def unfurl_refs(text, ignore_alt_text=None, auto_link_display=None):
# - <https://example.com|example with spaces>
# - <#C2147483705|#otherchannel>
# - <@U2147483697|@othernick>
+ # - <!subteam^U2147483697|@group>
# Test patterns lives in ./_pytest/test_unfurl.py
if ignore_alt_text is None:
@@ -3007,7 +3081,7 @@ def unfurl_refs(text, ignore_alt_text=None, auto_link_display=None):
if auto_link_display is None:
auto_link_display = config.unfurl_auto_link_display
- matches = re.findall(r"(<[@#]?(?:[^>]*)>)", text)
+ matches = re.findall(r"(<[@#!]?(?:[^>]*)>)", text)
for m in matches:
# Replace them with human readable strings
text = text.replace(
@@ -3026,6 +3100,12 @@ def unfurl_ref(ref, ignore_alt_text, auto_link_display):
display_text = "#{}".format(ref.split('|')[1])
elif id.startswith("@U"):
display_text = ref.split('|')[1]
+ elif id.startswith("!subteam"):
+ if ref.split('|')[1].startswith('@'):
+ handle = ref.split('|')[1][1:]
+ else:
+ handle = ref.split('|')[1]
+ display_text = '@{}'.format(handle)
else:
url, desc = ref.split('|', 1)
match_url = r"^\w+:(//)?{}$".format(re.escape(desc))
@@ -3506,6 +3586,35 @@ def command_users(data, current_buffer, args):
@slack_buffer_required
@utf8_decode
+def command_usergroups(data, current_buffer, args):
+ """
+
+ /slack usergroups [handle]
+ List the usergroups in the current team
+ If handle is given show the members in the usergroup
+ """
+ e = EVENTROUTER
+ team = e.weechat_controller.buffers[current_buffer].team
+ usergroups = team.generate_usergroup_map()
+ handle = args[1:] if args and args.startswith("@") else args
+
+ if handle and handle in usergroups.keys():
+ subteam = team.subteams[usergroups[handle]]
+ s = SlackRequest(team.token, "usergroups.users.list", { "usergroup": subteam.identifier }, team_hash=team.team_hash)
+ e.receive(s)
+ elif not handle:
+ team.buffer_prnt("Usergroups:")
+ for subteam in team.subteams.values():
+ team.buffer_prnt(" {:<25}(@{})".format(subteam.name, subteam.handle))
+ else:
+ w.prnt('', 'ERROR: Unknown usergroup handle: {}'.format(handle))
+ return w.WEECHAT_RC_ERROR
+
+ return w.WEECHAT_RC_OK_EAT
+
+
+@slack_buffer_required
+@utf8_decode
def command_talk(data, current_buffer, args):
"""
/slack talk <user>[,<user2>[,<user3>...]]
@@ -4060,6 +4169,7 @@ def setup_hooks():
w.hook_command(cmd, description, args, '', '', 'command_' + cmd, '')
w.hook_completion("nicks", "complete @-nicks for slack", "nick_completion_cb", "")
+ w.hook_completion("usergroups", "complete @-usergroups for slack", "usergroups_completion_cb", "")
w.hook_completion("emoji", "complete :emoji: for slack", "emoji_completion_cb", "")
w.key_bind("mouse", {
@@ -4185,6 +4295,10 @@ class PluginConfig(object):
" highlights, i.e. not @channel and @here. all_highlights: Show"
" all highlights, but not other messages. all: Show all activity,"
" like other channels."),
+ 'notify_usergroup_handle_updated': Setting(
+ default='false',
+ desc="Control if you want to see notification when a usergroup's"
+ " handle has changed, either true or false"),
'never_away': Setting(
default='false',
desc='Poke Slack every five minutes so that it never marks you "away".'),