From 619489a1d08fbdfe698fe625614d84b8f849c13d Mon Sep 17 00:00:00 2001 From: Hoffelhas Date: Mon, 9 Jan 2023 22:33:15 +0100 Subject: [PATCH 1/5] Initial update of check_header function. Still to finish and test --- autodoist.py | 185 +++++++++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 88 deletions(-) diff --git a/autodoist.py b/autodoist.py index 3282025..da78533 100644 --- a/autodoist.py +++ b/autodoist.py @@ -150,10 +150,10 @@ def db_check_existance(connection, model): if isinstance(model, Task): q_create = """ INSERT INTO - tasks (task_id, task_type, parent_type, r_tag) + tasks (task_id, task_type, parent_type, due_date, r_tag) VALUES - (%r, %s, %s, %i); - """ % (model.id, 'NULL', 'NULL', 0) + (%r, %s, %s, %s, %i); + """ % (model.id, 'NULL', 'NULL', 'NULL', 0) if isinstance(model, Section): q_create = """ @@ -208,6 +208,7 @@ def initialise_sqlite(): task_id INTEGER, task_type TEXT, parent_type TEXT, + due_date TEXT, r_tag INTEGER ); """ @@ -506,7 +507,7 @@ def get_type(args, connection, model, key): elif isinstance(model, Project): current_type = check_name(args, model.name, 3) # Projects - # Check if project type changed with respect to previous run + # Check if type changed with respect to previous run if old_type == current_type: type_changed = 0 else: @@ -607,25 +608,36 @@ def update_labels(api, overview_task_ids, overview_task_labels): # Check if header logic needs to be applied -def check_header(level): +def check_header(api, model): header_all_in_level = False unheader_all_in_level = False - method = 0 + regex_a = '(^[*]{2}\s*)(.*)' + regex_b = '(^!\*\s*)(.*)' - if method == 1: - if name[:3] == '** ': + if isinstance(model, Task): + ra = re.search(regex_a, model.content) + rb = re.search(regex_b, model.content) + prefix_a = ra[0] + prefix_b = rb[0] + + if prefix_a: header_all_in_level = True - level.update(name=name[3:]) - if name[:3] == '!* ' or name[:3] == '_* ': + api.update_task(task_id=model.id, content=ra[2]) + if prefix_b: unheader_all_in_level = True - level.update(name=name[3:]) - elif method == 2: - if content[:3] == '** ': - header_all_in_level = True - level.update(content=content[3:]) - if content[:3] == '!* ' or content[:3] == '_* ': - unheader_all_in_level = True - level.update(content=content[3:]) + api.update_task(task_id=model.id, content=ra[2]) + + # api.update_section(section_id="7025", name="Supermarket") + # api.update_project(project_id="2203306141", name="Things To Buy") + + # elif isinstance(model, Section) or isinstance(model, Project): + # if name[:3] == '** ': + # header_all_in_level = True + # level.update(name=name[3:]) + # if name[:3] == '!* ' or name[:3] == '_* ': + # unheader_all_in_level = True + # level.update(name=name[3:]) + else: pass @@ -687,43 +699,52 @@ def check_regen_mode(api, item, regen_labels_id): # Recurring lists logic -def run_recurring_lists_logic(args, api, item, child_items, child_items_all, regen_labels_id): +def run_recurring_lists_logic(args, api,connection, task, task_items, task_items_all, regen_labels_id): - if item['parent_id'] == 0: + if task.parent_id == 0: try: - if item['due']['is_recurring']: + if task.due.is_recurring: try: - # Check if the T0 task date has changed - if item['due']['date'][:10] != item['date_old']: + db_task_due_date = db_read_value(connection, task, 'due_date')[0][0] - # Mark children for action based on mode - if args.regeneration is not None: + if db_task_due_date is None: + # If date has never been saved before, create a new entry + logging.debug( + 'New recurring task detected: %s' % task.content) + db_update_value(connection, task, 'due_date', task.due.date) - # Check if task has a regen label - regen_mode = check_regen_mode( - api, item, regen_labels_id) + # Check if the T0 task date has changed, because a user has checked the task + if task.due.date != db_task_due_date: - # If no label, use general mode instead - if regen_mode is None: - regen_mode = args.regeneration - logging.debug('Using general recurring mode \'%s\' for item: %s', - regen_mode, item.content) - else: - logging.debug('Using recurring label \'%s\' for item: %s', - regen_mode, item.content) + #TODO: reevaluate regeneration mode. Disabled for now. + # # Mark children for action based on mode + # if args.regeneration is not None: - # Apply tags based on mode - give_regen_tag = 0 + # # Check if task has a regen label + # regen_mode = check_regen_mode( + # api, item, regen_labels_id) - if regen_mode == 1: # Regen all - give_regen_tag = 1 - elif regen_mode == 2: # Regen if all sub-tasks completed - if not child_items: - give_regen_tag = 1 + # # If no label, use general mode instead + # if regen_mode is None: + # regen_mode = args.regeneration + # logging.debug('Using general recurring mode \'%s\' for item: %s', + # regen_mode, item.content) + # else: + # logging.debug('Using recurring label \'%s\' for item: %s', + # regen_mode, item.content) - if give_regen_tag == 1: - for child_item in child_items_all: - child_item['r_tag'] = 1 + # # Apply tags based on mode + # give_regen_tag = 0 + + # if regen_mode == 1: # Regen all + # give_regen_tag = 1 + # elif regen_mode == 2: # Regen if all sub-tasks completed + # if not child_items: + # give_regen_tag = 1 + + # if give_regen_tag == 1: + # for child_item in child_items_all: + # child_item['r_tag'] = 1 # If alternative end of day, fix due date if needed if args.end is not None: @@ -735,10 +756,8 @@ def run_recurring_lists_logic(args, api, item, child_items, child_items_all, reg if (args.end - current_hour) > 0: # Determine the difference in days set by todoist - nd = [ - int(x) for x in item['due']['date'][:10].split('-')] - od = [ - int(x) for x in item['date_old'][:10].split('-')] + nd = [int(x) for x in task.due.date.split('-')] + od = [int(x) for x in db_task_due_date.split('-')] new_date = datetime( nd[0], nd[1], nd[2]) @@ -755,49 +774,39 @@ def run_recurring_lists_logic(args, api, item, child_items, child_items_all, reg if days_overdue >= 1 and days_difference == 1: # Find current date in string format - today_str = [str(x) for x in [ - today.year, today.month, today.day]] - if len(today_str[1]) == 1: - today_str[1] = ''.join( - ['0', today_str[1]]) + today_str = t.strftime("%Y-%m-%d") # Update due-date to today - item_due = item['due'] - item_due['date'] = '-'.join( - today_str) - item.update(due=item_due) - # item.update(due={'date': '2020-05-29', 'is_recurring': True, 'string': 'every day'}) + api.update_task(task_id=task.id, due_date=today_str) #TODO: Apparently this breaks the reccuring string... + logging.info("Update date on task: '%s'" % (task.content)) # Save the new date for reference us - item.update( - date_old=item['due']['date'][:10]) + db_update_value(connection, task, 'due_date', task.due.date) except: # If date has never been saved before, create a new entry logging.debug( - 'New recurring task detected: %s' % item.content) - item['date_old'] = item['due']['date'][:10] - api.items.update(item['id']) + 'New recurring task detected: %s' % task.content) + db_update_value(connection, task, 'due_date', task.due.date) except: - # logging.debug( - # 'Parent not recurring: %s' % item.content) pass + + #TODO: reevaluate regeneration mode. Disabled for now. + # if args.regeneration is not None and item.parent_id != 0: + # try: + # if item['r_tag'] == 1: + # item.update(checked=0) + # item.update(in_history=0) + # item['r_tag'] = 0 + # api.items.update(item['id']) - if args.regeneration is not None and item['parent_id'] != 0: - try: - if item['r_tag'] == 1: - item.update(checked=0) - item.update(in_history=0) - item['r_tag'] = 0 - api.items.update(item['id']) - - for child_item in child_items_all: - child_item['r_tag'] = 1 - except: - # logging.debug('Child not recurring: %s' % - # item.content) - pass + # for child_item in child_items_all: + # child_item['r_tag'] = 1 + # except: + # # logging.debug('Child not recurring: %s' % + # # item.content) + # pass # Find and clean all children under a task @@ -840,7 +849,7 @@ def autodoist_magic(args, api, connection): db_check_existance(connection, project) # Check if we need to (un)header entire project - header_all_in_p, unheader_all_in_p = check_header(project) + header_all_in_p, unheader_all_in_p = check_header(api, project) # Get project type if next_action_label is not None: @@ -896,7 +905,7 @@ def autodoist_magic(args, api, connection): db_check_existance(connection, section) # Check if we need to (un)header entire secion - header_all_in_s, unheader_all_in_s = check_header(section) + header_all_in_s, unheader_all_in_s = check_header(api, section) # Get section type if next_action_label: @@ -951,7 +960,7 @@ def autodoist_magic(args, api, connection): filter(lambda x: x.parent_id == task.id, non_completed_tasks)) # Check if we need to (un)header entire task tree - header_all_in_t, unheader_all_in_t = check_header(task) + header_all_in_t, unheader_all_in_t = check_header(api, task) # Modify headers where needed # TODO: DISABLED FOR NOW, FIX LATER @@ -968,10 +977,10 @@ def autodoist_magic(args, api, connection): # except: # pass - # # If options turned on, start recurring lists logic - # if args.regeneration is not None or args.end: - # run_recurring_lists_logic( - # args, api, item, child_items, child_items_all, regen_labels_id) + # If options turned on, start recurring lists logic #TODO: regeneration currently doesn't work, becaue TASK_ENDPOINT doesn't show completed tasks. Use workaround. + if args.regeneration is not None or args.end: + run_recurring_lists_logic( + args, api, connection, task, child_tasks, child_tasks_all, regen_labels_id) # If options turned on, start labelling logic if next_action_label is not None: From e1c0060afba369517b61e453acc48039aef94c2d Mon Sep 17 00:00:00 2001 From: Hoffelhas Date: Thu, 12 Jan 2023 21:32:51 +0100 Subject: [PATCH 2/5] check_header function updated --- autodoist.py | 54 +++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/autodoist.py b/autodoist.py index da78533..e314384 100644 --- a/autodoist.py +++ b/autodoist.py @@ -612,34 +612,40 @@ def check_header(api, model): header_all_in_level = False unheader_all_in_level = False regex_a = '(^[*]{2}\s*)(.*)' - regex_b = '(^!\*\s*)(.*)' + regex_b = '(^\-\*\s*)(.*)' - if isinstance(model, Task): - ra = re.search(regex_a, model.content) - rb = re.search(regex_b, model.content) - prefix_a = ra[0] - prefix_b = rb[0] + try: + if isinstance(model, Task): + ra = re.search(regex_a, model.content) + rb = re.search(regex_b, model.content) - if prefix_a: - header_all_in_level = True - api.update_task(task_id=model.id, content=ra[2]) - if prefix_b: - unheader_all_in_level = True - api.update_task(task_id=model.id, content=ra[2]) + if ra: + header_all_in_level = True + api.update_task(task_id=model.id, content=ra[2]) + if rb: + unheader_all_in_level = True + api.update_task(task_id=model.id, content=rb[2]) + else: + ra = re.search(regex_a, model.name) + rb = re.search(regex_b, model.name) - # api.update_section(section_id="7025", name="Supermarket") - # api.update_project(project_id="2203306141", name="Things To Buy") + if isinstance(model, Section): + if ra: + header_all_in_level = True + api.update_section(section_id=model.id, name=ra[2]) + if rb: + unheader_all_in_level = True + api.update_section(section_id=model.id, name=rb[2]) - # elif isinstance(model, Section) or isinstance(model, Project): - # if name[:3] == '** ': - # header_all_in_level = True - # level.update(name=name[3:]) - # if name[:3] == '!* ' or name[:3] == '_* ': - # unheader_all_in_level = True - # level.update(name=name[3:]) - - else: - pass + elif isinstance(model, Project): + if ra: + header_all_in_level = True + api.update_project(project_id=model.id, name=ra[2]) + if rb: + unheader_all_in_level = True + api.update_project(project_id=model.id, name=rb[2]) + except: + logging.debug('check_header: no right model found') return header_all_in_level, unheader_all_in_level From bf6ce05ad82c90a377e7918a37bf2b49a51f0565 Mon Sep 17 00:00:00 2001 From: Hoffelhas Date: Thu, 12 Jan 2023 21:42:21 +0100 Subject: [PATCH 3/5] bugfix needed: modify_headers does seem to work correctly at parentless task level --- autodoist.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/autodoist.py b/autodoist.py index e314384..21db084 100644 --- a/autodoist.py +++ b/autodoist.py @@ -652,20 +652,21 @@ def check_header(api, model): # Logic for applying and removing headers -def modify_headers(task, child_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t): +def modify_headers(api, task, child_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t): if any([header_all_in_p, header_all_in_s, header_all_in_t]): if task.content[0] != '*': - task.update(content='* ' + task.content) + api.update_task(task_id=task.id, content='* ' + task.content) + for ci in child_tasks: if not ci.content.startswith('*'): - ci.update(content='* ' + ci.content) + api.update_task(task_id=ci.id, content='* ' + ci.content) if any([unheader_all_in_p, unheader_all_in_s]): if task.content[0] == '*': - task.update(content=task.content[2:]) + api.update_task(task_id=task.id, content=task.content[2:]) + if unheader_all_in_t: - [ci.update(content=ci.content[2:]) - for ci in child_tasks] + [api.update_task(task_id=ci.id, content=ci.content[2:]) for ci in child_tasks] # Check regen mode based on label name @@ -969,8 +970,7 @@ def autodoist_magic(args, api, connection): header_all_in_t, unheader_all_in_t = check_header(api, task) # Modify headers where needed - # TODO: DISABLED FOR NOW, FIX LATER - # modify_headers(header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t) + modify_headers(api, task, child_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t) # TODO: Check is regeneration is still needed, now that it's part of core Todoist. Disabled for now. # Logic for recurring lists From 707482cf1769834aa6bc5d56091de15a5a48a2bf Mon Sep 17 00:00:00 2001 From: Hoffelhas Date: Fri, 13 Jan 2023 16:35:00 +0100 Subject: [PATCH 4/5] Adding and removing headers defined on parentless task level now processes all children correctly. --- autodoist.py | 51 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/autodoist.py b/autodoist.py index 21db084..fd93c19 100644 --- a/autodoist.py +++ b/autodoist.py @@ -621,9 +621,11 @@ def check_header(api, model): if ra: header_all_in_level = True + model.content = ra[2] # Local record api.update_task(task_id=model.id, content=ra[2]) if rb: unheader_all_in_level = True + model.content = rb[2] # Local record api.update_task(task_id=model.id, content=rb[2]) else: ra = re.search(regex_a, model.name) @@ -652,21 +654,27 @@ def check_header(api, model): # Logic for applying and removing headers -def modify_headers(api, task, child_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t): - if any([header_all_in_p, header_all_in_s, header_all_in_t]): - if task.content[0] != '*': +def modify_task_headers(api, task, section_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t): + + if any([header_all_in_p, header_all_in_s]): + if task.content[:2] != '* ': api.update_task(task_id=task.id, content='* ' + task.content) - - for ci in child_tasks: - if not ci.content.startswith('*'): - api.update_task(task_id=ci.id, content='* ' + ci.content) - + if any([unheader_all_in_p, unheader_all_in_s]): - if task.content[0] == '*': + if task.content[:2] == '* ': api.update_task(task_id=task.id, content=task.content[2:]) + if header_all_in_t: + if task.content[:2] != '* ': + api.update_task(task_id=task.id, content='* ' + task.content) + find_and_headerify_all_children(api, task, section_tasks, 1) + if unheader_all_in_t: - [api.update_task(task_id=ci.id, content=ci.content[2:]) for ci in child_tasks] + if task.content[:2] == '* ': + api.update_task(task_id=task.id, content=task.content[2:]) + find_and_headerify_all_children(api, task, section_tasks, 2) + + # Check regen mode based on label name @@ -829,6 +837,27 @@ def find_and_clean_all_children(task_ids, task, section_tasks): return task_ids +def find_and_headerify_all_children(api, task, section_tasks, mode): + + child_tasks = list(filter(lambda x: x.parent_id == task.id, section_tasks)) + + if child_tasks != []: + for child_task in child_tasks: + # Children found, go deeper + if mode == 1: + if child_task.content[:2] != '* ': + api.update_task(task_id=child_task.id, content='* ' + child_task.content) + + elif mode == 2: + if child_task.content[:2] == '* ': + api.update_task(task_id=child_task.id, content=child_task.content[2:]) + + find_and_headerify_all_children(api, child_task, section_tasks, mode) + + + + return 0 + # Contains all main autodoist functionalities @@ -970,7 +999,7 @@ def autodoist_magic(args, api, connection): header_all_in_t, unheader_all_in_t = check_header(api, task) # Modify headers where needed - modify_headers(api, task, child_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t) + modify_task_headers(api, task, section_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t) # TODO: Check is regeneration is still needed, now that it's part of core Todoist. Disabled for now. # Logic for recurring lists From 4dcce138c013335e727fbf8930c44eb2aea96436 Mon Sep 17 00:00:00 2001 From: Hoffelhas Date: Fri, 13 Jan 2023 16:58:16 +0100 Subject: [PATCH 5/5] Added logic to show correct change counter in terminal --- autodoist.py | 60 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/autodoist.py b/autodoist.py index fd93c19..2ffdd1a 100644 --- a/autodoist.py +++ b/autodoist.py @@ -377,7 +377,7 @@ def initialise_api(args): api = TodoistAPI(**api_arguments) - logging.info("Autodoist has connected and is running fine!\n") + logging.info("Autodoist has successfully connected to Todoist!\n") # Check if labels exist @@ -608,7 +608,7 @@ def update_labels(api, overview_task_ids, overview_task_labels): # Check if header logic needs to be applied -def check_header(api, model): +def check_header(api, model, overview_updated_ids): header_all_in_level = False unheader_all_in_level = False regex_a = '(^[*]{2}\s*)(.*)' @@ -623,10 +623,12 @@ def check_header(api, model): header_all_in_level = True model.content = ra[2] # Local record api.update_task(task_id=model.id, content=ra[2]) + # overview_updated_ids.append(model.id) # Ignore this one, since else it's count double if rb: unheader_all_in_level = True model.content = rb[2] # Local record api.update_task(task_id=model.id, content=rb[2]) + overview_updated_ids.append(model.id) else: ra = re.search(regex_a, model.name) rb = re.search(regex_b, model.name) @@ -635,17 +637,21 @@ def check_header(api, model): if ra: header_all_in_level = True api.update_section(section_id=model.id, name=ra[2]) + overview_updated_ids.append(model.id) if rb: unheader_all_in_level = True api.update_section(section_id=model.id, name=rb[2]) + overview_updated_ids.append(model.id) elif isinstance(model, Project): if ra: header_all_in_level = True api.update_project(project_id=model.id, name=ra[2]) + overview_updated_ids.append(model.id) if rb: unheader_all_in_level = True api.update_project(project_id=model.id, name=rb[2]) + overview_updated_ids.append(model.id) except: logging.debug('check_header: no right model found') @@ -654,25 +660,29 @@ def check_header(api, model): # Logic for applying and removing headers -def modify_task_headers(api, task, section_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t): +def modify_task_headers(api, task, section_tasks, overview_updated_ids, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t): if any([header_all_in_p, header_all_in_s]): if task.content[:2] != '* ': api.update_task(task_id=task.id, content='* ' + task.content) + overview_updated_ids.append(task.id) if any([unheader_all_in_p, unheader_all_in_s]): if task.content[:2] == '* ': api.update_task(task_id=task.id, content=task.content[2:]) + overview_updated_ids.append(task.id) if header_all_in_t: if task.content[:2] != '* ': api.update_task(task_id=task.id, content='* ' + task.content) - find_and_headerify_all_children(api, task, section_tasks, 1) + overview_updated_ids.append(task.id) + find_and_headerify_all_children(api, task, section_tasks, overview_updated_ids, 1) if unheader_all_in_t: if task.content[:2] == '* ': api.update_task(task_id=task.id, content=task.content[2:]) - find_and_headerify_all_children(api, task, section_tasks, 2) + overview_updated_ids.append(task.id) + find_and_headerify_all_children(api, task, section_tasks, overview_updated_ids, 2) @@ -714,7 +724,7 @@ def check_regen_mode(api, item, regen_labels_id): # Recurring lists logic -def run_recurring_lists_logic(args, api,connection, task, task_items, task_items_all, regen_labels_id): +def run_recurring_lists_logic(args, api, connection, overview_updated_ids, task, task_items, task_items_all, regen_labels_id): if task.parent_id == 0: try: @@ -793,7 +803,8 @@ def run_recurring_lists_logic(args, api,connection, task, task_items, task_items # Update due-date to today api.update_task(task_id=task.id, due_date=today_str) #TODO: Apparently this breaks the reccuring string... - logging.info("Update date on task: '%s'" % (task.content)) + logging.debug("Update date on task: '%s'" % (task.content)) + overview_updated_ids.append(task.id) # Save the new date for reference us db_update_value(connection, task, 'due_date', task.due.date) @@ -837,7 +848,7 @@ def find_and_clean_all_children(task_ids, task, section_tasks): return task_ids -def find_and_headerify_all_children(api, task, section_tasks, mode): +def find_and_headerify_all_children(api, task, section_tasks, overview_updated_ids, mode): child_tasks = list(filter(lambda x: x.parent_id == task.id, section_tasks)) @@ -847,12 +858,14 @@ def find_and_headerify_all_children(api, task, section_tasks, mode): if mode == 1: if child_task.content[:2] != '* ': api.update_task(task_id=child_task.id, content='* ' + child_task.content) + overview_updated_ids.append(child_task.id) elif mode == 2: if child_task.content[:2] == '* ': api.update_task(task_id=child_task.id, content=child_task.content[2:]) + overview_updated_ids.append(child_task.id) - find_and_headerify_all_children(api, child_task, section_tasks, mode) + find_and_headerify_all_children(api, child_task, section_tasks, overview_updated_ids, mode) @@ -866,10 +879,12 @@ def autodoist_magic(args, api, connection): # Preallocate dictionaries and other values overview_task_ids = {} overview_task_labels = {} + overview_updated_ids = [] next_action_label = args.label regen_labels_id = args.regen_label_names first_found = [False, False, False] - + + # Get all projects info try: projects = api.get_projects() except Exception as error: @@ -885,7 +900,7 @@ def autodoist_magic(args, api, connection): db_check_existance(connection, project) # Check if we need to (un)header entire project - header_all_in_p, unheader_all_in_p = check_header(api, project) + header_all_in_p, unheader_all_in_p = check_header(api, project, overview_updated_ids) # Get project type if next_action_label is not None: @@ -941,7 +956,7 @@ def autodoist_magic(args, api, connection): db_check_existance(connection, section) # Check if we need to (un)header entire secion - header_all_in_s, unheader_all_in_s = check_header(api, section) + header_all_in_s, unheader_all_in_s = check_header(api, section, overview_updated_ids) # Get section type if next_action_label: @@ -996,10 +1011,10 @@ def autodoist_magic(args, api, connection): filter(lambda x: x.parent_id == task.id, non_completed_tasks)) # Check if we need to (un)header entire task tree - header_all_in_t, unheader_all_in_t = check_header(api, task) + header_all_in_t, unheader_all_in_t = check_header(api, task, overview_updated_ids) # Modify headers where needed - modify_task_headers(api, task, section_tasks, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t) + modify_task_headers(api, task, section_tasks, overview_updated_ids, header_all_in_p, unheader_all_in_p, header_all_in_s, unheader_all_in_s, header_all_in_t, unheader_all_in_t) # TODO: Check is regeneration is still needed, now that it's part of core Todoist. Disabled for now. # Logic for recurring lists @@ -1015,7 +1030,7 @@ def autodoist_magic(args, api, connection): # If options turned on, start recurring lists logic #TODO: regeneration currently doesn't work, becaue TASK_ENDPOINT doesn't show completed tasks. Use workaround. if args.regeneration is not None or args.end: run_recurring_lists_logic( - args, api, connection, task, child_tasks, child_tasks_all, regen_labels_id) + args, api, connection, overview_updated_ids, task, child_tasks, child_tasks_all, regen_labels_id) # If options turned on, start labelling logic if next_action_label is not None: @@ -1280,7 +1295,7 @@ def autodoist_magic(args, api, connection): first_found[0] = True # Return all ids and corresponding labels that need to be modified - return overview_task_ids, overview_task_labels + return overview_task_ids, overview_task_labels, overview_updated_ids # Main @@ -1358,23 +1373,22 @@ def main(): # sync(api) # Evaluate projects, sections, and tasks - overview_task_ids, overview_task_labels = autodoist_magic( + overview_task_ids, overview_task_labels, overview_updated_ids = autodoist_magic( args, api, connection) # Commit next action label changes if args.label is not None: updated_ids = update_labels(api, overview_task_ids, overview_task_labels) + num_changes = len(updated_ids)+len(overview_updated_ids) - if len(updated_ids): - len_api_q = len(updated_ids) - - if len_api_q == 1: + if num_changes: + if num_changes == 1: logging.info( - '%d change committed to Todoist.', len_api_q) + '%d change committed to Todoist.', num_changes) else: logging.info( - '%d changes committed to Todoist.', len_api_q) + '%d changes committed to Todoist.', num_changes) else: logging.info('No changes in queue, skipping sync.')