From b766f12933d97426e00c0e182ebcc1259d77c4df Mon Sep 17 00:00:00 2001 From: Michael Davydov Date: Wed, 7 Dec 2022 12:36:23 +0300 Subject: [PATCH] Completely remove dependence on todoist-python --- app.py | 42 ++++++++++++++----------------------- requirements.txt | 1 - todoist_api.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 28 deletions(-) create mode 100644 todoist_api.py diff --git a/app.py b/app.py index 593a2f5..4bdc3aa 100644 --- a/app.py +++ b/app.py @@ -1,17 +1,12 @@ -# TODO: Remove dependence on todoist python api, it's broken and not needed - import os import yaml -import json -import todoist +from todoist_api import TodoistAPI import string import tempfile import sys # easywebdav python3 hack import easywebdav.client -from datetime import date, datetime, timedelta, timezone -import pytz -import pprint +from datetime import date, datetime, timedelta easywebdav.basestring = str easywebdav.client.basestring = str @@ -29,20 +24,19 @@ config = yaml.load(f.read()) # Fetch todoist items -api = todoist.TodoistAPI(config['todoist_token']) -api.sync() +api = TodoistAPI(config['todoist_token']) labels = {} -for label in api.state['labels']: +for label in api.get_items("labels"): labels[label['id']] = label['name'] projects = {} -for project in api.state['projects']: +for project in api.get_items("projects"): projects[project['id']] = project['name'] -if config['debug']: - with open(os.path.join(appdir, "debug.json"), "w+", encoding="utf-8") as f: - f.write(pprint.pformat(api.state, indent=4)) +# if config['debug']: +# with open(os.path.join(appdir, "debug.json"), "w+", encoding="utf-8") as f: +# f.write(pprint.pformat(api.state, indent=4)) def debug(text): if config['debug']: @@ -106,13 +100,9 @@ def completed_today(): def get_project_id(name): project_id = None # Find required project - for key, value in api.state.items(): - if key == 'projects': - # print (value) - for project in value: - if project['name'] == name: - project_id = project['id'] - break + for project in api.get_items("projects"): + if project['name'] == name: + project_id = project['id'] break return project_id @@ -121,7 +111,7 @@ def get_project_items(project_name): # Filter completed out project_id = get_project_id(project_name) items = [] - for item in api.state['items']: + for item in api.get_items(): # print(item) select = False if project_name == "Today": @@ -157,9 +147,7 @@ def get_project_items(project_name): remember_task(item['content']) if config['clean_up_completed_tasks']: print(f"Deleting task '{item['content']}'") - task = api.items.get_by_id(item['id']) - task.delete() - api.commit() + api.delete_item(item) elif item['checked'] != 1 and item['checked'] != 0: print("Something's not right, did Todoist change API? item['checked'] is not 0 or 1:") return items @@ -181,10 +169,10 @@ def generate_output_text(): output_text = f'TODAY (Done: {completed_today()}):\n\n{output_text}\n\nINBOX:\n\n{inbox_text}' return output_text -def get_archival_text(api): +def get_archival_text(api : TodoistAPI): tasks = [] - for item in api.state['items']: + for item in api.get_items(): tasks.append(todoist_item_to_txt(item)) archival_text = '' diff --git a/requirements.txt b/requirements.txt index 10944e7..a9235b5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,4 @@ PyYaml -todoist-python easywebdav icalendar requests \ No newline at end of file diff --git a/todoist_api.py b/todoist_api.py new file mode 100644 index 0000000..d565e95 --- /dev/null +++ b/todoist_api.py @@ -0,0 +1,54 @@ +import os +import yaml +import requests +from uuid import uuid4 + +appdir = os.path.dirname(os.path.realpath(__file__)) # rp, realpath + + +class TodoistAPI(): + def __init__(self, token) -> None: + self.headers = { + "Authorization": f"Bearer {token}", + "content-type": "application/json", + } + + self._state_cache = {} + + def get_items(self, items_type="items", force_update=False): + if items_type not in self._state_cache or force_update: + items = requests.post("https://api.todoist.com/sync/v9/sync", headers=self.headers, json={ + "sync_token": "*", + "resource_types": [items_type] + } + ).json()[items_type] + self._state_cache[items_type] = items + else: + items = self._state_cache[items_type] + return items + + def delete_item(self, item): + response = requests.post("https://api.todoist.com/sync/v9/sync", headers=self.headers, json={ + "commands": [ + { + "type": "item_delete", + "uuid": str(uuid4), + "args": {"id": item['id'] if isinstance(item, dict) else item} + } + ] + } + ) + return response + + def add_item(self, item_data): + task = requests.post("https://api.todoist.com/sync/v9/items/add", headers=self.headers, json=item_data + ).text + return task + + + # def add_task(self,) +if __name__ == "__main__": + # Testing + with open(os.path.join(appdir, 'config.yaml'), 'r') as f: + config = yaml.load(f.read()) + print(TodoistAPI(config['todoist_token']).get_items("projects")) \ No newline at end of file