From b915ef41c19a6eb4cb5f80e2f5f52b835afa9a53 Mon Sep 17 00:00:00 2001 From: jason Date: Tue, 9 Aug 2016 12:48:14 -0600 Subject: Updates for the standup plgin --- bin/dbolla | 1 + warmachine/addons/standup.py | 32 +++++++++++++++++++++++++++----- warmachine/connections/slack.py | 39 +++++++++++++++++++++++++++++++++++---- 3 files changed, 63 insertions(+), 9 deletions(-) diff --git a/bin/dbolla b/bin/dbolla index 2b4fe02..1f51225 100755 --- a/bin/dbolla +++ b/bin/dbolla @@ -123,6 +123,7 @@ if __name__ == "__main__": if args.config: settings = Config(args.config) else: + sys.stderr.write('Please specify a config file\n') sys.exit(1) bot = Bot(settings) diff --git a/warmachine/addons/standup.py b/warmachine/addons/standup.py index 7d1ec99..336177e 100644 --- a/warmachine/addons/standup.py +++ b/warmachine/addons/standup.py @@ -30,18 +30,24 @@ class StandUpPlugin(WarMachinePlugin): self._loop = asyncio.get_event_loop() if cmd == '!standup-add': - pretty_next_standup, next_standup_secs = \ - self.get_next_standup_secs(parts[0]) + next_standup = self.get_next_standup_secs(parts[0]) + pretty_next_standup = next_standup - datetime.now() + next_standup_secs = pretty_next_standup.seconds + + ### DEBUG + next_standup_secs = 5 + ### f = self._loop.call_later( next_standup_secs, functools.partial( self.standup_schedule_func, connection, message['channel'])) self.standup_schedules[message['channel']] = { 'future': f, + 'datetime': next_standup, } - await connection.say('Next standup in {}'.format( - pretty_next_standup), message['channel']) + await connection.say('Next standup in {} ({})'.format( + pretty_next_standup, next_standup), message['channel']) await connection.say(str(self.standup_schedules), message['channel']) @@ -50,12 +56,27 @@ class StandUpPlugin(WarMachinePlugin): async def start_standup(self, connection, channel): await connection.say('@channel Time for standup', channel) - connection.get_users_by_channel(channel) + users = connection.get_users_by_channel(channel) + + for u in users: + if u == connection.my_id: + continue + + self.log.debug('Messaging user: {} ({})'.format( + connection.user_map[u], u)) + + await connection.say('What did you do yesterday? What will you ' + 'do today? do you have any blockers? ' + '(standup for:{})'.format(channel), u) @classmethod def get_next_standup_secs(cls, time24h): """ calculate the number of seconds until the next standup time + + Returns: + datetime: Datetime object representing the next datetime the standup + will begin """ now = datetime.now() @@ -74,5 +95,6 @@ class StandUpPlugin(WarMachinePlugin): future = now + timedelta(hours=hours) next_standup = datetime(future.year, future.month, future.day, standup_hour, standup_minute) + return next_standup standup_in = next_standup-now return standup_in, standup_in.seconds diff --git a/warmachine/connections/slack.py b/warmachine/connections/slack.py index 7f54a55..845b5c8 100644 --- a/warmachine/connections/slack.py +++ b/warmachine/connections/slack.py @@ -30,6 +30,8 @@ class SlackWS(Connection): self.user_map = {} # user info keyed by their slack id self.user_nick_to_id = {} # slack user id mapped to the (nick)name + self.my_id = '000' + self.ws = None self.status = INITALIZED @@ -42,7 +44,7 @@ class SlackWS(Connection): async def read(self): if self.ws: message = json.loads(await self.ws.recv()) - + self.log.debug('REPLY: {}'.format(message)) # Slack is acknowledging a message was sent. Do nothing if 'type' not in message and 'reply_to' in message: # {'ok': True, @@ -76,11 +78,30 @@ class SlackWS(Connection): """ Say something in the provided channel or IM by id """ + + # If the destination is a user, figure out the DM channel id + if destination_id.startswith('U'): + url = 'https://slack.com/api/im.open?{}'.format(urlencode({ + 'token': self.token, + 'user': destination_id, + })) + + req = urllib.request.Request(url) + r = urllib.request.urlopen(req).read().decode('utf-8') + + data = json.loads(r) + + if not data['ok']: + raise Exception(data) + return + + destination_id = data['channel']['id'] + await self._send(json.dumps({ 'id': 1, # TODO: this should be a get_msgid call or something 'type': 'message', 'channel': destination_id, - 'text': message + 'text': str(message) })) async def _send(self, message): @@ -126,6 +147,12 @@ class SlackWS(Connection): self.status = CONNECTED + # Save the bot's id + try: + self.my_id = self._info['self'].get('id', '000') + except KeyError: + self.log.error('Unable to read self section of connect info') + # Map users for u in self._info.get('users', []): self.user_map[u['id']] = u @@ -205,9 +232,13 @@ class SlackWS(Connection): })) self.log.debug(url) req = urllib.request.Request(url) - r = urllib.request.urlopen(req).read().decode('utf-8') + r = json.loads(urllib.request.urlopen(req).read().decode('utf-8')) + + if channel.startswith('G'): + key = 'group' - self.log.debug(r) + self.log.debug(pformat(r['group']['members'])) + return r['group']['members'] async def on_group_join(self, channel): """ -- cgit v1.2.1