diff options
| author | jason | 2016-08-09 12:48:14 -0600 |
|---|---|---|
| committer | jason | 2016-08-09 12:48:14 -0600 |
| commit | b915ef41c19a6eb4cb5f80e2f5f52b835afa9a53 (patch) | |
| tree | 16ca76bd5a388b5b8f4af7b0883fdde3266988e0 | |
| parent | 1a54414afff62561dff03e8a9f43287fa38176b6 (diff) | |
| download | warmachine-ng-b915ef41c19a6eb4cb5f80e2f5f52b835afa9a53.tar.gz warmachine-ng-b915ef41c19a6eb4cb5f80e2f5f52b835afa9a53.zip | |
Updates for the standup plgin
| -rwxr-xr-x | bin/dbolla | 1 | ||||
| -rw-r--r-- | warmachine/addons/standup.py | 32 | ||||
| -rw-r--r-- | warmachine/connections/slack.py | 39 |
3 files changed, 63 insertions, 9 deletions
| @@ -123,6 +123,7 @@ if __name__ == "__main__": | |||
| 123 | if args.config: | 123 | if args.config: |
| 124 | settings = Config(args.config) | 124 | settings = Config(args.config) |
| 125 | else: | 125 | else: |
| 126 | sys.stderr.write('Please specify a config file\n') | ||
| 126 | sys.exit(1) | 127 | sys.exit(1) |
| 127 | 128 | ||
| 128 | bot = Bot(settings) | 129 | 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): | |||
| 30 | self._loop = asyncio.get_event_loop() | 30 | self._loop = asyncio.get_event_loop() |
| 31 | 31 | ||
| 32 | if cmd == '!standup-add': | 32 | if cmd == '!standup-add': |
| 33 | pretty_next_standup, next_standup_secs = \ | 33 | next_standup = self.get_next_standup_secs(parts[0]) |
| 34 | self.get_next_standup_secs(parts[0]) | ||
| 35 | 34 | ||
| 35 | pretty_next_standup = next_standup - datetime.now() | ||
| 36 | next_standup_secs = pretty_next_standup.seconds | ||
| 37 | |||
| 38 | ### DEBUG | ||
| 39 | next_standup_secs = 5 | ||
| 40 | ### | ||
| 36 | f = self._loop.call_later( | 41 | f = self._loop.call_later( |
| 37 | next_standup_secs, functools.partial( | 42 | next_standup_secs, functools.partial( |
| 38 | self.standup_schedule_func, connection, message['channel'])) | 43 | self.standup_schedule_func, connection, message['channel'])) |
| 39 | 44 | ||
| 40 | self.standup_schedules[message['channel']] = { | 45 | self.standup_schedules[message['channel']] = { |
| 41 | 'future': f, | 46 | 'future': f, |
| 47 | 'datetime': next_standup, | ||
| 42 | } | 48 | } |
| 43 | await connection.say('Next standup in {}'.format( | 49 | await connection.say('Next standup in {} ({})'.format( |
| 44 | pretty_next_standup), message['channel']) | 50 | pretty_next_standup, next_standup), message['channel']) |
| 45 | await connection.say(str(self.standup_schedules), | 51 | await connection.say(str(self.standup_schedules), |
| 46 | message['channel']) | 52 | message['channel']) |
| 47 | 53 | ||
| @@ -50,12 +56,27 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 50 | 56 | ||
| 51 | async def start_standup(self, connection, channel): | 57 | async def start_standup(self, connection, channel): |
| 52 | await connection.say('@channel Time for standup', channel) | 58 | await connection.say('@channel Time for standup', channel) |
| 53 | connection.get_users_by_channel(channel) | 59 | users = connection.get_users_by_channel(channel) |
| 60 | |||
| 61 | for u in users: | ||
| 62 | if u == connection.my_id: | ||
| 63 | continue | ||
| 64 | |||
| 65 | self.log.debug('Messaging user: {} ({})'.format( | ||
| 66 | connection.user_map[u], u)) | ||
| 67 | |||
| 68 | await connection.say('What did you do yesterday? What will you ' | ||
| 69 | 'do today? do you have any blockers? ' | ||
| 70 | '(standup for:{})'.format(channel), u) | ||
| 54 | 71 | ||
| 55 | @classmethod | 72 | @classmethod |
| 56 | def get_next_standup_secs(cls, time24h): | 73 | def get_next_standup_secs(cls, time24h): |
| 57 | """ | 74 | """ |
| 58 | calculate the number of seconds until the next standup time | 75 | calculate the number of seconds until the next standup time |
| 76 | |||
| 77 | Returns: | ||
| 78 | datetime: Datetime object representing the next datetime the standup | ||
| 79 | will begin | ||
| 59 | """ | 80 | """ |
| 60 | now = datetime.now() | 81 | now = datetime.now() |
| 61 | 82 | ||
| @@ -74,5 +95,6 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 74 | future = now + timedelta(hours=hours) | 95 | future = now + timedelta(hours=hours) |
| 75 | next_standup = datetime(future.year, future.month, future.day, | 96 | next_standup = datetime(future.year, future.month, future.day, |
| 76 | standup_hour, standup_minute) | 97 | standup_hour, standup_minute) |
| 98 | return next_standup | ||
| 77 | standup_in = next_standup-now | 99 | standup_in = next_standup-now |
| 78 | return standup_in, standup_in.seconds | 100 | 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): | |||
| 30 | self.user_map = {} # user info keyed by their slack id | 30 | self.user_map = {} # user info keyed by their slack id |
| 31 | self.user_nick_to_id = {} # slack user id mapped to the (nick)name | 31 | self.user_nick_to_id = {} # slack user id mapped to the (nick)name |
| 32 | 32 | ||
| 33 | self.my_id = '000' | ||
| 34 | |||
| 33 | self.ws = None | 35 | self.ws = None |
| 34 | 36 | ||
| 35 | self.status = INITALIZED | 37 | self.status = INITALIZED |
| @@ -42,7 +44,7 @@ class SlackWS(Connection): | |||
| 42 | async def read(self): | 44 | async def read(self): |
| 43 | if self.ws: | 45 | if self.ws: |
| 44 | message = json.loads(await self.ws.recv()) | 46 | message = json.loads(await self.ws.recv()) |
| 45 | 47 | self.log.debug('REPLY: {}'.format(message)) | |
| 46 | # Slack is acknowledging a message was sent. Do nothing | 48 | # Slack is acknowledging a message was sent. Do nothing |
| 47 | if 'type' not in message and 'reply_to' in message: | 49 | if 'type' not in message and 'reply_to' in message: |
| 48 | # {'ok': True, | 50 | # {'ok': True, |
| @@ -76,11 +78,30 @@ class SlackWS(Connection): | |||
| 76 | """ | 78 | """ |
| 77 | Say something in the provided channel or IM by id | 79 | Say something in the provided channel or IM by id |
| 78 | """ | 80 | """ |
| 81 | |||
| 82 | # If the destination is a user, figure out the DM channel id | ||
| 83 | if destination_id.startswith('U'): | ||
| 84 | url = 'https://slack.com/api/im.open?{}'.format(urlencode({ | ||
| 85 | 'token': self.token, | ||
| 86 | 'user': destination_id, | ||
| 87 | })) | ||
| 88 | |||
| 89 | req = urllib.request.Request(url) | ||
| 90 | r = urllib.request.urlopen(req).read().decode('utf-8') | ||
| 91 | |||
| 92 | data = json.loads(r) | ||
| 93 | |||
| 94 | if not data['ok']: | ||
| 95 | raise Exception(data) | ||
| 96 | return | ||
| 97 | |||
| 98 | destination_id = data['channel']['id'] | ||
| 99 | |||
| 79 | await self._send(json.dumps({ | 100 | await self._send(json.dumps({ |
| 80 | 'id': 1, # TODO: this should be a get_msgid call or something | 101 | 'id': 1, # TODO: this should be a get_msgid call or something |
| 81 | 'type': 'message', | 102 | 'type': 'message', |
| 82 | 'channel': destination_id, | 103 | 'channel': destination_id, |
| 83 | 'text': message | 104 | 'text': str(message) |
| 84 | })) | 105 | })) |
| 85 | 106 | ||
| 86 | async def _send(self, message): | 107 | async def _send(self, message): |
| @@ -126,6 +147,12 @@ class SlackWS(Connection): | |||
| 126 | 147 | ||
| 127 | self.status = CONNECTED | 148 | self.status = CONNECTED |
| 128 | 149 | ||
| 150 | # Save the bot's id | ||
| 151 | try: | ||
| 152 | self.my_id = self._info['self'].get('id', '000') | ||
| 153 | except KeyError: | ||
| 154 | self.log.error('Unable to read self section of connect info') | ||
| 155 | |||
| 129 | # Map users | 156 | # Map users |
| 130 | for u in self._info.get('users', []): | 157 | for u in self._info.get('users', []): |
| 131 | self.user_map[u['id']] = u | 158 | self.user_map[u['id']] = u |
| @@ -205,9 +232,13 @@ class SlackWS(Connection): | |||
| 205 | })) | 232 | })) |
| 206 | self.log.debug(url) | 233 | self.log.debug(url) |
| 207 | req = urllib.request.Request(url) | 234 | req = urllib.request.Request(url) |
| 208 | r = urllib.request.urlopen(req).read().decode('utf-8') | 235 | r = json.loads(urllib.request.urlopen(req).read().decode('utf-8')) |
| 236 | |||
| 237 | if channel.startswith('G'): | ||
| 238 | key = 'group' | ||
| 209 | 239 | ||
| 210 | self.log.debug(r) | 240 | self.log.debug(pformat(r['group']['members'])) |
| 241 | return r['group']['members'] | ||
| 211 | 242 | ||
| 212 | async def on_group_join(self, channel): | 243 | async def on_group_join(self, channel): |
| 213 | """ | 244 | """ |