markdown-to-confluence 0.3.0__py3-none-any.whl → 0.3.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info}/METADATA +3 -2
- markdown_to_confluence-0.3.2.dist-info/RECORD +20 -0
- {markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info}/WHEEL +1 -1
- md2conf/__init__.py +1 -1
- md2conf/__main__.py +8 -0
- md2conf/api.py +48 -28
- md2conf/application.py +9 -0
- md2conf/converter.py +10 -17
- md2conf/mermaid.py +5 -1
- md2conf/properties.py +1 -3
- markdown_to_confluence-0.3.0.dist-info/RECORD +0 -21
- md2conf/util.py +0 -27
- {markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info}/entry_points.txt +0 -0
- {markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info/licenses}/LICENSE +0 -0
- {markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info}/top_level.txt +0 -0
- {markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info}/zip-safe +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: markdown-to-confluence
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Publish Markdown files to Confluence wiki
|
|
5
5
|
Home-page: https://github.com/hunyadi/md2conf
|
|
6
6
|
Author: Levente Hunyadi
|
|
@@ -30,6 +30,7 @@ Requires-Dist: pyyaml>=6.0
|
|
|
30
30
|
Requires-Dist: types-PyYAML>=6.0
|
|
31
31
|
Requires-Dist: requests>=2.32
|
|
32
32
|
Requires-Dist: types-requests>=2.32
|
|
33
|
+
Dynamic: license-file
|
|
33
34
|
|
|
34
35
|
# Publish Markdown files to Confluence wiki
|
|
35
36
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
markdown_to_confluence-0.3.2.dist-info/licenses/LICENSE,sha256=Pv43so2bPfmKhmsrmXFyAvS7M30-1i1tzjz6-dfhyOo,1077
|
|
2
|
+
md2conf/__init__.py,sha256=IyztAgNkEXTxDlsTrxZOAkeNIzLSSzjNV0ZHg2SvDDE,402
|
|
3
|
+
md2conf/__main__.py,sha256=ypjV_5mE0smlIRBFrpikgzXq18as2hY43HJxMLpzGp4,7145
|
|
4
|
+
md2conf/api.py,sha256=-bneMbfpspfat4J63Z7bY0kdlW8yJguRRNbx6CaOkGY,20101
|
|
5
|
+
md2conf/application.py,sha256=5K-nCPHJZfIahjubrLtXTwI-zsTiD140fdYXDnh3GSk,9161
|
|
6
|
+
md2conf/converter.py,sha256=MoGbXqh5rE4qkdxxY8RHcnoZ5mz0aEuFz9nmUnt0WdM,36397
|
|
7
|
+
md2conf/emoji.py,sha256=IZeguWqcboeOyJkGLTVONDMO4ZXfYXPgfkp56PTI-hE,1924
|
|
8
|
+
md2conf/entities.dtd,sha256=M6NzqL5N7dPs_eUA_6sDsiSLzDaAacrx9LdttiufvYU,30215
|
|
9
|
+
md2conf/matcher.py,sha256=FgMFPvGiOqGezCs8OyerfsVo-iIHFoI6LRMzdcjM5UY,3693
|
|
10
|
+
md2conf/mermaid.py,sha256=Alzkv0BY-lju4ojtBdW2qtCLZ59MO9kaS2RpQO6Kyfk,2304
|
|
11
|
+
md2conf/processor.py,sha256=G-MIh1jGq9jjgogHnlnRUSrNgiV6_xO6Fy7ct9alqgM,4769
|
|
12
|
+
md2conf/properties.py,sha256=WaVVOYSck7drVQfcBJmBMa7Mb0KVOZl9UZHvLS1Du8U,1892
|
|
13
|
+
md2conf/puppeteer-config.json,sha256=-dMTAN_7kNTGbDlfXzApl0KJpAWna9YKZdwMKbpOb60,159
|
|
14
|
+
md2conf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
markdown_to_confluence-0.3.2.dist-info/METADATA,sha256=2exvsuRCcD3L9CN7fl0gqki1gsqQgHDxGyjnKhDeYmw,14958
|
|
16
|
+
markdown_to_confluence-0.3.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
17
|
+
markdown_to_confluence-0.3.2.dist-info/entry_points.txt,sha256=F1zxa1wtEObtbHS-qp46330WVFLHdMnV2wQ-ZorRmX0,50
|
|
18
|
+
markdown_to_confluence-0.3.2.dist-info/top_level.txt,sha256=_FJfl_kHrHNidyjUOuS01ngu_jDsfc-ZjSocNRJnTzU,8
|
|
19
|
+
markdown_to_confluence-0.3.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
20
|
+
markdown_to_confluence-0.3.2.dist-info/RECORD,,
|
md2conf/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@ Parses Markdown files, converts Markdown content into the Confluence Storage For
|
|
|
5
5
|
Confluence API endpoints to upload images and content.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
__version__ = "0.3.
|
|
8
|
+
__version__ = "0.3.2"
|
|
9
9
|
__author__ = "Levente Hunyadi"
|
|
10
10
|
__copyright__ = "Copyright 2022-2025, Levente Hunyadi"
|
|
11
11
|
__license__ = "MIT"
|
md2conf/__main__.py
CHANGED
|
@@ -38,6 +38,7 @@ class Arguments(argparse.Namespace):
|
|
|
38
38
|
ignore_invalid_url: bool
|
|
39
39
|
heading_anchors: bool
|
|
40
40
|
root_page: Optional[str]
|
|
41
|
+
keep_hierarchy: bool
|
|
41
42
|
generated_by: Optional[str]
|
|
42
43
|
render_mermaid: bool
|
|
43
44
|
diagram_output_format: Literal["png", "svg"]
|
|
@@ -109,6 +110,12 @@ def main() -> None:
|
|
|
109
110
|
dest="root_page",
|
|
110
111
|
help="Root Confluence page to create new pages. If omitted, will raise exception when creating new pages.",
|
|
111
112
|
)
|
|
113
|
+
parser.add_argument(
|
|
114
|
+
"--keep-hierarchy",
|
|
115
|
+
action="store_true",
|
|
116
|
+
default=False,
|
|
117
|
+
help="Maintain source directory structure when exporting to Confluence.",
|
|
118
|
+
)
|
|
112
119
|
parser.add_argument(
|
|
113
120
|
"--generated-by",
|
|
114
121
|
default="This page has been generated with a tool.",
|
|
@@ -189,6 +196,7 @@ def main() -> None:
|
|
|
189
196
|
ignore_invalid_url=args.ignore_invalid_url,
|
|
190
197
|
generated_by=args.generated_by,
|
|
191
198
|
root_page_id=args.root_page,
|
|
199
|
+
keep_hierarchy=args.keep_hierarchy,
|
|
192
200
|
render_mermaid=args.render_mermaid,
|
|
193
201
|
diagram_output_format=args.diagram_output_format,
|
|
194
202
|
webui_links=args.webui_links,
|
md2conf/api.py
CHANGED
|
@@ -22,7 +22,6 @@ import requests
|
|
|
22
22
|
|
|
23
23
|
from .converter import ParseError, sanitize_confluence
|
|
24
24
|
from .properties import ConfluenceError, ConfluenceProperties
|
|
25
|
-
from .util import removeprefix
|
|
26
25
|
|
|
27
26
|
# a JSON type with possible `null` values
|
|
28
27
|
JsonType = Union[
|
|
@@ -41,6 +40,17 @@ class ConfluenceVersion(enum.Enum):
|
|
|
41
40
|
VERSION_2 = "api/v2"
|
|
42
41
|
|
|
43
42
|
|
|
43
|
+
class ConfluencePageParentContentType(enum.Enum):
|
|
44
|
+
"""
|
|
45
|
+
Content types that can be a parent to a Confluence page
|
|
46
|
+
"""
|
|
47
|
+
PAGE = "page"
|
|
48
|
+
WHITEBOARD = "whiteboard"
|
|
49
|
+
DATABASE = "database"
|
|
50
|
+
EMBED = "embed"
|
|
51
|
+
FOLDER = "folder"
|
|
52
|
+
|
|
53
|
+
|
|
44
54
|
def build_url(base_url: str, query: Optional[dict[str, str]] = None) -> str:
|
|
45
55
|
"Builds a URL with scheme, host, port, path and query string parameters."
|
|
46
56
|
|
|
@@ -72,6 +82,8 @@ class ConfluenceAttachment:
|
|
|
72
82
|
class ConfluencePage:
|
|
73
83
|
id: str
|
|
74
84
|
space_id: str
|
|
85
|
+
parent_id: str
|
|
86
|
+
parent_type: ConfluencePageParentContentType
|
|
75
87
|
title: str
|
|
76
88
|
version: int
|
|
77
89
|
content: str
|
|
@@ -119,13 +131,17 @@ class ConfluenceSession:
|
|
|
119
131
|
session: requests.Session
|
|
120
132
|
domain: str
|
|
121
133
|
base_path: str
|
|
122
|
-
space_key: str
|
|
134
|
+
space_key: Optional[str]
|
|
123
135
|
|
|
124
136
|
_space_id_to_key: dict[str, str]
|
|
125
137
|
_space_key_to_id: dict[str, str]
|
|
126
138
|
|
|
127
139
|
def __init__(
|
|
128
|
-
self,
|
|
140
|
+
self,
|
|
141
|
+
session: requests.Session,
|
|
142
|
+
domain: str,
|
|
143
|
+
base_path: str,
|
|
144
|
+
space_key: Optional[str],
|
|
129
145
|
) -> None:
|
|
130
146
|
self.session = session
|
|
131
147
|
self.domain = domain
|
|
@@ -168,6 +184,10 @@ class ConfluenceSession:
|
|
|
168
184
|
url = self._build_url(version, path, query)
|
|
169
185
|
response = self.session.get(url)
|
|
170
186
|
response.raise_for_status()
|
|
187
|
+
if len(response.text) > 240:
|
|
188
|
+
LOGGER.debug("Received HTTP payload (truncated):\n%.240s...", response.text)
|
|
189
|
+
else:
|
|
190
|
+
LOGGER.debug("Received HTTP payload:\n%s", response.text)
|
|
171
191
|
return response.json()
|
|
172
192
|
|
|
173
193
|
def _save(self, version: ConfluenceVersion, path: str, data: dict) -> None:
|
|
@@ -187,7 +207,7 @@ class ConfluenceSession:
|
|
|
187
207
|
payload = self._invoke(
|
|
188
208
|
ConfluenceVersion.VERSION_2,
|
|
189
209
|
"/spaces",
|
|
190
|
-
{"ids": id, "
|
|
210
|
+
{"ids": id, "status": "current"},
|
|
191
211
|
)
|
|
192
212
|
payload = typing.cast(dict[str, JsonType], payload)
|
|
193
213
|
results = typing.cast(list[JsonType], payload["results"])
|
|
@@ -209,7 +229,7 @@ class ConfluenceSession:
|
|
|
209
229
|
payload = self._invoke(
|
|
210
230
|
ConfluenceVersion.VERSION_2,
|
|
211
231
|
"/spaces",
|
|
212
|
-
{"keys": key, "
|
|
232
|
+
{"keys": key, "status": "current"},
|
|
213
233
|
)
|
|
214
234
|
payload = typing.cast(dict[str, JsonType], payload)
|
|
215
235
|
results = typing.cast(list[JsonType], payload["results"])
|
|
@@ -252,10 +272,8 @@ class ConfluenceSession:
|
|
|
252
272
|
raw_data: Optional[bytes] = None,
|
|
253
273
|
content_type: Optional[str] = None,
|
|
254
274
|
comment: Optional[str] = None,
|
|
255
|
-
space_key: Optional[str] = None,
|
|
256
275
|
force: bool = False,
|
|
257
276
|
) -> None:
|
|
258
|
-
|
|
259
277
|
if attachment_path is None and raw_data is None:
|
|
260
278
|
raise ConfluenceError("required: `attachment_path` or `raw_data`")
|
|
261
279
|
|
|
@@ -286,7 +304,7 @@ class ConfluenceSession:
|
|
|
286
304
|
else:
|
|
287
305
|
raise NotImplementedError("never occurs")
|
|
288
306
|
|
|
289
|
-
id =
|
|
307
|
+
id = attachment.id.removeprefix("att")
|
|
290
308
|
path = f"/content/{page_id}/child/attachment/{id}/data"
|
|
291
309
|
|
|
292
310
|
except ConfluenceError:
|
|
@@ -345,27 +363,18 @@ class ConfluenceSession:
|
|
|
345
363
|
version = result["version"]["number"] + 1
|
|
346
364
|
|
|
347
365
|
# ensure path component is retained in attachment name
|
|
348
|
-
self._update_attachment(
|
|
349
|
-
page_id, attachment_id, version, attachment_name, space_key=space_key
|
|
350
|
-
)
|
|
366
|
+
self._update_attachment(page_id, attachment_id, version, attachment_name)
|
|
351
367
|
|
|
352
368
|
def _update_attachment(
|
|
353
|
-
self,
|
|
354
|
-
page_id: str,
|
|
355
|
-
attachment_id: str,
|
|
356
|
-
version: int,
|
|
357
|
-
attachment_title: str,
|
|
358
|
-
*,
|
|
359
|
-
space_key: Optional[str] = None,
|
|
369
|
+
self, page_id: str, attachment_id: str, version: int, attachment_title: str
|
|
360
370
|
) -> None:
|
|
361
|
-
id = removeprefix(
|
|
371
|
+
id = attachment_id.removeprefix("att")
|
|
362
372
|
path = f"/content/{page_id}/child/attachment/{id}"
|
|
363
373
|
data = {
|
|
364
374
|
"id": attachment_id,
|
|
365
375
|
"type": "attachment",
|
|
366
376
|
"status": "current",
|
|
367
377
|
"title": attachment_title,
|
|
368
|
-
"space": {"key": space_key or self.space_key},
|
|
369
378
|
"version": {"minorEdit": True, "number": version},
|
|
370
379
|
}
|
|
371
380
|
|
|
@@ -389,9 +398,12 @@ class ConfluenceSession:
|
|
|
389
398
|
LOGGER.info("Looking up page with title: %s", title)
|
|
390
399
|
path = "/pages"
|
|
391
400
|
query = {
|
|
392
|
-
"space-id": self.space_key_to_id(space_key or self.space_key),
|
|
393
401
|
"title": title,
|
|
394
402
|
}
|
|
403
|
+
coalesced_space_key = space_key or self.space_key
|
|
404
|
+
if coalesced_space_key is not None:
|
|
405
|
+
query["space-id"] = self.space_key_to_id(coalesced_space_key)
|
|
406
|
+
|
|
395
407
|
payload = self._invoke(ConfluenceVersion.VERSION_2, path, query)
|
|
396
408
|
payload = typing.cast(dict[str, JsonType], payload)
|
|
397
409
|
|
|
@@ -422,6 +434,8 @@ class ConfluenceSession:
|
|
|
422
434
|
return ConfluencePage(
|
|
423
435
|
id=page_id,
|
|
424
436
|
space_id=typing.cast(str, data["spaceId"]),
|
|
437
|
+
parent_id=typing.cast(str, data["parentId"]),
|
|
438
|
+
parent_type=ConfluencePageParentContentType(typing.cast(str, data["parentType"])),
|
|
425
439
|
title=typing.cast(str, data["title"]),
|
|
426
440
|
version=typing.cast(int, version["number"]),
|
|
427
441
|
content=typing.cast(str, storage["value"]),
|
|
@@ -432,7 +446,6 @@ class ConfluenceSession:
|
|
|
432
446
|
Retrieve a Confluence wiki page version.
|
|
433
447
|
|
|
434
448
|
:param page_id: The Confluence page ID.
|
|
435
|
-
:param space_key: The Confluence space key (unless the default space is to be used).
|
|
436
449
|
:returns: Confluence page version.
|
|
437
450
|
"""
|
|
438
451
|
|
|
@@ -454,7 +467,6 @@ class ConfluenceSession:
|
|
|
454
467
|
|
|
455
468
|
:param page_id: The Confluence page ID.
|
|
456
469
|
:param new_content: Confluence Storage Format XHTML.
|
|
457
|
-
:param space_key: The Confluence space key (unless the default space is to be used).
|
|
458
470
|
:param title: New title to assign to the page. Needs to be unique within a space.
|
|
459
471
|
"""
|
|
460
472
|
|
|
@@ -493,9 +505,15 @@ class ConfluenceSession:
|
|
|
493
505
|
Create a new page via Confluence API.
|
|
494
506
|
"""
|
|
495
507
|
|
|
508
|
+
coalesced_space_key = space_key or self.space_key
|
|
509
|
+
if coalesced_space_key is None:
|
|
510
|
+
raise ConfluenceError(
|
|
511
|
+
"Confluence space key required for creating a new page"
|
|
512
|
+
)
|
|
513
|
+
|
|
496
514
|
path = "/pages/"
|
|
497
515
|
query = {
|
|
498
|
-
"spaceId": self.space_key_to_id(
|
|
516
|
+
"spaceId": self.space_key_to_id(coalesced_space_key),
|
|
499
517
|
"status": "current",
|
|
500
518
|
"title": title,
|
|
501
519
|
"parentId": parent_page_id,
|
|
@@ -520,6 +538,8 @@ class ConfluenceSession:
|
|
|
520
538
|
return ConfluencePage(
|
|
521
539
|
id=typing.cast(str, data["id"]),
|
|
522
540
|
space_id=typing.cast(str, data["spaceId"]),
|
|
541
|
+
parent_id=typing.cast(str, data["parentId"]),
|
|
542
|
+
parent_type=ConfluencePageParentContentType(typing.cast(str, data["parentType"])),
|
|
523
543
|
title=typing.cast(str, data["title"]),
|
|
524
544
|
version=typing.cast(int, version["number"]),
|
|
525
545
|
content=typing.cast(str, storage["value"]),
|
|
@@ -553,10 +573,10 @@ class ConfluenceSession:
|
|
|
553
573
|
self, title: str, *, space_key: Optional[str] = None
|
|
554
574
|
) -> Optional[str]:
|
|
555
575
|
path = "/pages"
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
576
|
+
coalesced_space_key = space_key or self.space_key
|
|
577
|
+
query = {"title": title}
|
|
578
|
+
if coalesced_space_key is not None:
|
|
579
|
+
query["space-id"] = self.space_key_to_id(coalesced_space_key)
|
|
560
580
|
|
|
561
581
|
LOGGER.info("Checking if page exists with title: %s", title)
|
|
562
582
|
|
md2conf/application.py
CHANGED
|
@@ -131,6 +131,15 @@ class Application:
|
|
|
131
131
|
parent_doc = Path(local_dir) / "index.md"
|
|
132
132
|
elif (Path(local_dir) / "README.md") in files:
|
|
133
133
|
parent_doc = Path(local_dir) / "README.md"
|
|
134
|
+
elif (Path(local_dir) / f"{local_dir.name}.md") in files:
|
|
135
|
+
parent_doc = Path(local_dir) / f"{local_dir.name}.md"
|
|
136
|
+
|
|
137
|
+
if parent_doc is None and self.options.keep_hierarchy:
|
|
138
|
+
parent_doc = Path(local_dir) / "index.md"
|
|
139
|
+
|
|
140
|
+
# create a blank page in Confluence for the directory entry
|
|
141
|
+
with open(parent_doc, "w"):
|
|
142
|
+
pass
|
|
134
143
|
|
|
135
144
|
if parent_doc is not None:
|
|
136
145
|
files.remove(parent_doc)
|
md2conf/converter.py
CHANGED
|
@@ -13,7 +13,6 @@ import importlib.resources as resources
|
|
|
13
13
|
import logging
|
|
14
14
|
import os.path
|
|
15
15
|
import re
|
|
16
|
-
import sys
|
|
17
16
|
import uuid
|
|
18
17
|
import xml.etree.ElementTree
|
|
19
18
|
from dataclasses import dataclass
|
|
@@ -129,7 +128,7 @@ def _elements_from_strings(dtd_path: Path, items: list[str]) -> ET._Element:
|
|
|
129
128
|
|
|
130
129
|
data = [
|
|
131
130
|
'<?xml version="1.0"?>',
|
|
132
|
-
f'<!DOCTYPE ac:confluence PUBLIC "-//Atlassian//Confluence 4 Page//EN" "{dtd_path}">'
|
|
131
|
+
f'<!DOCTYPE ac:confluence PUBLIC "-//Atlassian//Confluence 4 Page//EN" "{dtd_path.as_posix()}">'
|
|
133
132
|
f"<root{ns_attr_list}>",
|
|
134
133
|
]
|
|
135
134
|
data.extend(items)
|
|
@@ -144,13 +143,9 @@ def _elements_from_strings(dtd_path: Path, items: list[str]) -> ET._Element:
|
|
|
144
143
|
def elements_from_strings(items: list[str]) -> ET._Element:
|
|
145
144
|
"Creates a fragment of several XML nodes from their string representation wrapped in a root element."
|
|
146
145
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
return _elements_from_strings(dtd_path, items)
|
|
151
|
-
else:
|
|
152
|
-
with resources.path(__package__, "entities.dtd") as dtd_path:
|
|
153
|
-
return _elements_from_strings(dtd_path, items)
|
|
146
|
+
resource_path = resources.files(__package__).joinpath("entities.dtd")
|
|
147
|
+
with resources.as_file(resource_path) as dtd_path:
|
|
148
|
+
return _elements_from_strings(dtd_path, items)
|
|
154
149
|
|
|
155
150
|
|
|
156
151
|
def elements_from_string(content: str) -> ET._Element:
|
|
@@ -244,7 +239,7 @@ class ConfluencePageMetadata:
|
|
|
244
239
|
domain: str
|
|
245
240
|
base_path: str
|
|
246
241
|
page_id: str
|
|
247
|
-
space_key: str
|
|
242
|
+
space_key: Optional[str]
|
|
248
243
|
title: str
|
|
249
244
|
|
|
250
245
|
|
|
@@ -976,6 +971,7 @@ class ConfluenceDocumentOptions:
|
|
|
976
971
|
conversion rules for the identifier.
|
|
977
972
|
:param generated_by: Text to use as the generated-by prompt (or `None` to omit a prompt).
|
|
978
973
|
:param root_page_id: Confluence page to assume root page role for publishing a directory of Markdown files.
|
|
974
|
+
:param keep_hierarchy: Whether to maintain source directory structure when exporting to Confluence.
|
|
979
975
|
:param render_mermaid: Whether to pre-render Mermaid diagrams into PNG/SVG images.
|
|
980
976
|
:param diagram_output_format: Target image format for diagrams.
|
|
981
977
|
:param webui_links: When true, convert relative URLs to Confluence Web UI links.
|
|
@@ -985,6 +981,7 @@ class ConfluenceDocumentOptions:
|
|
|
985
981
|
heading_anchors: bool = False
|
|
986
982
|
generated_by: Optional[str] = "This page has been generated with a tool."
|
|
987
983
|
root_page_id: Optional[str] = None
|
|
984
|
+
keep_hierarchy: bool = False
|
|
988
985
|
render_mermaid: bool = False
|
|
989
986
|
diagram_output_format: Literal["png", "svg"] = "png"
|
|
990
987
|
webui_links: bool = False
|
|
@@ -1132,10 +1129,6 @@ def _content_to_string(dtd_path: Path, content: str) -> str:
|
|
|
1132
1129
|
def content_to_string(content: str) -> str:
|
|
1133
1130
|
"Converts a Confluence Storage Format document returned by the API into a readable XML document."
|
|
1134
1131
|
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
return _content_to_string(dtd_path, content)
|
|
1139
|
-
else:
|
|
1140
|
-
with resources.path(__package__, "entities.dtd") as dtd_path:
|
|
1141
|
-
return _content_to_string(dtd_path, content)
|
|
1132
|
+
resource_path = resources.files(__package__).joinpath("entities.dtd")
|
|
1133
|
+
with resources.as_file(resource_path) as dtd_path:
|
|
1134
|
+
return _content_to_string(dtd_path, content)
|
md2conf/mermaid.py
CHANGED
|
@@ -29,7 +29,11 @@ def get_mmdc() -> str:
|
|
|
29
29
|
"Path to the Mermaid diagram converter."
|
|
30
30
|
|
|
31
31
|
if is_docker():
|
|
32
|
-
|
|
32
|
+
full_path = "/home/md2conf/node_modules/.bin/mmdc"
|
|
33
|
+
if os.path.exists(full_path):
|
|
34
|
+
return full_path
|
|
35
|
+
else:
|
|
36
|
+
return "mmdc"
|
|
33
37
|
elif os.name == "nt":
|
|
34
38
|
return "mmdc.cmd"
|
|
35
39
|
else:
|
md2conf/properties.py
CHANGED
|
@@ -17,7 +17,7 @@ class ConfluenceError(RuntimeError):
|
|
|
17
17
|
class ConfluenceProperties:
|
|
18
18
|
domain: str
|
|
19
19
|
base_path: str
|
|
20
|
-
space_key: str
|
|
20
|
+
space_key: Optional[str]
|
|
21
21
|
user_name: Optional[str]
|
|
22
22
|
api_key: str
|
|
23
23
|
headers: Optional[dict[str, str]]
|
|
@@ -43,8 +43,6 @@ class ConfluenceProperties:
|
|
|
43
43
|
opt_base_path = "/wiki/"
|
|
44
44
|
if not opt_api_key:
|
|
45
45
|
raise ConfluenceError("Confluence API key not specified")
|
|
46
|
-
if not opt_space_key:
|
|
47
|
-
raise ConfluenceError("Confluence space key not specified")
|
|
48
46
|
|
|
49
47
|
if opt_domain.startswith(("http://", "https://")) or opt_domain.endswith("/"):
|
|
50
48
|
raise ConfluenceError(
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
md2conf/__init__.py,sha256=Lveuwj776s0e_lokulqzAtv64eStsiMROB96DimCLd0,402
|
|
2
|
-
md2conf/__main__.py,sha256=Sga_W_b5E1YokJcBAXcmZVnYk-us8A0kkhfkmdHogsg,6883
|
|
3
|
-
md2conf/api.py,sha256=KIZNwdsMGXYy9i4FHSe0XbbCjjVJzTTlnryGesxM-GI,19312
|
|
4
|
-
md2conf/application.py,sha256=Udp79iB0bGc7sPmE3jD7PSK35yedS_XBhfTEVap91-o,8777
|
|
5
|
-
md2conf/converter.py,sha256=BlS51hjiJd0lgrh5wJkun1_FZ9kAtmInKjEYhr5YOLA,36620
|
|
6
|
-
md2conf/emoji.py,sha256=IZeguWqcboeOyJkGLTVONDMO4ZXfYXPgfkp56PTI-hE,1924
|
|
7
|
-
md2conf/entities.dtd,sha256=M6NzqL5N7dPs_eUA_6sDsiSLzDaAacrx9LdttiufvYU,30215
|
|
8
|
-
md2conf/matcher.py,sha256=FgMFPvGiOqGezCs8OyerfsVo-iIHFoI6LRMzdcjM5UY,3693
|
|
9
|
-
md2conf/mermaid.py,sha256=82NGv6x_LNrN3c-VPx368KCBO87_Sv8-uz2ue40DzKg,2192
|
|
10
|
-
md2conf/processor.py,sha256=G-MIh1jGq9jjgogHnlnRUSrNgiV6_xO6Fy7ct9alqgM,4769
|
|
11
|
-
md2conf/properties.py,sha256=HqFveB-Wgg29e60tARHSk21l8b-SCk953eb_Mw-nI80,1984
|
|
12
|
-
md2conf/puppeteer-config.json,sha256=-dMTAN_7kNTGbDlfXzApl0KJpAWna9YKZdwMKbpOb60,159
|
|
13
|
-
md2conf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
md2conf/util.py,sha256=Ct7T21oI2AUs6hIZVNljPhq5HbNscjnFXMpVCzRlRHw,743
|
|
15
|
-
markdown_to_confluence-0.3.0.dist-info/LICENSE,sha256=Pv43so2bPfmKhmsrmXFyAvS7M30-1i1tzjz6-dfhyOo,1077
|
|
16
|
-
markdown_to_confluence-0.3.0.dist-info/METADATA,sha256=oAWMGSnPXtLZZyDiwNdbb4QWwEP0uXPxzKiBqY9mfT0,14936
|
|
17
|
-
markdown_to_confluence-0.3.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
18
|
-
markdown_to_confluence-0.3.0.dist-info/entry_points.txt,sha256=F1zxa1wtEObtbHS-qp46330WVFLHdMnV2wQ-ZorRmX0,50
|
|
19
|
-
markdown_to_confluence-0.3.0.dist-info/top_level.txt,sha256=_FJfl_kHrHNidyjUOuS01ngu_jDsfc-ZjSocNRJnTzU,8
|
|
20
|
-
markdown_to_confluence-0.3.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
21
|
-
markdown_to_confluence-0.3.0.dist-info/RECORD,,
|
md2conf/util.py
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Publish Markdown files to Confluence wiki.
|
|
3
|
-
|
|
4
|
-
Copyright 2022-2025, Levente Hunyadi
|
|
5
|
-
|
|
6
|
-
:see: https://github.com/hunyadi/md2conf
|
|
7
|
-
"""
|
|
8
|
-
|
|
9
|
-
import sys
|
|
10
|
-
|
|
11
|
-
if sys.version_info >= (3, 9):
|
|
12
|
-
|
|
13
|
-
def removeprefix(string: str, prefix: str) -> str:
|
|
14
|
-
"If the string starts with the prefix, return the string without the prefix; otherwise, return the original string."
|
|
15
|
-
|
|
16
|
-
return string.removeprefix(prefix)
|
|
17
|
-
|
|
18
|
-
else:
|
|
19
|
-
|
|
20
|
-
def removeprefix(string: str, prefix: str) -> str:
|
|
21
|
-
"If the string starts with the prefix, return the string without the prefix; otherwise, return the original string."
|
|
22
|
-
|
|
23
|
-
if string.startswith(prefix):
|
|
24
|
-
prefix_len = len(prefix)
|
|
25
|
-
return string[prefix_len:]
|
|
26
|
-
else:
|
|
27
|
-
return string
|
{markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info/licenses}/LICENSE
RENAMED
|
File without changes
|
{markdown_to_confluence-0.3.0.dist-info → markdown_to_confluence-0.3.2.dist-info}/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|