From 8a5ea7d9a01ade013deed1a7f5d3c4030e3647bd Mon Sep 17 00:00:00 2001 From: adamhigerd Date: Thu, 24 Mar 2016 13:36:01 -0700 Subject: [PATCH 01/33] Adding !later command Standup groups can ask morgenbot to call on someone later if they're not ready to stand up yet. --- morgenbot.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/morgenbot.py b/morgenbot.py index 3c9428d..88322d9 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -209,6 +209,11 @@ def ignoring(): def skip(): post_message('Skipping @%s.' % current_user) next() + +def later(): + post_message('We\'ll call on @%s later.' % current_user) + users.append(current_user) + next() def table(topic_user, topic): global topics @@ -252,7 +257,7 @@ def giphy(text): def help(topic=''): if topic == '': - post_message('My commands are !standup, !start, !cancel, !next, !skip, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') + post_message('My commands are !standup, !start, !cancel, !next, !skip, !later, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') return topic = topic[1:] @@ -266,6 +271,8 @@ def help(topic=''): post_message('Type !next to call on the next person when you\'re done standing up') elif topic == 'skip' or topic == '!skip': post_message('Type !skip to skip someone who isn\'t standing up that day') + elif topic == 'later' or topic == '!later': + post_message('Type !later to move someone who isn\'t ready yet to the end of the list') elif topic == 'table' or topic == '!table': post_message('Type !table to save a topic for later discussion. I\'ll list these for you when standup is over.') elif topic == 'left' or topic == '!left': @@ -317,6 +324,8 @@ def main(): next() elif command == 'skip': skip() + elif command == 'later': + later() elif command == 'table': table(msguser, args) elif command == 'left': From dc0aba8c83a17086029d5812c7686260254eedcb Mon Sep 17 00:00:00 2001 From: adamhigerd Date: Thu, 24 Mar 2016 14:35:28 -0700 Subject: [PATCH 02/33] Improve command parsing, add prefix_only param Currently, morgenbot will respond to !commands anywhere in the string. However, if the command isn't the first thing in the line it doesn't parse the arguments correctly, and if the command is unrecognized, it chops out the wrong thing when assembling the giphy parameter. This PR fixes the arguments parsing and the giphy string and adds a configuration flag to only recognize !commands at the beginning of the input string, for users that desire that stricter behavior. --- morgenbot.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 3c9428d..3976645 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -26,6 +26,7 @@ start_message = os.getenv('START_MESSAGE', 'What did you work on yesterday? What are you working on today? What, if any, are your blockers?') giphy = True if os.getenv('GIPHY', 'false').lower() == 'true' else False +prefix_only = True if os.getenv('PREFIX_ONLY', 'false').lower() == 'true' else False commands = ['standup','start','cancel','next','skip','table','left','ignore','heed','ignoring','help'] @@ -290,16 +291,19 @@ def main(): text = request.form.get("text", "") # find !command, but ignore Date: Thu, 24 Mar 2016 15:11:59 -0700 Subject: [PATCH 03/33] Add !later command to commands list --- morgenbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morgenbot.py b/morgenbot.py index 88322d9..f63cab7 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -27,7 +27,7 @@ giphy = True if os.getenv('GIPHY', 'false').lower() == 'true' else False -commands = ['standup','start','cancel','next','skip','table','left','ignore','heed','ignoring','help'] +commands = ['standup','start','cancel','next','skip','later','table','left','ignore','heed','ignoring','help'] users = [] topics = [] From a98597047591a1d7d7fc3577b0aaa6dfd0407a60 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 14:03:17 -0400 Subject: [PATCH 04/33] Add support for skipping idle users --- morgenbot.py | 111 ++++++++++++++++++++++++++++++----------------- requirements.txt | 2 +- 2 files changed, 73 insertions(+), 40 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 3c9428d..9523612 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -21,6 +21,7 @@ icon_emoji = os.getenv('ICON_EMOJI', ':coffee:') channel = os.getenv('CHANNEL', '#standup') ignore_users = os.getenv('IGNORE_USERS', '[]') +skip_idle_users = False if os.getenv('SKIP_IDLE_USERS', 'true').lower() == 'false' else True init_greeting = os.getenv('INIT_GREETING', 'Good morning!') start_message = os.getenv('START_MESSAGE', 'What did you work on yesterday? What are you working on today? What, if any, are your blockers?') @@ -30,6 +31,7 @@ commands = ['standup','start','cancel','next','skip','table','left','ignore','heed','ignoring','help'] users = [] +idle_users = [] topics = [] time = [] in_progress = False @@ -44,25 +46,27 @@ def post_message(text, attachments=[]): link_names = 1, attachments = attachments, icon_emoji = icon_emoji) - + def get_user(id): user = slack.users.info(id).body return user['user']['name'] - + def get_channel(id): channel = slack.channels.info(id).body return channel['channel']['name'] - + def init(): global users + global idle_users global topics global time global in_progress - + if len(users) != 0: post_message('Looks like we have a standup already in process.') return users = standup_users() + idle_users = idle_users() topics = [] time = [] in_progress = True @@ -70,7 +74,7 @@ def init(): def start(): global time - + if len(time) != 0: post_message('But we\'ve already started!') return @@ -82,33 +86,35 @@ def cancel(): tabled() post_message('Standup is cancelled. Bye!') reset() - + def done(): global time - + time.append(datetime.datetime.now()) standup_time() tabled() post_message('Bye!') reset() - + def reset(): global users + global idle_users global topics global time global in_progress global current_user - + del users[:] + del idle_users[:] del topics[:] del time[:] in_progress = False current_user = '' - + def standup_users(): global ignore_users global absent_users - + ignore_users_array = eval(ignore_users) channel_id = ''; @@ -117,32 +123,38 @@ def standup_users(): for one_channel in all_channels.body['channels']: if one_channel['name'] == channel_name: channel_id = one_channel['id'] - + standup_room = slack.channels.info(channel_id).body['channel'] standup_users = standup_room['members'] active_users = [] - + for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] is_deleted = slack.users.info(user_id).body['user']['deleted'] if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) - + # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) - + return active_users def next(): global users global current_user - + global idle_users + global skip_idle_users + if len(users) == 0: done() else: current_user = users.pop() - post_message('@%s, you\'re up' % current_user) - + if skip_idle_users and current_user in idle_users: + post_message('Skipping @%s (idle)' % current_user) + next() + else: + post_message('@%s, you\'re up' % current_user) + def standup_time(): if len(time) != 2: return seconds = (time[1] - time[0]).total_seconds() @@ -152,18 +164,18 @@ def standup_time(): def left(): if len(users) == 0: post_message('That\'s everyone!') - else: + else: post_message('Here\'s who\'s left: @' + ', @'.join(users)) - + def ignore(user): global ignore_users global absent_users active_users = standup_users() - + if user == '': post_message('Who should I ignore?') return - + user = user[1:] if user not in active_users and user not in ignore_users and user not in absent_users: post_message('I don\'t recognize that user.') @@ -172,16 +184,16 @@ def ignore(user): elif user in active_users: absent_users.append(user) post_message('I won\'t call on @%s again until I am told to using !heed .' % user) - + def heed(user): global ignore_users global absent_users active_users = standup_users() - + if user == '': post_message('Who should I heed?') return - + user = user[1:] if user not in active_users and user not in ignore_users and user not in absent_users: post_message('I don\'t recognize that user.') @@ -192,18 +204,18 @@ def heed(user): elif user in absent_users: absent_users.remove(user) post_message('I\'ll start calling on @%s again at the next standup.' % user) - + def ignoring(): global ignore_users global absent_users - + if len(ignore_users) == 0 and len(absent_users) == 0: post_message('We\'re not ignoring anyone.') return - - if len(ignore_users) != 0: + + if len(ignore_users) != 0: post_message('Here\'s who we never call on: ' + ignore_users) - if len(absent_users) != 0: + if len(absent_users) != 0: post_message('Here\'s who we\'re ignoring for now: ' + ', '.join(absent_users)) def skip(): @@ -212,7 +224,7 @@ def skip(): def table(topic_user, topic): global topics - + channels = re.findall(r"<#(.*?)>", topic) users = re.findall(r"<@(.*?)>", topic) @@ -223,7 +235,7 @@ def table(topic_user, topic): for user in users: user_name = get_user(user) topic = topic.replace('<@%s>' % user, '@%s' % user_name) - + post_message('@%s: Tabled.' % topic_user) topics.append(str(topic)) @@ -232,12 +244,12 @@ def tabled(): post_message('Tabled topics:') for topic in topics: post_message('-%s' % topic) - + def giphy(text): url = 'http://api.giphy.com/v1/gifs/search?q=%s&api_key=dc6zaTOxFJmzC&limit=1' % urllib2.quote(text.encode("utf8")) response = urllib2.urlopen(url) data = json.loads(response.read()) - + if len(data['data']) == 0: post_message('Not sure what "%s" is.' % text) else: @@ -247,14 +259,35 @@ def giphy(text): 'title_link': data['data'][0]['url'], 'image_url': data['data'][0]['images']['fixed_height']['url'] }] - + post_message('Not sure what "%s" is.' % text, json.dumps(attachments)) +def idle_users(): + idle_users = [] + channel_id = '' + channel_name = channel.replace('#', '') # for some reason we skip the # in this API call + all_channels = slack.channels.list(1) # 1 means we skip any archived rooms + + for one_channel in all_channels.body['channels']: + if one_channel['name'] == channel_name: + channel_id = one_channel['id'] + + standup_room = slack.channels.info(channel_id).body['channel'] + standup_users = standup_room['members'] + + for user_id in standup_users: + user_name = slack.users.info(user_id).body['user']['name'] + if slack.users.get_presence(user_id).body['presence'] != 'active': + idle_users.append(user_name) + + return idle_users + + def help(topic=''): if topic == '': post_message('My commands are !standup, !start, !cancel, !next, !skip, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') return - + topic = topic[1:] if topic == 'standup' or topic == '!standup': post_message('Type !standup to initiate a new standup') @@ -296,7 +329,7 @@ def main(): command = match[0] args = text.replace("!%s" % command, '') command = command.lower() - + if command not in commands: if giphy: giphy(text[1:]) @@ -306,7 +339,7 @@ def main(): elif not in_progress and command != 'standup' and command != 'help' and command != 'ignore' and command != 'heed' and command != 'ignoring': post_message('Looks like standup hasn\'t started yet. Type !standup.') return json.dumps({ }) - + if command == 'standup': init() elif command == 'start': @@ -329,7 +362,7 @@ def main(): ignoring() elif command == 'help': help(args) - + return json.dumps({ }) if __name__ == "__main__": diff --git a/requirements.txt b/requirements.txt index 49b5644..b3439a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ Flask==0.10.1 requests==2.2.1 wsgiref==0.1.2 gunicorn==18.0 -slacker==0.4.0 +slacker==0.9.15 From 5cae237fa947b504e2bdd73f57461ed9b60283c4 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 14:22:47 -0400 Subject: [PATCH 05/33] Restore upstream whitespace for pull request, fix Slacker requirement to 0.5.4 where users.getPresence was added --- morgenbot.py | 75 ++++++++++++++++++++++++------------------------ requirements.txt | 2 +- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 9523612..cc152b2 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -46,22 +46,22 @@ def post_message(text, attachments=[]): link_names = 1, attachments = attachments, icon_emoji = icon_emoji) - + def get_user(id): user = slack.users.info(id).body return user['user']['name'] - + def get_channel(id): channel = slack.channels.info(id).body return channel['channel']['name'] - + def init(): global users global idle_users global topics global time global in_progress - + if len(users) != 0: post_message('Looks like we have a standup already in process.') return @@ -74,7 +74,7 @@ def init(): def start(): global time - + if len(time) != 0: post_message('But we\'ve already started!') return @@ -86,16 +86,16 @@ def cancel(): tabled() post_message('Standup is cancelled. Bye!') reset() - + def done(): global time - + time.append(datetime.datetime.now()) standup_time() tabled() post_message('Bye!') reset() - + def reset(): global users global idle_users @@ -103,18 +103,18 @@ def reset(): global time global in_progress global current_user - + del users[:] del idle_users[:] del topics[:] del time[:] in_progress = False current_user = '' - + def standup_users(): global ignore_users global absent_users - + ignore_users_array = eval(ignore_users) channel_id = ''; @@ -123,20 +123,20 @@ def standup_users(): for one_channel in all_channels.body['channels']: if one_channel['name'] == channel_name: channel_id = one_channel['id'] - + standup_room = slack.channels.info(channel_id).body['channel'] standup_users = standup_room['members'] active_users = [] - + for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] is_deleted = slack.users.info(user_id).body['user']['deleted'] if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) - + # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) - + return active_users def next(): @@ -144,7 +144,7 @@ def next(): global current_user global idle_users global skip_idle_users - + if len(users) == 0: done() else: @@ -164,18 +164,18 @@ def standup_time(): def left(): if len(users) == 0: post_message('That\'s everyone!') - else: + else: post_message('Here\'s who\'s left: @' + ', @'.join(users)) - + def ignore(user): global ignore_users global absent_users active_users = standup_users() - + if user == '': post_message('Who should I ignore?') return - + user = user[1:] if user not in active_users and user not in ignore_users and user not in absent_users: post_message('I don\'t recognize that user.') @@ -184,16 +184,16 @@ def ignore(user): elif user in active_users: absent_users.append(user) post_message('I won\'t call on @%s again until I am told to using !heed .' % user) - + def heed(user): global ignore_users global absent_users active_users = standup_users() - + if user == '': post_message('Who should I heed?') return - + user = user[1:] if user not in active_users and user not in ignore_users and user not in absent_users: post_message('I don\'t recognize that user.') @@ -204,18 +204,18 @@ def heed(user): elif user in absent_users: absent_users.remove(user) post_message('I\'ll start calling on @%s again at the next standup.' % user) - + def ignoring(): global ignore_users global absent_users - + if len(ignore_users) == 0 and len(absent_users) == 0: post_message('We\'re not ignoring anyone.') return - - if len(ignore_users) != 0: + + if len(ignore_users) != 0: post_message('Here\'s who we never call on: ' + ignore_users) - if len(absent_users) != 0: + if len(absent_users) != 0: post_message('Here\'s who we\'re ignoring for now: ' + ', '.join(absent_users)) def skip(): @@ -224,7 +224,7 @@ def skip(): def table(topic_user, topic): global topics - + channels = re.findall(r"<#(.*?)>", topic) users = re.findall(r"<@(.*?)>", topic) @@ -235,7 +235,7 @@ def table(topic_user, topic): for user in users: user_name = get_user(user) topic = topic.replace('<@%s>' % user, '@%s' % user_name) - + post_message('@%s: Tabled.' % topic_user) topics.append(str(topic)) @@ -244,12 +244,12 @@ def tabled(): post_message('Tabled topics:') for topic in topics: post_message('-%s' % topic) - + def giphy(text): url = 'http://api.giphy.com/v1/gifs/search?q=%s&api_key=dc6zaTOxFJmzC&limit=1' % urllib2.quote(text.encode("utf8")) response = urllib2.urlopen(url) data = json.loads(response.read()) - + if len(data['data']) == 0: post_message('Not sure what "%s" is.' % text) else: @@ -259,7 +259,7 @@ def giphy(text): 'title_link': data['data'][0]['url'], 'image_url': data['data'][0]['images']['fixed_height']['url'] }] - + post_message('Not sure what "%s" is.' % text, json.dumps(attachments)) def idle_users(): @@ -282,12 +282,11 @@ def idle_users(): return idle_users - def help(topic=''): if topic == '': post_message('My commands are !standup, !start, !cancel, !next, !skip, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') return - + topic = topic[1:] if topic == 'standup' or topic == '!standup': post_message('Type !standup to initiate a new standup') @@ -329,7 +328,7 @@ def main(): command = match[0] args = text.replace("!%s" % command, '') command = command.lower() - + if command not in commands: if giphy: giphy(text[1:]) @@ -339,7 +338,7 @@ def main(): elif not in_progress and command != 'standup' and command != 'help' and command != 'ignore' and command != 'heed' and command != 'ignoring': post_message('Looks like standup hasn\'t started yet. Type !standup.') return json.dumps({ }) - + if command == 'standup': init() elif command == 'start': @@ -362,7 +361,7 @@ def main(): ignoring() elif command == 'help': help(args) - + return json.dumps({ }) if __name__ == "__main__": diff --git a/requirements.txt b/requirements.txt index b3439a3..dff65d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ Flask==0.10.1 requests==2.2.1 wsgiref==0.1.2 gunicorn==18.0 -slacker==0.9.15 +slacker>=0.5.4 From 3194aabda74262940d5810b7747dd91a2e8dc948 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:01:33 -0400 Subject: [PATCH 06/33] Choose next user by passing username to "next" --- morgenbot.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index cc152b2..40d05a1 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -139,16 +139,26 @@ def standup_users(): return active_users -def next(): +def next(args): global users global current_user global idle_users global skip_idle_users - + if len(users) == 0: done() else: - current_user = users.pop() + if args: + next_user = args.split(' ')[0].replace('@', '') + if next_user in users: + current_user = next_user + users.remove(current_user) + else: + post_message('I don\'t recognize "@%s". Moving on...' % args) + current_user = users.pop() + else: + current_user = users.pop() + if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) next() @@ -346,7 +356,7 @@ def main(): elif command == 'cancel': cancel() elif command == 'next': - next() + next(args) elif command == 'skip': skip() elif command == 'table': From 3c3a3e48b62489f4d0ed6e18d2f68256f71570ba Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:10:10 -0400 Subject: [PATCH 07/33] Choose next user by passing username to "next" --- morgenbot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/morgenbot.py b/morgenbot.py index 40d05a1..d01d9c2 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -150,12 +150,13 @@ def next(args): else: if args: next_user = args.split(' ')[0].replace('@', '') + if next_user in users: current_user = next_user users.remove(current_user) else: post_message('I don\'t recognize "@%s". Moving on...' % args) - current_user = users.pop() + next() else: current_user = users.pop() From 70dca4f89637266b8a63b520001104fe1b01c804 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:12:36 -0400 Subject: [PATCH 08/33] Choose next user by passing username to "next" --- morgenbot.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index d01d9c2..0eaacc2 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -163,8 +163,7 @@ def next(args): if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) next() - else: - post_message('@%s, you\'re up' % current_user) + post_message('@%s, you\'re up' % current_user) def standup_time(): if len(time) != 2: return From 198a19a93d00ec943b8b037087a7e900141ff2a1 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:15:51 -0400 Subject: [PATCH 09/33] Choose next user by passing username to "next" --- morgenbot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 0eaacc2..e0859f2 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -149,8 +149,7 @@ def next(args): done() else: if args: - next_user = args.split(' ')[0].replace('@', '') - + next_user = args.strip().split(' ')[0].replace('@', '') if next_user in users: current_user = next_user users.remove(current_user) @@ -163,6 +162,7 @@ def next(args): if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) next() + post_message('@%s, you\'re up' % current_user) def standup_time(): From de363e5001fc5eb4d9e2467ba3222e744a543e1c Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:24:45 -0400 Subject: [PATCH 10/33] Choose next user by passing username to "next" --- morgenbot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index e0859f2..6eda8e5 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -148,10 +148,10 @@ def next(args): if len(users) == 0: done() else: + post_message 'args is "%s"' % args if args: - next_user = args.strip().split(' ')[0].replace('@', '') - if next_user in users: - current_user = next_user + current_user = args.strip().split(' ')[0].replace('@', '') + if current_user in users: users.remove(current_user) else: post_message('I don\'t recognize "@%s". Moving on...' % args) From 241acd2ce961de1cbb080d45bef80f9dc3b6c353 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:25:36 -0400 Subject: [PATCH 11/33] Choose next user by passing username to "next" --- morgenbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morgenbot.py b/morgenbot.py index 6eda8e5..d612a0f 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -148,7 +148,7 @@ def next(args): if len(users) == 0: done() else: - post_message 'args is "%s"' % args + post_message('args is "%s"' % args) if args: current_user = args.strip().split(' ')[0].replace('@', '') if current_user in users: From 01aafcb6a0cf2b0bf2962fbb73b26d2244566365 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:28:54 -0400 Subject: [PATCH 12/33] Choose next user by passing username to "next" --- morgenbot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index d612a0f..6a5c955 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -80,7 +80,7 @@ def start(): return time.append(datetime.datetime.now()) post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) - next() + next(False) def cancel(): tabled() @@ -155,13 +155,13 @@ def next(args): users.remove(current_user) else: post_message('I don\'t recognize "@%s". Moving on...' % args) - next() + next(False) else: current_user = users.pop() if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) - next() + next(False) post_message('@%s, you\'re up' % current_user) @@ -230,7 +230,7 @@ def ignoring(): def skip(): post_message('Skipping @%s.' % current_user) - next() + next(False) def table(topic_user, topic): global topics From 6765f5b144e32e1070e118aacb698bb4963c31a4 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:31:15 -0400 Subject: [PATCH 13/33] Choose next user by passing username to "next" --- morgenbot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/morgenbot.py b/morgenbot.py index 6a5c955..ebcae64 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -148,7 +148,6 @@ def next(args): if len(users) == 0: done() else: - post_message('args is "%s"' % args) if args: current_user = args.strip().split(' ')[0].replace('@', '') if current_user in users: From 08da43008c36f49cc27cfafab76479a1157c6af7 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 17:56:49 -0400 Subject: [PATCH 14/33] Choose next user by passing username to "next" --- morgenbot.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index ebcae64..1bb7e11 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -80,7 +80,7 @@ def start(): return time.append(datetime.datetime.now()) post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) - next(False) + next(None) def cancel(): tabled() @@ -152,15 +152,16 @@ def next(args): current_user = args.strip().split(' ')[0].replace('@', '') if current_user in users: users.remove(current_user) + post_message('Removed %s. Users left: %s' % (current_user, ', '.join(users))) else: post_message('I don\'t recognize "@%s". Moving on...' % args) - next(False) + next(None) else: current_user = users.pop() if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) - next(False) + next(None) post_message('@%s, you\'re up' % current_user) @@ -229,7 +230,7 @@ def ignoring(): def skip(): post_message('Skipping @%s.' % current_user) - next(False) + next(None) def table(topic_user, topic): global topics From 34e7dde3ebe71236d04220300622af05414aee7e Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 18:16:22 -0400 Subject: [PATCH 15/33] Choose next user by passing username to "next" --- morgenbot.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/morgenbot.py b/morgenbot.py index 1bb7e11..ba156cc 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -149,14 +149,17 @@ def next(args): done() else: if args: + print 'args is set' current_user = args.strip().split(' ')[0].replace('@', '') if current_user in users: users.remove(current_user) - post_message('Removed %s. Users left: %s' % (current_user, ', '.join(users))) + print 'removed %s. Users left: %s' % (current_user, ', '.join(users)) else: + print 'Didn\'t recognize %s' % args post_message('I don\'t recognize "@%s". Moving on...' % args) next(None) else: + print 'args is NOT set' current_user = users.pop() if skip_idle_users and current_user in idle_users: From 21c9703a744ecf2c3249fb21f373e7fc069ae537 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 18:26:11 -0400 Subject: [PATCH 16/33] Choose next user by passing username to "next" --- morgenbot.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index ba156cc..543b181 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -149,17 +149,13 @@ def next(args): done() else: if args: - print 'args is set' current_user = args.strip().split(' ')[0].replace('@', '') if current_user in users: users.remove(current_user) - print 'removed %s. Users left: %s' % (current_user, ', '.join(users)) else: - print 'Didn\'t recognize %s' % args post_message('I don\'t recognize "@%s". Moving on...' % args) - next(None) + current_user = users.pop() else: - print 'args is NOT set' current_user = users.pop() if skip_idle_users and current_user in idle_users: From 01019e55ff215ed5cebe2a2ab4fe1a3eaa481175 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 19:23:07 -0400 Subject: [PATCH 17/33] Choose next user by passing username to "next" --- morgenbot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/morgenbot.py b/morgenbot.py index 543b181..f14a53b 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -148,6 +148,7 @@ def next(args): if len(users) == 0: done() else: + post_message('Starting with: %s' % ', '.join(users)) if args: current_user = args.strip().split(' ')[0].replace('@', '') if current_user in users: @@ -163,6 +164,7 @@ def next(args): next(None) post_message('@%s, you\'re up' % current_user) + post_message('Remaining: %s' % ', '.join(users)) def standup_time(): if len(time) != 2: return From f99424ac4dc357b4a5071ae58cc82858bd70e1db Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 20:00:08 -0400 Subject: [PATCH 18/33] Choose next user by passing username to "next" --- morgenbot.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index f14a53b..cddebf4 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -148,7 +148,6 @@ def next(args): if len(users) == 0: done() else: - post_message('Starting with: %s' % ', '.join(users)) if args: current_user = args.strip().split(' ')[0].replace('@', '') if current_user in users: @@ -161,10 +160,8 @@ def next(args): if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) - next(None) - - post_message('@%s, you\'re up' % current_user) - post_message('Remaining: %s' % ', '.join(users)) + else: + post_message('@%s, you\'re up' % current_user) def standup_time(): if len(time) != 2: return From 7317afc63a640a6ee98fe3fd6b578bb8da022d8a Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 20:08:48 -0400 Subject: [PATCH 19/33] Choose next user by passing username to "next" --- morgenbot.py | 1 + 1 file changed, 1 insertion(+) diff --git a/morgenbot.py b/morgenbot.py index cddebf4..bf8df07 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -160,6 +160,7 @@ def next(args): if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) + next(None) else: post_message('@%s, you\'re up' % current_user) From e08cbec95ec4a1c4f23a2c035c4c47de5d9d416f Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 20:15:10 -0400 Subject: [PATCH 20/33] Choose next user by passing username to "next" --- morgenbot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/morgenbot.py b/morgenbot.py index bf8df07..80a7797 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -160,7 +160,8 @@ def next(args): if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) - next(None) + if users: + next(None) else: post_message('@%s, you\'re up' % current_user) From 718accae9cd9dedade9f3fef4e77ab67aeae2856 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 20:19:54 -0400 Subject: [PATCH 21/33] Choose next user by passing username to "next" --- morgenbot.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 80a7797..ff278ac 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -151,16 +151,13 @@ def next(args): if args: current_user = args.strip().split(' ')[0].replace('@', '') if current_user in users: - users.remove(current_user) - else: - post_message('I don\'t recognize "@%s". Moving on...' % args) - current_user = users.pop() - else: - current_user = users.pop() + users.insert(0, users.pop(users.index(current_user))) + + current_user = users.pop() if skip_idle_users and current_user in idle_users: post_message('Skipping @%s (idle)' % current_user) - if users: + if len(users) != 0: next(None) else: post_message('@%s, you\'re up' % current_user) From 984daee5b2888fc4aa0c8fadec45cd0ea146787b Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 20:41:06 -0400 Subject: [PATCH 22/33] Choose next user by passing username to "next" --- morgenbot.py | 54 ++++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index ff278ac..4bd48ac 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -31,7 +31,6 @@ commands = ['standup','start','cancel','next','skip','table','left','ignore','heed','ignoring','help'] users = [] -idle_users = [] topics = [] time = [] in_progress = False @@ -57,7 +56,6 @@ def get_channel(id): def init(): global users - global idle_users global topics global time global in_progress @@ -66,7 +64,6 @@ def init(): post_message('Looks like we have a standup already in process.') return users = standup_users() - idle_users = idle_users() topics = [] time = [] in_progress = True @@ -74,12 +71,15 @@ def init(): def start(): global time + global users if len(time) != 0: post_message('But we\'ve already started!') return time.append(datetime.datetime.now()) + post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) + next(None) def cancel(): @@ -98,14 +98,12 @@ def done(): def reset(): global users - global idle_users global topics global time global in_progress global current_user del users[:] - del idle_users[:] del topics[:] del time[:] in_progress = False @@ -114,6 +112,7 @@ def reset(): def standup_users(): global ignore_users global absent_users + global skip_idle_users ignore_users_array = eval(ignore_users) @@ -131,7 +130,8 @@ def standup_users(): for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] is_deleted = slack.users.info(user_id).body['user']['deleted'] - if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: + is_idle = skip_idle_users and slack.users.get_presence(user_id).body['presence'] != 'active' + if not is_idle and not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) # don't forget to shuffle so we don't go in the same order every day! @@ -142,25 +142,23 @@ def standup_users(): def next(args): global users global current_user - global idle_users global skip_idle_users if len(users) == 0: done() else: if args: - current_user = args.strip().split(' ')[0].replace('@', '') - if current_user in users: - users.insert(0, users.pop(users.index(current_user))) - - current_user = users.pop() - - if skip_idle_users and current_user in idle_users: - post_message('Skipping @%s (idle)' % current_user) - if len(users) != 0: - next(None) + args = args.strip() + next_user = args.split(' ')[0].replace('@', '') + if next_user in users: + current_user = users.pop(users.index(next_user)) + else: + post_message('I don\'t recognize "%s". Moving on...' % args) + current_user = users.pop() else: - post_message('@%s, you\'re up' % current_user) + current_user = users.pop() + + post_message('@%s, you\'re up' % current_user) def standup_time(): if len(time) != 2: return @@ -269,26 +267,6 @@ def giphy(text): post_message('Not sure what "%s" is.' % text, json.dumps(attachments)) -def idle_users(): - idle_users = [] - channel_id = '' - channel_name = channel.replace('#', '') # for some reason we skip the # in this API call - all_channels = slack.channels.list(1) # 1 means we skip any archived rooms - - for one_channel in all_channels.body['channels']: - if one_channel['name'] == channel_name: - channel_id = one_channel['id'] - - standup_room = slack.channels.info(channel_id).body['channel'] - standup_users = standup_room['members'] - - for user_id in standup_users: - user_name = slack.users.info(user_id).body['user']['name'] - if slack.users.get_presence(user_id).body['presence'] != 'active': - idle_users.append(user_name) - - return idle_users - def help(topic=''): if topic == '': post_message('My commands are !standup, !start, !cancel, !next, !skip, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') From e29027cdd484e6604a10fc817a6802452ce51951 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 20:45:27 -0400 Subject: [PATCH 23/33] Choose next user by passing username to "next" --- morgenbot.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/morgenbot.py b/morgenbot.py index 4bd48ac..d62b6cd 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -36,6 +36,7 @@ in_progress = False current_user = '' absent_users = [] +idle_users = [] def post_message(text, attachments=[]): slack.chat.post_message(channel = channel, @@ -72,12 +73,17 @@ def init(): def start(): global time global users + global skip_idle_users + global idle_users if len(time) != 0: post_message('But we\'ve already started!') return time.append(datetime.datetime.now()) + if skip_idle_users and idle_users: + post_message('Skipping idle users: @' + ', @'.join(idle_users)) + post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) next(None) @@ -113,6 +119,7 @@ def standup_users(): global ignore_users global absent_users global skip_idle_users + global idle_users ignore_users_array = eval(ignore_users) @@ -133,6 +140,9 @@ def standup_users(): is_idle = skip_idle_users and slack.users.get_presence(user_id).body['presence'] != 'active' if not is_idle and not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) + + if is_idle: + idle_users.append(user_name) # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) From f3244197071020db832c0d5677fc63d3c1916a3e Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 20:49:00 -0400 Subject: [PATCH 24/33] Choose next user by passing username to "next" --- morgenbot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/morgenbot.py b/morgenbot.py index d62b6cd..bfc8452 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -64,6 +64,7 @@ def init(): if len(users) != 0: post_message('Looks like we have a standup already in process.') return + idle_users = [] users = standup_users() topics = [] time = [] @@ -110,6 +111,7 @@ def reset(): global current_user del users[:] + del idle_users[:] del topics[:] del time[:] in_progress = False From 04566a2d19df89b8ddbe53df14c4be05eb042d77 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 20:51:45 -0400 Subject: [PATCH 25/33] Choose next user by passing username to "next" --- morgenbot.py | 69 +++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index cc152b2..bfc8452 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -31,12 +31,12 @@ commands = ['standup','start','cancel','next','skip','table','left','ignore','heed','ignoring','help'] users = [] -idle_users = [] topics = [] time = [] in_progress = False current_user = '' absent_users = [] +idle_users = [] def post_message(text, attachments=[]): slack.chat.post_message(channel = channel, @@ -57,7 +57,6 @@ def get_channel(id): def init(): global users - global idle_users global topics global time global in_progress @@ -65,8 +64,8 @@ def init(): if len(users) != 0: post_message('Looks like we have a standup already in process.') return + idle_users = [] users = standup_users() - idle_users = idle_users() topics = [] time = [] in_progress = True @@ -74,13 +73,21 @@ def init(): def start(): global time + global users + global skip_idle_users + global idle_users if len(time) != 0: post_message('But we\'ve already started!') return time.append(datetime.datetime.now()) + + if skip_idle_users and idle_users: + post_message('Skipping idle users: @' + ', @'.join(idle_users)) + post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) - next() + + next(None) def cancel(): tabled() @@ -98,7 +105,6 @@ def done(): def reset(): global users - global idle_users global topics global time global in_progress @@ -114,6 +120,8 @@ def reset(): def standup_users(): global ignore_users global absent_users + global skip_idle_users + global idle_users ignore_users_array = eval(ignore_users) @@ -131,29 +139,38 @@ def standup_users(): for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] is_deleted = slack.users.info(user_id).body['user']['deleted'] - if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: + is_idle = skip_idle_users and slack.users.get_presence(user_id).body['presence'] != 'active' + if not is_idle and not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) + + if is_idle: + idle_users.append(user_name) # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) return active_users -def next(): +def next(args): global users global current_user - global idle_users global skip_idle_users - + if len(users) == 0: done() else: - current_user = users.pop() - if skip_idle_users and current_user in idle_users: - post_message('Skipping @%s (idle)' % current_user) - next() + if args: + args = args.strip() + next_user = args.split(' ')[0].replace('@', '') + if next_user in users: + current_user = users.pop(users.index(next_user)) + else: + post_message('I don\'t recognize "%s". Moving on...' % args) + current_user = users.pop() else: - post_message('@%s, you\'re up' % current_user) + current_user = users.pop() + + post_message('@%s, you\'re up' % current_user) def standup_time(): if len(time) != 2: return @@ -220,7 +237,7 @@ def ignoring(): def skip(): post_message('Skipping @%s.' % current_user) - next() + next(None) def table(topic_user, topic): global topics @@ -262,26 +279,6 @@ def giphy(text): post_message('Not sure what "%s" is.' % text, json.dumps(attachments)) -def idle_users(): - idle_users = [] - channel_id = '' - channel_name = channel.replace('#', '') # for some reason we skip the # in this API call - all_channels = slack.channels.list(1) # 1 means we skip any archived rooms - - for one_channel in all_channels.body['channels']: - if one_channel['name'] == channel_name: - channel_id = one_channel['id'] - - standup_room = slack.channels.info(channel_id).body['channel'] - standup_users = standup_room['members'] - - for user_id in standup_users: - user_name = slack.users.info(user_id).body['user']['name'] - if slack.users.get_presence(user_id).body['presence'] != 'active': - idle_users.append(user_name) - - return idle_users - def help(topic=''): if topic == '': post_message('My commands are !standup, !start, !cancel, !next, !skip, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') @@ -346,7 +343,7 @@ def main(): elif command == 'cancel': cancel() elif command == 'next': - next() + next(args) elif command == 'skip': skip() elif command == 'table': From 209bf6b0d61f0e216dcfba18a67e35bec3dd818d Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 21:59:56 -0400 Subject: [PATCH 26/33] Choose next user by passing username to "next" --- morgenbot.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index bfc8452..40d5468 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -60,6 +60,7 @@ def init(): global topics global time global in_progress + global idle_users if len(users) != 0: post_message('Looks like we have a standup already in process.') @@ -154,21 +155,19 @@ def standup_users(): def next(args): global users global current_user - global skip_idle_users + next_user_index = 0 if len(users) == 0: done() else: if args: - args = args.strip() next_user = args.split(' ')[0].replace('@', '') if next_user in users: - current_user = users.pop(users.index(next_user)) + next_user_index = users.index(next_user) else: post_message('I don\'t recognize "%s". Moving on...' % args) - current_user = users.pop() - else: - current_user = users.pop() + + current_user = users.pop(next_user_index) post_message('@%s, you\'re up' % current_user) @@ -343,7 +342,7 @@ def main(): elif command == 'cancel': cancel() elif command == 'next': - next(args) + next(args.strip()) elif command == 'skip': skip() elif command == 'table': From 9c763cad9fe9e54f07a1eb85ee989256aba5357d Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 22:06:44 -0400 Subject: [PATCH 27/33] Revert "Choose next user by passing username to "next"" This reverts commit 04566a2d19df89b8ddbe53df14c4be05eb042d77. --- morgenbot.py | 69 +++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index bfc8452..cc152b2 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -31,12 +31,12 @@ commands = ['standup','start','cancel','next','skip','table','left','ignore','heed','ignoring','help'] users = [] +idle_users = [] topics = [] time = [] in_progress = False current_user = '' absent_users = [] -idle_users = [] def post_message(text, attachments=[]): slack.chat.post_message(channel = channel, @@ -57,6 +57,7 @@ def get_channel(id): def init(): global users + global idle_users global topics global time global in_progress @@ -64,8 +65,8 @@ def init(): if len(users) != 0: post_message('Looks like we have a standup already in process.') return - idle_users = [] users = standup_users() + idle_users = idle_users() topics = [] time = [] in_progress = True @@ -73,21 +74,13 @@ def init(): def start(): global time - global users - global skip_idle_users - global idle_users if len(time) != 0: post_message('But we\'ve already started!') return time.append(datetime.datetime.now()) - - if skip_idle_users and idle_users: - post_message('Skipping idle users: @' + ', @'.join(idle_users)) - post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) - - next(None) + next() def cancel(): tabled() @@ -105,6 +98,7 @@ def done(): def reset(): global users + global idle_users global topics global time global in_progress @@ -120,8 +114,6 @@ def reset(): def standup_users(): global ignore_users global absent_users - global skip_idle_users - global idle_users ignore_users_array = eval(ignore_users) @@ -139,38 +131,29 @@ def standup_users(): for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] is_deleted = slack.users.info(user_id).body['user']['deleted'] - is_idle = skip_idle_users and slack.users.get_presence(user_id).body['presence'] != 'active' - if not is_idle and not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: + if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) - - if is_idle: - idle_users.append(user_name) # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) return active_users -def next(args): +def next(): global users global current_user + global idle_users global skip_idle_users - + if len(users) == 0: done() else: - if args: - args = args.strip() - next_user = args.split(' ')[0].replace('@', '') - if next_user in users: - current_user = users.pop(users.index(next_user)) - else: - post_message('I don\'t recognize "%s". Moving on...' % args) - current_user = users.pop() + current_user = users.pop() + if skip_idle_users and current_user in idle_users: + post_message('Skipping @%s (idle)' % current_user) + next() else: - current_user = users.pop() - - post_message('@%s, you\'re up' % current_user) + post_message('@%s, you\'re up' % current_user) def standup_time(): if len(time) != 2: return @@ -237,7 +220,7 @@ def ignoring(): def skip(): post_message('Skipping @%s.' % current_user) - next(None) + next() def table(topic_user, topic): global topics @@ -279,6 +262,26 @@ def giphy(text): post_message('Not sure what "%s" is.' % text, json.dumps(attachments)) +def idle_users(): + idle_users = [] + channel_id = '' + channel_name = channel.replace('#', '') # for some reason we skip the # in this API call + all_channels = slack.channels.list(1) # 1 means we skip any archived rooms + + for one_channel in all_channels.body['channels']: + if one_channel['name'] == channel_name: + channel_id = one_channel['id'] + + standup_room = slack.channels.info(channel_id).body['channel'] + standup_users = standup_room['members'] + + for user_id in standup_users: + user_name = slack.users.info(user_id).body['user']['name'] + if slack.users.get_presence(user_id).body['presence'] != 'active': + idle_users.append(user_name) + + return idle_users + def help(topic=''): if topic == '': post_message('My commands are !standup, !start, !cancel, !next, !skip, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') @@ -343,7 +346,7 @@ def main(): elif command == 'cancel': cancel() elif command == 'next': - next(args) + next() elif command == 'skip': skip() elif command == 'table': From bfd3d74294af67bd1c8a6a10203074f81610f74b Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 22:06:55 -0400 Subject: [PATCH 28/33] Revert "Restore upstream whitespace for pull request, fix Slacker requirement to 0.5.4 where users.getPresence was added" This reverts commit 5cae237fa947b504e2bdd73f57461ed9b60283c4. --- morgenbot.py | 75 ++++++++++++++++++++++++------------------------ requirements.txt | 2 +- 2 files changed, 39 insertions(+), 38 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index cc152b2..9523612 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -46,22 +46,22 @@ def post_message(text, attachments=[]): link_names = 1, attachments = attachments, icon_emoji = icon_emoji) - + def get_user(id): user = slack.users.info(id).body return user['user']['name'] - + def get_channel(id): channel = slack.channels.info(id).body return channel['channel']['name'] - + def init(): global users global idle_users global topics global time global in_progress - + if len(users) != 0: post_message('Looks like we have a standup already in process.') return @@ -74,7 +74,7 @@ def init(): def start(): global time - + if len(time) != 0: post_message('But we\'ve already started!') return @@ -86,16 +86,16 @@ def cancel(): tabled() post_message('Standup is cancelled. Bye!') reset() - + def done(): global time - + time.append(datetime.datetime.now()) standup_time() tabled() post_message('Bye!') reset() - + def reset(): global users global idle_users @@ -103,18 +103,18 @@ def reset(): global time global in_progress global current_user - + del users[:] del idle_users[:] del topics[:] del time[:] in_progress = False current_user = '' - + def standup_users(): global ignore_users global absent_users - + ignore_users_array = eval(ignore_users) channel_id = ''; @@ -123,20 +123,20 @@ def standup_users(): for one_channel in all_channels.body['channels']: if one_channel['name'] == channel_name: channel_id = one_channel['id'] - + standup_room = slack.channels.info(channel_id).body['channel'] standup_users = standup_room['members'] active_users = [] - + for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] is_deleted = slack.users.info(user_id).body['user']['deleted'] if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) - + # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) - + return active_users def next(): @@ -144,7 +144,7 @@ def next(): global current_user global idle_users global skip_idle_users - + if len(users) == 0: done() else: @@ -164,18 +164,18 @@ def standup_time(): def left(): if len(users) == 0: post_message('That\'s everyone!') - else: + else: post_message('Here\'s who\'s left: @' + ', @'.join(users)) - + def ignore(user): global ignore_users global absent_users active_users = standup_users() - + if user == '': post_message('Who should I ignore?') return - + user = user[1:] if user not in active_users and user not in ignore_users and user not in absent_users: post_message('I don\'t recognize that user.') @@ -184,16 +184,16 @@ def ignore(user): elif user in active_users: absent_users.append(user) post_message('I won\'t call on @%s again until I am told to using !heed .' % user) - + def heed(user): global ignore_users global absent_users active_users = standup_users() - + if user == '': post_message('Who should I heed?') return - + user = user[1:] if user not in active_users and user not in ignore_users and user not in absent_users: post_message('I don\'t recognize that user.') @@ -204,18 +204,18 @@ def heed(user): elif user in absent_users: absent_users.remove(user) post_message('I\'ll start calling on @%s again at the next standup.' % user) - + def ignoring(): global ignore_users global absent_users - + if len(ignore_users) == 0 and len(absent_users) == 0: post_message('We\'re not ignoring anyone.') return - - if len(ignore_users) != 0: + + if len(ignore_users) != 0: post_message('Here\'s who we never call on: ' + ignore_users) - if len(absent_users) != 0: + if len(absent_users) != 0: post_message('Here\'s who we\'re ignoring for now: ' + ', '.join(absent_users)) def skip(): @@ -224,7 +224,7 @@ def skip(): def table(topic_user, topic): global topics - + channels = re.findall(r"<#(.*?)>", topic) users = re.findall(r"<@(.*?)>", topic) @@ -235,7 +235,7 @@ def table(topic_user, topic): for user in users: user_name = get_user(user) topic = topic.replace('<@%s>' % user, '@%s' % user_name) - + post_message('@%s: Tabled.' % topic_user) topics.append(str(topic)) @@ -244,12 +244,12 @@ def tabled(): post_message('Tabled topics:') for topic in topics: post_message('-%s' % topic) - + def giphy(text): url = 'http://api.giphy.com/v1/gifs/search?q=%s&api_key=dc6zaTOxFJmzC&limit=1' % urllib2.quote(text.encode("utf8")) response = urllib2.urlopen(url) data = json.loads(response.read()) - + if len(data['data']) == 0: post_message('Not sure what "%s" is.' % text) else: @@ -259,7 +259,7 @@ def giphy(text): 'title_link': data['data'][0]['url'], 'image_url': data['data'][0]['images']['fixed_height']['url'] }] - + post_message('Not sure what "%s" is.' % text, json.dumps(attachments)) def idle_users(): @@ -282,11 +282,12 @@ def idle_users(): return idle_users + def help(topic=''): if topic == '': post_message('My commands are !standup, !start, !cancel, !next, !skip, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') return - + topic = topic[1:] if topic == 'standup' or topic == '!standup': post_message('Type !standup to initiate a new standup') @@ -328,7 +329,7 @@ def main(): command = match[0] args = text.replace("!%s" % command, '') command = command.lower() - + if command not in commands: if giphy: giphy(text[1:]) @@ -338,7 +339,7 @@ def main(): elif not in_progress and command != 'standup' and command != 'help' and command != 'ignore' and command != 'heed' and command != 'ignoring': post_message('Looks like standup hasn\'t started yet. Type !standup.') return json.dumps({ }) - + if command == 'standup': init() elif command == 'start': @@ -361,7 +362,7 @@ def main(): ignoring() elif command == 'help': help(args) - + return json.dumps({ }) if __name__ == "__main__": diff --git a/requirements.txt b/requirements.txt index dff65d5..b3439a3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ Flask==0.10.1 requests==2.2.1 wsgiref==0.1.2 gunicorn==18.0 -slacker>=0.5.4 +slacker==0.9.15 From 95b5a8848a0c126d18b1fa90d9a2940a67a1777f Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 22:06:58 -0400 Subject: [PATCH 29/33] Revert "Add support for skipping idle users" This reverts commit a98597047591a1d7d7fc3577b0aaa6dfd0407a60. --- morgenbot.py | 111 +++++++++++++++++------------------------------ requirements.txt | 2 +- 2 files changed, 40 insertions(+), 73 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 9523612..3c9428d 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -21,7 +21,6 @@ icon_emoji = os.getenv('ICON_EMOJI', ':coffee:') channel = os.getenv('CHANNEL', '#standup') ignore_users = os.getenv('IGNORE_USERS', '[]') -skip_idle_users = False if os.getenv('SKIP_IDLE_USERS', 'true').lower() == 'false' else True init_greeting = os.getenv('INIT_GREETING', 'Good morning!') start_message = os.getenv('START_MESSAGE', 'What did you work on yesterday? What are you working on today? What, if any, are your blockers?') @@ -31,7 +30,6 @@ commands = ['standup','start','cancel','next','skip','table','left','ignore','heed','ignoring','help'] users = [] -idle_users = [] topics = [] time = [] in_progress = False @@ -46,27 +44,25 @@ def post_message(text, attachments=[]): link_names = 1, attachments = attachments, icon_emoji = icon_emoji) - + def get_user(id): user = slack.users.info(id).body return user['user']['name'] - + def get_channel(id): channel = slack.channels.info(id).body return channel['channel']['name'] - + def init(): global users - global idle_users global topics global time global in_progress - + if len(users) != 0: post_message('Looks like we have a standup already in process.') return users = standup_users() - idle_users = idle_users() topics = [] time = [] in_progress = True @@ -74,7 +70,7 @@ def init(): def start(): global time - + if len(time) != 0: post_message('But we\'ve already started!') return @@ -86,35 +82,33 @@ def cancel(): tabled() post_message('Standup is cancelled. Bye!') reset() - + def done(): global time - + time.append(datetime.datetime.now()) standup_time() tabled() post_message('Bye!') reset() - + def reset(): global users - global idle_users global topics global time global in_progress global current_user - + del users[:] - del idle_users[:] del topics[:] del time[:] in_progress = False current_user = '' - + def standup_users(): global ignore_users global absent_users - + ignore_users_array = eval(ignore_users) channel_id = ''; @@ -123,38 +117,32 @@ def standup_users(): for one_channel in all_channels.body['channels']: if one_channel['name'] == channel_name: channel_id = one_channel['id'] - + standup_room = slack.channels.info(channel_id).body['channel'] standup_users = standup_room['members'] active_users = [] - + for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] is_deleted = slack.users.info(user_id).body['user']['deleted'] if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) - + # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) - + return active_users def next(): global users global current_user - global idle_users - global skip_idle_users - + if len(users) == 0: done() else: current_user = users.pop() - if skip_idle_users and current_user in idle_users: - post_message('Skipping @%s (idle)' % current_user) - next() - else: - post_message('@%s, you\'re up' % current_user) - + post_message('@%s, you\'re up' % current_user) + def standup_time(): if len(time) != 2: return seconds = (time[1] - time[0]).total_seconds() @@ -164,18 +152,18 @@ def standup_time(): def left(): if len(users) == 0: post_message('That\'s everyone!') - else: + else: post_message('Here\'s who\'s left: @' + ', @'.join(users)) - + def ignore(user): global ignore_users global absent_users active_users = standup_users() - + if user == '': post_message('Who should I ignore?') return - + user = user[1:] if user not in active_users and user not in ignore_users and user not in absent_users: post_message('I don\'t recognize that user.') @@ -184,16 +172,16 @@ def ignore(user): elif user in active_users: absent_users.append(user) post_message('I won\'t call on @%s again until I am told to using !heed .' % user) - + def heed(user): global ignore_users global absent_users active_users = standup_users() - + if user == '': post_message('Who should I heed?') return - + user = user[1:] if user not in active_users and user not in ignore_users and user not in absent_users: post_message('I don\'t recognize that user.') @@ -204,18 +192,18 @@ def heed(user): elif user in absent_users: absent_users.remove(user) post_message('I\'ll start calling on @%s again at the next standup.' % user) - + def ignoring(): global ignore_users global absent_users - + if len(ignore_users) == 0 and len(absent_users) == 0: post_message('We\'re not ignoring anyone.') return - - if len(ignore_users) != 0: + + if len(ignore_users) != 0: post_message('Here\'s who we never call on: ' + ignore_users) - if len(absent_users) != 0: + if len(absent_users) != 0: post_message('Here\'s who we\'re ignoring for now: ' + ', '.join(absent_users)) def skip(): @@ -224,7 +212,7 @@ def skip(): def table(topic_user, topic): global topics - + channels = re.findall(r"<#(.*?)>", topic) users = re.findall(r"<@(.*?)>", topic) @@ -235,7 +223,7 @@ def table(topic_user, topic): for user in users: user_name = get_user(user) topic = topic.replace('<@%s>' % user, '@%s' % user_name) - + post_message('@%s: Tabled.' % topic_user) topics.append(str(topic)) @@ -244,12 +232,12 @@ def tabled(): post_message('Tabled topics:') for topic in topics: post_message('-%s' % topic) - + def giphy(text): url = 'http://api.giphy.com/v1/gifs/search?q=%s&api_key=dc6zaTOxFJmzC&limit=1' % urllib2.quote(text.encode("utf8")) response = urllib2.urlopen(url) data = json.loads(response.read()) - + if len(data['data']) == 0: post_message('Not sure what "%s" is.' % text) else: @@ -259,35 +247,14 @@ def giphy(text): 'title_link': data['data'][0]['url'], 'image_url': data['data'][0]['images']['fixed_height']['url'] }] - + post_message('Not sure what "%s" is.' % text, json.dumps(attachments)) -def idle_users(): - idle_users = [] - channel_id = '' - channel_name = channel.replace('#', '') # for some reason we skip the # in this API call - all_channels = slack.channels.list(1) # 1 means we skip any archived rooms - - for one_channel in all_channels.body['channels']: - if one_channel['name'] == channel_name: - channel_id = one_channel['id'] - - standup_room = slack.channels.info(channel_id).body['channel'] - standup_users = standup_room['members'] - - for user_id in standup_users: - user_name = slack.users.info(user_id).body['user']['name'] - if slack.users.get_presence(user_id).body['presence'] != 'active': - idle_users.append(user_name) - - return idle_users - - def help(topic=''): if topic == '': post_message('My commands are !standup, !start, !cancel, !next, !skip, !table, !left, !ignore, !heed, and !ignoring.\nAsk me "!help to learn what they do.') return - + topic = topic[1:] if topic == 'standup' or topic == '!standup': post_message('Type !standup to initiate a new standup') @@ -329,7 +296,7 @@ def main(): command = match[0] args = text.replace("!%s" % command, '') command = command.lower() - + if command not in commands: if giphy: giphy(text[1:]) @@ -339,7 +306,7 @@ def main(): elif not in_progress and command != 'standup' and command != 'help' and command != 'ignore' and command != 'heed' and command != 'ignoring': post_message('Looks like standup hasn\'t started yet. Type !standup.') return json.dumps({ }) - + if command == 'standup': init() elif command == 'start': @@ -362,7 +329,7 @@ def main(): ignoring() elif command == 'help': help(args) - + return json.dumps({ }) if __name__ == "__main__": diff --git a/requirements.txt b/requirements.txt index b3439a3..49b5644 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ Flask==0.10.1 requests==2.2.1 wsgiref==0.1.2 gunicorn==18.0 -slacker==0.9.15 +slacker==0.4.0 From 498d3f488045bd6669e33eda295882533e5537c6 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 22:21:24 -0400 Subject: [PATCH 30/33] Testing cleaner skip idle users --- morgenbot.py | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 40d5468..54df5e7 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -82,13 +82,10 @@ def start(): post_message('But we\'ve already started!') return time.append(datetime.datetime.now()) - if skip_idle_users and idle_users: post_message('Skipping idle users: @' + ', @'.join(idle_users)) - post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) - - next(None) + next() def cancel(): tabled() @@ -143,8 +140,7 @@ def standup_users(): is_idle = skip_idle_users and slack.users.get_presence(user_id).body['presence'] != 'active' if not is_idle and not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) - - if is_idle: + else if is_idle: idle_users.append(user_name) # don't forget to shuffle so we don't go in the same order every day! @@ -152,25 +148,16 @@ def standup_users(): return active_users -def next(args): +def next(): global users global current_user - next_user_index = 0 - + if len(users) == 0: done() else: - if args: - next_user = args.split(' ')[0].replace('@', '') - if next_user in users: - next_user_index = users.index(next_user) - else: - post_message('I don\'t recognize "%s". Moving on...' % args) - - current_user = users.pop(next_user_index) - + current_user = users.pop() post_message('@%s, you\'re up' % current_user) - + def standup_time(): if len(time) != 2: return seconds = (time[1] - time[0]).total_seconds() @@ -236,7 +223,7 @@ def ignoring(): def skip(): post_message('Skipping @%s.' % current_user) - next(None) + next() def table(topic_user, topic): global topics @@ -342,7 +329,7 @@ def main(): elif command == 'cancel': cancel() elif command == 'next': - next(args.strip()) + next() elif command == 'skip': skip() elif command == 'table': From 69d54a11a4e50e77be81153e83d1ff26a8822328 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 22:23:54 -0400 Subject: [PATCH 31/33] Testing cleaner skip idle users --- morgenbot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morgenbot.py b/morgenbot.py index 54df5e7..1a720bd 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -140,7 +140,7 @@ def standup_users(): is_idle = skip_idle_users and slack.users.get_presence(user_id).body['presence'] != 'active' if not is_idle and not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) - else if is_idle: + elif is_idle: idle_users.append(user_name) # don't forget to shuffle so we don't go in the same order every day! From 4d82b4b50d0e054f73b955e763d0d9ee288233a2 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Wed, 18 May 2016 22:30:26 -0400 Subject: [PATCH 32/33] Add support for skipping idle users --- morgenbot.py | 17 ++++++++++++++++- requirements.txt | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 3c9428d..1a720bd 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -21,6 +21,7 @@ icon_emoji = os.getenv('ICON_EMOJI', ':coffee:') channel = os.getenv('CHANNEL', '#standup') ignore_users = os.getenv('IGNORE_USERS', '[]') +skip_idle_users = False if os.getenv('SKIP_IDLE_USERS', 'true').lower() == 'false' else True init_greeting = os.getenv('INIT_GREETING', 'Good morning!') start_message = os.getenv('START_MESSAGE', 'What did you work on yesterday? What are you working on today? What, if any, are your blockers?') @@ -35,6 +36,7 @@ in_progress = False current_user = '' absent_users = [] +idle_users = [] def post_message(text, attachments=[]): slack.chat.post_message(channel = channel, @@ -58,10 +60,12 @@ def init(): global topics global time global in_progress + global idle_users if len(users) != 0: post_message('Looks like we have a standup already in process.') return + idle_users = [] users = standup_users() topics = [] time = [] @@ -70,11 +74,16 @@ def init(): def start(): global time + global users + global skip_idle_users + global idle_users if len(time) != 0: post_message('But we\'ve already started!') return time.append(datetime.datetime.now()) + if skip_idle_users and idle_users: + post_message('Skipping idle users: @' + ', @'.join(idle_users)) post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) next() @@ -100,6 +109,7 @@ def reset(): global current_user del users[:] + del idle_users[:] del topics[:] del time[:] in_progress = False @@ -108,6 +118,8 @@ def reset(): def standup_users(): global ignore_users global absent_users + global skip_idle_users + global idle_users ignore_users_array = eval(ignore_users) @@ -125,8 +137,11 @@ def standup_users(): for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] is_deleted = slack.users.info(user_id).body['user']['deleted'] - if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: + is_idle = skip_idle_users and slack.users.get_presence(user_id).body['presence'] != 'active' + if not is_idle and not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) + elif is_idle: + idle_users.append(user_name) # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) diff --git a/requirements.txt b/requirements.txt index 49b5644..dff65d5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,4 @@ Flask==0.10.1 requests==2.2.1 wsgiref==0.1.2 gunicorn==18.0 -slacker==0.4.0 +slacker>=0.5.4 From a2d2479d581558e348be38e4c4d9b516d4e43880 Mon Sep 17 00:00:00 2001 From: Bill Edgington Date: Thu, 19 May 2016 16:11:32 -0400 Subject: [PATCH 33/33] Add !next @user support, add !later support, skip idle users just-in-time instead of at start of standup --- morgenbot.py | 89 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 26 deletions(-) diff --git a/morgenbot.py b/morgenbot.py index 16c80cf..819e6d0 100644 --- a/morgenbot.py +++ b/morgenbot.py @@ -37,7 +37,8 @@ in_progress = False current_user = '' absent_users = [] -idle_users = [] +user_ids = {} +user_names = {} def post_message(text, attachments=[]): slack.chat.post_message(channel = channel, @@ -61,12 +62,10 @@ def init(): global topics global time global in_progress - global idle_users - + if len(users) != 0: post_message('Looks like we have a standup already in process.') return - idle_users = [] users = standup_users() topics = [] time = [] @@ -76,17 +75,13 @@ def init(): def start(): global time global users - global skip_idle_users - global idle_users if len(time) != 0: post_message('But we\'ve already started!') return time.append(datetime.datetime.now()) - if skip_idle_users and idle_users: - post_message('Skipping idle users: @' + ', @'.join(idle_users)) post_message('Let\'s get started! %s\nWhen you\'re done, please type !next' % start_message) - next() + next(None) def cancel(): tabled() @@ -104,13 +99,16 @@ def done(): def reset(): global users + global user_ids + global user_names global topics global time global in_progress global current_user - + del users[:] - del idle_users[:] + del user_ids[:] + del user_names[:] del topics[:] del time[:] in_progress = False @@ -119,8 +117,8 @@ def reset(): def standup_users(): global ignore_users global absent_users - global skip_idle_users - global idle_users + global user_ids + global user_names ignore_users_array = eval(ignore_users) @@ -137,33 +135,67 @@ def standup_users(): for user_id in standup_users: user_name = slack.users.info(user_id).body['user']['name'] + user_ids[user_name] = user_id + user_names[user_id] = user_name is_deleted = slack.users.info(user_id).body['user']['deleted'] - is_idle = skip_idle_users and slack.users.get_presence(user_id).body['presence'] != 'active' - if not is_idle and not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: + if not is_deleted and user_name not in ignore_users_array and user_name not in absent_users: active_users.append(user_name) - elif is_idle: - idle_users.append(user_name) # don't forget to shuffle so we don't go in the same order every day! random.shuffle(active_users) return active_users -def next(): +def next(args): global users global current_user + global ignore_users + global absent_users + global user_ids + global user_names + active_users = standup_users() + next_user_index = 0 if len(users) == 0: done() else: - current_user = users.pop() - post_message('@%s, you\'re up' % current_user) + if args is not None and args != '': + search_obj = re.search(ur'<@([^>]+)>', args) + if search_obj is not None: + user_id = search_obj.group(1) + if user_id in user_names: + user = user_names[user_id] + else: + user = '' + else: + user = args.strip().replace('@', '') + if user == current_user: + post_message('That makes no sense.'); + next_user_index = 0; + elif user not in active_users and user not in ignore_users and user not in absent_users: + post_message('I don\'t recognize that user.') + elif user in ignore_users: + post_message('I\'m already ignoring that user.') + elif user in absent_users: + post_message('That user is absent.') + elif user in active_users: + next_user_index = users.index(user) + current_user = users.pop(next_user_index) + + if skip_idle_users and slack.users.get_presence(user_ids[current_user]).body['presence'] != 'active': + post_message('Skipping @%s (idle).' % current_user) + next(None) + else: + post_message('@%s, you\'re up' % current_user) def standup_time(): if len(time) != 2: return seconds = (time[1] - time[0]).total_seconds() minutes = seconds / 60 - post_message('That\'s everyone! Standup took us %d minutes.' % minutes) + if minutes < 1: + post_message('That\'s everyone! Standup took us %d seconds.' % seconds) + else: + post_message('That\'s everyone! Standup took us %d minutes.' % minutes) def left(): if len(users) == 0: @@ -224,12 +256,17 @@ def ignoring(): def skip(): post_message('Skipping @%s.' % current_user) - next() + next(None) def later(): - post_message('We\'ll call on @%s later.' % current_user) - users.append(current_user) - next() + global users + if len(users) > 1: + post_message('We\'ll call on @%s later.' % current_user) + users.append(current_user) + else: + post_message('We can\'t call on @%s later. @%s is the last one left.' % (current_user, current_user)) + users.insert(current_user) + next(None) def table(topic_user, topic): global topics @@ -340,7 +377,7 @@ def main(): elif command == 'cancel': cancel() elif command == 'next': - next() + next(args) elif command == 'skip': skip() elif command == 'later':