def __init__(self, api_token, api_url): # initiate a todoist api instance self.api = TodoistAPI(api_token) self.api_token = api_token self.api_url = api_url
from todoist.api import TodoistAPI import pandas as pd token = 'd9deec7ba39852d370168e80ebb66e4b60d927df' # I made this up # create a TodoistAPI object with the token, which we store to the api variable api = TodoistAPI(token) # Fetches the latest updated data from the server. api.sync() # .data attribute retrieves a python dictionary rather than todoist.models.Project projects = [project.data for project in api.state['projects']] # print(projects) # I can easily create a DataFrame on the 'projects' list of dicts df_projects = pd.DataFrame(projects) # print(df_projects.head()) tasks = [task.data for task in api.state['items']] df_tasks = pd.DataFrame(tasks) # print(df_tasks) # Convert Date strings (in UTC by default) to datetime and format it df_tasks['date_added'] = pd.to_datetime(( pd.to_datetime(df_tasks['date_added'], utc=True).dt.tz_convert( 'Europe/Budapest') # my current timezone .dt.strftime("%Y-%m-%d %H:%M:%S"))) # easier to handle format """ df_tasks['due_date_utc'] = pd.to_datetime( (pd.to_datetime(df_tasks['due_date_utc'], utc=True) .dt.tz_convert('Europe/Budapest') .dt.strftime("%Y-%m-%d %H:%M:%S"))) """ df_tasks['date_completed'] = pd.to_datetime((pd.to_datetime(
def main(): """Main process function.""" parser = argparse.ArgumentParser() parser.add_argument('-a', '--api_key', help='Todoist API Key') parser.add_argument('-l', '--label', help='The next action label to use', default='next_action') parser.add_argument('-s', '--skip_label', help = "Label to prevent next action", default="Someday") parser.add_argument('-d', '--delay', help='Specify the delay in seconds between syncs', default=5, type=int) parser.add_argument('--debug', help='Enable debugging', action='store_true') parser.add_argument('--inbox', help='The method the Inbox project should be processed', default='none', choices=['parallel', 'serial', 'none']) parser.add_argument('--parallel_suffix', default='.') parser.add_argument('--serial_suffix', default='_') parser.add_argument('--hide_future', help='Hide future dated next actions until the specified number of days', default=7, type=int) parser.add_argument('--onetime', help='Update Todoist once and exit', action='store_true') parser.add_argument('--nocache', help='Disables caching data to disk for quicker syncing', action='store_true') args = parser.parse_args() # Set debug if args.debug: log_level = logging.DEBUG else: log_level = logging.INFO logging.basicConfig(level=log_level) # Check we have a API key if not args.api_key: logging.error('No API key set, exiting...') sys.exit(1) # Run the initial sync logging.debug('Connecting to the Todoist API') api_arguments = {'token': args.api_key} if args.nocache: logging.debug('Disabling local caching') api_arguments['cache'] = None api = TodoistAPI(**api_arguments) logging.debug('Syncing the current state from the API') api.sync() # Check the next action label exists labels = api.labels.all(lambda x: x['name'] == args.label) skip_labels = api.labels.all(lambda x: x['name'] == args.skip_label) if len(labels) > 0: label_id = labels[0]['id'] skip_label_id = skip_labels[0]['id'] logging.debug('Label %s found as label id %d', args.label, label_id) else: logging.error("Label %s doesn't exist, please create it or change TODOIST_NEXT_ACTION_LABEL.", args.label) sys.exit(1) def get_project_type(project_object): """Identifies how a project should be handled.""" name = project_object['name'].strip() if name == 'Inbox': return args.inbox elif name[-1] == args.parallel_suffix: return 'parallel' elif name[-1] == args.serial_suffix: return 'serial' else: return 'none' def get_item_type(item): """Identifies how a item with sub items should be handled.""" name = item['content'].strip() if name[-1] == args.parallel_suffix: return 'parallel' elif name[-1] == args.serial_suffix: return 'serial' else: return 'None' def add_label(item, label, skip_label): if label not in item['labels'] and skip_label not in item['labels']: labels = item['labels'] logging.debug('Updating %s with label', item['content']) labels.append(label) items_labels_added.append(item['id']) api.items.update(item['id'], labels=labels) def remove_label(item, label): if label in item['labels']: labels = item['labels'] logging.debug('Updating %s without label', item['content']) labels.remove(label) items_labels_removed.append(item['id']) api.items.update(item['id'], labels=labels) # Main loop while True: items_labels_added = [] items_labels_removed = [] try: api.sync() except Exception as e: logging.exception('Error trying to sync with Todoist API: %s' % str(e)) else: for project in api.projects.all(): project_type = get_project_type(project) if project_type: logging.debug('Project %s being processed as %s', project['name'], project_type) # Get all items for the project, sort by the item_order field. items = sorted(api.items.all(lambda x: x['project_id'] == project['id']), key=lambda x: x['item_order']) # Tracks whether the first visible item at the root of the project has been found. root_first_found = False project_has_next_action = False previous_indent = 0 for item in items: if not is_item_visible(item): continue # If its too far in the future, remove the next_action tag and skip if args.hide_future > 0 and 'due_date_utc' in item.data and item['due_date_utc'] is not None: due_date = datetime.strptime(item['due_date_utc'], '%a %d %b %Y %H:%M:%S +0000') future_diff = (due_date - datetime.utcnow()).total_seconds() if future_diff >= (args.hide_future * 86400): remove_label(item, label_id) root_first_found = True continue item_type = get_item_type(item) child_items = get_subitems(items, item) item_indent = item['indent'] if item_indent == 1: parent_type1 = item_type parent_type2 = 'None' parent_type3 = 'None' parent_type = 'None' elif item_indent == 2: parent_type2 = item_type parent_type3 = 'None' parent_type = parent_type1 elif item_indent == 3: parent_type3 = item_type if parent_type2 =="None": parent_type = parent_type1 else: parent_type = parent_type2 elif item_indent == 4: if parent_type3 != "None": parent_type = parent_type3 elif parent_type2 != "None": parent_type = parent_type2 else: parent_type = parent_type1 if item_type =='parallel' or item_type =='serial': logging.debug('Identified %s as %s type', item['content'], item_type) if item_type != 'None' or len(child_items) > 0: # If the project is serial and there is a next action, # remove the next_action from all children. if (project_type == 'serial' or parent_type == 'serial') and project_has_next_action: for child_item in child_items: remove_label(child_item, label_id) # Process serial tagged items elif item_type == 'serial': first_found = False if parent_type == 'parallel' and len(child_items) > 0: remove_label(item,label_id) root_first_found = True for child_item in child_items: if is_item_visible(child_item) and not first_found: add_label(child_item, label_id, skip_label_id) project_has_next_action = True first_found = True else: remove_label(child_item, label_id) # Process parallel tagged items or untagged parents elif item_type =='parallel' or project_type =='parallel' or parent_type == 'parallel': for child_item in child_items: add_label(child_item, label_id, skip_label_id) # Remove the label from the parent remove_label(item, label_id) root_first_found = True # Process items as per project type on indent 1 if untagged else: if item['indent'] == 1: if project_type == 'serial': if is_item_visible(item) and not root_first_found: add_label(item, label_id, skip_label_id) root_first_found = True project_has_next_action = True else: remove_label(item, label_id) elif project_type == 'parallel': add_label(item, label_id, skip_label_id) if label_id in item['labels'] and skip_label_id in item['labels']: remove_label(item,label_id) if sorted(items_labels_added) == sorted(items_labels_removed): api.queue = [] if len(api.queue): logging.debug('%d changes queued for sync... commiting to Todoist.', len(api.queue)) api.commit() else: logging.debug('No changes queued, skipping sync.') # If onetime is set, exit after first execution. if args.onetime: break logging.debug('Sleeping for %d seconds', args.delay) time.sleep(args.delay)
from todoist.api import TodoistAPI api = TodoistAPI('c420b289cf0cdc6f84dbbbd98bef00b62fc3aff6') api.sync() #print (api.state['projects']) # What do you want to do? # Menu to create project, update project, add task to project, change color, etc def add_project(): project1 = api.projects.add('Project1') api.commit() print(project1) def add_task(): project1 = api.projects.add('Project1') task1 = api.items.add('Task1', project_id=project1['id']) task2 = api.items.add('Task2', project_id=project1['id']) api.commit() print(task1, task2) def modify_task(): project1 = api.projects.get_by_id(2230297078) task1 = api.items.update(content='NewTask1', due={'string': 'tomorrow at 10:00'}, project_id=project1['id'], item_id=(3723463411)) api.commit()
def initialise(args): # Check we have a API key if not args.api_key: logging.error( "\n\nNo API key set. Run Autodoist with '-a <YOUR_API_KEY>'\n") sys.exit(1) # Check if alternative end of day is used if args.end is not None: if args.end < 1 or args.end > 24: logging.error( "\n\nPlease choose a number from 1 to 24 to indicate which hour is used as alternative end-of-day time.\n") sys.exit(1) else: pass # Check if proper regeneration mode has been selected if args.regeneration is not None: if not set([0,1,2]) & set([args.regeneration]): logging.error('Wrong regeneration mode. Please choose a number from 0 to 2. Check --help for more information on the available modes.') exit(1) # Show which modes are enabled: modes = [] m_num = 0 for x in [args.label, args.regeneration, args.end]: if x: modes.append('Enabled') m_num += 1 else: modes.append('Disabled') logging.info("You are running with the following functionalities:\n\n Next action labelling mode: {}\n Regenerate sub-tasks mode: {}\n Shifted end-of-day mode: {}\n".format(*modes)) if m_num == 0: logging.info( "\n No functionality has been enabled. Please see --help for the available options.\n") exit(0) # Run the initial sync logging.debug('Connecting to the Todoist API') api_arguments = {'token': args.api_key} if args.nocache: logging.debug('Disabling local caching') api_arguments['cache'] = None api = TodoistAPI(**api_arguments) sync(api) # If labeling argument is used if args.label is not None: # Verify that the next action label exists; ask user if it needs to be created label_id = verify_label_existance(args, api, args.label, 1) else: # Label functionality not needed label_id = None logging.info("Autodoist has connected and is running fine!\n") # If regeneration mode is used, verify labels if args.regeneration is not None: # Verify the existance of the regeneraton labels; force creation of label regen_labels_id = [verify_label_existance( args, api, regen_label, 2) for regen_label in args.regen_label_names] else: # Label functionality not needed regen_labels_id = [None, None, None] return api, label_id, regen_labels_id
from todoist.api import TodoistAPI from datetime import date api = TodoistAPI('API KEY') api.sync() current_date = str(date.today()) items = api.state["items"] def CheckDateLess(specDate): splitDate = specDate.split('-') today = date.today() if((int(splitDate[0]) <= today.year) and ( int(splitDate[1]) <= today.month) and (int(splitDate[2]) < today.day)): return 1 else: return 0 def ReadAllCurrent(): current_task_name= [] for i in range(len(items)): if (items[i]['due'] != None): if (items[i]['due']['date'] == current_date): current_task_name.append(items[i]['content']) return current_task_name def ReadAllOverdue(): overdue_task_name= [] for i in range(len(items)): if (items[i]['due'] != None):
return events try: client = InfluxDBClient(host=INFLUXDB_HOST, port=INFLUXDB_PORT, username=INFLUXDB_USERNAME, password=INFLUXDB_PASSWORD) client.create_database(INFLUXDB_DATABASE) client.switch_database(INFLUXDB_DATABASE) except InfluxDBClientError as err: print("InfluxDB connection failed: %s" % (err)) sys.exit() api = TodoistAPI(TODOIST_ACCESS_TOKEN) api.sync() page = 0 activity = get_activity(page) projects = {} for event in activity: if event['object_type'] == 'item': if event['event_type'] == 'added' or event['event_type'] == 'completed': project = None try: if event['parent_project_id'] in projects: project = projects[event['parent_project_id']] else: project = api.projects.get(event['parent_project_id']) projects[event['parent_project_id']] = project
import argparse import io import json import os import requests import sys from todoist.api import TodoistAPI from os.path import join, dirname from dotenv import load_dotenv dotenv_path = join(dirname(__file__), '.env') load_dotenv(dotenv_path) api = TodoistAPI(os.environ.get("APITOKEN")) api.sync() def projects(): list = api.state['projects'] print('### プロジェクト一覧') for name in list: print(name['name']) def tasks(args): list = api.state['projects'] for projects_id in list: if projects_id['name'] == args.tasks: tasks_project_id = projects_id['id'] break ## 例外キャッチ: tasks_project_idがセットされていなければ終了する
from todoist.api import TodoistAPI # Load environment variables load_dotenv() # Initialize app app = Flask(__name__) # Set SQLAlchemy databse URI app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DATABASE_URL") # Initialize db db = SQLAlchemy(app) # Create Todoist API client api = TodoistAPI(os.environ.get("TODOIST_API_TOKEN")) class Item(db.Model): __tablename__ = "items" project_id: int = db.Column(db.Integer) responsible_uid: int = db.Column(db.Integer) section_id: int = db.Column(db.Integer) sync_id: int = db.Column(db.Integer) user_id: int = db.Column(db.Integer) added_by_uid: int = db.Column(db.Integer) assigned_by_uid: int = db.Column(db.Integer) checked: int = db.Column(db.Integer) child_order: int = db.Column(db.Integer) collapsed: int = db.Column(db.Integer) content: str = db.Column(db.String)
def get_task(self, id): api = TodoistAPI('313f6bf203b35e7ac56e39561a80633e459c9c54') if api.items.get_by_id(id) != None: return True else: return False
unix_lib_path = os.path.expanduser("~/work/pa/PersonalAssistant") win_lib_path = 'C:\\Users\\Petr\\Desktop\\HomeAutomation\\PersonalAssistant' def is_unix(): val = os.path.join('_', '_') return val == "_/_" if is_unix(): if unix_lib_path not in sys.path: sys.path.append(unix_lib_path) else: if win_lib_path not in sys.path: sys.path.append(win_lib_path) import lib.stack as palib import pyutils import resources # ---------------------------------------------------------------------------------------------------------------------- # 2) class TodoistAPI from todoist.api import TodoistAPI api = TodoistAPI(pyutils.get_token()) # ---------------------------------------------------------------------------------------------------------------------- # 3) class PersonalAssistant pa = palib.PersonalAssistant()
def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Todoist platform.""" # Check token: token = config.get(CONF_TOKEN) # Look up IDs based on (lowercase) names. project_id_lookup = {} label_id_lookup = {} from todoist.api import TodoistAPI api = TodoistAPI(token) api.sync() # Setup devices: # Grab all projects. projects = api.state[PROJECTS] # Grab all labels labels = api.state[LABELS] # Add all Todoist-defined projects. project_devices = [] for project in projects: # Project is an object, not a dict! # Because of that, we convert what we need to a dict. project_data = {CONF_NAME: project[NAME], CONF_ID: project[ID]} project_devices.append( TodoistProjectDevice(hass, project_data, labels, api)) # Cache the names so we can easily look up name->ID. project_id_lookup[project[NAME].lower()] = project[ID] # Cache all label names for label in labels: label_id_lookup[label[NAME].lower()] = label[ID] # Check config for more projects. extra_projects = config.get(CONF_EXTRA_PROJECTS) for project in extra_projects: # Special filter: By date project_due_date = project.get(CONF_PROJECT_DUE_DATE) # Special filter: By label project_label_filter = project.get(CONF_PROJECT_LABEL_WHITELIST) # Special filter: By name # Names must be converted into IDs. project_name_filter = project.get(CONF_PROJECT_WHITELIST) project_id_filter = [ project_id_lookup[project_name.lower()] for project_name in project_name_filter ] # Create the custom project and add it to the devices array. project_devices.append( TodoistProjectDevice(hass, project, labels, api, project_due_date, project_label_filter, project_id_filter)) add_devices(project_devices) # Services: descriptions = load_yaml_config_file( os.path.join(os.path.dirname(__file__), 'services.yaml')) def handle_new_task(call): """Called when a user creates a new Todoist Task from HASS.""" project_name = call.data[PROJECT_NAME] project_id = project_id_lookup[project_name] # Create the task item = api.items.add(call.data[CONTENT], project_id) if LABELS in call.data: task_labels = call.data[LABELS] label_ids = [ label_id_lookup[label.lower()] for label in task_labels ] item.update(labels=label_ids) if PRIORITY in call.data: item.update(priority=call.data[PRIORITY]) if DUE_DATE in call.data: due_date = dt.parse_datetime(call.data[DUE_DATE]) if due_date is None: due = dt.parse_date(call.data[DUE_DATE]) due_date = datetime(due.year, due.month, due.day) # Format it in the manner Todoist expects due_date = dt.as_utc(due_date) date_format = '%Y-%m-%dT%H:%M' due_date = datetime.strftime(due_date, date_format) item.update(due_date_utc=due_date) # Commit changes api.commit() _LOGGER.debug("Created Todoist task: %s", call.data[CONTENT]) hass.services.register(DOMAIN, SERVICE_NEW_TASK, handle_new_task, descriptions[DOMAIN][SERVICE_NEW_TASK], schema=NEW_TASK_SERVICE_SCHEMA)
import logging import pandas as pd from todoist.api import TodoistAPI logging.basicConfig(level=logging.INFO) LOGGER = logging.getLogger("main") TODOIST_TOKEN = os.getenv('TODOIST_TOKEN') if TODOIST_TOKEN is None: LOGGER.error("TODOIST_TOKEN env is not set") exit(1) LOGGER.info("Syncing Todoist ...") api = TodoistAPI(TODOIST_TOKEN) api.sync() LOGGER.info("Synced...") # The API limits 100 activities to be retrieved per call, so a loop is needed # Items are retrieved in descending order by date. # offset indicates how many items should be skipped activity_list = [] limit = 100 offset = 0 while True: LOGGER.info(f"Getting activities, batch {int((offset+100)/100)}") # API call, retrieving between 0 and 100 activities activities = api.activity.get(limit=limit, offset=offset)
47: "#808080", 38: "#158fad", 48: "#b8b8b8", 39: "#14aaf5", 49: "#ccac93" } print( "Esse script gera um gráfico com suas tarefas completadas por dia e coloridas\n" "de acordo com o projeto a que pertenciam em um dado período de interesse") # Recebe token do usuário token = input("\nInsira seu token de acesso: ") # Autentica e sincroniza os dados do Todoist api = TodoistAPI("a24619b4c0cae7ad1c1bf43bf9bd81a0588fdd76" if len(token) == 0 else token) api.sync() # Ensina o Python a processar as datas def process(date): words = [s.strip() for s in date.split("de")] day, month, year = int(words[0]), month_number[words[1].lower()[:3]], \ "20" + words[2][-2:] if len(words) == 3 else "2020" return "{}-{}-{}T00:00".format(year, month, day) # Recebe e processa o intervalo desejado since = process(input("> Desde a data: ")) until = process(input("> Até a data : "))[:-5] + "23:59"
def __init__(self): self.token = os.getenv('TOKEN') self.api = TodoistAPI(self.token) self.api.sync() self.project_id = None
default='', help='the actual text for the task') inputArgs = parser.parse_args() # Load ~/.cmd_tricks.json config file config = None with open(os.path.join(Path.home(), ".cmd_tricks.json")) as f: config = json.load(f) # Exit if no config is found if config is None: print("Could not load config file (at ~/.cmd_tricks.json)") sys.exit(1) # Read Todoist API key form .cmd_tricks.json api = TodoistAPI(config["todoist"]["api_key"]) # get contents from clipboard cbContents = None if inputArgs.clipboard: cbContents = clipboard.paste() ############################ # Add GUI functions ############################ class UserInterface: def __init__(self, todoistApi, taskName, taskNote): # super().__init__() self.todoistApi = todoistApi
from dev.tasks import create_jira_admin_task from dev.tasks import create_branch_subtask from dev.tasks import create_merge_subtask from dev.tasks import create_subtask from dev.tasks import create_terraform_merge_subtask from dev.ui import print_heading from dev.ui import ui_create_root_dev_task from dev.ui import ui_create_subtasks from dev.ui import ui_get_jira_reference from todoist.api import TodoistAPI from labels import get_label_ids from projects import ui_select_project api_token = os.getenv('TODOIST_API_TOKEN') api = TodoistAPI(api_token) api.sync() def ui_get_terraform_modules(): print_heading("Module Selection") modules = [ "terraform_cms_dns", "terraform_dcf_entrypoint", "terraform_dcf_networking" ] print("The following modules are available to work with:") count = 1 for module in modules: print("{num}. {name}".format(num=count, name=module)) count += 1 print("Select a module or use a comma separated list to select multiple")
def __init__(self): self.api = TodoistAPI(Config.TODOIST_API_KEY) self.api.sync() self.mt = MusicTools()
def create_task(key=tovakey): api = TodoistAPI(key) api.sync() payload = request.get_json() task1_to_add = payload["context"]["facts"]["task1_to_add"]["grammar_entry"] no_of_tasks = 1 if "due_date" in payload['context']['facts'].keys(): due_date = payload["context"]["facts"]["due_date"]["grammar_entry"] else: due_date = None if "task2_to_add" in payload['context']['facts'].keys(): task2_to_add = payload["context"]["facts"]["task2_to_add"][ "grammar_entry"] no_of_tasks = 2 if "task3_to_add" in payload['context']['facts'].keys(): task3_to_add = payload["context"]["facts"]["task3_to_add"][ "grammar_entry"] no_of_tasks = 3 if "project_to_add" in payload['context']['facts'].keys(): target_project = payload["context"]["facts"]["project_to_add"][ "grammar_entry"] projects = extract_projects(api) project_found = False for project in projects: if project[0].lower() == target_project.lower(): project_found = True if no_of_tasks == 1: added_task1 = api.items.add(task1_to_add, project_id=project[1], due={"string": due_date}) elif no_of_tasks == 2: added_task1 = api.items.add(task1_to_add, project_id=project[1], due={"string": due_date}) added_task2 = api.items.add(task2_to_add, project_id=project[1], due={"string": due_date}) elif no_of_tasks == 3: added_task1 = api.items.add(task1_to_add, project_id=project[1], due={"string": due_date}) added_task2 = api.items.add(task2_to_add, project_id=project[1], due={"string": due_date}) added_task3 = api.items.add(task3_to_add, project_id=project[1], due={"string": due_date}) if project_found == False: added_project = api.projects.add(target_project, due={"string": due_date}) if no_of_tasks == 1: added_task1 = api.items.add(task1_to_add, project_id=added_project['id'], due={"string": due_date}) elif no_of_tasks == 2: added_task1 = api.items.add(task1_to_add, project_id=added_project['id'], due={"string": due_date}) added_task2 = api.items.add(task2_to_add, project_id=added_project['id'], due={"string": due_date}) elif no_of_tasks == 3: added_task1 = api.items.add(task1_to_add, project_id=added_project['id'], due={"string": due_date}) added_task2 = api.items.add(task2_to_add, project_id=added_project['id'], due={"string": due_date}) added_task3 = api.items.add(task3_to_add, project_id=added_project['id'], due={"string": due_date}) else: if no_of_tasks == 1: added_task1 = api.items.add(task1_to_add, due={"string": due_date}) elif no_of_tasks == 2: added_task1 = api.items.add(task1_to_add, due={"string": due_date}) added_task2 = api.items.add(task2_to_add, due={"string": due_date}) elif no_of_tasks == 3: added_task1 = api.items.add(task1_to_add, due={"string": due_date}) added_task2 = api.items.add(task2_to_add, due={"string": due_date}) added_task3 = api.items.add(task3_to_add, due={"string": due_date}) api.commit() return action_success_response()
def find_project_id(self, project_name): api_call = TodoistAPI(self.api_key) api_call.sync() for project in range(len(api_call.state['projects'])): if api_call.state['projects'][project].data['name'].lower() == project_name.lower(): return api_call.state['projects'][project].data['id']
from todoist.api import TodoistAPI api = TodoistAPI('d9deec7ba39852d370168e80ebb66e4b60d927df') api.sync() #print(api.state['projects']) # project1 = api.projects.add('Project1') """ api.commit() print(project1) """ project1 = api.projects.add('Project1') task1 = api.items.add('Task1', project_id=project1['id']) task2 = api.items.add('Task2', project_id=project1['id']) api.commit() #print(api.state['projects']) # project1 = api.projects.add('Project1')
def list_project_tasks(self, project_id): api_call = TodoistAPI(self.api_key) api_call.sync() for item in range(len(api_call.state['items'])): if api_call.state['items'][item].data['project_id'] == project_id: print(api_call.state['items'][item].data['content'])
import todoist as td from todoist.api import TodoistAPI api = TodoistAPI('<put API Token here>') # For Adding Project for i in range(3): #print ('San_{}'.format(151+i)) api.projects.add('San_{}'.format(151 + i)) api.commit() #print(project1)
def __init__(self): self.api_key = os.environ.get("API_KEY") self.api_call = TodoistAPI(self.api_key) self.api_call.sync()
def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the Todoist platform.""" token = config.get(CONF_TOKEN) # Look up IDs based on (lowercase) names. project_id_lookup = {} label_id_lookup = {} api = TodoistAPI(token) api.sync() # Setup devices: # Grab all projects. projects = api.state[PROJECTS] # Grab all labels labels = api.state[LABELS] # Add all Todoist-defined projects. project_devices = [] for project in projects: # Project is an object, not a dict! # Because of that, we convert what we need to a dict. project_data = {CONF_NAME: project[NAME], CONF_ID: project[ID]} project_devices.append( TodoistProjectDevice(hass, project_data, labels, api)) # Cache the names so we can easily look up name->ID. project_id_lookup[project[NAME].lower()] = project[ID] # Cache all label names for label in labels: label_id_lookup[label[NAME].lower()] = label[ID] # Check config for more projects. extra_projects = config[CONF_EXTRA_PROJECTS] for project in extra_projects: # Special filter: By date project_due_date = project.get(CONF_PROJECT_DUE_DATE) # Special filter: By label project_label_filter = project[CONF_PROJECT_LABEL_WHITELIST] # Special filter: By name # Names must be converted into IDs. project_name_filter = project[CONF_PROJECT_WHITELIST] project_id_filter = [ project_id_lookup[project_name.lower()] for project_name in project_name_filter ] # Create the custom project and add it to the devices array. project_devices.append( TodoistProjectDevice( hass, project, labels, api, project_due_date, project_label_filter, project_id_filter, )) add_entities(project_devices) def handle_new_task(call): """Call when a user creates a new Todoist Task from Home Assistant.""" project_name = call.data[PROJECT_NAME] project_id = project_id_lookup[project_name] # Create the task item = api.items.add(call.data[CONTENT], project_id=project_id) if LABELS in call.data: task_labels = call.data[LABELS] label_ids = [ label_id_lookup[label.lower()] for label in task_labels ] item.update(labels=label_ids) if PRIORITY in call.data: item.update(priority=call.data[PRIORITY]) _due: dict = {} if DUE_DATE_STRING in call.data: _due["string"] = call.data[DUE_DATE_STRING] if DUE_DATE_LANG in call.data: _due["lang"] = call.data[DUE_DATE_LANG] if DUE_DATE in call.data: due_date = dt.parse_datetime(call.data[DUE_DATE]) if due_date is None: due = dt.parse_date(call.data[DUE_DATE]) due_date = datetime(due.year, due.month, due.day) # Format it in the manner Todoist expects due_date = dt.as_utc(due_date) date_format = "%Y-%m-%dT%H:%M%S" due_date = datetime.strftime(due_date, date_format) _due["date"] = due_date if _due: item.update(due=_due) _reminder_due: dict = {} if REMINDER_DATE_STRING in call.data: _reminder_due["string"] = call.data[REMINDER_DATE_STRING] if REMINDER_DATE_LANG in call.data: _reminder_due["lang"] = call.data[REMINDER_DATE_LANG] if REMINDER_DATE in call.data: due_date = dt.parse_datetime(call.data[REMINDER_DATE]) if due_date is None: due = dt.parse_date(call.data[REMINDER_DATE]) due_date = datetime(due.year, due.month, due.day) # Format it in the manner Todoist expects due_date = dt.as_utc(due_date) date_format = "%Y-%m-%dT%H:%M:%S" due_date = datetime.strftime(due_date, date_format) _reminder_due["date"] = due_date if _reminder_due: api.reminders.add(item["id"], due=_reminder_due) # Commit changes api.commit() _LOGGER.debug("Created Todoist task: %s", call.data[CONTENT]) hass.services.register(DOMAIN, SERVICE_NEW_TASK, handle_new_task, schema=NEW_TASK_SERVICE_SCHEMA)
import pandas as pd from todoist.api import TodoistAPI api = TodoistAPI('df864d9cbf7b4e669e50bf626fa088eef855ff5e') api.sync() # .data attribute retrieves a python dictionary rather than todoist.models.Project projects = [project.data for project in api.state['projects']] # I can easily create a DataFrame on the 'projects' list of dicts df_projects = pd.DataFrame(projects) df_projects.head() tasks = [task.data for task in api.state['items']] df_tasks = pd.DataFrame(tasks) df_tasks.head() df_tasks['date_added'] = pd.to_datetime(( pd.to_datetime(df_tasks['date_added'], utc=True).dt.tz_convert( 'Europe/Budapest') # my current timezone .dt.strftime("%Y-%m-%d %H:%M:%S"))) # easier to handle format df_tasks['due_date_utc'] = pd.to_datetime((pd.to_datetime( df_tasks['due_date_utc'], utc=True).dt.tz_convert('Europe/Budapest').dt.strftime("%Y-%m-%d %H:%M:%S") )) df_tasks['date_completed'] = pd.to_datetime((pd.to_datetime( df_tasks['date_completed'], utc=True).dt.tz_convert('Europe/Budapest').dt.strftime("%Y-%m-%d %H:%M:%S")
def __init__(self, token_line, token_todoist, vacation_mode_pj=None): self._holidays = requests.get( "https://holidays-jp.github.io/api/v1/date.json").json() self._line_notify = LineNotify(token_line, name="todoist") self._todoist_api = TodoistAPI(token_todoist, cache="/tmp/") self._todoist_vacation_mode_pj = vacation_mode_pj
#!/usr/local/bin/python # TODOIST from datetime import date, timedelta, datetime from dateutil import parser from todoist.api import TodoistAPI import creds # PROJECTS / IDs todoist_api = TodoistAPI() # GET ALL TASKS WITH DUE DATE def todoist_list(date): # Sync (load) data todoist_api.sync() tasks = [] for item in todoist_api.state['items']: due = item['due_date_utc'] if due: # Slicing :10 gives us the relevant parts if due[:10] == date: tasks.append(item) # Sort by priority
def __init__(self): self.api = TodoistAPI(get_token()) self.api.sync()
# Todoist Export for Python 3 from todoist.api import TodoistAPI import pandas as pd import json # Authentification with open("credentials.json", "r") as file: credentials = json.load(file) todoist_cr = credentials['todoist'] TOKEN = todoist_cr['TOKEN'] api = TodoistAPI(TOKEN) # Intitial Sync api.sync() # User Info user = api.state['user'] user_name = user['full_name'] # User Projects user_projects = api.state['projects'] projects = pd.DataFrame([p.data for p in user_projects]) print("Creating Export of Current Todoist Projects") df.write_csv("data/todoist-projects.csv") # User Stats stats = api.completed.get_stats()