mirror of https://github.com/Hoffelhas/autodoist
Minor cleanup
parent
3a02d0d8c9
commit
e41dab3156
182
autodoist.py
182
autodoist.py
|
@ -51,7 +51,8 @@ def execute_query(connection, query, *args):
|
|||
cursor = connection.cursor()
|
||||
try:
|
||||
value = args[0]
|
||||
cursor.execute(query,(value,)) # Useful to pass None/NULL value correctly
|
||||
# Useful to pass None/NULL value correctly
|
||||
cursor.execute(query, (value,))
|
||||
except:
|
||||
cursor.execute(query)
|
||||
|
||||
|
@ -118,7 +119,8 @@ def db_update_value(connection, model, column, value):
|
|||
db_name = 'projects'
|
||||
goal = 'project_id'
|
||||
|
||||
query = """UPDATE %s SET %s = ? WHERE %s = %r""" % (db_name, column, goal, model.id)
|
||||
query = """UPDATE %s SET %s = ? WHERE %s = %r""" % (
|
||||
db_name, column, goal, model.id)
|
||||
|
||||
result = execute_query(connection, query, value)
|
||||
|
||||
|
@ -432,6 +434,7 @@ def check_for_update(current_version):
|
|||
|
||||
# Get all data through the SYNC API. Needed to see e.g. any completed tasks.
|
||||
|
||||
|
||||
def get_all_data(api):
|
||||
BASE_URL = "https://api.todoist.com"
|
||||
SYNC_VERSION = "v9"
|
||||
|
@ -482,8 +485,6 @@ def check_name(args, string, num):
|
|||
logging.debug("String {} not recognised.".format(string))
|
||||
current_type = None
|
||||
|
||||
|
||||
|
||||
return current_type
|
||||
|
||||
# Scan the end of a name to find what type it is
|
||||
|
@ -502,11 +503,11 @@ def get_type(args, connection, model, key):
|
|||
old_type = None
|
||||
|
||||
if isinstance(model, Task):
|
||||
current_type = check_name(args, model.content, 1) # Tasks
|
||||
current_type = check_name(args, model.content, 1) # Tasks
|
||||
elif isinstance(model, Section):
|
||||
current_type = check_name(args, model.name, 2) # Sections
|
||||
current_type = check_name(args, model.name, 2) # Sections
|
||||
elif isinstance(model, Project):
|
||||
current_type = check_name(args, model.name, 3) # Projects
|
||||
current_type = check_name(args, model.name, 3) # Projects
|
||||
|
||||
# Check if type changed with respect to previous run
|
||||
if old_type == current_type:
|
||||
|
@ -622,12 +623,12 @@ def check_header(api, model, overview_updated_ids):
|
|||
|
||||
if ra:
|
||||
header_all_in_level = True
|
||||
model.content = ra[2] # Local record
|
||||
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
|
||||
model.content = rb[2] # Local record
|
||||
api.update_task(task_id=model.id, content=rb[2])
|
||||
overview_updated_ids.append(model.id)
|
||||
else:
|
||||
|
@ -677,14 +678,15 @@ def modify_task_headers(api, task, section_tasks, overview_updated_ids, header_a
|
|||
if task.content[:2] != '* ':
|
||||
api.update_task(task_id=task.id, content='* ' + task.content)
|
||||
overview_updated_ids.append(task.id)
|
||||
find_and_headerify_all_children(api, task, section_tasks, overview_updated_ids, 1)
|
||||
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:])
|
||||
overview_updated_ids.append(task.id)
|
||||
find_and_headerify_all_children(api, task, section_tasks, overview_updated_ids, 2)
|
||||
|
||||
find_and_headerify_all_children(
|
||||
api, task, section_tasks, overview_updated_ids, 2)
|
||||
|
||||
|
||||
# Check regen mode based on label name
|
||||
|
@ -731,18 +733,20 @@ def run_recurring_lists_logic(args, api, connection, overview_updated_ids, task,
|
|||
try:
|
||||
if task.due.is_recurring:
|
||||
try:
|
||||
db_task_due_date = db_read_value(connection, task, 'due_date')[0][0]
|
||||
db_task_due_date = db_read_value(
|
||||
connection, task, 'due_date')[0][0]
|
||||
|
||||
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)
|
||||
db_update_value(connection, task,
|
||||
'due_date', task.due.date)
|
||||
|
||||
# Check if the T0 task date has changed, because a user has checked the task
|
||||
if task.due.date != db_task_due_date:
|
||||
|
||||
#TODO: reevaluate regeneration mode. Disabled for now.
|
||||
# TODO: reevaluate regeneration mode. Disabled for now.
|
||||
# # Mark children for action based on mode
|
||||
# if args.regeneration is not None:
|
||||
|
||||
|
@ -783,7 +787,8 @@ def run_recurring_lists_logic(args, api, connection, overview_updated_ids, task,
|
|||
|
||||
# Determine the difference in days set by todoist
|
||||
nd = [int(x) for x in task.due.date.split('-')]
|
||||
od = [int(x) for x in db_task_due_date.split('-')]
|
||||
od = [int(x)
|
||||
for x in db_task_due_date.split('-')]
|
||||
|
||||
new_date = datetime(
|
||||
nd[0], nd[1], nd[2])
|
||||
|
@ -803,22 +808,26 @@ def run_recurring_lists_logic(args, api, connection, overview_updated_ids, task,
|
|||
today_str = t.strftime("%Y-%m-%d")
|
||||
|
||||
# Update due-date to today
|
||||
api.update_task(task_id=task.id, due_date=today_str, due_string=task.due.string) #TODO: Apparently this breaks the reccuring string...
|
||||
logging.info("Update date on task: '%s'" % (task.content))
|
||||
api.update_task(
|
||||
task_id=task.id, due_date=today_str, due_string=task.due.string)
|
||||
logging.info(
|
||||
"Update date on task: '%s'" % (task.content))
|
||||
|
||||
# Save the new date for reference us
|
||||
db_update_value(connection, task, 'due_date', task.due.date)
|
||||
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' % task.content)
|
||||
db_update_value(connection, task, 'due_date', task.due.date)
|
||||
db_update_value(connection, task,
|
||||
'due_date', task.due.date)
|
||||
|
||||
except:
|
||||
pass
|
||||
|
||||
#TODO: reevaluate regeneration mode. Disabled for now.
|
||||
# TODO: reevaluate regeneration mode. Disabled for now.
|
||||
# if args.regeneration is not None and item.parent_id != 0:
|
||||
# try:
|
||||
# if item['r_tag'] == 1:
|
||||
|
@ -836,6 +845,7 @@ def run_recurring_lists_logic(args, api, connection, overview_updated_ids, task,
|
|||
|
||||
# Find and clean all children under a task
|
||||
|
||||
|
||||
def find_and_clean_all_children(task_ids, task, section_tasks):
|
||||
|
||||
child_tasks = list(filter(lambda x: x.parent_id == task.id, section_tasks))
|
||||
|
@ -844,10 +854,12 @@ def find_and_clean_all_children(task_ids, task, section_tasks):
|
|||
for child_task in child_tasks:
|
||||
# Children found, go deeper
|
||||
task_ids.append(child_task.id)
|
||||
task_ids = find_and_clean_all_children(task_ids, child_task, section_tasks)
|
||||
task_ids = find_and_clean_all_children(
|
||||
task_ids, child_task, section_tasks)
|
||||
|
||||
return task_ids
|
||||
|
||||
|
||||
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))
|
||||
|
@ -857,17 +869,18 @@ def find_and_headerify_all_children(api, task, section_tasks, overview_updated_i
|
|||
# Children found, go deeper
|
||||
if mode == 1:
|
||||
if child_task.content[:2] != '* ':
|
||||
api.update_task(task_id=child_task.id, content='* ' + child_task.content)
|
||||
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:])
|
||||
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, overview_updated_ids, mode)
|
||||
|
||||
|
||||
find_and_headerify_all_children(
|
||||
api, child_task, section_tasks, overview_updated_ids, mode)
|
||||
|
||||
return 0
|
||||
|
||||
|
@ -900,7 +913,8 @@ 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, overview_updated_ids)
|
||||
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:
|
||||
|
@ -920,7 +934,8 @@ def autodoist_magic(args, api, connection):
|
|||
if next_action_label is not None:
|
||||
if project_type_changed == 1:
|
||||
for task in project_tasks:
|
||||
remove_label(task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
remove_label(task, next_action_label,
|
||||
overview_task_ids, overview_task_labels)
|
||||
db_update_value(connection, task, 'task_type', None)
|
||||
db_update_value(connection, task, 'parent_type', None)
|
||||
|
||||
|
@ -956,7 +971,8 @@ 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, overview_updated_ids)
|
||||
header_all_in_s, unheader_all_in_s = check_header(
|
||||
api, section, overview_updated_ids)
|
||||
|
||||
# Get section type
|
||||
if next_action_label:
|
||||
|
@ -968,7 +984,7 @@ def autodoist_magic(args, api, connection):
|
|||
|
||||
# Get all tasks for the section
|
||||
section_tasks = [x for x in project_tasks if x.section_id
|
||||
== section.id]
|
||||
== section.id]
|
||||
|
||||
# Change top tasks parents_id from 'None' to '0' in order to numerically sort later on
|
||||
for task in section_tasks:
|
||||
|
@ -985,7 +1001,8 @@ def autodoist_magic(args, api, connection):
|
|||
if next_action_label is not None:
|
||||
if section_type_changed == 1:
|
||||
for task in section_tasks:
|
||||
remove_label(task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
remove_label(task, next_action_label,
|
||||
overview_task_ids, overview_task_labels)
|
||||
db_update_value(connection, task, 'task_type', None)
|
||||
db_update_value(connection, task, 'parent_type', None)
|
||||
|
||||
|
@ -1001,7 +1018,6 @@ def autodoist_magic(args, api, connection):
|
|||
# Check db existance
|
||||
db_check_existance(connection, task)
|
||||
|
||||
|
||||
# Determine which child_tasks exist, both all and the ones that have not been checked yet
|
||||
non_completed_tasks = list(
|
||||
filter(lambda x: not x.is_completed, section_tasks))
|
||||
|
@ -1011,10 +1027,12 @@ 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, overview_updated_ids)
|
||||
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, 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)
|
||||
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
|
||||
|
@ -1045,13 +1063,18 @@ def autodoist_magic(args, api, connection):
|
|||
db_update_value(connection, task, 'task_type', None)
|
||||
db_update_value(connection, task, 'parent_type', None)
|
||||
|
||||
task_ids = find_and_clean_all_children([], task, section_tasks)
|
||||
child_tasks_all = list(filter(lambda x: x.id in task_ids, section_tasks))
|
||||
task_ids = find_and_clean_all_children(
|
||||
[], task, section_tasks)
|
||||
child_tasks_all = list(
|
||||
filter(lambda x: x.id in task_ids, section_tasks))
|
||||
|
||||
for child_task in child_tasks_all:
|
||||
remove_label(child_task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
db_update_value(connection, child_task, 'task_type', None)
|
||||
db_update_value(connection, child_task, 'parent_type', None)
|
||||
remove_label(child_task, next_action_label,
|
||||
overview_task_ids, overview_task_labels)
|
||||
db_update_value(
|
||||
connection, child_task, 'task_type', None)
|
||||
db_update_value(
|
||||
connection, child_task, 'parent_type', None)
|
||||
|
||||
continue
|
||||
|
||||
|
@ -1064,13 +1087,18 @@ def autodoist_magic(args, api, connection):
|
|||
if task_type_changed == 1:
|
||||
|
||||
# Find all children under this task
|
||||
task_ids = find_and_clean_all_children([], task, section_tasks)
|
||||
child_tasks_all = list(filter(lambda x: x.id in task_ids, section_tasks))
|
||||
task_ids = find_and_clean_all_children(
|
||||
[], task, section_tasks)
|
||||
child_tasks_all = list(
|
||||
filter(lambda x: x.id in task_ids, section_tasks))
|
||||
|
||||
for child_task in child_tasks_all:
|
||||
remove_label(child_task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
db_update_value(connection, child_task, 'task_type', None)
|
||||
db_update_value(connection, child_task, 'parent_type', None)
|
||||
remove_label(
|
||||
child_task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
db_update_value(
|
||||
connection, child_task, 'task_type', None)
|
||||
db_update_value(
|
||||
connection, child_task, 'parent_type', None)
|
||||
|
||||
# Determine hierarchy types for logic
|
||||
hierarchy_types = [task_type,
|
||||
|
@ -1080,7 +1108,8 @@ def autodoist_magic(args, api, connection):
|
|||
|
||||
# If task has no type, but has a label, most likely the order has been changed by user. Remove data.
|
||||
if not True in hierarchy_boolean and next_action_label in task.labels:
|
||||
remove_label(task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
remove_label(task, next_action_label,
|
||||
overview_task_ids, overview_task_labels)
|
||||
db_update_value(connection, task, 'task_type', None)
|
||||
db_update_value(connection, task, 'parent_type', None)
|
||||
|
||||
|
@ -1106,51 +1135,63 @@ def autodoist_magic(args, api, connection):
|
|||
|
||||
if dominant_type[1] == 's':
|
||||
if not first_found[1]:
|
||||
add_label(connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
add_label(
|
||||
connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
elif next_action_label in task.labels:
|
||||
# Probably the task has been manually moved, so if it has a label, let's remove it.
|
||||
remove_label(task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
remove_label(
|
||||
task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
elif dominant_type[1] == 'p':
|
||||
add_label(connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
add_label(
|
||||
connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
elif dominant_type[0] == 'p':
|
||||
|
||||
if dominant_type[1] == 's':
|
||||
if not first_found[1]:
|
||||
add_label(connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
add_label(
|
||||
connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
elif next_action_label in task.labels:
|
||||
# Probably the task has been manually moved, so if it has a label, let's remove it.
|
||||
remove_label(task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
remove_label(
|
||||
task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
elif dominant_type[1] == 'p':
|
||||
add_label(connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
add_label(
|
||||
connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
# If indicated on section level
|
||||
if dominant_type[0] == 'x' and dominant_type[1] == 's':
|
||||
if not first_found[1]:
|
||||
add_label(connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
add_label(
|
||||
connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
elif next_action_label in task.labels:
|
||||
# Probably the task has been manually moved, so if it has a label, let's remove it.
|
||||
remove_label(task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
remove_label(
|
||||
task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
elif dominant_type[0] == 'x' and dominant_type[1] == 'p':
|
||||
add_label(connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
add_label(connection, task, dominant_type, next_action_label,
|
||||
overview_task_ids, overview_task_labels)
|
||||
|
||||
# If indicated on parentless task level
|
||||
if dominant_type[1] == 'x' and dominant_type[2] == 's':
|
||||
if not first_found[1]:
|
||||
add_label(connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
add_label(
|
||||
connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
if next_action_label in task.labels:
|
||||
# Probably the task has been manually moved, so if it has a label, let's remove it.
|
||||
remove_label(task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
# Probably the task has been manually moved, so if it has a label, let's remove it.
|
||||
remove_label(
|
||||
task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
elif dominant_type[1] == 'x' and dominant_type[2] == 'p':
|
||||
add_label(connection, task, dominant_type, next_action_label, overview_task_ids, overview_task_labels)
|
||||
add_label(connection, task, dominant_type, next_action_label,
|
||||
overview_task_ids, overview_task_labels)
|
||||
|
||||
# If a parentless or sub-task which has children
|
||||
if len(child_tasks) > 0:
|
||||
|
@ -1181,7 +1222,8 @@ def autodoist_magic(args, api, connection):
|
|||
continue
|
||||
|
||||
# Clean up for good measure.
|
||||
remove_label(child_task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
remove_label(
|
||||
child_task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
|
||||
# Pass task_type down to the children
|
||||
db_update_value(
|
||||
|
@ -1230,7 +1272,8 @@ def autodoist_magic(args, api, connection):
|
|||
|
||||
# If start-date has not passed yet, remove label
|
||||
try:
|
||||
f1 = re.search('start=(\d{2}[-]\d{2}[-]\d{4})', task.content)
|
||||
f1 = re.search(
|
||||
'start=(\d{2}[-]\d{2}[-]\d{4})', task.content)
|
||||
if f1:
|
||||
start_date = f1.groups()[0]
|
||||
start_date = datetime.strptime(
|
||||
|
@ -1252,7 +1295,8 @@ def autodoist_magic(args, api, connection):
|
|||
# Recurring task friendly - remove label with relative change from due date
|
||||
if task.due is not None:
|
||||
try:
|
||||
f2 = re.search('start=due-(\d+)([dw])', task.content)
|
||||
f2 = re.search(
|
||||
'start=due-(\d+)([dw])', task.content)
|
||||
|
||||
if f2:
|
||||
offset = f2.groups()[0]
|
||||
|
@ -1264,9 +1308,11 @@ def autodoist_magic(args, api, connection):
|
|||
|
||||
# Determine start-date
|
||||
try:
|
||||
due_date = datetime.strptime(task.due.datetime, "%Y-%m-%dT%H:%M:%S")
|
||||
due_date = datetime.strptime(
|
||||
task.due.datetime, "%Y-%m-%dT%H:%M:%S")
|
||||
except:
|
||||
due_date = datetime.strptime(task.due.date, "%Y-%m-%d")
|
||||
due_date = datetime.strptime(
|
||||
task.due.date, "%Y-%m-%d")
|
||||
|
||||
start_date = due_date - td
|
||||
|
||||
|
@ -1278,7 +1324,7 @@ def autodoist_magic(args, api, connection):
|
|||
remove_label(
|
||||
task, next_action_label, overview_task_ids, overview_task_labels)
|
||||
[remove_label(child_task, next_action_label, overview_task_ids,
|
||||
overview_task_labels) for child_task in child_tasks]
|
||||
overview_task_labels) for child_task in child_tasks]
|
||||
continue
|
||||
|
||||
except:
|
||||
|
@ -1287,11 +1333,13 @@ def autodoist_magic(args, api, connection):
|
|||
continue
|
||||
|
||||
# Mark first found task in section
|
||||
if next_action_label is not None and first_found[1] == False: #TODO: is this always true? What about starred tasks?
|
||||
# TODO: is this always true? What about starred tasks?
|
||||
if next_action_label is not None and first_found[1] == False:
|
||||
first_found[1] = True
|
||||
|
||||
# Mark first found section with tasks in project (to account for None section)
|
||||
if next_action_label is not None and first_found[0] == False and section_tasks: #TODO: is this always true? What about starred tasks?
|
||||
# TODO: is this always true? What about starred tasks?
|
||||
if next_action_label is not None and first_found[0] == False and section_tasks:
|
||||
first_found[0] = True
|
||||
|
||||
# Return all ids and corresponding labels that need to be modified
|
||||
|
|
BIN
metadata.sqlite
BIN
metadata.sqlite
Binary file not shown.
Loading…
Reference in New Issue