def check_for_errors(response): """ Check response for errors and log help if necessary :param response: the received response :return """ try: response.raise_for_status() except requests.RequestException as err: LOGGER.error('err.response: %s', err) if response.status_code == 404: LOGGER.error('Error: Page not found. Check the following are correct:') LOGGER.error('Space Key : %s', SPACE_KEY) LOGGER.error('Confluence URL : %s', CONFLUENCE_API_URL) else: LOGGER.error('Error: %d - %s', response.status_code, response.content) sys.exit(1)
def _make_request(callback, check_response = True): """ Make a request """ session = _session() session.headers.update({'Content-Type': 'application/json'}) response = callback(session) # This happens intermittently; if it does, wait a second and try again retries = 2 while retries and response.status_code == 401: retries = retries - 1 time.sleep(1) response = callback(session) if check_response: if response.status_code >= 400: LOGGER.error('Error Response Content: %s', response.content) response.raise_for_status() return response
def make_request_upload(url, file_to_upload): """ Upload a file to a url """ # this is different enough from the normal make_request # that factoring out the commonalities makes it hard # to follow the logic; I preferred to just duplicate session = _session() session.headers.update({'X-Atlassian-Token': 'no-check'}) response = session.post(url, files=file_to_upload) # This happens intermittently; if it does, wait a second and try again retries = 2 while retries and response.status_code == 401: retries = retries - 1 time.sleep(1) response = session.post(url, files=file_to_upload) if response.status_code >= 400: LOGGER.error('Error Response Content: %s', response.content) response.raise_for_status() return response
def __upload_attachment(self, page_id, file, comment): """ Upload an attachment :param page_id: confluence page id :param file: attachment file :param comment: attachment comment :return: boolean """ if re.search('http.*', file): return False content_type = mimetypes.guess_type(file)[0] filename = os.path.basename(file) if not os.path.isfile(file): LOGGER.error('File %s cannot be found --> skip ', file) return False sha = FILE_API.get_sha_hash(file) file_to_upload = { 'comment': comment, 'file': (filename, open(file, 'rb'), content_type, { 'Expires': '0' }) } attachment = self.__get_attachment(page_id, filename) if attachment: if sha == attachment.hash: LOGGER.info('File %s has not changed --> skip', file) return True else: LOGGER.debug('File %s has changed', file) url = '%s/rest/api/content/%s/child/attachment/%s/data' % \ (CONFLUENCE_API_URL, page_id, attachment.id) else: LOGGER.debug('File %s is new', file) url = '%s/rest/api/content/%s/child/attachment/' % ( CONFLUENCE_API_URL, page_id) LOGGER.info('Uploading attachment %s...', filename) response = common.make_request_upload(url, file_to_upload) data = response.json() LOGGER.debug('data: %s', str(data)) # depending on create or update, sometimes you get a collection # and sometimes you get a single item if u'results' in data: data = data[u'results'][0] attachment_id = data['id'] # Set the SHA hash metadata on the attachment so that it can be later compared # first, get the current version of the property if it exists url = '%s/rest/api/content/%s/property/hash' % (CONFLUENCE_API_URL, attachment_id) response = common.make_request_get(url, False) if response.status_code == 200: data = response.json() LOGGER.debug('data: %s', str(data)) version = data[u'version'][u'number'] else: version = 0 # then set the hash propery page_json = { "value": { "sha256": sha }, "version": { "number": version + 1, "minorEdit": True } } LOGGER.debug('data: %s', json.dumps(page_json)) response = common.make_request_put(url, data=json.dumps(page_json)) return True