Exemplo n.º 1
0
    def __get_attachment(self, page_id, filename):
        """
        Get page attachment

        :param page_id: confluence page id
        :param filename: attachment filename
        :return: attachment info in case of success, False otherwise
        """
        url = '%s/rest/api/content/%s/child/attachment?filename=%s' \
              '&expand=metadata.properties.hash' \
              % (CONFLUENCE_API_URL, page_id, filename)

        response = common.make_request_get(url)
        data = response.json()
        LOGGER.debug('data: %s', str(data))

        if len(data[u'results']) >= 1:
            data = data[u'results'][0]
            att_id = data[u'id']

            att_hash = None
            props = data[u'metadata'][u'properties']
            if u'hash' in props:
                hash_prop = props[u'hash'][u'value']
                if u'sha256' in hash_prop:
                    att_hash = hash_prop[u'sha256']

            att_info = collections.namedtuple('AttachmentInfo', ['id', 'hash'])
            attr_info = att_info(att_id, att_hash)
            return attr_info

        return False
Exemplo n.º 2
0
    def __delete_page(self, page_id, trash_ancestor):
        """
        Delete a page by moving it to the orphan folder

        :param page_id: confluence page id
        :return: None
        """
        LOGGER.info('Moving page %s to ORPHAN...', page_id)
        url = '%s/rest/api/content/%s?expand=version' % (CONFLUENCE_API_URL,
                                                         page_id)

        response = common.make_request_get(url)
        data = response.json()
        LOGGER.debug("data: %s", str(data))

        page_id = data[u'id']
        version = data[u'version'][u'number']
        title = data[u'title']
        ancestors = common.get_page_as_ancestor(trash_ancestor)

        url = '%s/rest/api/content/%s' % (CONFLUENCE_API_URL, page_id)
        page_json = {
            "id": page_id,
            "type": "page",
            "title": title,
            "version": {
                "number": version + 1,
                "minorEdit": True
            },
            'ancestors': ancestors
        }
        LOGGER.debug("data: %s", json.dumps(page_json))

        common.make_request_put(url, data=json.dumps(page_json))
Exemplo n.º 3
0
    def get_page(self, title):
        """
        Retrieve page details by title

        :param title: page tile
        :return: Confluence page info
        """
        if title in self.__CACHED_PAGE_INFO:
            return self.__CACHED_PAGE_INFO[title]

        LOGGER.info('Retrieving page information: %s', title)
        url = '%s/rest/api/content?title=%s&spaceKey=%s' \
              '&expand=version,ancestors,metadata.labels,body.storage' \
              % (CONFLUENCE_API_URL, urllib.parse.quote_plus(title), SPACE_KEY)

        response = common.make_request_get(url)
        data = response.json()
        LOGGER.debug("data: %s", str(data))

        if len(data[u'results']) >= 1:
            data = data[u'results'][0]
            page_id = data[u'id']
            version_num = data[u'version'][u'number']
            link = '%s%s' % (CONFLUENCE_API_URL, data[u'_links'][u'webui'])
            ancestor = data[u'ancestors'][-1][u'id']
            labels = map(lambda r: r[u'name'],
                         data[u'metadata'][u'labels'][u'results'])
            body = data[u'body'][u'storage'][u'value']

            # These properties do not round-trip; confluence adds them, so strip them out
            body = re.sub(' ac:schema-version="[^"]+"', '', body)
            body = re.sub(' ac:macro-id="[^"]+"', '', body)
            # Confluence replaces some quotes (but not all) with xml quotes
            body = re.sub('"', '"', body)

            title = data[u'title']

            page_info = collections.namedtuple('PageInfo',
                            ['id', 'version', 'link', 'ancestor', 'labels', 'body', 'title'])
            page = page_info(page_id, version_num, link, ancestor, labels, body, title)
            self.__CACHED_PAGE_INFO[title] = page
            return page

        return False
Exemplo n.º 4
0
    def __get_direct_child_pages(self, page_id):
        """
        Retrieve every direct child page id

        :param page_id: page id
        :return: ids of immediate child pages
        """
        url = '%s/rest/api/content/search?cql=parent=%s' % \
            (CONFLUENCE_API_URL, urllib.parse.quote_plus(page_id))

        response = common.make_request_get(url)
        data = response.json()
        LOGGER.debug("data: %s", str(data))

        page_ids = []
        for result in data[u'results']:
            page_ids.append(result[u'id'])

        return page_ids
Exemplo n.º 5
0
    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