From bdeaf3d619ee92210dc5c8d7619591e1edd7899d Mon Sep 17 00:00:00 2001 From: gkowalc Date: Mon, 30 Sep 2024 17:27:51 +0200 Subject: [PATCH 1/2] [bug][jira] jira get_issue_tree_recursive method overwrites default params values from previous executions (#1461) * added two new methods: download_attachments.from_issue and get_attachments_ids_from_issue --------- Co-authored-by: gkowalc <> Co-authored-by: Greg --- atlassian/jira.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/atlassian/jira.py b/atlassian/jira.py index acdd4d9ab..898db0651 100644 --- a/atlassian/jira.py +++ b/atlassian/jira.py @@ -1730,20 +1730,21 @@ def get_issue_remote_links(self, issue_key, global_id=None, internal_id=None): url += "/" + internal_id return self.get(url, params=params) - def get_issue_tree_recursive(self, issue_key, tree=[], depth=0): - """ - Returns list that contains the tree structure of the root issue, with all subtasks and inward linked issues. - (!) Function only returns child issues from the same jira instance or from instance to which api key has access to. - (!) User asssociated with API key must have access to the all child issues in order to get them. - :param jira issue_key: - :param tree: blank parameter used for recursion. Don't change it. - :param depth: blank parameter used for recursion. Don't change it. - :return: list of dictioanries, key is the parent issue key, value is the child/linked issue key - - """ - + def get_issue_tree_recursive(self, issue_key, tree=None, depth=None): + """ + Returns a list that contains the tree structure of the root issue, with all subtasks and inward linked issues. + (!) Function only returns child issues from the same Jira instance or from an instance to which the API key has access. + :param issue_key: Jira issue key + :param tree: list to store the tree structure for recursion. Do not change it. + :param depth: current depth of the tree for recursion. Do not change it. + :return: list of dictionaries containing the tree structure. Dictionary element contains a key (parent issue) and value (child issue). + """ + if tree is None: + tree = [] + if depth is None: + depth = 0 # Check the recursion depth. In case of any bugs that would result in infinite recursion, this will prevent the function from crashing your app. Python default for REcursionError is 1000 - if depth > 50: + if depth > 150: raise Exception("Recursion depth exceeded") issue = self.get_issue(issue_key) issue_links = issue["fields"]["issuelinks"] @@ -1761,9 +1762,9 @@ def get_issue_tree_recursive(self, issue_key, tree=[], depth=0): for subtask in subtasks: if subtask.get("key") is not None: parent_issue_key = issue["key"] - if not [x for x in tree if subtask["key"] in x.keys()]: # condition to avoid infinite recursion + if not [x for x in tree if subtask["key"] in x.keys()]: tree.append({parent_issue_key: subtask["key"]}) - self.get_issue_tree_recursive(subtask["key"], tree, depth + 1) # recursive call of the function + self.get_issue_tree_recursive(subtask["key"], tree, depth + 1) return tree def create_or_update_issue_remote_links( From 78fe140bddc7703abae5656f9d847f829469d5e9 Mon Sep 17 00:00:00 2001 From: Steffen Baarsgaard Date: Tue, 1 Oct 2024 05:13:58 +0200 Subject: [PATCH 2/2] Confluence: Add function get_all_pages_by_space_ids_confluence_cloud (#1460) * Confluence: Add function get_all_pages_by_space_ids_confluence_cloud * Confluence: Set default batch_size for get_all_pages_by_space_ids_confluence_cloud * Confluence: Fix black formatting errors --- atlassian/confluence.py | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/atlassian/confluence.py b/atlassian/confluence.py index 7076774e8..1c8648d11 100644 --- a/atlassian/confluence.py +++ b/atlassian/confluence.py @@ -692,6 +692,73 @@ def get_all_draft_pages_from_space_through_cql(self, space, start=0, limit=500, return response.get("results") + def get_all_pages_by_space_ids_confluence_cloud( + self, + space_ids, + batch_size=250, + sort=None, + status=None, + title=None, + body_format=None, + ): + """ + Get all pages from a set of space ids: + https://developer.atlassian.com/cloud/confluence/rest/v2/api-group-page/#api-pages-get + + :param space_ids: A Set of space IDs passed as a filter to Confluence + :param batch_size: OPTIONAL: The batch size of pages to retrieve from confluence per request MAX is 250. + Default: 250 + :param sort: OPTIONAL: The order the pages are retrieved in. + Valid values: id, -id, created-date, -created-date, modified-date, -modified-date, title, -title + :param status: OPTIONAL: Filter pages based on their status. + Valid values: current, archived, deleted, trashed + Default: current,archived + :param title: OPTIONAL: Filter pages based on their title. + :param body-format: OPTIONAL: The format of the body in the response. Valid values: storage, atlas_doc_format + :return: + """ + path = "/api/v2/pages" + params = {} + if space_ids: + params["space-id"] = ",".join(space_ids) + if batch_size: + params["limit"] = batch_size + if sort: + params["sort"] = sort + if status: + params["status"] = status + if title: + params["title"] = title + if body_format: + params["body-format"] = body_format + + _all_pages = [] + try: + while True: + response = self.get(path, params=params) + + pages = response.get("results") + _all_pages = _all_pages + pages + + links = response.get("_links") + if links is not None and "next" in links: + path = response["_links"]["next"].removeprefix("/wiki/") + params = {} + else: + break + except HTTPError as e: + if e.response.status_code == 400: + raise ApiValueError( + "The configured params cannot be interpreted by Confluence" + "Check the api documentation for valid values for status, expand, and sort params", + reason=e, + ) + if e.response.status_code == 401: + raise HTTPError("Unauthorized (401)", response=response) + raise + + return _all_pages + @deprecated(version="2.4.2", reason="Use get_all_restrictions_for_content()") def get_all_restictions_for_content(self, content_id): """Let's use the get_all_restrictions_for_content()"""