Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- Counts overdue tasks on Todoist.
- Works for tasks that have only a "due date".
- Get an API token from todoist and set your environment variable
- TODOIST_API_TOKEN to it. Also set the variable BEEMINDER_AUTH_TOKEN.
- Set up a cron job for this script and run it at night.
- (E.g. every day at 4am.)
- """
- import http
- import json
- import os
- import time
- from datetime import datetime
- from datetime import timedelta
- import pytz
- from dateutil import parser
- from todoist.api import TodoistAPI
- BEEMINDER_GOAL_NAME = 'todoist-overdue'
- def count_overdue():
- api_token = os.getenv('TODOIST_API_TOKEN', None)
- if api_token is None:
- raise ValueError('Please set environment variable '
- 'TODOIST_API_TOKEN')
- api = TodoistAPI(token=api_token)
- api.sync()
- user_tz = get_todoist_user_timezone(api)
- overdue_counter = 0
- for item in api['items']:
- if 'due' in item and item['due'] is not None:
- due_datetime = parser.parse(item['due']['date'])
- due_datetime = user_tz.localize(due_datetime)
- now = datetime.now(tz=user_tz)
- # We define "overdue" as: it is at least 24 hours past
- # the due datetime. E.g. if the due date is given as
- # 2020-04-10 then it becomes overdue at 2020-04-11 00:00
- # It would be more accurate to
- # check whether the due date is provided as a date or
- # a date+time and then compare individually, but for
- # my usage, this is good enough.
- overdue = now >= (due_datetime + timedelta(hours=24))
- # Count "unchecked" (i.e. uncompleted) overdue tasks
- if 'checked' in item and not item['checked'] and overdue:
- overdue_counter += 1
- print(due_datetime)
- print(item['content'])
- print('---------')
- return overdue_counter
- def get_todoist_user_timezone(api: TodoistAPI) -> pytz.timezone:
- tz_str = api.user.get('tz_info')['timezone']
- return pytz.timezone(tz_str)
- def enter_beeminder_value(value, goal_name, timestamp=None, request_id=None,
- daystamp=None):
- auth_token = os.getenv('BEEMINDER_AUTH_TOKEN', None)
- if auth_token is None:
- raise ValueError('Please set environment variable '
- 'BEEMINDER_AUTH_TOKEN')
- username = os.getenv('BEEMINDER_USERNAME', None)
- if username is None:
- raise ValueError('Please set environment variable '
- 'BEEMINDER_USERNAME')
- if daystamp is not None:
- time_or_date_stamp = f'daystamp={daystamp}'
- elif timestamp is not None:
- time_or_date_stamp = f'timestamp={timestamp}'
- else: # timestamp is None and daystamp is None:
- time_or_date_stamp = f'timestamp={int(time.time())}'
- comment = 'python'
- query_str = (
- f'/api/v1/users/{username}/'
- f'goals/{goal_name}/'
- f'datapoints.json?'
- f'auth_token={auth_token}&'
- f'{time_or_date_stamp}&'
- f'value={value}&'
- f'comment={comment}')
- if request_id is not None:
- query_str += f'&requestid={request_id}'
- connection = http.client.HTTPSConnection('www.beeminder.com')
- connection.request('POST', query_str)
- reply = json.loads(connection.getresponse().read())
- return reply
- if __name__ == '__main__':
- n_overdue = count_overdue()
- print(f'n_overdue: {n_overdue}')
- reply = enter_beeminder_value(n_overdue,
- goal_name=BEEMINDER_GOAL_NAME)
- print(reply)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement