101 lines
2.6 KiB
Python
101 lines
2.6 KiB
Python
import argparse
|
|
import itertools
|
|
import json
|
|
import sys
|
|
from calendar import day_abbr, day_name
|
|
from math import floor
|
|
|
|
with open("data.json") as jsonfile:
|
|
raw_data = json.loads(jsonfile.read())
|
|
|
|
parser = argparse.ArgumentParser(
|
|
prog=sys.argv[0], description="Find autono-meeting times"
|
|
)
|
|
|
|
parser.add_argument("members", nargs="*", choices=[m["name"] for m in raw_data])
|
|
parser.add_argument("-n", "--number", default=2, type=int)
|
|
parser.add_argument("-d", "--days", nargs="+")
|
|
parser.add_argument("-v", "--verbose", action='store_true')
|
|
|
|
args = parser.parse_args()
|
|
|
|
data = {}
|
|
|
|
|
|
def slot2name(slot):
|
|
time, day = slot.split("-")
|
|
name = day_name[int(day) - 1]
|
|
return f"{time} {name}"
|
|
|
|
|
|
members_count = len(raw_data)
|
|
if args.members:
|
|
members_count = len(args.members)
|
|
|
|
if args.verbose:
|
|
print(f"I: finding slots for {members_count} members")
|
|
|
|
days = [str(d) for d in list(range(1, 8))]
|
|
if args.days:
|
|
days = [str(list(day_abbr).index(d) + 1) for d in args.days]
|
|
|
|
for member in raw_data:
|
|
name = member["name"]
|
|
if args.members and name not in args.members:
|
|
continue
|
|
for slot in member["availability"]:
|
|
if "00-" not in slot:
|
|
# not starting at an hour
|
|
continue
|
|
slot_day = slot.split("-")[1]
|
|
if slot_day not in days:
|
|
# not in specified days
|
|
continue
|
|
try:
|
|
data[slot].append(name)
|
|
except KeyError:
|
|
data[slot] = [name]
|
|
|
|
if args.verbose:
|
|
print(f"I: Checking {len(data.keys())} possible slots")
|
|
|
|
seen_times = []
|
|
counter = 1
|
|
|
|
l = [list(data.keys())] * args.number
|
|
combinations = list(itertools.product(*l))
|
|
|
|
if args.verbose:
|
|
print(f"I: Scanning {len(combinations)} combinations")
|
|
|
|
for combination in combinations:
|
|
if len(set(combination)) < args.number:
|
|
continue
|
|
if set(combination) in seen_times:
|
|
continue
|
|
seen_times.append(set(combination))
|
|
|
|
attendees_per_slot = [data[slot] for slot in combination]
|
|
attendees = set(itertools.chain(*attendees_per_slot))
|
|
|
|
if (
|
|
(len(attendees) == members_count)
|
|
and all(
|
|
[len(s) >= floor(members_count / args.number) for s in attendees_per_slot]
|
|
)
|
|
and all(
|
|
[
|
|
len(s) < (floor(members_count / args.number) + 2)
|
|
for s in attendees_per_slot
|
|
]
|
|
)
|
|
):
|
|
print(f"Option {counter}")
|
|
for i, slot in enumerate(combination):
|
|
print(f" Meeting {i+1}: ", slot2name(slot))
|
|
print(" ", ", ".join(attendees_per_slot[i]))
|
|
counter += 1
|
|
|
|
if counter == 1:
|
|
print("Oh no, no slots found")
|