From 6b537ae76a85925219f4197c8c73d3e9edacb333 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Thu, 5 Jun 2025 16:10:09 -0400 Subject: [PATCH] v2 > let's add an endpoint for getting bookmarks by label. The Readeck API enpoint for that is GET /bookmarks/labels/{name} (or to see all labels is GET /bookmarks/labels). --- main.py | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 7f85d08..ff7cb74 100644 --- a/main.py +++ b/main.py @@ -257,4 +257,114 @@ class Tools: limit=limit, tags=tags, __user__=__user__ - ) \ No newline at end of file + ) + + async def get_labels( + self, + __user__: Optional[dict] = None + ) -> str: + """ + Get all labels from Readeck + """ + + if not self.valves.readeck_url or not self.valves.api_token: + return "Error: Readeck URL and API token must be configured in the tool settings." + + # Make request to Readeck API + result = self._make_request("/bookmarks/labels") + + if "error" in result: + return f"Error fetching labels: {result['error']}" + + labels = result.get("labels", []) + + if not labels: + return "No labels found." + + # Format labels for display + formatted_labels = [] + for label in labels: + if isinstance(label, str): + # Simple string label + formatted_labels.append({ + "name": label, + "bookmark_count": None + }) + elif isinstance(label, dict): + # Label object with additional info + formatted_labels.append({ + "name": label.get("name"), + "bookmark_count": label.get("bookmark_count"), + "created_at": label.get("created_at"), + "updated_at": label.get("updated_at") + }) + + return json.dumps({ + "labels": formatted_labels, + "total": len(formatted_labels) + }, indent=2) + + async def get_bookmarks_by_label( + self, + label_name: str, + limit: int = 20, + offset: int = 0, + __user__: Optional[dict] = None + ) -> str: + """ + Get bookmarks filtered by a specific label + + Args: + label_name: Name of the label to filter by + limit: Number of bookmarks to return (default: 20, max: 100) + offset: Number of bookmarks to skip (default: 0) + """ + + if not self.valves.readeck_url or not self.valves.api_token: + return "Error: Readeck URL and API token must be configured in the tool settings." + + if not label_name: + return "Error: label_name is required." + + # Build query parameters + params = { + "limit": min(limit, 100), # Cap at 100 to prevent excessive requests + "offset": offset + } + + # Make request to Readeck API + result = self._make_request(f"/bookmarks/labels/{label_name}", params) + + if "error" in result: + return f"Error fetching bookmarks for label '{label_name}': {result['error']}" + + # Format the response + bookmarks = result.get("bookmarks", []) + total = result.get("total", len(bookmarks)) + + if not bookmarks: + return f"No bookmarks found with label '{label_name}'." + + # Format bookmarks for display + formatted_bookmarks = [] + for bookmark in bookmarks: + formatted_bookmark = { + "id": bookmark.get("id"), + "title": bookmark.get("title", "Untitled"), + "url": bookmark.get("url"), + "excerpt": bookmark.get("excerpt", "")[:200] + "..." if bookmark.get("excerpt", "") else "", + "tags": bookmark.get("tags", []), + "labels": bookmark.get("labels", []), + "collection": bookmark.get("collection", {}).get("name", ""), + "created_at": bookmark.get("created_at"), + "updated_at": bookmark.get("updated_at") + } + formatted_bookmarks.append(formatted_bookmark) + + return json.dumps({ + "label": label_name, + "bookmarks": formatted_bookmarks, + "total": total, + "limit": params["limit"], + "offset": params["offset"] + }, indent=2)