Enhance get_todos method to handle pagination in BasecampClient
Updated the get_todos method to retrieve all todos from a todolist by handling pagination transparently. The method now aggregates todos across multiple pages and updates the README to reflect this change.
This commit is contained in:
@@ -154,7 +154,7 @@ Once configured, you can use these tools in Cursor:
|
|||||||
- `get_projects` - Get all Basecamp projects
|
- `get_projects` - Get all Basecamp projects
|
||||||
- `get_project` - Get details for a specific project
|
- `get_project` - Get details for a specific project
|
||||||
- `get_todolists` - Get todo lists for a project
|
- `get_todolists` - Get todo lists for a project
|
||||||
- `get_todos` - Get todos from a todo list
|
- `get_todos` - Get todos from a todo list (returns all pages; handles Basecamp pagination transparently)
|
||||||
- `search_basecamp` - Search across projects, todos, and messages
|
- `search_basecamp` - Search across projects, todos, and messages
|
||||||
- `get_comments` - Get comments for a Basecamp item
|
- `get_comments` - Get comments for a Basecamp item
|
||||||
- `get_campfire_lines` - Get recent messages from a Basecamp campfire
|
- `get_campfire_lines` - Get recent messages from a Basecamp campfire
|
||||||
|
|||||||
@@ -144,12 +144,36 @@ class BasecampClient:
|
|||||||
|
|
||||||
# To-do methods
|
# To-do methods
|
||||||
def get_todos(self, project_id, todolist_id):
|
def get_todos(self, project_id, todolist_id):
|
||||||
"""Get all todos in a todolist."""
|
"""Get all todos in a todolist, handling pagination.
|
||||||
response = self.get(f'buckets/{project_id}/todolists/{todolist_id}/todos.json')
|
|
||||||
if response.status_code == 200:
|
Basecamp paginates list endpoints (commonly 15 items per page). This
|
||||||
return response.json()
|
implementation follows pagination via the `page` query parameter and
|
||||||
else:
|
the HTTP `Link` header if present, aggregating all pages before
|
||||||
raise Exception(f"Failed to get todos: {response.status_code} - {response.text}")
|
returning the combined list.
|
||||||
|
"""
|
||||||
|
endpoint = f'buckets/{project_id}/todolists/{todolist_id}/todos.json'
|
||||||
|
|
||||||
|
all_todos = []
|
||||||
|
page = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
response = self.get(endpoint, params={"page": page})
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise Exception(f"Failed to get todos: {response.status_code} - {response.text}")
|
||||||
|
|
||||||
|
page_items = response.json() or []
|
||||||
|
all_todos.extend(page_items)
|
||||||
|
|
||||||
|
# Check for next page using Link header or by empty result
|
||||||
|
link_header = response.headers.get("Link", "")
|
||||||
|
has_next = 'rel="next"' in link_header if link_header else False
|
||||||
|
|
||||||
|
if not page_items or not has_next:
|
||||||
|
break
|
||||||
|
|
||||||
|
page += 1
|
||||||
|
|
||||||
|
return all_todos
|
||||||
|
|
||||||
def get_todo(self, todo_id):
|
def get_todo(self, todo_id):
|
||||||
"""Get a specific todo."""
|
"""Get a specific todo."""
|
||||||
|
|||||||
Reference in New Issue
Block a user