schedulebot: Add ability to hard-code a group membership by shift

This feature is intended for implementing a "current wub wrangler" group, which:
a) Isn't on the schedule
b) Can't be put on the schedule as it would overlap with other duties
c) We don't want to announce in "starting/ending shift" messages.
pull/349/head
Mike Lang 1 year ago
parent 91d99bb22b
commit 5a8bf99d12

@ -217,6 +217,9 @@
Editor: 17, Editor: 17,
ChatOps: 18, ChatOps: 18,
}, },
// Map from group id to a hard-coded set of 4 user ids, one per shift.
groups_by_shift: {
},
// Map from schedule names to zulip user ids // Map from schedule names to zulip user ids
members: { members: {
ekimekim: 8, ekimekim: 8,

@ -46,15 +46,36 @@ def get_display_name(client, user_id):
return client.request("GET", "users", user_id)["user"]["full_name"] return client.request("GET", "users", user_id)["user"]["full_name"]
def update_groups(client, group_ids, schedule, hour, last): def update_groups(client, group_ids, groups_by_shift, schedule, hour, start_time, last):
logging.info("Setting groups for hour {}".format(hour)) logging.info("Setting groups for hour {}".format(hour))
members = get_membership(client) members = get_membership(client)
_, shift, _, _ = hour_to_shift(hour, start_time)
def run_group(item): def run_group(item):
group_name, group_id = item group_name, group_id = item
new_members = set() if hour == last else determine_members(schedule, group_name, hour) new_members = set() if hour == last else determine_members(schedule, group_name, hour)
assert group_id in members, "group {} doesn't exist".format(group_id) assert group_id in members, "group {} doesn't exist".format(group_id)
update_members(client, group_id, members[group_id], new_members) update_members(client, group_id, members[group_id], new_members)
def run_group_by_shift(item):
group_id, user_ids = item
user_id = user_ids[shift]
update_members(client, group_id, members[group_id], {user_id})
gevent.pool.Group().map(run_group, group_ids.items()) gevent.pool.Group().map(run_group, group_ids.items())
gevent.pool.Group().map(run_group_by_shift, groups_by_shift.items())
def hour_to_shift(hour, start_time):
"""Converts an hour number into a datetime, shift number (0-3), shift name, and hour-of-shift (1-6)"""
start_time = datetime.utcfromtimestamp(start_time)
current_time = (start_time + timedelta(hours=hour)).replace(minute=0, second=0, microsecond=0)
current_time_pst = current_time - timedelta(hours=8)
hour_pst = current_time_pst.hour
shift = hour_pst // 6
shift_name = ["zeta", "dawn-guard", "alpha-flight", "night-watch"][shift]
shift_hour = hour_pst % 6 + 1
return current_time, shift, shift_name, shift_hour
def post_schedule(client, send_client, start_time, schedule, stream, hour, no_mentions, last, omega): def post_schedule(client, send_client, start_time, schedule, stream, hour, no_mentions, last, omega):
@ -92,13 +113,7 @@ def post_schedule(client, send_client, start_time, schedule, stream, hour, no_me
logging.info(f"Going offline: {going_offline}") logging.info(f"Going offline: {going_offline}")
logging.info(f"Coming online: {coming_online}") logging.info(f"Coming online: {coming_online}")
start_time = datetime.utcfromtimestamp(start_time) current_time, _, shift, shift_hour = hour_to_shift(hour, start_time)
current_time = (start_time + timedelta(hours=hour)).replace(minute=0, second=0, microsecond=0)
current_time_pst = current_time - timedelta(hours=8)
hour_pst = current_time_pst.hour
shift = hour_pst // 6
shift = ["zeta", "dawn-guard", "alpha-flight", "night-watch"][shift]
shift_hour = hour_pst % 6 + 1
if omega >= 0 and hour >= omega: if omega >= 0 and hour >= omega:
shift = "omega" shift = "omega"
@ -199,6 +214,10 @@ def main(conf_file, hour=-1, no_groups=False, stream="General", no_mentions=Fals
NAME: USER_ID NAME: USER_ID
groups: groups:
NAME: GROUP_ID NAME: GROUP_ID
groups_by_shift:
GROUP_ID: [USER_ID, USER_ID, USER_ID, USER_ID]
Populates membership of given group as a hard-coded list of one user per DB shift.
This is NOT reported in start/end of shifts.
authentication is an object {email, api_key} authentication is an object {email, api_key}
""" """
config = get_config(conf_file) config = get_config(conf_file)
@ -208,9 +227,10 @@ def main(conf_file, hour=-1, no_groups=False, stream="General", no_mentions=Fals
group_ids = config["groups"] group_ids = config["groups"]
start_time = timegm(time.strptime(config["start_time"], "%Y-%m-%dT%H:%M:%S")) start_time = timegm(time.strptime(config["start_time"], "%Y-%m-%dT%H:%M:%S"))
schedule = parse_schedule(config["members"], config["schedule"]) schedule = parse_schedule(config["members"], config["schedule"])
groups_by_shift = {int(id): shifts for id, shifts in config["groups_by_shift"].items()}
if hour >= 0: if hour >= 0:
if not no_groups: if not no_groups:
update_groups(client, group_ids, schedule, hour, last) update_groups(client, group_ids, groups_by_shift, schedule, hour, start_time, last)
if stream: if stream:
post_schedule(client, send_client, start_time, schedule, stream, hour, no_mentions, last, omega) post_schedule(client, send_client, start_time, schedule, stream, hour, no_mentions, last, omega)
return return
@ -218,7 +238,7 @@ def main(conf_file, hour=-1, no_groups=False, stream="General", no_mentions=Fals
hour = int((time.time() - start_time) / 3600) hour = int((time.time() - start_time) / 3600)
if not no_initial: if not no_initial:
if not no_groups: if not no_groups:
update_groups(client, group_ids, schedule, hour, last) update_groups(client, group_ids, groups_by_shift, schedule, hour, start_time, last)
if stream: if stream:
post_schedule(client, send_client, start_time, schedule, stream, hour, no_mentions, last, omega) post_schedule(client, send_client, start_time, schedule, stream, hour, no_mentions, last, omega)
no_initial = False no_initial = False

Loading…
Cancel
Save