Compare commits

...

145 Commits

Author SHA1 Message Date
Hoffelhas 335cb3ae75 Update README.me to v2.0 2023-01-15 22:17:09 +01:00
Hoffelhas 6a0b64f256
Update README v2.0 2023-01-15 22:11:11 +01:00
Hoffelhas a560a59857 Final preparations for v2.0 2023-01-15 22:00:00 +01:00
Hoffelhas 1f8f6ab182
Merge pull request #31 from obbardc/wip/obbardc/docker-dev
Build and publish Docker image in GitHub actions
2023-01-15 21:57:12 +01:00
Hoffelhas 8a1bc1d5ec Final preparations for v2.0 2023-01-15 21:55:30 +01:00
Hoffelhas 2ce81df5bd
Update README to v2.0 functionalities 2023-01-15 18:10:43 +01:00
Hoffelhas 956f5176af Final preparations for v2.0 2023-01-15 16:38:34 +01:00
Hoffelhas 8fe99f4942
Update README to v2.0.0 functionality. 2023-01-15 15:50:00 +01:00
Hoffelhas 78dca0483e
Update README to v2.0.0 functionality. 2023-01-15 15:48:22 +01:00
Hoffelhas 565967cdc1
Update README to v2.0.0 functionality. 2023-01-15 15:44:37 +01:00
Hoffelhas d6d1ba121f
Update README to v2.0.0 functionality. 2023-01-15 15:42:17 +01:00
Hoffelhas 8b23fbd59a Final preparations for v2.0 2023-01-15 14:08:25 +01:00
Hoffelhas a4f99fa0c1 Minor clean-up of code 2023-01-15 13:53:28 +01:00
Hoffelhas a66905e88c Only sync changes if api.queue has content. Else we'll time out after 45 minutes of no changes. 2023-01-15 11:02:26 +01:00
Hoffelhas cf57687068 Implemented the filtered lists. Significant decrease of api requests and noticable speed-up! 2023-01-15 00:24:17 +01:00
Hoffelhas adb7ae86de Build project and section dictionary from api.get_tasks() to save on api requests. Still todo: implement this into the loops. 2023-01-14 23:57:22 +01:00
Hoffelhas 8541f06d92 Implemented SYNC API and commit queue, to ensure task content updates are sent in batches. This to ensure we don't run into the requests limits. 2023-01-14 22:01:09 +01:00
Hoffelhas b741b83b14 Added possibility to ignore section labelling by providing a * either at the start or end of the section name. Useful for additional flexibility with e.g. kanban board. 2023-01-13 21:32:06 +01:00
Christopher Obbard 0231937b8f Build and publish Docker image in GitHub actions
Add the ability to build a Docker image in GitHub actions and push that
image to the GitHub container registry.

Signed-off-by: Christopher Obbard <chris.obbard@collabora.com>
2023-01-13 18:13:17 +00:00
Christopher Obbard 2ee1088e9c Add Dockerfile
Add a Dockerfile to have the ability to build a container from the app.

Signed-off-by: Christopher Obbard <chris.obbard@collabora.com>
2023-01-13 18:13:17 +00:00
Christopher Obbard f47e974c7c Allow setting Todoist API key from environment variable
In the Docker world, secrets (e.g. passwords, API keys) are usually shared
with an application as environment variables so that they can be imported
from separate secure areas: in docker-compose you can specify a file
where secrets are imported from as environment variables.

Read the API key from the TODOIST_API_KEY environment variable first, then
check the command-line argument.

