Compare commits

...

7 Commits

Author SHA1 Message Date
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
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
5 changed files with 92 additions and 24 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 }}

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

@ -4,10 +4,10 @@
This program adds four major functionalities to Todoist to help automate your workflow:
1) Assign automatic next-action labels for a more GTD-like workflow
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) Enable regeneration of sub-tasks in lists with a recurring date. Multiple modes possile.
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
@ -19,7 +19,7 @@ If this tool helped you out, I would really appreciate your support by providing
# Requirements
Autodoist has been build with Python 3.9.1, which is the recommended version. Older versions of 3.x should be compatible, however be aware that they have not been tested.
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.
To run Autodoist the following packages are required:
* ```todoist-python```
@ -33,19 +33,19 @@ For your convenience a requirements.txt is provided, which allows you to install
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.
Projects, sections, and parentless tasks can be tagged independently from 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.
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:
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 suquentially 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.
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)
@ -61,9 +61,9 @@ Projects, sections, and (parentless) tasks can be used to specify how the levels
- 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 specifcy how its sub-tasks 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 one each level simultaneously , where the lower level setting will always override the one specified in the levels above.
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
@ -90,7 +90,7 @@ If fewer tags then needed are specified, the last one is simply copied. E.g. if
- 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:
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.
@ -99,7 +99,7 @@ A standard workflow for Kanban boards is to have one actionable task per column/
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!
- 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>'.
@ -124,11 +124,11 @@ To give you more flexibility, multiple modes are provided:
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 recurrings task. These labels will automatically be created for you.
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 nights rest you can't complete the task that 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.
@ -152,7 +152,7 @@ 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 ony if all sub-tasks are completed):
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>
@ -182,3 +182,14 @@ In addition, if you experience issues with syncing you can increase the api sync
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

View File

@ -324,7 +324,7 @@ def initialise_api(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")
"\n\nNo API key set. Run Autodoist with '-a <YOUR_API_KEY>' or set the environment variable TODOIST_API_KEY.\n")
sys.exit(1)
# Check if alternative end of day is used
@ -362,13 +362,19 @@ def initialise_api(args):
# Run the initial sync
logging.debug('Connecting to the Todoist API')
api_arguments = {'token': args.api_key}
api = TodoistAPI(**api_arguments)
logging.info("Autodoist has successfully connected to Todoist!")
try:
api_arguments = {'token': args.api_key}
api = TodoistAPI(**api_arguments)
sync_api = initialise_sync_api(api)
# Save SYNC API token to enable partial syncs
api.sync_token = sync_api['sync_token']
sync_api = initialise_sync_api(api)
# Save SYNC API token to enable partial syncs
api.sync_token = sync_api['sync_token']
except Exception as e:
logging.error(
f"Could not connect to Todoist: '{e}'")
exit(0)
logging.info("Autodoist has successfully connected to Todoist!")
# Check if labels exist
@ -1442,8 +1448,8 @@ def main():
# Main process functions.
parser = argparse.ArgumentParser(
formatter_class=make_wide(argparse.HelpFormatter, w=120, h=60))
parser.add_argument('-a', '--api_key',
help='takes your Todoist API Key.', type=str)
parser.add_argument(
'-a', '--api_key', help='takes your Todoist API Key.', default=os.environ.get('TODOIST_API_KEY'), type=str)
parser.add_argument(
'-l', '--label', help='enable next action labelling. Define which label to use.', type=str)
parser.add_argument(

View File

@ -2,12 +2,12 @@ from setuptools import setup
setup(
name='autodoist',
version='1.5',
version='2.0',
py_modules=['autodoist'],
url='https://github.com/Hoffelhas/automation-todoist',
license='MIT',
author='Alexander Haselhoff',
author_email='alexander.haselhoff@outlook.com',
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',