Skip to content
This repository has been archived by the owner on Feb 21, 2022. It is now read-only.

How to uncheck a subtree of tasks? #93

Open
dluxhu opened this issue Dec 22, 2020 · 9 comments
Open

How to uncheck a subtree of tasks? #93

dluxhu opened this issue Dec 22, 2020 · 9 comments

Comments

@dluxhu
Copy link

dluxhu commented Dec 22, 2020

Is it possible to query completed subtasks of active tasks somehow? I couldn't figure it out how:

  • api.items does not seem to return them.
  • api.completed.get_all() returns them, but they don't return the full property list (parent_id is missing for example) and it is not possible to filter for parent_id either.

What I'd like to do is to uncheck a whole subtree of tasks given a root task id.

@LloydThinks
Copy link

I have written a script that does this. You need to loop through all children one at a time, and uncomplete them.

@dluxhu
Copy link
Author

dluxhu commented Jan 31, 2021 via email

@dluxhu
Copy link
Author

dluxhu commented Jul 18, 2021

Any update on this by any chance?

@LloydThinks
Copy link

Hey @dluxhu perhaps I can help you out here. As I said, I have already written this functionality using this Todoist Python library. I will paste the function here that does it.

def get_sub_items(self, parent_id):
    sub_items = []
    for tds_item in self.api.state['items']:
        if tds_item['parent_id'] == parent_id:
            sub_items.append(self._tds_item_to_item(tds_item))
    return sub_items

def uncomplete_item(self, item, *, recursively=True):

    # Get the raw item, and complete it
    tds_item = item.tds_item
    
    # Only perform the uncomplete action IF the item is checked
    if tds_item['checked']:
        tds_item.uncomplete()
    
    # If the user wants it, uncomplete the children and attributes as well
    if recursively:
        # Uncomplete all sub-items (if they exist and have been requested above)
        for sub_item in self.get_sub_items(tds_item['id']):
            self.uncomplete_item(sub_item, recursively=True)
    
    return True

My code has some helper functions that translate data, etc., but this should give you an idea.

Lloyd

@dluxhu
Copy link
Author

dluxhu commented Jul 18, 2021 via email

@LloydThinks
Copy link

Hi @dluxhu , you'll notice that I am searching every item to find the sub-items. This means looping over every single Todoist item in my account. Thankfully, Python is fast and I only have perhaps 1000 Todoist items at one time. Even if you have many thousands of Todoist items (what are you doing in Todoist..?), it would still be a quick operation.

As for your questions about caching and stale data. Perhaps I do not understand your use case. You can request a sync of your data 50 times a minute, which is an absurdly high and useful limit for most people. Here is the code I call before I do an operation:

api = TodoistAPI(user_api_token)
api.sync()

After this, all data is synced and correct.

Are you in need of something in addition to that?

Lloyd

@dluxhu
Copy link
Author

dluxhu commented Jul 19, 2021 via email

@LloydThinks
Copy link

I have a Heroku-based Python client that allows me to do special things with Todoist. One of them allows me to uncheck all children of a repeating task, when I complete the repeating task. I have been using this system for around 6 months, and it has not failed me yet. However, out of curiosity, I ran a test to try and replicate your issue.

Test 1

  1. Create a repeating task
  2. Add a subtask
  3. Mark repeating task (parent) complete. This of course does not actually mark the parent as complete, since it is repeating.
  4. (server automatically notices change and runs code)
  5. Child is uncompleted: Success!

Test 2

  1. Create a repeating task
  2. Add a subtask
  3. Restart my Heroku servers (dynos)
  4. Mark repeating task complete
  5. (server automatically notices change and runs code)
  6. Child is left completed: Failure...
  7. Add a new child and complete it
  8. Mark repeating task as complete again
  9. New child is uncompleted (Success!), old child is still left completed (Failure...)

It appears you have identified a bug in my code, and a limitation of the Todoist SyncAPI I was not aware of until right now. It is both frustrating that sync does not include completed tasks (for this exact reason) and a really good thing (for performance reasons).

I may not work on this code for another couple of months, so unfortunately I cannot immediately try to resolve both of our issues here. Have you looked into this to see if there is a way to force-sync completed tasks? I think there is a way based on some documentation I read awhile ago, but I cannot remember it right now.

Lloyd

@dluxhu
Copy link
Author

dluxhu commented Jul 20, 2021

Hi Lloyd,

What I found in the API is in the first comment of this bug, but it is not adequate.

Balázs

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants