Merge pull request #4 from pawelsikora/rel_0.2.5

Handle the case when nav section is missing in mkdocs.yml
This commit is contained in:
pawelsikora 2022-03-23 20:35:34 +01:00 committed by GitHub
commit 70844b3532
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 166 additions and 60 deletions

View File

@ -1,11 +1,14 @@
import time import time
import os import os
import sys
import re import re
import tempfile import tempfile
import shutil import shutil
import requests import requests
import mimetypes import mimetypes
import mistune import mistune
import contextlib
from time import sleep
from mkdocs.config import config_options from mkdocs.config import config_options
from mkdocs.plugins import BasePlugin from mkdocs.plugins import BasePlugin
from md2cf.confluence_renderer import ConfluenceRenderer from md2cf.confluence_renderer import ConfluenceRenderer
@ -14,6 +17,19 @@ from os import environ
TEMPLATE_BODY = "<p> TEMPLATE </p>" TEMPLATE_BODY = "<p> TEMPLATE </p>"
@contextlib.contextmanager
def nostdout():
save_stdout = sys.stdout
sys.stdout = DummyFile()
yield
sys.stdout = save_stdout
class DummyFile(object):
def write(self, x):
pass
class MkdocsWithConfluence(BasePlugin): class MkdocsWithConfluence(BasePlugin):
_id = 0 _id = 0
config_scheme = ( config_scheme = (
@ -38,21 +54,51 @@ class MkdocsWithConfluence(BasePlugin):
def on_nav(self, nav, config, files): def on_nav(self, nav, config, files):
MkdocsWithConfluence.tab_nav = [] MkdocsWithConfluence.tab_nav = []
navigation_items = nav.__repr__() navigation_items = nav.__repr__()
for n in navigation_items.split("\n"): for n in navigation_items.split("\n"):
# print(f"* {n}")
leading_spaces = len(n) - len(n.lstrip(" ")) leading_spaces = len(n) - len(n.lstrip(" "))
spaces = leading_spaces * " " spaces = leading_spaces * " "
if "Page" in n: if "Page" in n:
p = spaces + self.__get_page_title(n) try:
self.page_title = self.__get_page_title(n)
if self.page_title is None:
raise AttributeError
except AttributeError:
self.page_local_path = self.__get_page_url(n)
print(
f"WARN - Page from path {self.page_local_path} has no"
f" entity in the mkdocs.yml nav section. It will be uploaded"
f" to the Confluence, but you may not see it on the web server!"
)
self.page_local_name = self.__get_page_name(n)
self.page_title = self.page_local_name
p = spaces + self.page_title
MkdocsWithConfluence.tab_nav.append(p) MkdocsWithConfluence.tab_nav.append(p)
if "Section" in n: if "Section" in n:
s = spaces + self.__get_section_title(n) try:
self.section_title = self.__get_section_title(n)
if self.section_title is None:
raise AttributeError
except AttributeError:
self.section_local_path = self.__get_page_url(n)
print(
f"WARN - Section from path {self.section_local_path} has no"
f" entity in the mkdocs.yml nav section. It will be uploaded"
f" to the Confluence, but you may not see it on the web server!"
)
self.section_local_name = self.__get_section_title(n)
self.section_title = self.section_local_name
s = spaces + self.section_title
MkdocsWithConfluence.tab_nav.append(s) MkdocsWithConfluence.tab_nav.append(s)
def on_files(self, files, config): def on_files(self, files, config):
pages = files.documentation_pages() pages = files.documentation_pages()
self.flen = len(pages) try:
print(f"Number of Files: {self.flen}") self.flen = len(pages)
print(f"Number of Files in directory tree: {self.flen}")
except 0:
print("ERR: You have no documentation pages" "in the directory tree, please add at least one!")
def on_post_template(self, output_content, template_name, config): def on_post_template(self, output_content, template_name, config):
if self.config["verbose"] is False and self.config["debug"] is False: if self.config["verbose"] is False and self.config["debug"] is False:
@ -75,7 +121,7 @@ class MkdocsWithConfluence(BasePlugin):
else: else:
print( print(
"INFO - Mkdocs With Confluence: Exporting MKDOCS pages to Confluence " "INFO - Mkdocs With Confluence: Exporting MKDOCS pages to Confluence "
"turned ON by var {env_name}==1!" f"turned ON by var {env_name}==1!"
) )
self.enabled = True self.enabled = True
else: else:
@ -108,25 +154,27 @@ class MkdocsWithConfluence(BasePlugin):
print("-", end="", flush=True) print("-", end="", flush=True)
print(f"] ({MkdocsWithConfluence._id} / {self.flen})", end="\r", flush=True) print(f"] ({MkdocsWithConfluence._id} / {self.flen})", end="\r", flush=True)
if self.config["verbose"]: if self.config["debug"]:
print(f"\nHandling Page '{page.title}' (And Parent Nav Pages if necessary):\n") print(f"\nDEBUG - Handling Page '{page.title}' (And Parent Nav Pages if necessary):\n")
if not all(self.config_scheme): if not all(self.config_scheme):
print("ERR: YOU HAVE EMPTY VALUES IN YOUR CONFIG. ABORTING") print("DEBUG - ERR: YOU HAVE EMPTY VALUES IN YOUR CONFIG. ABORTING")
return markdown return markdown
try: try:
if self.config["verbose"]: if self.config["debug"]:
print("Get section first parent title...: ") print("DEBUG - Get section first parent title...: ")
try: try:
parent = self.__get_section_title(page.ancestors[0].__repr__()) parent = self.__get_section_title(page.ancestors[0].__repr__())
except IndexError as e: except IndexError as e:
print( if self.config["debug"]:
f'ERR({e}): No second parent! Assuming self.config["parent_page_name"]' print(
f"{self.config['parent_page_name']}..." f"DEBUG - WRN({e}): No first parent! Assuming "
) f"DEBUG - {self.config['parent_page_name']}..."
)
parent = None parent = None
if self.config["verbose"]: if self.config["debug"]:
print(f"{parent}") print(f"DEBUG - {parent}")
if not parent: if not parent:
parent = self.config["parent_page_name"] parent = self.config["parent_page_name"]
@ -135,23 +183,30 @@ class MkdocsWithConfluence(BasePlugin):
else: else:
main_parent = self.config["space"] main_parent = self.config["space"]
if self.config["verbose"]: if self.config["debug"]:
print("Get section second parent title...: ") print("DEBUG - Get section second parent title...: ")
try: try:
parent1 = self.__get_section_title(page.ancestors[1].__repr__()) parent1 = self.__get_section_title(page.ancestors[1].__repr__())
except IndexError as e: except IndexError as e:
print(f"ERR({e}) No second parent! Assuming second parent is main parent: {main_parent}...") if self.config["debug"]:
print(
f"DEBUG - ERR({e}) No second parent! Assuming "
f"second parent is main parent: {main_parent}..."
)
parent1 = None parent1 = None
if self.config["verbose"]: if self.config["debug"]:
print(f"{parent}") print(f"{parent}")
if not parent1: if not parent1:
parent1 = main_parent parent1 = main_parent
if self.config["verbose"]: if self.config["debug"]:
print(f"ONLY ONE PARENT FOUND. ASSUMING AS A FIRST NODE after main parent config {main_parent}") print(
f"DEBUG - ONLY ONE PARENT FOUND. ASSUMING AS A "
f"FIRST NODE after main parent config {main_parent}"
)
if self.config["verbose"]: if self.config["debug"]:
print(f"PARENT0: {parent}, PARENT1: {parent1}, MAIN PARENT: {main_parent}") print(f"DEBUG - PARENT0: {parent}, PARENT1: {parent1}, MAIN PARENT: {main_parent}")
tf = tempfile.NamedTemporaryFile(delete=False) tf = tempfile.NamedTemporaryFile(delete=False)
f = open(tf.name, "w") f = open(tf.name, "w")
@ -160,11 +215,11 @@ class MkdocsWithConfluence(BasePlugin):
try: try:
for match in re.finditer(r'img src="file://(.*)" s', markdown): for match in re.finditer(r'img src="file://(.*)" s', markdown):
if self.config["debug"]: if self.config["debug"]:
print(f"FOUND IMAGE: {match.group(1)}") print(f"DEBUG - FOUND IMAGE: {match.group(1)}")
files.append(match.group(1)) files.append(match.group(1))
except AttributeError as e: except AttributeError as e:
if self.config["debug"]: if self.config["debug"]:
print(f"WARN(({e}): No images found in markdown. Proceed..") print(f"DEBUG - WARN(({e}): No images found in markdown. Proceed..")
new_markdown = re.sub( new_markdown = re.sub(
r'<img src="file:///tmp/', '<p><ac:image ac:height="350"><ri:attachment ri:filename="', markdown r'<img src="file:///tmp/', '<p><ac:image ac:height="350"><ri:attachment ri:filename="', markdown
@ -181,30 +236,30 @@ class MkdocsWithConfluence(BasePlugin):
if self.config["debug"]: if self.config["debug"]:
print( print(
f"\nUPDATING PAGE TO CONFLUENCE, DETAILS:\n" f"\nDEBUG - UPDATING PAGE TO CONFLUENCE, DETAILS:\n"
f"HOST: {self.config['host_url']}\n" f"DEBUG - HOST: {self.config['host_url']}\n"
f"SPACE: {self.config['space']}\n" f"DEBUG - SPACE: {self.config['space']}\n"
f"TITLE: {page.title}\n" f"DEBUG - TITLE: {page.title}\n"
f"PARENT: {parent}\n" f"DEBUG - PARENT: {parent}\n"
f"BODY: {confluence_body}\n" f"DEBUG - BODY: {confluence_body}\n"
) )
page_id = self.find_page_id(page.title) page_id = self.find_page_id(page.title)
if page_id is not None: if page_id is not None:
if self.config["debug"]: if self.config["debug"]:
print( print(
f"JUST ONE STEP FROM UPDATE OF PAGE '{page.title}' \n" f"DEBUG - JUST ONE STEP FROM UPDATE OF PAGE '{page.title}' \n"
f"CHECKING IF PARENT PAGE ON CONFLUENCE IS THE SAME AS HERE" f"DEBUG - CHECKING IF PARENT PAGE ON CONFLUENCE IS THE SAME AS HERE"
) )
parent_name = self.find_parent_name_of_page(page.title) parent_name = self.find_parent_name_of_page(page.title)
if parent_name == parent: if parent_name == parent:
if self.config["debug"]: if self.config["debug"]:
print(" - OK, Parents match. Continue...") print("DEBUG - Parents match. Continue...")
else: else:
if self.config["debug"]: if self.config["debug"]:
print(f" - ERR, Parents does not match: '{parent}' =/= '{parent_name}' Aborting...") print(f"DEBUG - ERR, Parents does not match: '{parent}' =/= '{parent_name}' Aborting...")
return markdown return markdown
self.update_page(page.title, confluence_body) self.update_page(page.title, confluence_body)
for i in MkdocsWithConfluence.tab_nav: for i in MkdocsWithConfluence.tab_nav:
@ -212,8 +267,11 @@ class MkdocsWithConfluence(BasePlugin):
n_kol = len(i + " *NEW PAGE*") n_kol = len(i + " *NEW PAGE*")
print(f"INFO - Mkdocs With Confluence: {i} *UPDATE*") print(f"INFO - Mkdocs With Confluence: {i} *UPDATE*")
else: else:
# if self.config['debug']: if self.config["debug"]:
print(f"PAGE: {page.title}, PARENT0: {parent}, PARENT1: {parent1}, MAIN PARENT: {main_parent}") print(
f"DEBUG - PAGE: {page.title}, PARENT0: {parent}, "
f"PARENT1: {parent1}, MAIN PARENT: {main_parent}"
)
parent_id = self.find_page_id(parent) parent_id = self.find_page_id(parent)
self.wait_until(parent_id, 1, 20) self.wait_until(parent_id, 1, 20)
second_parent_id = self.find_page_id(parent1) second_parent_id = self.find_page_id(parent1)
@ -226,8 +284,11 @@ class MkdocsWithConfluence(BasePlugin):
print("ERR: MAIN PARENT UNKNOWN. ABORTING!") print("ERR: MAIN PARENT UNKNOWN. ABORTING!")
return markdown return markdown
# if self.config['debug']: if self.config["debug"]:
print(f"Trying to ADD page '{parent1}' to main parent({main_parent}) ID: {main_parent_id}") print(
f"DEBUG - Trying to ADD page '{parent1}' to "
f"main parent({main_parent}) ID: {main_parent_id}"
)
body = TEMPLATE_BODY.replace("TEMPLATE", parent1) body = TEMPLATE_BODY.replace("TEMPLATE", parent1)
self.add_page(parent1, main_parent_id, body) self.add_page(parent1, main_parent_id, body)
for i in MkdocsWithConfluence.tab_nav: for i in MkdocsWithConfluence.tab_nav:
@ -236,8 +297,11 @@ class MkdocsWithConfluence(BasePlugin):
print(f"INFO - Mkdocs With Confluence: {i} *NEW PAGE*") print(f"INFO - Mkdocs With Confluence: {i} *NEW PAGE*")
time.sleep(1) time.sleep(1)
# if self.config['debug']: if self.config["debug"]:
print(f"Trying to ADD page '{parent}' to parent1({parent1}) ID: {second_parent_id}") print(
f"DEBUG - Trying to ADD page '{parent}' "
f"to parent1({parent1}) ID: {second_parent_id}"
)
body = TEMPLATE_BODY.replace("TEMPLATE", parent) body = TEMPLATE_BODY.replace("TEMPLATE", parent)
self.add_page(parent, second_parent_id, body) self.add_page(parent, second_parent_id, body)
for i in MkdocsWithConfluence.tab_nav: for i in MkdocsWithConfluence.tab_nav:
@ -247,8 +311,24 @@ class MkdocsWithConfluence(BasePlugin):
time.sleep(1) time.sleep(1)
# if self.config['debug']: # if self.config['debug']:
print(f"Trying to ADD page '{page.title}' to parent0({parent}) ID: {parent_id}")
if parent_id is None:
for i in range(11):
while parent_id is None:
try:
self.add_page(page.title, parent_id, confluence_body)
except requests.exceptions.HTTPError:
print(
f"ERR - HTTP error on adding page. It probably occured due to "
f"parent ID('{parent_id}') page is not YET synced on server. Retry nb {i}/10..."
)
sleep(5)
parent_id = self.find_page_id(parent)
break
self.add_page(page.title, parent_id, confluence_body) self.add_page(page.title, parent_id, confluence_body)
print(f"Trying to ADD page '{page.title}' to parent0({parent}) ID: {parent_id}")
for i in MkdocsWithConfluence.tab_nav: for i in MkdocsWithConfluence.tab_nav:
if page.title in i: if page.title in i:
n_kol = len(i + "INFO - Mkdocs With Confluence:" + " *NEW PAGE*") n_kol = len(i + "INFO - Mkdocs With Confluence:" + " *NEW PAGE*")
@ -256,14 +336,16 @@ class MkdocsWithConfluence(BasePlugin):
if files: if files:
if self.config["debug"]: if self.config["debug"]:
print(f"\nUPLOADING ATTACHMENTS TO CONFLUENCE, DETAILS:\n" f"FILES: {files}\n") print(f"\nDEBUG - UPLOADING ATTACHMENTS TO CONFLUENCE, DETAILS:\n" f"FILES: {files}\n")
n_kol = len(" *NEW ATTACHMENTS({len(files)})*")
print(f"\033[A\033[F\033[{n_kol}G *NEW ATTACHMENTS({len(files)})*") print(f"\033[A\033[F\033[{n_kol}G *NEW ATTACHMENTS({len(files)})*")
for f in files: for f in files:
self.add_attachment(page.title, f) self.add_attachment(page.title, f)
except IndexError as e: except IndexError as e:
print(f"ERR({e}): Exception error!") if self.config["debug"]:
print(f"DEBUG - ERR({e}): Exception error!")
return markdown return markdown
return markdown return markdown
@ -271,15 +353,39 @@ class MkdocsWithConfluence(BasePlugin):
def on_page_content(self, html, page, config, files): def on_page_content(self, html, page, config, files):
return html return html
def __get_page_url(self, section):
return re.search("url='(.*)'\\)", section).group(1)[:-1] + ".md"
def __get_page_name(self, section):
return os.path.basename(re.search("url='(.*)'\\)", section).group(1)[:-1])
def __get_section_name(self, section):
if self.config["debug"]:
print(f"DEBUG - SECTION name: {section}")
return os.path.basename(re.search("url='(.*)'\\/", section).group(1)[:-1])
def __get_section_title(self, section): def __get_section_title(self, section):
return re.search("Section\\(title='(.*)'\\)", section).group(1) if self.config["debug"]:
print(f"DEBUG - SECTION title: {section}")
try:
r = re.search("Section\\(title='(.*)'\\)", section)
return r.group(1)
except AttributeError:
name = self.__get_section_name(section)
print(f"WRN - Section '{name}' doesn't exist in the mkdocs.yml nav section!")
return name
def __get_page_title(self, section): def __get_page_title(self, section):
return re.search("\\s*Page\\(title='(.*)',", section).group(1) try:
r = re.search("\\s*Page\\(title='(.*)',", section)
return r.group(1)
except AttributeError:
name = self.__get_page_url(section)
print(f"WRN - Page '{name}' doesn't exist in the mkdocs.yml nav section!")
return name
def add_attachment(self, page_name, filepath): def add_attachment(self, page_name, filepath):
if self.config["verbose"]: print(f"INFO - Mkdocs With Confluence * {page_name} *NEW ATTACHMENT* {filepath}")
print(f"INFO - Mkdocs With Confluence * {page_name} *NEW ATTACHMENT* {filepath}")
if self.config["debug"]: if self.config["debug"]:
print(f" * Mkdocs With Confluence: Add Attachment: PAGE NAME: {page_name}, FILE: {filepath}") print(f" * Mkdocs With Confluence: Add Attachment: PAGE NAME: {page_name}, FILE: {filepath}")
page_id = self.find_page_id(page_name) page_id = self.find_page_id(page_name)
@ -318,7 +424,8 @@ class MkdocsWithConfluence(BasePlugin):
auth = (self.user, self.pw) auth = (self.user, self.pw)
r = requests.get(url, auth=auth) r = requests.get(url, auth=auth)
r.raise_for_status() r.raise_for_status()
response_json = r.json() with nostdout():
response_json = r.json()
if response_json["results"]: if response_json["results"]:
if self.config["debug"]: if self.config["debug"]:
print(f"ID: {response_json['results'][0]['id']}") print(f"ID: {response_json['results'][0]['id']}")
@ -329,8 +436,7 @@ class MkdocsWithConfluence(BasePlugin):
return None return None
def add_page(self, page_name, parent_page_id, page_content_in_storage_format): def add_page(self, page_name, parent_page_id, page_content_in_storage_format):
# if self.config['verbose']: print(f"INFO - * Mkdocs With Confluence: {page_name} - *NEW PAGE*")
# print(f"INFO - * Mkdocs With Confluence: {page_name} - *NEW PAGE*")
if self.config["debug"]: if self.config["debug"]:
print(f" * Mkdocs With Confluence: Adding Page: PAGE NAME: {page_name}, parent ID: {parent_page_id}") print(f" * Mkdocs With Confluence: Adding Page: PAGE NAME: {page_name}, parent ID: {parent_page_id}")
@ -361,8 +467,7 @@ class MkdocsWithConfluence(BasePlugin):
def update_page(self, page_name, page_content_in_storage_format): def update_page(self, page_name, page_content_in_storage_format):
page_id = self.find_page_id(page_name) page_id = self.find_page_id(page_name)
if self.config["verbose"]: print(f"INFO - * Mkdocs With Confluence: {page_name} - *UPDATE*")
print(f"INFO - * Mkdocs With Confluence: {page_name} - *UPDATE*")
if self.config["debug"]: if self.config["debug"]:
print(f" * Mkdocs With Confluence: Update PAGE ID: {page_id}, PAGE NAME: {page_name}") print(f" * Mkdocs With Confluence: Update PAGE ID: {page_id}, PAGE NAME: {page_name}")
if page_id: if page_id:
@ -401,12 +506,12 @@ class MkdocsWithConfluence(BasePlugin):
print(f"INFO - * Mkdocs With Confluence: Find PAGE VERSION, PAGE NAME: {page_name}") print(f"INFO - * Mkdocs With Confluence: Find PAGE VERSION, PAGE NAME: {page_name}")
name_confl = page_name.replace(" ", "+") name_confl = page_name.replace(" ", "+")
url = self.config["host_url"] + "?title=" + name_confl + "&spaceKey=" + self.config["space"] + "&expand=version" url = self.config["host_url"] + "?title=" + name_confl + "&spaceKey=" + self.config["space"] + "&expand=version"
auth = (self.user, self.pw) auth = (self.user, self.pw)
r = requests.get(url, auth=auth) r = requests.get(url, auth=auth)
r.raise_for_status() r.raise_for_status()
response_json = r.json() with nostdout():
if response_json["results"]: response_json = r.json()
if response_json["results"] is not None:
if self.config["debug"]: if self.config["debug"]:
print(f"VERSION: {response_json['results'][0]['version']['number']}") print(f"VERSION: {response_json['results'][0]['version']['number']}")
return response_json["results"][0]["version"]["number"] return response_json["results"][0]["version"]["number"]
@ -424,7 +529,8 @@ class MkdocsWithConfluence(BasePlugin):
auth = (self.user, self.pw) auth = (self.user, self.pw)
r = requests.get(url, auth=auth) r = requests.get(url, auth=auth)
r.raise_for_status() r.raise_for_status()
response_json = r.json() with nostdout():
response_json = r.json()
if response_json: if response_json:
if self.config["debug"]: if self.config["debug"]:
print(f"PARENT NAME: {response_json['ancestors'][-1]['title']}") print(f"PARENT NAME: {response_json['ancestors'][-1]['title']}")

View File

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup( setup(
name="mkdocs-with-confluence", name="mkdocs-with-confluence",
version="0.2.2", version="0.2.5",
description="MkDocs plugin for uploading markdown documentation to Confluence via Confluence REST API", description="MkDocs plugin for uploading markdown documentation to Confluence via Confluence REST API",
keywords="mkdocs markdown confluence documentation rest python", keywords="mkdocs markdown confluence documentation rest python",
url="https://github.com/pawelsikora/mkdocs-with-confluence/", url="https://github.com/pawelsikora/mkdocs-with-confluence/",