#!/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")