Skip to content

Instantly share code, notes, and snippets.

@ftobia
Created September 7, 2018 17:26
Show Gist options
  • Save ftobia/e7040792bf6f86d35dd58a887d6d258a to your computer and use it in GitHub Desktop.
Save ftobia/e7040792bf6f86d35dd58a887d6d258a to your computer and use it in GitHub Desktop.
"""
FSEND standup bot script.
Calls on people via MacOS's "say" command.
Tracks timings for how long different parts of the standup take.
Code is written in Python 3
"""
import datetime
import random
import json
import subprocess
class Standup:
prompt_strings = [
'Status time, {}!',
"{}, why don't you go ahead?",
"{}, what's up?",
"How's it going {}?",
"{}, how's it going?",
'{}, can you give your status please?',
'{}, could you please give your status?',
'Could you please give your status, {}?',
'Would you go ahead {}?',
"{}, you're up.",
]
def doit(self):
timer = Timer()
timer.start()
# Prompt for attendance.
missing = input('Is anyone missing? ')
timer.event('Standup intro')
print()
if 'no' not in missing.strip().lower():
missing_peeps = [p.strip().lower() for p in missing.split(',')]
else:
missing_peeps = []
attendees = Attendees(missing_peeps)
# Say what the schedule is.
print('First up: pass-up pass-down')
print('Second: QA status')
print('Lastly: Dev status')
potential_arrivals = input('Are you done with pass-up pass-down yet? ')
print()
print("Here's the order for today:")
print('\n'.join([a.capitalize() for a in attendees.remaining()]))
attendees.parse_potential_arrivals(potential_arrivals)
while attendees.remaining():
print()
prompt_fmt = random.choice(self.prompt_strings)
self.prompt_strings.remove(prompt_fmt)
next_attendee = attendees.next().capitalize()
prompt_str = prompt_fmt.format(next_attendee)
subprocess.Popen(['say', '-v', 'Samantha', '-r', '250', prompt_str])
timer.event(next_attendee)
potential_arrivals = input(prompt_str + ' ')
attendees.parse_potential_arrivals(potential_arrivals)
timer.event('OUTRO')
print("I think that's it!")
input('Is there anything else?')
timer.stop()
timer.write()
class Attendees:
qa = ['renuka', 'scott', 'yidie']
devs = ['ian', 'rob', 'dennis',
'casey', 'charlie',
'frank']
def __init__(self, missing_peeps=None):
self.ordered_peeps = \
sorted(self.qa, key=lambda x: random.random()) + \
sorted(self.devs, key=lambda x: random.random())
self.statuses_given = []
for person in (missing_peeps or []):
try:
self.ordered_peeps.remove(person)
except ValueError:
...
def parse_potential_arrivals(self, potential_arrivals):
if 'arrived' in potential_arrivals:
s = potential_arrivals[:-len('arrived')]
late_arrivals = [r.strip().lower() for r in s.split(',')]
for person in late_arrivals:
self.late_arrival(person)
def remaining(self):
return list(self.ordered_peeps)
def next(self):
person = self.ordered_peeps.pop(0)
self.statuses_given.append(person)
return person
def late_arrival(self, person):
self.ordered_peeps.append(person)
class Timer:
def __init__(self):
self._events = []
self._ongoing_event = 'PRE'
self._time = datetime.datetime.now()
def start(self):
self.event('START')
def stop(self):
self.event('STOP')
self.event(None)
def event(self, event):
"""
Log an "event" string and keep track of how
long each event is going on for.
"""
now = datetime.datetime.now()
self._events.append((self._ongoing_event, self._time, now))
self._ongoing_event = event
self._time = now
def write(self):
filename = '{}.json'.format(datetime.datetime.now().strftime('%Y-%m-%d'))
with open(filename, 'w') as f:
f.write(json.dumps(self._events, indent=2, cls=DatetimeEncoder))
class DatetimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.strftime("%Y-%m-%dT%H:%M:%S.%f%z")
return super().default(obj)
if __name__ == '__main__':
Standup().doit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment