#!/usr/bin/env python3 import os import sys import argparse import json import todoist from pprint import pprint TOKEN_FILE_NAME = ".todoist_token" DUMP_FILENAME = "dump.txt" def arg_parser(): parser = argparse.ArgumentParser() parser.add_argument("--token", metavar="ACCESS_TOKEN_STRING", help="Store or change access token", type=str) parser.add_argument("--get-token", help="Get current token (e.g. for revocation)", action="store_true") parser.add_argument("--dump", help="Dump data to file to " + DUMP_FILENAME + " and exit", action="store_true") parser.add_argument("-p", "--project", metavar="PROJECT_NAME", help="Project name (lowercase!)", type=str) parser.add_argument("-s", "--severity", help="Severity (or priority) of task", type=int, choices=[1, 2, 3, 4]) parser.add_argument("-a", "--assign", metavar="NAME", help="Assign to collaborator", type=str) parser.add_argument("-d", "--date", metavar="DATE", help="Date string", type=str, default="today") parser.add_argument("msg", metavar="MSG", nargs='*', help="Content of new Task - stdin if absent") return parser.parse_args() def token_path(): return os.path.join(os.path.expanduser("~"), TOKEN_FILE_NAME) def get_token(): path = token_path() with open(path, mode="r") as f: for line in f: token = line.strip() ## Get first line only break return token def store_token(token): path = token_path() with open(path, mode="w+") as f: f.write(token) def build_project_list(data): projects = { proj["name"].lower(): proj["id"] for proj in data["Projects"] } return projects def build_collaborators_list(data): collaborators = { col["full_name"].lower(): col["id"] for col in data["Collaborators"] } return collaborators def main(): args = arg_parser() if args.token: store_token(args.token) print("Token stored") sys.exit(0) token = get_token() if not token: print("Couldn't read token. Is token stored?", file=sys.stderr) sys.exit(1) if args.get_token: print(token) sys.exit(0) api = todoist.TodoistAPI(token) data = api.sync(resource_types=['all']) if "error" in data: print("Failed to connect or authenticate to server:", file=sys.stderr) print(data["error"], file=sys.stderr) sys.exit(1) if args.dump: with open(DUMP_FILENAME, mode="w") as f: pprint(data, f) sys.exit(0) projects = build_project_list(data) collaborators = build_collaborators_list(data) ## Prepare data if not args.msg: msg = sys.stdin.read().strip() else: msg = " ".join(args.msg) ## Prepare arguments kwargs = {} kwargs["date_string"] = args.date if args.project: proj = args.project.lower() if proj in projects: kwargs["project_id"] = projects[proj] else: print("WARNING: Unknown project. Task will be stored in Inbox", file=sys.stderr) if args.severity: kwargs["priority"] = args.severity if args.assign: name = args.assign.lower() aid = None for k, v in collaborators.items(): if k.find(name) != -1: aid = v break if not aid: print("ERROR: Unknown person", file=sys.stderr) sys.exit(1) kwargs["responsible_uid"] = aid ## Store task status = api.add_item(msg, **kwargs) if "error" in status: print("Store failed:", file=sys.stderr) print(status["error"], file=sys.stderr) sys.exit(1) api.commit() if __name__ == "__main__": main()