diff --git a/todoist_github/tasks/assigned_issues.py b/todoist_github/tasks/assigned_issues.py index 8daf477..22d6793 100644 --- a/todoist_github/tasks/assigned_issues.py +++ b/todoist_github/tasks/assigned_issues.py @@ -6,6 +6,7 @@ from dateutil.relativedelta import relativedelta from todoist_github.clients import github, todoist from todoist_github.utils import get_github_issue_details, get_issue from todoist_github.utils.todoist import ( + get_project_for_issue, get_relevant_todoist_tasks, is_task_completed, issue_to_task_name, @@ -14,6 +15,10 @@ from todoist_github.utils.todoist import ( def assigned_issues(): todoist_tasks = get_relevant_todoist_tasks(todoist) + todoist.projects.sync() + todoist_projects = { + project["name"].lower(): project for project in todoist.state["projects"] + } relevant_since = datetime.datetime.now() - relativedelta( weeks=30 ) # TODO: Make this a sane number @@ -36,10 +41,15 @@ def assigned_issues(): if task["content"] != issue_to_task_name(assigned_issue): logging.info("Updating issue name for '%s'", assigned_issue.title) task.update(content=issue_to_task_name(assigned_issue)) + if assigned_issue.milestone and assigned_issue.milestone.due_on: task.update( date_string=assigned_issue.milestone.due_on.strftime("%d/%m/%Y") ) + todoist_project = get_project_for_issue(assigned_issue, todoist_projects) + if todoist_project and task["project_id"] != todoist_project["id"]: + logging.info("Updating project for '%s'", assigned_issue.title) + task.move(project_id=todoist_project["id"]) for task in todoist_tasks.values(): if not is_task_completed(task) or task["id"] in tasks_actioned: diff --git a/todoist_github/tasks/prs_to_review.py b/todoist_github/tasks/prs_to_review.py index 9a19545..f60f25e 100644 --- a/todoist_github/tasks/prs_to_review.py +++ b/todoist_github/tasks/prs_to_review.py @@ -1,7 +1,11 @@ import logging from todoist_github.clients import github, todoist -from todoist_github.utils.todoist import get_relevant_todoist_tasks, pr_to_task_name +from todoist_github.utils.todoist import ( + get_project_for_issue, + get_relevant_todoist_tasks, + pr_to_task_name, +) SEARCH_STRING = "is:pr review-requested:{username} archived:false" @@ -10,6 +14,10 @@ def prs_to_review(): relevant_tasks = get_relevant_todoist_tasks(todoist) me = github.get_user() search_string = SEARCH_STRING.format(username=me.login) + todoist.projects.sync() + todoist_projects = { + project["name"].lower(): project for project in todoist.state["projects"] + } tasks_actioned = [] for issue in github.search_issues(search_string): task = relevant_tasks.get(issue.html_url) @@ -22,3 +30,8 @@ def prs_to_review(): if task["content"] != pr_to_task_name(issue): logging.info("Updating issue name for '%s'", issue.title) task.update(content=pr_to_task_name(issue)) + + todoist_project = get_project_for_issue(issue, todoist_projects) + if todoist_project and task["project_id"] != todoist_project["id"]: + logging.info("Updating project for '%s'", issue.title) + task.move(project_id=todoist_project["id"]) diff --git a/todoist_github/utils/todoist.py b/todoist_github/utils/todoist.py index b1ba14b..40e8e1c 100644 --- a/todoist_github/utils/todoist.py +++ b/todoist_github/utils/todoist.py @@ -1,7 +1,12 @@ +import os +from itertools import chain + from github.Issue import Issue from . import get_github_task +SUB_PROJECT_NAMES = ["Tasks", "GitHub"] + def get_issue_link(issue_or_pr) -> str: return "[#{id}]({url})".format(id=issue_or_pr.number, url=issue_or_pr.html_url) @@ -27,3 +32,30 @@ def get_relevant_todoist_tasks(todoist): if github_task: tasks[github_task] = task return tasks + + +def get_project_for_issue(issue: Issue, todoist_projects: dict): + repo_name = issue.repository.full_name.split("/")[1] + search_terms = [ + issue.repository.full_name.split("/")[0], + ] + if issue.repository.organization: + search_terms.insert(0, issue.repository.organization.name) + elif issue.repository.owner: + search_terms.insert(0, issue.repository.owner.login) + search_terms.insert(0, issue.repository.owner.name) + search_terms.append(repo_name) # Always be at the end, as it's the least specific + + for search_term in search_terms: + if search_term.lower() in todoist_projects: + found_project = todoist_projects[search_term.lower()] + for project in todoist_projects.values(): + if project["parent_id"] != found_project["id"]: + continue + for sub_project_name in chain(SUB_PROJECT_NAMES, [repo_name]): + if project["name"].lower() == sub_project_name.lower(): + return project + return found_project + return todoist_projects.get( + os.environ.get("DEFAULT_TODOIST_PROJECT_NAME", "").lower() + )