Signed-off-by: Christopher Obbard <chris.obbard@collabora.com>
2023-01-13 18:11:53 +00:00
Hoffelhas 1312474e53 Manually added a similar fix as proposed in pull request #20 2023-01-13 18:02:46 +01:00
Hoffelhas e41dab3156 Minor cleanup 2023-01-13 17:02:53 +01:00
Hoffelhas 3a02d0d8c9 Fixed merge issues 2023-01-13 17:01:43 +01:00
Hoffelhas 4dcce138c0 Added logic to show correct change counter in terminal 2023-01-13 16:58:16 +01:00
Hoffelhas 707482cf17 Adding and removing headers defined on parentless task level now processes all children correctly. 2023-01-13 16:35:00 +01:00
Hoffelhas bf6ce05ad8 bugfix needed: modify_headers does seem to work correctly at parentless task level 2023-01-12 21:42:21 +01:00
Hoffelhas e1c0060afb check_header function updated 2023-01-12 21:32:51 +01:00
Hoffelhas 685da743ab Fix found for updating the due task date, which keeps the recurring string intact 2023-01-12 21:04:49 +01:00
Hoffelhas 7f766a5df7 Minor update 2023-01-10 20:24:33 +01:00
Hoffelhas ce8044d5a7 Minor update to get_all_data 2023-01-10 20:20:54 +01:00
Hoffelhas 619489a1d0 Initial update of check_header function. Still to finish and test 2023-01-09 22:33:15 +01:00
Hoffelhas af63bb97c0 Minor addition of logging 2023-01-09 21:45:08 +01:00
Hoffelhas 24d88460fb Changed end-of-day functionality, but apparently updating the due-date with the new API will remove the recurring settings. Brilliant. Need to find a fix for this. 2023-01-08 22:23:54 +01:00
Hoffelhas 4aad462ce3 Start=due-x functionality working again. Time set by user is now also included in the diff calculation 2023-01-08 18:42:16 +01:00
Hoffelhas 81769968ae Start=DD-MM-YYYY functionality working again. 2023-01-08 18:13:06 +01:00
Hoffelhas 43e598a87a Fixed -hf flag not working correctly 2023-01-08 17:37:24 +01:00
Hoffelhas b2f2fa270e Bugfix where manually changing the order of sequential tasks would not remove old labels. 2023-01-08 17:11:47 +01:00
Hoffelhas 97a7073f1c Minor cleanup of code 2023-01-08 16:21:50 +01:00
Hoffelhas a589c159c0 Type indication now seems to work on all levels 2023-01-08 15:32:21 +01:00
Hoffelhas 86eb720f50 Overhaul labelling functionality now working on project level. Next: debug section and parentless tasks level. 2023-01-08 14:58:49 +01:00
Hoffelhas aa274d5132 Additional testing of labelling logic 2023-01-07 16:13:43 +01:00
Hoffelhas e9b2dd6f21 Fixed labelling bug with SEQ mode due to legacy code 2023-01-07 15:44:56 +01:00
Hoffelhas fc9aa8da4f Children are now cleaned correctly after task_type change 2023-01-07 15:07:57 +01:00
Hoffelhas 0c64e99455 Core labelling functionality now seems to function. Still need to fix one bug with cleaning children if task_type is set. 2023-01-04 21:12:39 +01:00
Hoffelhas 4a236153d0 Added 'get_all_data' function to use the SYNC API v9 to obtain all the data in your Todoist. Needed for seeing e.g. completed tasks, which the REST API v2 does not provide. 2023-01-04 10:01:00 +01:00
Hoffelhas 374d216a83 Basic SQLite DB functionality now working. Next: rewrite 'get_task_type()' function, and start some refactoring/debugging. 2023-01-03 16:06:46 +01:00
Hoffelhas 2625547002 Basic labelling functionality working again. Still need to fix metadata storage 2023-01-02 16:28:16 +01:00
Hoffelhas 95a71524cd Initial changes made to REST API. Working on a Sync API workaround to find completed tasks now. 2022-12-17 19:31:19 +01:00
Hoffelhas 3a25e05aa3 Initial check of 'T0 task date has changed' still included the time, hence check always failed. Now [:10] has been added to exclude a time during the check 2021-09-20 13:26:47 +02:00
Hoffelhas 7857a397fc Times in a due date could now be processed. At the moment, only the first 10 string characters are read, which only includes 'YYYY-MM-DD'. This has been updated for all relevant variables which use the due date. 2021-08-24 16:14:22 +02:00
Hoffelhas 67935a5b0c
Update README.md 2021-08-24 14:53:59 +02:00
Hoffelhas 482f27ff50 Added hotfix for detection of underscore replacement of the exclamation mark 2021-08-24 14:49:34 +02:00
Hoffelhas 2dd6f06b13
Merge pull request #15 from GwyndolynMarchant/datefix
Fix for shifted end-of-day
2021-08-24 14:22:10 +02:00
Gwyndolyn Marchant d0b074e0fe fix for shifted end-of-day 2021-06-16 23:02:27 -04:00
Hoffelhas 5f3fef0e8f
Update README.md 2021-01-25 19:50:42 +01:00
Hoffelhas 50c126b332
Update README.md 2021-01-25 19:49:24 +01:00
Hoffelhas 11f9830fea
Update README.md 2021-01-25 19:48:45 +01:00
Hoffelhas 0215af31fd
Update README.md 2021-01-25 18:27:07 +01:00
Hoffelhas a38f14e40c
Update README.md 2021-01-25 18:25:28 +01:00
Hoffelhas 319171251f
Update README.md 2021-01-25 18:21:50 +01:00
Hoffelhas c7ab4e564c v1.5 2021-01-25 18:00:43 +01:00
Hoffelhas d129885bbc setup.py update 2021-01-23 21:53:17 +01:00
Hoffelhas 097ea0caae Updated todoist-python to version 8.1.3 and added requests 2.25.1 2021-01-23 21:48:19 +01:00
Hoffelhas 4c421b7577 Fixed bug with incorrect label recognition. Added new debug logging lines, and removed redundant ones 2021-01-23 21:29:06 +01:00
Hoffelhas a4ac562068 Made -r tag backwards compatible with v1.4 2021-01-17 15:14:33 +01:00
Hoffelhas bd9e5d021b Fixed a view bugs for the new regeneration mode, plus some additional clean-up of code. In addition fixed a labelling bug on deeper levels, and headered items will be cleaned of old next-action labels. 2021-01-17 14:58:14 +01:00
Hoffelhas f97c7e70e0 Implemented new structure for regeneration mode. New modes have been added, and specific modes can be assigned to tasks by use of labels. 2021-01-16 22:42:46 +01:00
Hoffelhas 376e176d6b General clean-up of code 2021-01-16 17:14:22 +01:00
Hoffelhas 17cc3a8418 Wrong warning message was given for a different kind of wrong syntax; additional warning added. 2021-01-16 15:54:21 +01:00
Hoffelhas 16d404a9ed Fixed bug which caused a wrong read of the start=DATE string 2020-12-31 16:02:58 +01:00
Hoffelhas 22fab54dfc
Update README.md 2020-12-30 14:22:33 +01:00
Hoffelhas d1f6ac802c
Update README.md 2020-12-30 14:12:56 +01:00
Hoffelhas ea20ad2aa1 Clean-up for v1.4 2020-12-30 13:46:20 +01:00
Hoffelhas ecbe8a28fa Added logic to header or unheader multiple items, specifiec from project, section, or top item level 2020-12-30 13:21:16 +01:00
Hoffelhas 346702b904 Debug header_items 2020-12-30 01:32:17 +01:00
Hoffelhas 3e14d69653 Added possibility to define start-date as an offset from due-date. 2020-12-30 00:35:07 +01:00
Hoffelhas 41c3cc3b5c Tested new section logic. In addition 'delay' has been optimised by taking computation time into account. General clean-up of code 2020-12-29 22:56:55 +01:00
Hoffelhas c50f62d946 Sections refactoring completed. Next up, code-cleanup and testing 2020-12-28 23:18:54 +01:00
Hoffelhas 3943c5c614 Pseudocode updated, section loop build-in, still need to build a class to handle 'no section' tasks, and finalize labeling logic 2020-12-17 21:02:30 +01:00
Hoffelhas a913c74086 Decided to add a separate section loop to allow for a better flow of the logic. Initial start made, still needs to be fleshed out. 2020-12-16 22:05:27 +01:00
Hoffelhas 6d3439019c Continued work on section labelling 2020-12-07 22:45:12 +01:00
Hoffelhas c1b14f55ac Added section type functionality. Still needs incorporation with label logic 2020-12-07 17:44:12 +01:00
Hoffelhas 70567cacf5 Initial modifications to include section type 2020-12-06 23:08:47 +01:00
Hoffelhas 0d18c8c8b6
Update README.md 2020-09-25 13:59:54 +02:00
Hoffelhas f3bd20cf8c
Update README.md 2020-06-15 19:01:23 +02:00
Hoffelhas 4f7981aee8
Update README.md 2020-06-13 18:55:14 +02:00
Hoffelhas 21d80334ee
Update README.md 2020-06-13 18:41:47 +02:00
Hoffelhas bc7f6938b6
Update README.md 2020-06-13 18:39:24 +02:00
Hoffelhas b6466130f4
Update README.md 2020-06-13 18:37:39 +02:00
Hoffelhas 7bd8b5a91a
Update README.md 2020-06-13 18:36:37 +02:00
Hoffelhas 4f531dd0dc
Update README.md 2020-06-13 18:27:15 +02:00
Hoffelhas 55e0153677 Testing start-date and hide-future concluded 2020-06-13 17:45:08 +02:00
Hoffelhas 9645942c5c 1) Hide-future date has been fixed 2) start-date functionality added 2020-06-13 15:26:56 +02:00
Hoffelhas 82b8bd2385 Implemented first iteration of asynchronous labelling of proejct/parentless tasks and sub-tasks 2020-06-13 11:13:03 +02:00
Hoffelhas 50830eaaa8 Prompt if user wants to create an undefined label, instead of auto-creating 2020-06-07 16:20:55 +02:00
Hoffelhas fa3d7fa1dd If the given label doesn't exists, a new one is now automatically created! 2020-06-07 15:18:12 +02:00
Hoffelhas b2430dcb1e Added modes check and CLI output as additional feedback during initialising 2020-06-07 14:59:47 +02:00
Hoffelhas 9c947b7292
Update README.md 2020-05-30 15:34:19 +02:00
Hoffelhas 3d8fb97c93
Update README.md 2020-05-30 14:46:19 +02:00
Hoffelhas ff31adc65b Put second sync back in, for some reason this makes it much more stable.
Final testing concluded, pushing for release.
2020-05-30 13:49:37 +02:00
Hoffelhas a552954d8b Bug has magically gone away on Todoist's end. For now moving on.
Parser lay-out, help content, and arguments have been improved.
2020-05-30 13:14:07 +02:00
Hoffelhas c4792b9a17 Strange bug found when testing the modulised lay-out.
Tasks that have been given an old_date show unexplained behaviour.
If set on today and recurring every day, checking it will move it TWO days.
2020-05-30 12:29:25 +02:00
Hoffelhas 4690b68245 Finalised test of alternative end-of-day time 2020-05-30 10:19:45 +02:00
Hoffelhas f51d7cb46a Implemented the functionality for an alternative end-of-day time. 2020-05-29 22:11:27 +02:00
Hoffelhas 011e100173 Quick and dirty test for an alternative end-of-day time when checking a daily recurring task. 2020-05-28 21:51:20 +02:00
Hoffelhas f9fddf934e
Update README.md 2020-05-24 18:10:06 +02:00
Hoffelhas d288738652 Modified logger to include console output.
Modified log-messages to be more read-friendly.
Decreased default delay from 10 to 5 seconds
2020-05-24 17:50:09 +02:00
Hoffelhas 0c47cfa81c Complete overhaul of label-logic.
1) Labels are again used as primary markers for cascading the information.
2) API queue only gets filled with items that require an update. This drastically lowers the size of the queue.
3) Removal of legacy code.
2020-05-24 15:57:47 +02:00
Hoffelhas 9e9567efaf version check logic added 2020-05-24 11:11:17 +02:00
Hoffelhas 473964155c
Update README.md 2020-05-21 19:07:18 +02:00
Hoffelhas e38409eac1
Update README.md 2020-05-21 19:06:31 +02:00
Hoffelhas f1fc145157 Modified .gitignore 2020-05-21 10:32:14 +02:00
Hoffelhas 4f21175f65 Update 2020-05-21 10:12:14 +02:00
Hoffelhas cbe5cba074 - Bugfix: serial tag on task level and project level not working properly
- Bugfix: Recurring task child_list has to include all children, even if checked. Not relevant for labels. Hence two lists are now created for both purposes.
2020-05-21 10:00:06 +02:00
Hoffelhas 1926c2e6a3 - Fixed a bug that prevented sequential subtasks in a parallel project
- Renamed legacy 'serial' keywords to 'sequential'
2020-05-17 18:02:38 +02:00
Hoffelhas a21d271c98
Update README.md 2020-05-15 21:35:47 +02:00
Hoffelhas b7d27f7bdd
Update README.md 2020-05-13 22:35:07 +02:00
Hoffelhas b24dd9b868 Update README.md 2020-05-13 21:27:25 +02:00
Hoffelhas a106464764 Update autodoist.py
Fixed bug in which checked children were still processed in the sequential loop
2020-05-13 21:27:22 +02:00
Hoffelhas f021a84bf7 Applied fix to the sequential label logic 2020-05-13 21:27:20 +02:00
Hoffelhas 9dbbd87720 Stash 2020-05-13 21:27:17 +02:00
Hoffelhas f8fb8a77aa Update README.md 2020-05-13 21:27:14 +02:00
Hoffelhas a8d9ce9f09 setup.py update 2020-05-13 21:27:11 +02:00
Hoffelhas 5efacae2c7 Update README.md 2020-05-13 21:27:09 +02:00
Hoffelhas fe4894262c Update README.md 2020-05-13 21:27:06 +02:00
Hoffelhas 37110c13b4 Updated logging 2020-05-13 21:27:04 +02:00
Hoffelhas 3bdf7c0cfe Update README.md 2020-05-13 21:27:00 +02:00
Hoffelhas 40bba64a96 Update README.md 2020-05-13 21:26:57 +02:00
Hoffelhas 7a3ef7eb76 Update README.md 2020-05-13 21:26:54 +02:00
Hoffelhas ce75dcfe50 Fix of recursive mode parser argument 2020-05-13 21:26:39 +02:00
Hoffelhas 5d034abf53 Update README.md
Addition of new functionality.
2020-05-13 21:26:33 +02:00
Hoffelhas d5cda02204 Merge branch 'master' of https://github.com/Hoffelhas/automation-todoist 2020-05-13 21:26:24 +02:00
Hoffelhas 03a16b7d77 Update README.md
Added gifs with examples of the possible types.
2020-05-13 21:26:21 +02:00
Hoffelhas c9031a3c07 Namechange to autodoist 2020-05-13 21:26:18 +02:00
Hoffelhas 56ced1ca1e Namechange to autodoist 2020-05-13 21:26:15 +02:00
Hoffelhas 6b4ad87457 Added parse option and logic for re-use of sub-tasks if a parentless task is recursive 2020-05-13 21:26:12 +02:00
Hoffelhas 27ac1abdfc Minor bugfix and reformatting 2020-05-13 21:26:09 +02:00
Hoffelhas 91523cbbe1 Minor bugfixes 2020-05-13 21:26:06 +02:00
Hoffelhas b7ba10c001 Minor bugfixes in serial and parallel logic 2020-05-13 21:26:03 +02:00
Hoffelhas 347e0afcf1 Minor bugfixes in serial and parallel logic 2020-05-13 21:26:01 +02:00
Hoffelhas a4fd835474 Update README.md 2020-05-13 21:25:58 +02:00
Hoffelhas f89bb1abfe Update README.md 2020-05-13 21:25:51 +02:00
Hoffelhas a616e2eba9 Update README.md 2020-05-13 21:25:49 +02:00
Hoffelhas 3ef9371967 Major overhaul of the program functionality.
- Projects can be of types parallel, serial, or none.
- Parentless tasks can be given a type independently of the project type which is enforced on its own tree of tasks.
	- If a project has a type, but a parentless task has not: project type is used.
	- If a project has a type, but so does the parentless task: the latter type is used.
	- If a project has no type, but a parentless task has: the latter type is used.
