Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
1e5181b
Add lockfile tracking for exported pages
naoki-tateyama Feb 2, 2026
90f211c
feat: Incremental page download using lockfile
naoki-tateyama Feb 3, 2026
8691524
add prune command
naoki-tateyama Feb 3, 2026
0b5dbd3
add incremental export option to pages command
naoki-tateyama Feb 8, 2026
6bac022
fix performance issue by adding Descendant type
naoki-tateyama Feb 8, 2026
6edb622
integrate version property into Descendant class
naoki-tateyama Feb 8, 2026
70617ea
fix performance issue by avoiding ancestor fetching in the _template_…
naoki-tateyama Feb 8, 2026
d34eff7
add documentation for the new incremental option
naoki-tateyama Feb 8, 2026
bd13853
remove expand parameters from from_id and from_url methods.
naoki-tateyama Feb 8, 2026
2516f41
move LockfileManager to outside of the Page class
naoki-tateyama Feb 9, 2026
5029d3d
parse ancestor in simpler way
naoki-tateyama Feb 9, 2026
4201ccf
add tests for lockfile utils
naoki-tateyama Feb 11, 2026
8603a3b
refactor Ancestor and Descendant classes
naoki-tateyama Feb 11, 2026
dd86763
atomic file writes
naoki-tateyama Feb 15, 2026
5263c39
Update confluence_markdown_exporter/utils/lockfile.py
naoki-tateyama Mar 4, 2026
6f15581
fix Ancestor.id type from str to int
naoki-tateyama Mar 4, 2026
02562ff
prefilter pages before tqdm progress bar
naoki-tateyama Mar 4, 2026
509d3e6
sort lockfile entries by key for stable git diffs
naoki-tateyama Mar 4, 2026
4253132
make skip_unchanged a config option enabled by default
naoki-tateyama Mar 4, 2026
ed2f5a1
add automatic cleanup for deleted and moved pages
naoki-tateyama Mar 4, 2026
f899267
Introduce new config options and refactor clean
Spenhouet Mar 5, 2026
a115f39
Fix connection config
Spenhouet Mar 6, 2026
1439186
Redownload if file is missing
Spenhouet Mar 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
"ms-python.python",
"ms-python.vscode-pylance",
"njpwerner.autodocstring",
"visualstudioexptteam.vscodeintellicode",
"charliermarsh.ruff",
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": []
}
}
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.analysis.typeCheckingMode": "standard",
"python.defaultInterpreterPath": ".venv/bin/python",
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"jupyter.notebookFileRoot": "${workspaceFolder}",
"task.autoDetect": "off",
"python.analysis.diagnosticSeverityOverrides": {
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
- Converts Confluence macros to equivalent Markdown syntax where possible.
- Handles images and attachments by linking them appropriately in the Markdown output.
- Supports extended Markdown features like tasks, alerts, and front matter.
- Skips unchanged pages by default — only re-exports pages that have changed since the last run.
- Supports Confluence add-ons: [draw.io](https://marketplace.atlassian.com/apps/1210933/draw-io-diagrams-uml-bpmn-aws-erd-flowcharts), [PlantUML](https://marketplace.atlassian.com/apps/1222993/flowchart-plantuml-diagrams-for-confluence)

## Supported Markdown Elements
Expand Down Expand Up @@ -94,7 +95,7 @@ Export all Confluence pages of a single Space:
confluence-markdown-exporter spaces <space-key e.g. MYSPACE> <output path e.g. ./output_path/>
```

#### 2.3. Export all Spaces
#### 2.4. Export all Spaces

Export all Confluence pages across all spaces:

Expand Down Expand Up @@ -149,12 +150,17 @@ This will open a menu where you can:
| export.filename_encoding | Character mapping for filename encoding. | Default mappings for forbidden characters. |
| export.filename_length | Maximum length of filenames. | 255 |
| export.include_document_title | Whether to include the document title in the exported markdown file. | True |
| export.skip_unchanged | Skip exporting pages that have not changed since last export. Uses a lockfile to track page versions. | True |
| export.cleanup_stale | After export, delete local files for pages removed from Confluence or whose export path has changed. | True |
| export.lockfile_name | Name of the lock file used to track exported pages. | confluence-lock.json |
| export.existence_check_batch_size | Number of page IDs per batch when checking page existence during cleanup. Capped at 25 for self-hosted (CQL). | 250 |
| connection_config.backoff_and_retry | Enable automatic retry with exponential backoff | True |
| connection_config.backoff_factor | Multiplier for exponential backoff | 2 |
| connection_config.max_backoff_seconds | Maximum seconds to wait between retries | 60 |
| connection_config.max_backoff_retries | Maximum number of retry attempts | 5 |
| connection_config.retry_status_codes | HTTP status codes that trigger a retry | \[413, 429, 502, 503, 504\] |
| connection_config.verify_ssl | Whether to verify SSL certificates for HTTPS requests. | True |
| connection_config.use_v2_api | Enable Confluence REST API v2 endpoints. Supported on Atlassian Cloud and Data Center 8+. Disable for self-hosted Server instances. | False |
| auth.confluence.url | Confluence instance URL | "" |
| auth.confluence.username | Confluence username/email | "" |
| auth.confluence.api_token | Confluence API token | "" |
Expand Down
8 changes: 4 additions & 4 deletions confluence_markdown_exporter/api_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ def get_confluence_instance() -> ConfluenceApiSdk:
"""Get authenticated Confluence API client using current settings."""
settings = get_settings()
auth = settings.auth
connection_config = settings.connection_config.model_dump()
connection_config = settings.connection_config.model_dump(exclude={"use_v2_api"})

while True:
try:
confluence = ApiClientFactory(connection_config).create_confluence(auth.confluence)
break
except ConnectionError:
except ConnectionError as e:
questionary.print(
"Confluence connection failed: Redirecting to Confluence authentication config...",
f"{e}\nRedirecting to Confluence authentication config...",
style="fg:red bold",
)
main_config_menu_loop("auth.confluence")
Expand All @@ -99,7 +99,7 @@ def get_jira_instance() -> JiraApiSdk:
"""Get authenticated Jira API client using current settings with required authentication."""
settings = get_settings()
auth = settings.auth
connection_config = settings.connection_config.model_dump()
connection_config = settings.connection_config.model_dump(exclude={"use_v2_api"})

while True:
try:
Expand Down
Loading