Exemple #1
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))
Exemple #2
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
Exemple #3
0
    def get_html(self, filepath):
        """
        Generate html from md file

        :param filepath: the file to translate to html
        :return: html translation
        """
        with codecs.open(filepath, 'r', 'utf-8') as mdfile:
            read = mdfile.read()
            read = macros.remove_collapsible_headings(read)
            html = markdown.markdown(read, extensions=['markdown.extensions.tables',
                                                    'markdown.extensions.fenced_code',
                                                    'mdx_truly_sane_lists'])
        html = '\n'.join(html.split('\n')[1:])
        html = macros.add_note(html)
        html = macros.convert_info_macros(html)
        html = macros.convert_comment_block(html)
        html = macros.convert_code_block(html)
        html = macros.remove_empty_list_items(html)
        if CONTENTS:
            html = macros.add_contents(html)

        html = macros.process_refs(html)
        html = PAGE_CACHE.resolve_refs(html, filepath)
        if LOG_HTML:
            title = self.get_title(filepath)
            html_log_file = open(os.path.dirname(LOG_FILE) + title + '.html', 'w+')
            html_log_file.write('<h1>' + title + '</h1>')
            html_log_file.write(html)
        else:
            LOGGER.debug('file: %s\n\nhtml: %s\n\n', filepath, html)

        return html
Exemple #4
0
    def create_or_update_page(self, title, body, ancestors, filepath):
        """
        Create a new page

        :param title: confluence page title
        :param body: confluence page content
        :param ancestors: confluence page ancestor
        :param filepath: markdown file full path
        :return: created or updated page id
        """
        page = PAGE_CACHE.get_page(title)
        if page:
            return self.update_page(page.id, title, body, page.version,
                                    ancestors, filepath)
        else:
            LOGGER.info('Creating page %s...', title)

            url = '%s/rest/api/content/' % CONFLUENCE_API_URL
            new_page = {
                'type': 'page',
                'title': title,
                'space': {
                    'key': SPACE_KEY
                },
                'body': {
                    'storage': {
                        'value': body,
                        'representation': 'storage'
                    }
                },
                'ancestors': ancestors
            }
            LOGGER.debug("data: %s", json.dumps(new_page))

            response = common.make_request_post(url, data=json.dumps(new_page))

            data = response.json()
            space_name = data[u'space'][u'name']
            page_id = data[u'id']
            version = data[u'version'][u'number']
            link = '%s%s' % (CONFLUENCE_API_URL, data[u'_links'][u'webui'])

            LOGGER.info('Page created in %s with ID: %s.', space_name, page_id)
            LOGGER.info('URL: %s', link)

            # label the page
            self.__label_page(page_id)

            img_check = re.search(r'<img(.*?)\/>', body)
            if img_check:
                LOGGER.info('Attachments found, update procedure called.')
                return self.update_page(page_id, title, body, version,
                                        ancestors, filepath)
            else:
                return page_id
Exemple #5
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('&quot;', '"', 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
Exemple #6
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
Exemple #7
0
def createDB(dbFilePath_) :
	"""Create table in the given database file
	
	:param String dbFilePath_: file path of the database file
	"""
	if os.path.isfile(dbFilePath_) :
		return
		#os.remove(dbFilePath_)

	LOGGER.info('Creating database file: %s', dbFilePath_)
	command = """create table series (id INTEGER PRIMARY KEY,
				name VARCHAR(50),
				title VARCHAR(255),
				season INTEGER,
				episode INTEGER,
				sub_en INTEGER,
				sub_fr INTEGER,
				downloading INTEGER)"""
	LOGGER.debug(command)
		
	conn = sqlite3.connect(dbFilePath_)
	c = conn.cursor()
	c.execute(command)
	conn.close()
Exemple #8
0
def moveFile(srcFilePath_, destFilePath_) :
	LOGGER.debug('Moving file:');
	LOGGER.debug('  From: %s', srcFilePath_)
	LOGGER.debug('  To: %s', destFilePath_)
	
	if SIMULATE_MODE :
		return
	
	if (not os.path.isdir(os.path.dirname(destFilePath_))) :
		os.makedirs(os.path.dirname(destFilePath_))
	#os.rename(srcFilePath_, destFilePath_)
	shutil.move(srcFilePath_, destFilePath_)
Exemple #9
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
Exemple #10
0
    def update_page(self, page_id, title, body, version, ancestors, filepath):
        """
        Update a page

        :param page_id: confluence page id
        :param title: confluence page title
        :param body: confluence page content
        :param version: confluence page version
        :param ancestors: confluence page ancestor
        :param filepath: markdown file full path
        :return: updated page id
        """
        LOGGER.info('Updating page %s...', title)

        # Add images and attachments
        body = self.__add_images(page_id, body, filepath)

        # See if the page actually needs to be updated or not
        existing = PAGE_CACHE.get_page(title)
        if existing:
            if  title == existing.title and \
                body == existing.body and \
                ancestors[0]['id'] == existing.ancestor:
                LOGGER.info('No changes on the page; update not necessary')
                return page_id
            else:
                LOGGER.info('Changes detected; update nessary')
                if title != existing.title:
                    LOGGER.debug('update required: title %s != %s', title,
                                 existing.title)
                if body != existing.body:
                    LOGGER.debug('update required: body %s != %s', body,
                                 existing.body)
                if ancestors[0]['id'] != existing.ancestor:
                    LOGGER.debug('update required: ancestor %s != %s',
                                 ancestors[0]['id'], existing.ancestor)

        PAGE_CACHE.forget_page(title)

        url = '%s/rest/api/content/%s' % (CONFLUENCE_API_URL, page_id)
        page_json = {
            "id": page_id,
            "type": "page",
            "title": title,
            "space": {
                "key": SPACE_KEY
            },
            "body": {
                "storage": {
                    "value": body,
                    "representation": "storage"
                }
            },
            "version": {
                "number": version + 1,
                "minorEdit": True
            },
            'ancestors': ancestors
        }

        response = common.make_request_put(url, data=json.dumps(page_json))

        data = response.json()
        link = '%s%s' % (CONFLUENCE_API_URL, data[u'_links'][u'webui'])

        LOGGER.info("Page updated successfully.")
        LOGGER.info('URL: %s', link)
        return data[u'id']