- Tags on projects and parentless tasks can be removed, which will automatically clear next-actions labels.
2020-05-13 21:25:45 +02:00
9 changed files with 1804 additions and 221 deletions

41
.github/workflows/ci.yaml vendored Normal file
View File

@ -0,0 +1,41 @@
name: Build and publish Docker image
on:
push:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-publish-docker-image:
name: Build and publish Docker image
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Log in to the Container registry
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v3
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- name: Build and push Docker image
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

6
.gitignore vendored
View File

@ -57,4 +57,8 @@ target/
# IDEA
.idea/
.env
.env
# VSCODE
.json
.vscode

10
Dockerfile Normal file
View File

@ -0,0 +1,10 @@
FROM python:3-slim-bullseye
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
ENTRYPOINT [ "python", "./autodoist.py" ]

View File

@ -1 +0,0 @@
nextaction: python nextaction.py -a $TODOIST_API_KEY -l $TODOIST_NEXT_ACTION_LABEL $DEBUG --nocache

209
README.md
View File

@ -1,40 +1,195 @@
NextAction
==========
# Autodoist
A more GTD-like workflow for Todoist. Uses the REST API to add and remove a `@next_action` label from tasks.
*Note: v2.0 is a major overhaul of Autodoist, so please be sure to view the README in order to get up to speed with the latest changes. Thanks to everyone for helping out and supporting this project!*
This program looks at every list in your Todoist account.
Any list that ends with `_` or `.` is treated specially, and processed by NextAction.
This program adds four major functionalities to Todoist to help automate your workflow:
Note that NextAction requires Todoist Premium to function properly, as labels are a premium feature.
1) Assign automatic `@next_action` labels for a more GTD-like workflow
- Flexible options to label tasks sequentially or in parallel
- Limit labels based on a start-date or hide future tasks based on the due date
2) [Temporary disabled] Enable regeneration of sub-tasks in lists with a recurring date. Multiple modes possible.
3) Postpone the end-of-day time to after midnight to finish your daily recurring tasks
4) Make multiple tasks (un)checkable at the same time
Requirements
============
If this tool helped you out, I would really appreciate your support by providing me with some coffee!
* Python 2.7, Python 3.0+ is unsupported at the moment
* ```todoist-python``` package.
<a href=https://ko-fi.com/hoffelhas>
<img src="https://i.imgur.com/MU1rAPG.png" width="150">
</a>
Activating NextAction
=====================
# Requirements
Sequential list processing
--------------------------
If a project or task ends with `_`, the child tasks will be treated as a priority queue and the most important will be labeled `@next_action`.
Importance is determined by order in the list
Autodoist has been build with Python 3.11.1, which is the recommended version. Older versions of 3.x should be compatible, however be aware that they have not been tested.
Parallel list processing
------------------------
If a project or task name ends with `.`, the child tasks will be treated as parallel `@next_action`s.
The waterfall processing will be applied the same way as sequential lists - every parent task will be treated as sequential. This can be overridden by appending `_` to the name of the parent task.
To run Autodoist the following packages are required:
* ```todoist-python```
* ```requests```
Executing NextAction
====================
For your convenience a requirements.txt is provided, which allows you to install them by using pip:
You can run NexAction from any system that supports Python.
`pip install -r requirements.txt`
Running NextAction
------------------
# 1. Automatic next action labels
NextAction will read your environment to retrieve your Todoist API key, so to run on a Linux/Mac OSX you can use the following commandline
The program looks for pre-defined tags in the name of every project, section, or parentless tasks in your Todoist account to automatically add and remove `@next_action` labels.
python nextaction.py -a <API Key>
Projects, sections, and parentless tasks can be tagged independently of each other to create the required functionality. If this tag is not defined, it will not activate this functionality. The result will be a clear, current and comprehensive list of next actions without the need for further thought.
See the example given at [running Autodoist](#running-autodoist) on how to run this mode. If the label does not exist yet in your Todoist, a possibility is given to automatically create it.
## Useful filter tip
For a more GTD-like workflow, you can use Todoist filters to create a clean and cohesive list that only contains your actionable tasks. As a simple example, you could use the following filter:
`@next_action & #PROJECT_NAME`
## Sequential processing
If a project, section, or parentless task ends with a dash `-`, the tasks will be treated sequentially in a priority queue, where only the first task that is found is labeled. If a task contains sub-tasks, the first lowest task is labeled instead.
![Sequential task labeling](https://i.imgur.com/ZUKbA8E.gif)
## Parallel processing
If a project, section, or parentless task name ends with an equal sign `=`, all tasks will be treated in parallel. A waterfall processing is applied, where the lowest possible (sub-)tasks are labelled.
![Parallel task labeling](https://i.imgur.com/xZZ0kEM.gif)
## Advanced labelling
Projects, sections, and (parentless) tasks can be used to specify how the levels under them should behave. This means that:
- A project can accept up to three tags, to specify how the sections, parentless tasks, and subtasks should behave.
- A section can accept up to two tags, to specify parentless tasks and subtasks should behave.
- A task at any level can be labelled with one tag, to specify how its sub-tasks should behave.
Tags can be applied on each level simultaneously, where the lower level setting will always override the one specified in the levels above.
### Shorthand notation
If fewer tags then needed are specified, the last one is simply copied. E.g. if a project has the tag `=` this is similar to `===`, or if a project has `=-` this is similar to `=--`. Same for sections, `=` is similar to `==`.
### Project labeling examples
- If a project ends with `---`, only the first section has tasks that are handled sequentially.
- If a project ends with `=--`, all sections have tasks that are handled sequentially.
- If a project ends with `-=-`, only the first section has parallel parentless tasks with sequential sub-tasks.
- If a project ends with `--=`, only the first section and first parentless tasks has parallel sub-tasks.
- If a project ends with `==-`, all sections and all parentless tasks will have sub-tasks are handled sequentially.
- If a project ends with `=-=`, all sections will have parentless tasks that are processed sequentially, but all sub-tasks are handled in parallel.
- If a project ends with `-==`, only the first section has parallel tasks.
- If a project ends with `===`, all tasks are handled in parallel.
### Section labeling examples
- If a section ends with `--`, only the first parentless task will have sub-tasks that are handled sequentially.
- If a section ends with `=-`, all parentless tasks will have sub-tasks that are handled sequentially.
- If a section ends with `-=`, only the first parentless task has sub-tasks that are handled in parallel.
- If a section ends with `==`, all tasks are handled in parallel.
### Tasks labeling examples
- If a task ends with `-`, the sub-tasks are handled sequentially.
- If a task ends with `=`, the sub-tasks are handled in parallel.
### Kanban board labeling
A standard workflow for Kanban boards is to have one actionable task per column/section, which is then moved to the next column when needed. Most often, the most right column is the 'done' section. To ensure that every column only has one labelled task and the last column contains no labelled tasks, you could do either of two things:
- Add the `=--` tag to the project name, and disable labelling for the 'done' section by adding `*` to either the start or end of the section name.
- Add the `--` tag to every section that you want to have labels.
## Start/Due date enhanced experience
Two methods are provided to hide tasks that are not relevant yet.
- Prevent labels by defining a start-date that is added to the task itself. The label is only assigned if this date is reached. You can define the start-date by adding 'start=DD-MM-YYYY'. On the other hand, the start date can be defined as several days or weeks before the due-date by using either 'start=due-<NUMBER_OF_DAYS>d' or 'start=due-<NUMBER_OF_WEEKS>w'. This is especially useful for recurring tasks!
[See an example of using start-dates](https://i.imgur.com/WJRoJzW.png).
- Prevent labels of all tasks if the due date is too far in the future. Define the amount by running with the argument '-hf <NUMBER_OF_DAYS>'.
[See an example of the hide-future functionality](https://i.imgur.com/LzSoRUm.png).
# 2. Regenerate sub-tasks in recurring lists
*DISCLAIMER: This feature has been disabled for now due to two reasons:*
- *Regeneration is a [core feature of Todoist nowadays](https://todoist.com/help/articles/can-i-reset-sub-tasks). This was made possible thanks to all of you who are using and supporting Autodoist, which resulted in Doist to include this too! Thank you all for making this happen!*
- *In the new REST API v2 it's currently not possible to see completed tasks, which makes regeneration a bit difficult.*
*Nevertheless, the Todoist implementation is still more limited than Autodoist, it does not restore the original order of the sub-tasks, and deeper sub-tasks can't be reset. I therefore believe it is still useful for this feature to be re-enabled in the near future.*
Autodoist looks for all parentless tasks with a recurring date. If they contain sub-tasks, they will be regenerated in the same order when the parentless task is checked.
![See example](https://i.imgur.com/WKKd14o.gif)
To give you more flexibility, multiple modes are provided:
1. No regeneration
2. Checking the main task regenerates all sub-tasks
3. Checking the main task regenerates all sub-tasks only if all sub-tasks have been checked first
When this functionality is activated, it is possible to chose which mode is used as overall functionality for your Todoist. See the example given at [running Autodoist](#running-autodoist).
In addition you can override the overall mode by adding the labels `Regen_off`, `Regen_all`, or `Regen_all_if_completed` to one of your main recurring task. These labels will automatically be created for you.
# 3. Postpone the end-of-day
You have a daily recurring task, but you're up working late and now it's past midnight. When this happens, Todoist will automatically mark it overdue and when checked by you it moves to tomorrow. This means that after a good night's rest you can't complete the task that day!
By setting an alternative time for the end-of-day you can now finish your work after midnight and the new date will automatically be corrected for you.
![See example 1](https://i.imgur.com/tvnTMOJ.gif)
# 4. Make multiple tasks uncheckable / re-checkable at the same time
Todoist allows the asterisk symbol `* ` to be used to ensure tasks can't be checked by turning them into headers. Now you are able to do this en masse!
Simply add `** ` or `-* ` in front of a project, section, or parentless task to automatically turn all the tasks that it includes into respectively headers or checkable tasks.
# Executing Autodoist
You can run Autodoist from any system that supports Python.
## Running Autodoist
Autodoist will read your environment to retrieve your Todoist API key and additional arguments. In order to run on Windows/Linux/Mac OSX you can use the following command lines.
If you want to enable labelling mode, run with the `-l` argument:
python autodoist.py -a <API Key> -l <LABEL_NAME>
If you want to enable regeneration of sub-tasks in recurring lists, run with the `-r` argument followed by a mode number for the overall functionality (1: no regeneration, 2: regenerate all, 3: regenerate only if all sub-tasks are completed):
python autodoist.py -a <API Key> -r <NUMBER>
If you want to enable an alternative end-of-day, run with the `-e` argument and a number from 1 to 24 to specify which hour:
python autodoist.py -a <API Key> -e <NUMBER>
These modes can be run individually, or combined with each other.
## Additional arguments
Several additional arguments can be provided, for example to change the suffix tags for parallel and sequential projects:
python autodoist.py --p_suffix <tag>
python autodoist.py --s_suffix <tag>
Note: Be aware that Todoist sections don't like to have a slash '/' in the name, which will automatically change to an underscore. Detection of the tag will not work.
If you want to hide all tasks due in the future:
python autodoist.py --hf <NUMBER_OF_DAYS>
In addition, if you experience issues with syncing you can increase the api syncing time (default 5 seconds):
python autodoist.py --delay <time in seconds>
For all arguments, please check out the help:
python autodoist.py --help
## Docker container
To build the docker container, check out the repository and run:
docker build . --tag autodoist:latest
To run autodoist inside the docker container:
docker run -it autodoist:latest

1556
autodoist.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,179 +0,0 @@
#!/usr/bin/env python
import logging
import argparse
from todoist.api import TodoistAPI
import time
import sys
from datetime import datetime
CHECKED = 1
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('-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='parallel', choices=['parallel', 'serial'])
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)
if len(labels) > 0:
label_id = 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'
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'
def add_label(item, label):
if label not in item['labels']:
labels = item['labels']
logging.debug('Updating \'%s\' with label', item['content'])
labels.append(label)
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)
api.items.update(item['id'], labels=labels)
# Main loop
while True:
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
items = sorted(api.items.all(lambda x: x['project_id'] == project['id']),
key=lambda x: x['child_order'])
# filter for completable items
items = list(filter(lambda x: not x['content'].startswith('*'), items))
first_found = False
for item in items:
# 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)
continue
if item['parent_id'] is None:
if project_type == 'serial':
if not first_found:
add_label(item, label_id)
first_found = True
else:
remove_label(item, label_id)
elif project_type == 'parallel':
add_label(item, label_id)
item_type = get_item_type(item)
child_items = list(filter(lambda x: x['parent_id'] == item['id'], items))
if item_type:
logging.debug('Identified \'%s\' as %s type', item['content'], item_type)
if item_type or len(child_items) > 0:
if label_id in item['labels']:
# Process serial tagged items
if item_type == 'serial':
child_first_found = False
for child_item in child_items:
if child_item['checked'] == 0 and not child_first_found:
add_label(child_item, label_id)
child_first_found = True
else:
remove_label(child_item, label_id)
# Process parallel tagged items or untagged parents
elif item_type == 'parallel':
for child_item in child_items:
add_label(child_item, label_id)
# Remove the label from the parent
remove_label(item, label_id)
else:
for child_item in child_items:
remove_label(child_item, label_id)
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)
if __name__ == '__main__':
main()

View File

@ -1 +1,2 @@
todoist-python>=8.1.1
requests==2.28.1
todoist_api_python==2.0.2

View File

@ -1,20 +1,16 @@
from setuptools import setup
setup(
name='NextAction',
version='0.5',
py_modules=['nextaction'],
url='https://github.com/nikdoof/NextAction',
name='autodoist',
version='2.0',
py_modules=['autodoist'],
url='https://github.com/Hoffelhas/automation-todoist',
license='MIT',
author='Andrew Williams',
author_email='andy@tensixtyone.com',
description='A more GTD-like workflow for Todoist. Uses the REST API to add and remove a @next_action label from tasks.',
entry_points={
"console_scripts": [
"nextaction=nextaction:main",
],
},
author='Alexander Haselhoff',
author_email='xela@live.nl',
description='Added functionality for Todoist: 1) next-action labels, 2) sub-task regeneration, 3) postpone end of day, and 4) (un)header items simultaneously)',
install_requires=[
'todoist-python',
'requests',
]
)