''' Base class and some helper functions''' from __future__ import print_function import re from slackclient import SlackClient from functions import fail_unless class Base(object): # pylint: disable=too-few-public-methods,too-many-instance-attributes """Slack Concourse resource implementation""" def __init__(self, **kwargs): self.slack_client = SlackClient(kwargs.get("slack_token")) self.bot = kwargs.get("bot_name") self.channel = kwargs.get("channel") self.grammar = kwargs.get("grammar") self.version = kwargs.get("version") self.working_dir = kwargs.get("working_dir") self.slack_unread = kwargs.get("slack_unread") self.users = self._call_api("users.list", presence=0) self.mention = kwargs.get("mention") if self.mention: self.bot_id = self._filter(self.users['members'], "id", "name", self.bot) fail_unless(self.bot_id, "Unable to find bot name '{}'".format(self.bot)) if not self.grammar and not self.mention: fail_unless(False, "At least one parameter is required 'grammar', 'mention'.") self.channel_id, self.channel_type = self._get_channel_group_info() fail_unless(self.channel_id, "Unable to find channel/group '{}'".format(self.channel)) def _call_api(self, method, **kwargs): """Interface to Slack API""" api_response = self.slack_client.api_call(method, **kwargs) response_status = api_response.get("ok", False) fail_unless(response_status, "Slack API Call failed. method={} response={}".format(method, api_response)) return api_response @staticmethod def _remove_bot_id(msg, bot_id): '''Return a text after removing <@BOT_NAME> from message.''' regex = re.compile(r"^(\s+)?<@{}>(.*)".format(bot_id)) regex = regex.match(msg) if not regex: return None return regex.groups()[1].strip() def _msg_grammar(self, msg): ''' Return only message if grammar is not defined. Return regex if grammar is defined. And None if no match''' if self.mention: msg = self._remove_bot_id(msg, self.bot_id) if not self.grammar or not msg: # No grammar rule or or no mention of the bot, Just return msg return msg try: regex = re.compile(r"{}".format(self.grammar)) except re.error as regex_error: fail_unless(False, "The grammar expression '{}' has an error : {}".format(self.grammar, regex_error)) return regex.match(msg) @staticmethod def _filter(items, return_field, filter_field, filter_value): '''Return 'return_field' if filter_value in items filter_field else return none''' for item in items: if filter_value == item.get(filter_field, None): return item.get(return_field, None) return None def _get_channel_group_id(self, channel_type): items = self._call_api("{}.list".format(channel_type), exclude_members=1) return self._filter(items[channel_type], "id", "name", self.channel) def _get_channel_group_info(self): '''Return ID and type of channel (channel|groups)''' channel_id = self._get_channel_group_id("groups") if channel_id: return channel_id, "groups" channel_id = self._get_channel_group_id("channels") return channel_id, "channels"