diff options
| author | jason | 2016-08-18 18:18:33 -0600 |
|---|---|---|
| committer | jason | 2016-08-18 18:18:33 -0600 |
| commit | d3fc36c85d4b58bfb852c86ad09f95f8e24e4db3 (patch) | |
| tree | f2975bc8d6f0cced69ce00b72a273a280b1c109d | |
| parent | 76b17a8e720e78d3700b05879dc333f08b087392 (diff) | |
| download | warmachine-ng-d3fc36c85d4b58bfb852c86ad09f95f8e24e4db3.tar.gz warmachine-ng-d3fc36c85d4b58bfb852c86ad09f95f8e24e4db3.zip | |
misc updates
- updates slack.py to use 'unique' message ids
- updates standup to clear out channels waiting for a reply after 8 hours
| -rw-r--r-- | warmachine/addons/standup.py | 47 | ||||
| -rw-r--r-- | warmachine/connections/slack.py | 19 |
2 files changed, 58 insertions, 8 deletions
diff --git a/warmachine/addons/standup.py b/warmachine/addons/standup.py index fd75473..6ee6378 100644 --- a/warmachine/addons/standup.py +++ b/warmachine/addons/standup.py | |||
| @@ -257,7 +257,7 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 257 | def clear_old_standup_message_schedule_func(self, user): | 257 | def clear_old_standup_message_schedule_func(self, user): |
| 258 | """ | 258 | """ |
| 259 | This function is scheduled to remove old standup messages so that the | 259 | This function is scheduled to remove old standup messages so that the |
| 260 | user is asked about standup the following day. | 260 | user is asked for updates on the next standup. |
| 261 | """ | 261 | """ |
| 262 | self.log.info('Clearing old standup message for {}'.format(user)) | 262 | self.log.info('Clearing old standup message for {}'.format(user)) |
| 263 | del self.users_awaiting_reply[user]['clear_standup_msg_f'] | 263 | del self.users_awaiting_reply[user]['clear_standup_msg_f'] |
| @@ -287,6 +287,17 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 287 | else: | 287 | else: |
| 288 | await self.standup_priv_msg(connection, u, channel) | 288 | await self.standup_priv_msg(connection, u, channel) |
| 289 | 289 | ||
| 290 | # schedule a function to run in 12 hours to clear out this channel from | ||
| 291 | # self.users_awaiting_reply for all `users`. | ||
| 292 | # This is assuming that after 12 hours, nobody cares about the report | ||
| 293 | # from people who never reported earlier. It will prevent flooding | ||
| 294 | # "tomorrow's" response to channels whose standup is scheduled for | ||
| 295 | # later. | ||
| 296 | self._loop.call_later(8*(60*60), # 8 hours | ||
| 297 | self.clean_channel_from_waiting_replies, channel, | ||
| 298 | users) | ||
| 299 | |||
| 300 | |||
| 290 | async def standup_priv_msg(self, connection, user, channel, pester=600, | 301 | async def standup_priv_msg(self, connection, user, channel, pester=600, |
| 291 | pester_count=0): | 302 | pester_count=0): |
| 292 | """ | 303 | """ |
| @@ -314,11 +325,13 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 314 | 'for_channels': [channel, ], | 325 | 'for_channels': [channel, ], |
| 315 | } | 326 | } |
| 316 | 327 | ||
| 328 | for_channels = self.users_awaiting_reply[user]['for_channels'] | ||
| 317 | await connection.say('What did you do yesterday? What will you ' | 329 | await connection.say('What did you do yesterday? What will you ' |
| 318 | 'do today? do you have any blockers? ' | 330 | 'do today? do you have any blockers? ' |
| 319 | '(standup for:{})'.format(channel), user) | 331 | '(standup for:{})'.format( |
| 332 | ', '.join(for_channels)), user) | ||
| 320 | 333 | ||
| 321 | if pester > 0 and pester_count <= 6: | 334 | if pester > 0 and pester_count <= 5: |
| 322 | self.log.info('Scheduling pester for {} {}m from now'.format( | 335 | self.log.info('Scheduling pester for {} {}m from now'.format( |
| 323 | user, pester/60)) | 336 | user, pester/60)) |
| 324 | f = self._loop.call_later( | 337 | f = self._loop.call_later( |
| @@ -366,6 +379,31 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 366 | 379 | ||
| 367 | return next_standup | 380 | return next_standup |
| 368 | 381 | ||
| 382 | def clean_channel_from_waiting_replies(self, channel, users): | ||
| 383 | """ | ||
| 384 | This clears ``channel`` from the list of interested channels for a | ||
| 385 | user's stand up, so that when the next stand up comes and they answer, | ||
| 386 | the other channels won't recieve information they are most likely not | ||
| 387 | interested in anymore | ||
| 388 | |||
| 389 | Args: | ||
| 390 | channel (str): The channel to clear out | ||
| 391 | users (list): List of users to check for | ||
| 392 | """ | ||
| 393 | for u in users: | ||
| 394 | if u in self.users_awaiting_reply: | ||
| 395 | self.log.info('Clearing channel {} from list of waiting ' | ||
| 396 | 'channels for user {}'.format(channel, u)) | ||
| 397 | self.users_awaiting_reply[u]['for_channels'].remove(channel) | ||
| 398 | |||
| 399 | # if that was the last channel, kill any pester tasks | ||
| 400 | if not self.users_awaiting_reply[u]['for_channels'] and \ | ||
| 401 | self.users_awaiting_reply[u]['pester_task']: | ||
| 402 | self.log.info('No more interested channels for {}. ' | ||
| 403 | 'Cancelling pester.'.format(u)) | ||
| 404 | self.users_awaiting_reply[u]['pester_task'].cancel() | ||
| 405 | del self.users_awaiting_reply[u]['pester_task'] | ||
| 406 | |||
| 369 | def save_schedule(self, connection): | 407 | def save_schedule(self, connection): |
| 370 | """ | 408 | """ |
| 371 | Save all channel schedules to a file. | 409 | Save all channel schedules to a file. |
| @@ -394,6 +432,9 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 394 | self.log.debug('Error loading standup schedules: {}'.format(e)) | 432 | self.log.debug('Error loading standup schedules: {}'.format(e)) |
| 395 | return | 433 | return |
| 396 | 434 | ||
| 435 | if connection.id not in data: | ||
| 436 | return | ||
| 437 | |||
| 397 | for channel in data[connection.id]: | 438 | for channel in data[connection.id]: |
| 398 | self.schedule_standup( | 439 | self.schedule_standup( |
| 399 | connection, channel, data[connection.id][channel]['time24h']) | 440 | connection, channel, data[connection.id][channel]['time24h']) |
diff --git a/warmachine/connections/slack.py b/warmachine/connections/slack.py index 79c80a2..07e026c 100644 --- a/warmachine/connections/slack.py +++ b/warmachine/connections/slack.py | |||
| @@ -34,6 +34,8 @@ class SlackWS(Connection): | |||
| 34 | self.my_id = '000' | 34 | self.my_id = '000' |
| 35 | 35 | ||
| 36 | self.ws = None | 36 | self.ws = None |
| 37 | # used to give messages an id. slack requirement | ||
| 38 | self._internal_msgid = 0 | ||
| 37 | 39 | ||
| 38 | self.status = INITALIZED | 40 | self.status = INITALIZED |
| 39 | 41 | ||
| @@ -53,7 +55,14 @@ class SlackWS(Connection): | |||
| 53 | 55 | ||
| 54 | async def read(self): | 56 | async def read(self): |
| 55 | if self.ws: | 57 | if self.ws: |
| 56 | message = json.loads(await self.ws.recv()) | 58 | try: |
| 59 | message = json.loads(await self.ws.recv()) | ||
| 60 | except websockets.ConnectionClosed as e: | ||
| 61 | self.log.error('Connection Closed: {}'.format(e)) | ||
| 62 | while not self.connect(): | ||
| 63 | self.error('Trying to reconnect...') | ||
| 64 | await asyncio.sleep(300) | ||
| 65 | return | ||
| 57 | # Slack is acknowledging a message was sent. Do nothing | 66 | # Slack is acknowledging a message was sent. Do nothing |
| 58 | if 'reply_to' in message: | 67 | if 'reply_to' in message: |
| 59 | # {'ok': True, | 68 | # {'ok': True, |
| @@ -61,10 +70,10 @@ class SlackWS(Connection): | |||
| 61 | # 'text': "['!whois', 'synic']", | 70 | # 'text': "['!whois', 'synic']", |
| 62 | # 'ts': '1469743355.000150'} | 71 | # 'ts': '1469743355.000150'} |
| 63 | self.log.debug('Ignoring reply_to message: {}'.format( | 72 | self.log.debug('Ignoring reply_to message: {}'.format( |
| 64 | pformat(message))) | 73 | message)) |
| 65 | return | 74 | return |
| 66 | 75 | ||
| 67 | self.log.debug('new slack message: {}'.format(pformat(message))) | 76 | self.log.debug('new slack message: {}'.format(message)) |
| 68 | if message['type'] == 'message' and 'subtype' not in message: | 77 | if message['type'] == 'message' and 'subtype' not in message: |
| 69 | # Handle text messages from users | 78 | # Handle text messages from users |
| 70 | return await self.process_message(message) | 79 | return await self.process_message(message) |
| @@ -104,8 +113,9 @@ class SlackWS(Connection): | |||
| 104 | 113 | ||
| 105 | destination = self.get_dm_id_by_user(_user) | 114 | destination = self.get_dm_id_by_user(_user) |
| 106 | 115 | ||
| 116 | self._internal_msgid += 1 | ||
| 107 | message = { | 117 | message = { |
| 108 | 'id': 1, # TODO: this should be a get_msgid call or something | 118 | 'id': self._internal_msgid, |
| 109 | 'type': 'message', | 119 | 'type': 'message', |
| 110 | 'channel': destination, | 120 | 'channel': destination, |
| 111 | 'text': str(message) | 121 | 'text': str(message) |
| @@ -301,7 +311,6 @@ class SlackWS(Connection): | |||
| 301 | for u_id in r[key]['members']: | 311 | for u_id in r[key]['members']: |
| 302 | users.append(self.user_map[u_id]['name']) | 312 | users.append(self.user_map[u_id]['name']) |
| 303 | 313 | ||
| 304 | self.log.debug(pformat(users)) | ||
| 305 | return users | 314 | return users |
| 306 | 315 | ||
| 307 | async def on_group_join(self, channel): | 316 | async def on_group_join(self, channel): |