diff options
| author | jason | 2016-08-11 12:57:31 -0600 |
|---|---|---|
| committer | jason | 2016-08-11 12:57:31 -0600 |
| commit | 0869a7f4d57b592058ca907b7d92cc5d4b7e77e3 (patch) | |
| tree | 44876a7229cd19fa58521446acbac0d1f284cb2d | |
| parent | c6d5658f571e7a9e754886dd3ee37813d70a9fcc (diff) | |
| download | warmachine-ng-0869a7f4d57b592058ca907b7d92cc5d4b7e77e3.tar.gz warmachine-ng-0869a7f4d57b592058ca907b7d92cc5d4b7e77e3.zip | |
More or less, a working standup bot.
| -rw-r--r-- | warmachine/addons/standup.py | 139 |
1 files changed, 104 insertions, 35 deletions
diff --git a/warmachine/addons/standup.py b/warmachine/addons/standup.py index 52d9df0..dfcb6ab 100644 --- a/warmachine/addons/standup.py +++ b/warmachine/addons/standup.py | |||
| @@ -22,11 +22,17 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 22 | def __init__(self, *args, **kwargs): | 22 | def __init__(self, *args, **kwargs): |
| 23 | super().__init__(*args, **kwargs) | 23 | super().__init__(*args, **kwargs) |
| 24 | 24 | ||
| 25 | # 'CHANNEL': { | ||
| 26 | # 'future': Task for running next standup, | ||
| 27 | # 'time24': Original 24h time to schedule, | ||
| 28 | # 'datetime': datetime object of when the next schedule will run, | ||
| 29 | # 'ignoring': list of users to ignore when priv messaging, | ||
| 30 | # } | ||
| 25 | self.standup_schedules = {} | 31 | self.standup_schedules = {} |
| 26 | 32 | ||
| 27 | # 'DM_CHANNEL': { | 33 | # 'DM_CHANNEL': { |
| 28 | # 'user': 'UID', | 34 | # 'user': 'UID', |
| 29 | # 'for_channel': 'CHID', | 35 | # 'for_channel': 'CHID', |
| 30 | # } | 36 | # } |
| 31 | self.users_awaiting_reply = {} | 37 | self.users_awaiting_reply = {} |
| 32 | 38 | ||
| @@ -75,45 +81,98 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 75 | 81 | ||
| 76 | cmd = message['message'].split(' ')[0] | 82 | cmd = message['message'].split(' ')[0] |
| 77 | parts = message['message'].split(' ')[1:] | 83 | parts = message['message'].split(' ')[1:] |
| 78 | 84 | channel = message['channel'] | |
| 79 | ################ | 85 | |
| 80 | # !standup-add # | 86 | # ====================================================================== |
| 81 | ################ | 87 | # !standup-add <24h time> |
| 82 | if cmd == '!standup-add': | 88 | # |
| 83 | self.schedule_standup(connection, message['channel'], parts[0]) | 89 | # Add (or update if one exists) a schedule for standup at the given 24h |
| 90 | # time M-F | ||
| 91 | # ====================================================================== | ||
| 92 | if cmd == '!standup-add' and not channel.startswith('D'): | ||
| 93 | # If there is already a schedule, kill the task for the old one. | ||
| 94 | if channel in self.standup_schedules: | ||
| 95 | self.standup_schedules[channel]['future'].cancel() | ||
| 96 | self.log.info('Unscheduling existing schedule for {} at ' | ||
| 97 | '{}'.format( | ||
| 98 | channel, | ||
| 99 | self.standup_schedules[channel]['time24h'])) | ||
| 100 | |||
| 101 | self.schedule_standup(connection, channel, parts[0]) | ||
| 84 | self.save_schedule(connection) | 102 | self.save_schedule(connection) |
| 85 | 103 | # ====================================================================== | |
| 86 | ###################### | 104 | # !standup-remove |
| 87 | # !standup-schedules # | 105 | # |
| 88 | ###################### | 106 | # Remove an existing schedule from the channel |
| 89 | elif message['channel'].startswith('D') and cmd == '!standup-schedules': | 107 | # ====================================================================== |
| 108 | elif cmd == '!standup-remove' and not channel.startswith('D'): | ||
| 109 | if channel in self.standup_schedules: | ||
| 110 | self.standup_schedules[channel]['future'].cancel() | ||
| 111 | del self.standup_schedules[channel] | ||
| 112 | self.save_schedule(connection) | ||
| 113 | self.log.info('Removed standup for channel {}'.format(channel)) | ||
| 114 | |||
| 115 | # ====================================================================== | ||
| 116 | # !standup-ignore | ||
| 117 | # !standup-ignore <comma seperated list of users to ignore> | ||
| 118 | # | ||
| 119 | # Ignore users provided when private messaging asking the standup | ||
| 120 | # questions. | ||
| 121 | # If no users are provided, display the users currently being ignored | ||
| 122 | # ====================================================================== | ||
| 123 | elif cmd == '!standup-ignore' and not channel.startswith('D') \ | ||
| 124 | and channel in self.standup_schedules: | ||
| 125 | if parts: | ||
| 126 | users = ''.join(parts).split(',') | ||
| 127 | for u in users: | ||
| 128 | if u not in self.standup_schedules[channel]['ignoring']: | ||
| 129 | self.log.info('Ignoring {} in channel {}'.format( | ||
| 130 | u, channel)) | ||
| 131 | self.standup_schedules[channel]['ignoring'].append(u) | ||
| 132 | self.save_schedule(connection) | ||
| 133 | |||
| 134 | ignoring = ', '.join( | ||
| 135 | self.standup_schedules[channel]['ignoring']) | ||
| 136 | if not ignoring: | ||
| 137 | ignoring = 'no one' | ||
| 138 | |||
| 139 | await connection.say('Currently ignoring {}'.format(ignoring), | ||
| 140 | channel) | ||
| 141 | |||
| 142 | # ====================================================================== | ||
| 143 | # !standup-schedules | ||
| 144 | # | ||
| 145 | # Report the current standup schedule dict to the requesting user | ||
| 146 | # ====================================================================== | ||
| 147 | elif channel.startswith('D') and cmd == '!standup-schedules': | ||
| 90 | self.log.info('Reporting standup schedules to DM {}'.format( | 148 | self.log.info('Reporting standup schedules to DM {}'.format( |
| 91 | message['channel'])) | 149 | channel)) |
| 92 | await connection.say('Standup Schedules', message['channel']) | 150 | await connection.say('Standup Schedules', channel) |
| 93 | await connection.say('-----------------', message['channel']) | 151 | await connection.say('-----------------', channel) |
| 94 | await connection.say( | ||
| 95 | 'Current Loop Time: {}'.format(self._loop.time()), | ||
| 96 | message['channel']) | ||
| 97 | await connection.say( | 152 | await connection.say( |
| 98 | 'Current Time: {}'.format(datetime.now()), message['channel']) | 153 | 'Current Loop Time: {}'.format(self._loop.time()), channel) |
| 99 | await connection.say( | 154 | await connection.say( |
| 100 | pformat(self.standup_schedules), message['channel']) | 155 | 'Current Time: {}'.format(datetime.now()), channel) |
| 101 | 156 | await connection.say(pformat(self.standup_schedules), channel) | |
| 102 | ############################ | 157 | |
| 103 | # !standup-waiting_replies # | 158 | # ====================================================================== |
| 104 | ############################ | 159 | # !standup-waiting_replies |
| 105 | elif message['channel'].startswith('D') and \ | 160 | # |
| 161 | # Report the data struct of users we are waiting on a reply from to the | ||
| 162 | # requesting user. | ||
| 163 | # ====================================================================== | ||
| 164 | elif channel.startswith('D') and \ | ||
| 106 | cmd == '!standup-waiting_replies': | 165 | cmd == '!standup-waiting_replies': |
| 107 | self.log.info('Reporting who we are waiting on replies for to DM ' | 166 | self.log.info('Reporting who we are waiting on replies for to DM ' |
| 108 | ' {}'.format(message['channel'])) | 167 | ' {}'.format(channel)) |
| 109 | await connection.say('Waiting for Replies From', message['channel']) | 168 | await connection.say('Waiting for Replies From', channel) |
| 110 | await connection.say('------------------------', message['channel']) | 169 | await connection.say('------------------------', channel) |
| 111 | await connection.say( | 170 | await connection.say( |
| 112 | pformat(self.users_awaiting_reply), message['channel']) | 171 | pformat(self.users_awaiting_reply), channel) |
| 113 | 172 | ||
| 114 | def schedule_standup(self, connection, channel, time24h): | 173 | def schedule_standup(self, connection, channel, time24h): |
| 115 | """ | 174 | """ |
| 116 | Schedules a standup | 175 | Schedules a standup by creating a Task to be run in the future. |
| 117 | """ | 176 | """ |
| 118 | next_standup = self.get_next_standup_secs(time24h) | 177 | next_standup = self.get_next_standup_secs(time24h) |
| 119 | 178 | ||
| @@ -128,6 +187,7 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 128 | 'future': f, | 187 | 'future': f, |
| 129 | 'datetime': next_standup, | 188 | 'datetime': next_standup, |
| 130 | 'time24h': time24h, | 189 | 'time24h': time24h, |
| 190 | 'ignoring': [], | ||
| 131 | } | 191 | } |
| 132 | 192 | ||
| 133 | self.log.info('New schedule added to channel {} for {}'.format( | 193 | self.log.info('New schedule added to channel {} for {}'.format( |
| @@ -154,7 +214,7 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 154 | """ | 214 | """ |
| 155 | self.log.info('Pestering user {} to give a standup for channel ' | 215 | self.log.info('Pestering user {} to give a standup for channel ' |
| 156 | '{} (interval: {}s)'.format( | 216 | '{} (interval: {}s)'.format( |
| 157 | connection.user_map[user_id], | 217 | connection.user_map[user_id]['name'], |
| 158 | connection.channel_map[channel]['name'], | 218 | connection.channel_map[channel]['name'], |
| 159 | pester)) | 219 | pester)) |
| 160 | asyncio.ensure_future(self.standup_priv_msg( | 220 | asyncio.ensure_future(self.standup_priv_msg( |
| @@ -169,7 +229,8 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 169 | users = connection.get_users_by_channel(channel) | 229 | users = connection.get_users_by_channel(channel) |
| 170 | 230 | ||
| 171 | for u in users: | 231 | for u in users: |
| 172 | if u == connection.my_id: | 232 | if u == connection.my_id or \ |
| 233 | u in self.standup_schedules[channel]['ignoring']: | ||
| 173 | continue | 234 | continue |
| 174 | 235 | ||
| 175 | await self.standup_priv_msg(connection, u, channel) | 236 | await self.standup_priv_msg(connection, u, channel) |
| @@ -254,7 +315,7 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 254 | """ | 315 | """ |
| 255 | Save all channel schedules to a file. | 316 | Save all channel schedules to a file. |
| 256 | """ | 317 | """ |
| 257 | keys_to_save = ['time24h', ] | 318 | keys_to_save = ['time24h', 'ignoring'] |
| 258 | data = {} | 319 | data = {} |
| 259 | for channel in self.standup_schedules: | 320 | for channel in self.standup_schedules: |
| 260 | data[channel] = {} | 321 | data[channel] = {} |
| @@ -274,9 +335,17 @@ class StandUpPlugin(WarMachinePlugin): | |||
| 274 | with open('/home/jason/.warmachine/standup_schedules.json', 'r') as f: | 335 | with open('/home/jason/.warmachine/standup_schedules.json', 'r') as f: |
| 275 | try: | 336 | try: |
| 276 | data = json.loads(f.read()) | 337 | data = json.loads(f.read()) |
| 277 | except: | 338 | except Exception as e: |
| 339 | self.log.debug('Error loading standup schedules: {}'.format(e)) | ||
| 278 | return | 340 | return |
| 279 | 341 | ||
| 280 | for channel in data[connection.id]: | 342 | for channel in data[connection.id]: |
| 281 | self.schedule_standup( | 343 | self.schedule_standup( |
| 282 | connection, channel, data[connection.id][channel]['time24h']) | 344 | connection, channel, data[connection.id][channel]['time24h']) |
| 345 | |||
| 346 | # Restore the ignore list | ||
| 347 | try: | ||
| 348 | self.standup_schedules[channel]['ignoring'] = \ | ||
| 349 | data[connection.id][channel]['ignoring'] | ||
| 350 | except KeyError: | ||
| 351 | pass | ||