From d11bbb1ae84775988da671bdb9b04d2d3ee3240a Mon Sep 17 00:00:00 2001
From: Gonchik Tsymzhitov <gonchik.tsymzhitov@atlassiancommunity.com>
Date: Fri, 24 Feb 2023 22:55:31 +0200
Subject: [PATCH] Confluence: add collaborative editing methods

---
 atlassian/confluence.py | 106 +++++++++++++++++++++++++++++++++++++---
 atlassian/errors.py     |   4 ++
 2 files changed, 102 insertions(+), 8 deletions(-)

diff --git a/atlassian/confluence.py b/atlassian/confluence.py
index 0f64c69f0..18fc7f452 100644
--- a/atlassian/confluence.py
+++ b/atlassian/confluence.py
@@ -7,13 +7,7 @@
 from requests import HTTPError
 from deprecated import deprecated
 from atlassian import utils
-from .errors import (
-    ApiError,
-    ApiNotFoundError,
-    ApiPermissionError,
-    ApiValueError,
-    ApiConflictError,
-)
+from .errors import ApiError, ApiNotFoundError, ApiPermissionError, ApiValueError, ApiConflictError, ApiNotAcceptable
 from .rest_client import AtlassianRestAPI
 
 log = logging.getLogger(__name__)
@@ -1572,17 +1566,18 @@ def update_existing_page(
         representation="storage",
         minor_edit=False,
         version_comment=None,
+        full_width=False,
     ):
         """Duplicate update_page. Left for the people who used it before. Use update_page instead"""
         return self.update_page(
             page_id=page_id,
             title=title,
             body=body,
-            parent_id=None,
             type=type,
             representation=representation,
             minor_edit=minor_edit,
             version_comment=version_comment,
+            full_width=full_width,
         )
 
     def update_page(
@@ -2943,6 +2938,101 @@ def clean_jira_metadata_cache(self, global_id):
         params = {"globalId": global_id}
         return self.delete(url, params=params)
 
+    # Collaborative editing
+    def collaborative_editing_get_configuration(self):
+        """
+        Get collaborative editing configuration
+        Related to the on-prem setup Confluence Data Center
+        :return:
+        """
+        if self.cloud:
+            return ApiNotAcceptable
+        url = "rest/synchrony-interop/configuration"
+        return self.get(url, headers=self.no_check_headers)
+
+    def collaborative_editing_disable(self):
+        """
+        Disable collaborative editing
+        Related to the on-prem setup Confluence Data Center
+        :return:
+        """
+        if self.cloud:
+            return ApiNotAcceptable
+        url = "rest/synchrony-interop/disable"
+        return self.post(url, headers=self.no_check_headers)
+
+    def collaborative_editing_enable(self):
+        """
+        Disable collaborative editing
+        Related to the on-prem setup Confluence Data Center
+        :return:
+        """
+        if self.cloud:
+            return ApiNotAcceptable
+        url = "rest/synchrony-interop/enable"
+        return self.post(url, headers=self.no_check_headers)
+
+    def collaborative_editing_restart(self):
+        """
+        Disable collaborative editing
+        Related to the on-prem setup Confluence Data Center
+        :return:
+        """
+        if self.cloud:
+            return ApiNotAcceptable
+        url = "rest/synchrony-interop/restart"
+        return self.post(url, headers=self.no_check_headers)
+
+    def collaborative_editing_shared_draft_status(self):
+        """
+        Status of collaborative editing
+        Related to the on-prem setup Confluence Data Center
+        :return: false or true parameter in json
+                {
+                     "sharedDraftsEnabled": false
+                }
+        """
+        if self.cloud:
+            return ApiNotAcceptable
+        url = "rest/synchrony-interop/status"
+        return self.get(url, headers=self.no_check_headers)
+
+    def collaborative_editing_synchrony_status(self):
+        """
+        Status of collaborative editing
+        Related to the on-prem setup Confluence Data Center
+        :return: stopped or running parameter in json
+            {
+                "status": "stopped"
+            }
+        """
+        if self.cloud:
+            return ApiNotAcceptable
+        url = "rest/synchrony-interop/synchrony-status"
+        return self.get(url, headers=self.no_check_headers)
+
+    def synchrony_get_configuration(self):
+        """
+        Status of collaborative editing
+        Related to the on-prem setup Confluence Data Center
+        :return:
+        """
+        if self.cloud:
+            return ApiNotAcceptable
+        url = "rest/synchrony/1.0/config/status"
+        return self.get(url, headers=self.no_check_headers)
+
+    def synchrony_remove_draft(self, page_id):
+        """
+        Status of collaborative editing
+        Related to the on-prem setup Confluence Data Center
+        :return:
+        """
+        if self.cloud:
+            return ApiNotAcceptable
+        url = "rest/synchrony/1.0/content/{pageId}/changes/unpublished".format(pageId=page_id)
+        return self.delete(url)
+
     def get_license_details(self):
         """
         Returns the license detailed information
diff --git a/atlassian/errors.py b/atlassian/errors.py
index dfb4eb8fd..c4cf8a79f 100644
--- a/atlassian/errors.py
+++ b/atlassian/errors.py
@@ -21,3 +21,7 @@ class ApiValueError(ApiError):
 
 class ApiConflictError(ApiError):
     pass
+
+
+class ApiNotAcceptable(ApiError):
+    pass