commit 5d3c2a4909e612ba2c81a31ad848d1e0a0047ded Author: Yannik Enss Date: Thu May 6 12:15:14 2021 +0200 first working version diff --git a/c.py b/c.py new file mode 100755 index 0000000..5cace5f --- /dev/null +++ b/c.py @@ -0,0 +1,113 @@ +#!/usr/bin/python3 +import requests +import sys +import bs4 +import datetime +import argparse +import subprocess + +from pprint import pprint +from dateutil import parser as dparser + +MAPPING = { 0: "No", + 1: "Maybe", + 2: "Yes" } + +def get_html(url): + html_text = requests.post(url, data={"lang":"en"}).text + soup = bs4.BeautifulSoup(html_text, 'html.parser') + return soup + +def submit_choices(url, choices, name, token): + choices_formatted = { f"choices[{i}]":x for i,x in enumerate(choices) } + data = { "name": name, + "control": token, + "save": "", + **choices_formatted } + response = requests.post(url, data=data) + response.raise_for_status() + +def get_datetimes(soup): + table = soup.find("table") + + months = [] + days = [] + times = [] + + datetimes = [] + + headers = table.thead.find_all("tr") + + months = headers[0].find_all("th", colspan=True) + days = headers[1].find_all("th", colspan=True) + times = headers[2].find_all("th", colspan=True) + + months_tmp = [] + days_tmp = [] + + for month in months: + months_tmp.extend([month]*int(month["colspan"])) + + for day in days: + days_tmp.extend([day]*int(day["colspan"])) + + for i, time in enumerate(times): + time_str = time.contents[0].replace("&colon", ":") + datetimes.append((dparser.parse(months_tmp[i].contents[0]+" "+days_tmp[i].contents[0]+" "+time_str), + (months_tmp[i]["id"], days_tmp[i]["id"], time["id"]))) + + return datetimes + +def get_control_token(soup): + return soup.find("input", attrs={"name":"control"})["value"] + +def get_name(soup): + return soup.h3.contents[0] + +def ask_date(dt, buffer): + start_time = dt - buffer + end_time = dt + buffer + + result = subprocess.run(["khal", "list", start_time.date().isoformat(), start_time.time().isoformat("minutes"), end_time.date().isoformat(), end_time.time().isoformat("minutes")], capture_output=True, text=True) + print(result.stderr, file=sys.stderr, end="") + print(result.stdout, end="") + print(f"Do you have time at {dt.strftime('%A')}, {dt.isoformat()}?") + if result.stdout.strip() == "No events": + i = input(f"(Y/n/m): ") + if not i: + i = "y" + else: + i = input(f"(y/N/m): ") + if not i: + i = "n" + print("------------") + return {"y":2, "n":0, "m":1}[i.lower()] + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("--buffer", "-b", type=int, default=60) + parser.add_argument("--name", "-n", default="y") + parser.add_argument("url") + args = parser.parse_args() + + buffer = datetime.timedelta(minutes=args.buffer) + + soup = get_html(args.url) + + datetimes = get_datetimes(soup) + + choices = [] + + title = get_name(soup) + + print(f"Poll: {title}") + print("------------") + + for datetime, classes in datetimes: + choices.append(ask_date(datetime, buffer)) + + if input("Do you want to submit? (Y/n) ").lower() in ("y", ""): + submit_choices(args.url, choices=choices, name=args.name, token=get_control_token(soup)) + print("submitted") +