Add sync engine, web UI, Docker setup, and tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
205
CLAUDE.md
205
CLAUDE.md
@@ -1,206 +1,7 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with this repository.
|
||||
|
||||
## Project Overview
|
||||
For detailed technical guidance, architecture details, common pitfalls, and code patterns, please see [AGENTS.md](./AGENTS.md).
|
||||
|
||||
This is a tool for exporting Outline wiki data via API. The script runs inside a Docker container on the `domnet` network to bypass Authentik SSO authentication and access the internal Outline API directly (`http://outline:3000`).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Run the export with tree visualization
|
||||
./export_with_trees.sh
|
||||
|
||||
# Preview without exporting (dry run)
|
||||
./export_with_trees.sh --dry-run
|
||||
|
||||
# Run with verbose output
|
||||
./export_with_trees.sh -v
|
||||
```
|
||||
|
||||
### CLI Options
|
||||
```
|
||||
--dry-run, -n Preview what would be exported without writing files
|
||||
--output, -o DIR Output directory (overrides settings.json)
|
||||
--verbose, -v Increase verbosity (-vv for debug)
|
||||
--skip-verify Skip post-export verification
|
||||
--skip-health-check Skip pre-export health check
|
||||
--settings FILE Path to settings file (default: settings.json)
|
||||
```
|
||||
|
||||
### Running the Python Export Directly
|
||||
```bash
|
||||
docker run --rm --network domnet \
|
||||
-v "$(pwd):/work" \
|
||||
-w /work \
|
||||
python:3.11-slim \
|
||||
bash -c "pip install -q requests tqdm && python3 outline_export_fixed.py"
|
||||
|
||||
# With options
|
||||
docker run --rm --network domnet \
|
||||
-v "$(pwd):/work" \
|
||||
-w /work \
|
||||
python:3.11-slim \
|
||||
bash -c "pip install -q requests tqdm && python3 outline_export_fixed.py --dry-run"
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Docker Network Integration
|
||||
- Script runs in Docker container attached to `domnet` bridge network
|
||||
- Direct API access to `http://outline:3000` (internal) bypasses SSO
|
||||
- Uses `python:3.11-slim` image with `requests` and `tqdm` dependencies
|
||||
|
||||
### Export Flow
|
||||
1. Fetch collections via `/api/collections.list`
|
||||
2. Get navigation tree via `/api/collections.documents` (source of truth for hierarchy)
|
||||
3. Fetch full document content via `/api/documents.info` (with caching)
|
||||
4. Export recursively maintaining parent-child structure
|
||||
5. Save metadata (`_collection_metadata.json`) per collection
|
||||
6. Generate manifest with checksums for verification
|
||||
|
||||
### Key Files
|
||||
- `export_with_trees.sh` - Main export script with tree visualization
|
||||
- `outline_export_fixed.py` - Core export logic with `OutlineExporter` class
|
||||
- `settings.json` - API URL and token configuration (contains secrets)
|
||||
- `outline_export/` - Output directory with markdown files and metadata
|
||||
- `outline_backup_*.tar.gz` - Timestamped compressed backups
|
||||
|
||||
### Configuration
|
||||
Settings are in `settings.json`:
|
||||
- `source.url` - Internal Docker URL (`http://outline:3000`)
|
||||
- `source.token` - Outline API token
|
||||
- `export.output_directory` - Output path (default: `outline_export`)
|
||||
- `advanced.max_hierarchy_depth` - Prevent infinite recursion (default: 100)
|
||||
|
||||
## Important Notes
|
||||
|
||||
### Security
|
||||
- `settings.json` contains API token - never commit to git
|
||||
- Backup files may contain sensitive wiki content
|
||||
|
||||
### Backup System
|
||||
- Each export automatically backs up previous exports to `outline_backup_YYYYMMDD_HHMMSS.tar.gz`
|
||||
- Old uncompressed export directory is deleted after backup
|
||||
- Backups achieve 90%+ compression on markdown content
|
||||
|
||||
### Reliability Features
|
||||
- **Health check**: Verifies API connectivity before export
|
||||
- **Retry logic**: Failed API requests retry up to 3 times with exponential backoff
|
||||
- **Logging**: Structured logging with configurable verbosity levels
|
||||
|
||||
### Document Counting
|
||||
The navigation tree (`/api/collections.documents`) is the source of truth for document hierarchy. Document counting is recursive to include all nested children.
|
||||
|
||||
---
|
||||
|
||||
## Import Tool
|
||||
|
||||
The import script restores exported markdown files back into Outline, preserving the full document hierarchy.
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
# Import all collections from outline_export/
|
||||
./import_to_outline.sh
|
||||
|
||||
# Preview what would be imported (no changes made)
|
||||
./import_to_outline.sh --dry-run
|
||||
|
||||
# Import into a single timestamped collection
|
||||
./import_to_outline.sh --single
|
||||
|
||||
# Import from a different directory
|
||||
./import_to_outline.sh -d exports/
|
||||
|
||||
# Overwrite existing collections
|
||||
./import_to_outline.sh --force
|
||||
```
|
||||
|
||||
### CLI Options
|
||||
```
|
||||
-s, --single Import all into single timestamped collection
|
||||
-n, --dry-run Preview operations without making changes
|
||||
-d, --source DIR Source directory (default: outline_export)
|
||||
-v, --verbose Increase verbosity (-vv for debug)
|
||||
-f, --force Overwrite existing collections (instead of skip)
|
||||
--settings FILE Path to settings file (default: settings.json)
|
||||
-h, --help Show help message
|
||||
```
|
||||
|
||||
### Import Modes
|
||||
|
||||
**Collection-per-Folder (Default)**
|
||||
Each subdirectory becomes a separate collection:
|
||||
```
|
||||
outline_export/
|
||||
├── Bewerbungen/ → Creates "Bewerbungen" collection
|
||||
├── Projekte/ → Creates "Projekte" collection
|
||||
└── Privat/ → Creates "Privat" collection
|
||||
```
|
||||
|
||||
**Single Collection (`--single`)**
|
||||
All content goes into one timestamped collection:
|
||||
```
|
||||
outline_export/
|
||||
├── Bewerbungen/ → Becomes parent doc "Bewerbungen"
|
||||
├── Projekte/ → Becomes parent doc "Projekte"
|
||||
└── Privat/ → Becomes parent doc "Privat"
|
||||
|
||||
All imported into: "import_20260119_143052" collection
|
||||
```
|
||||
|
||||
### Import Flow
|
||||
1. Load `_collection_metadata.json` from each collection directory
|
||||
2. Build document tree maintaining parent-child relationships
|
||||
3. Create collections via `/api/collections.create`
|
||||
4. Create documents via `/api/documents.create` with proper `parentDocumentId`
|
||||
5. Map old IDs to new IDs to maintain hierarchy
|
||||
6. Display tree-style progress with status indicators
|
||||
|
||||
### Key Files
|
||||
- `import_to_outline.sh` - Bash wrapper with Docker execution
|
||||
- `outline_import.py` - Core import logic with `OutlineImporter` class
|
||||
|
||||
### Output Example
|
||||
```
|
||||
════════════════════════════════════════════════════════════
|
||||
OUTLINE IMPORT
|
||||
════════════════════════════════════════════════════════════
|
||||
|
||||
Source: outline_export/
|
||||
Target: http://outline:3000
|
||||
Mode: Collection per folder
|
||||
|
||||
Checking API connectivity... ✓
|
||||
|
||||
Bewerbungen/ (11 documents)
|
||||
Creating collection... ✓ (id: 7f3a...)
|
||||
├── CV.md ✓ created
|
||||
├── Tipico.md ✓ created
|
||||
│ ├── Pitch Tipico.md ✓ created
|
||||
│ └── Fragen 3. Runde.md ✓ created
|
||||
└── Ihre PVS.md ✓ created
|
||||
|
||||
════════════════════════════════════════════════════════════
|
||||
SUMMARY
|
||||
════════════════════════════════════════════════════════════
|
||||
Collections: 1 created, 0 skipped, 0 errors
|
||||
Documents: 11 created, 0 skipped, 0 errors
|
||||
Duration: 2.3 seconds
|
||||
════════════════════════════════════════════════════════════
|
||||
```
|
||||
|
||||
### Duplicate Handling
|
||||
| Scenario | Default | With `--force` |
|
||||
|----------|---------|----------------|
|
||||
| Collection exists | Skip entire collection | Delete and recreate |
|
||||
| Document exists | Skip document | Update document |
|
||||
|
||||
### Error Handling
|
||||
- **API connection failure**: Abort with error message
|
||||
- **Collection creation fails**: Abort that collection, continue others
|
||||
- **Document creation fails**: Log error, continue with siblings
|
||||
- **Missing markdown file**: Log warning, skip document
|
||||
- **Parent not found**: Create as root-level document
|
||||
This is an Outline export/import tool that uses Docker to bypass Authentik SSO and access the internal API directly at `http://outline:3000`.
|
||||
|
||||
Reference in New Issue
Block a user