nds-mapviewer 2026.4.2.dev203__tar.gz → 2026.4.2.dev205__tar.gz
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.
- nds_mapviewer-2026.4.2.dev205/.gitignore +5 -0
- nds_mapviewer-2026.4.2.dev205/CHANGELOG.md +91 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/PKG-INFO +1 -1
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/nds_mapviewer.egg-info/PKG-INFO +1 -1
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/nds_mapviewer.egg-info/SOURCES.txt +3 -0
- nds_mapviewer-2026.4.2.dev205/tests/conftest.py +142 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/README.md +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/pyproject.toml +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/setup.cfg +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/setup.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/nds_mapviewer.egg-info/dependency_links.txt +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/nds_mapviewer.egg-info/entry_points.txt +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/nds_mapviewer.egg-info/requires.txt +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/nds_mapviewer.egg-info/top_level.txt +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/__init__.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/browser.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/cli.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/clipboard.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/config.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/container_runtime.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/docker_client.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/exceptions.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/tui.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/ui.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/viewer.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/tests/test_cli.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/tests/test_clipboard.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/tests/test_config.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/tests/test_docker_client.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/tests/test_tui.py +0 -0
- {nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/tests/test_viewer.py +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `--debug` flag to enable container debug logging (sets `HTTP_LOG_LEVEL=debug`)
|
|
13
|
+
- `--env KEY=VALUE` (repeatable, short `-E`) to pass custom environment
|
|
14
|
+
variables into the container; overrides `--debug` on key collision
|
|
15
|
+
- `--network NAME` to attach the container to a specific network (e.g. `host`);
|
|
16
|
+
in `host` mode port publishing is skipped and the viewer is reached on the
|
|
17
|
+
container's internal port
|
|
18
|
+
- Run screen now shows a config line below the info banner with the source
|
|
19
|
+
(config file or directly-passed data-source path, e.g. a `*.ndslive`
|
|
20
|
+
filestore) and the mapped config mounted into the container
|
|
21
|
+
- Accept an http(s) service URL directly as a source (e.g.
|
|
22
|
+
`mapviewer https://my-host/openapi.json`), turned into a
|
|
23
|
+
`SmartLayerTileService`; the bare-URL form configures no auth — use
|
|
24
|
+
ndslive-server as a proxy or a config.yaml with `http-settings` for
|
|
25
|
+
authenticated services
|
|
26
|
+
- Default Docker image version pinned to package (`--image-version` defaults to
|
|
27
|
+
matching calver instead of `"latest"`)
|
|
28
|
+
- SCM-based versioning — package version derived from MapViewer git tags
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
- Clipboard copy in the Docker screen now uses the native OS clipboard
|
|
33
|
+
(`clip.exe` / `pbcopy` / `wl-copy`/`xclip`/`xsel`) instead of relying on the
|
|
34
|
+
OSC 52 terminal escape, which is unreliable on Windows; warns when a copy
|
|
35
|
+
cannot be confirmed
|
|
36
|
+
- Quitting the TUI no longer hangs — the log-follow stream is torn down by
|
|
37
|
+
terminating the process before closing pipes, and container shutdown is
|
|
38
|
+
bounded so the terminal is always returned to the user
|
|
39
|
+
- `localhost`/`127.0.0.1` in service `uri` values and `http-settings` `scope`
|
|
40
|
+
values are now translated to `host.docker.internal`, so a service running on
|
|
41
|
+
the host machine is reachable from the container without `--network host`
|
|
42
|
+
- Container readiness check uses log sentinel before HTTP polling to avoid
|
|
43
|
+
startup crash (mapget#151)
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Version scheme: package now follows MapViewer calver (e.g. 2025.6.2)
|
|
48
|
+
with post-release dev builds between releases
|
|
49
|
+
|
|
50
|
+
## [0.1.0] - Unreleased
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- **CLI Commands**
|
|
55
|
+
- `setup` - Interactive setup wizard for Docker, registry auth, and image download
|
|
56
|
+
- `run` - Run MapViewer with a local path, saved config, or `--demo` mode
|
|
57
|
+
- `connect` - Interactive connection picker / wizard for saved or new data sources
|
|
58
|
+
- `update` - Check for and pull newer MapViewer Docker images
|
|
59
|
+
- Shorthand: `mapviewer <path>` resolves `.ndslive` files, SmartLayer folders, or saved config names
|
|
60
|
+
|
|
61
|
+
- **Python API**
|
|
62
|
+
- `MapViewer` class for programmatic container lifecycle management
|
|
63
|
+
- Context manager support for automatic cleanup
|
|
64
|
+
- `start()` / `stop()` / `restart()` for container control
|
|
65
|
+
- `connect()` class method to attach to a running container by name
|
|
66
|
+
- `logs()` with real-time streaming and severity filtering
|
|
67
|
+
- `status()` and `get_datasources()` for runtime introspection
|
|
68
|
+
- `open_browser()` to launch the viewer in a system or bundled browser
|
|
69
|
+
|
|
70
|
+
- **Configuration**
|
|
71
|
+
- Automatic path transformation (host paths to container mount points)
|
|
72
|
+
- Volume mount generation with read-only mounts and parent-directory deduplication
|
|
73
|
+
- Localhost translation to `host.docker.internal`
|
|
74
|
+
- YAML config creation helpers for filestores, SmartLayer folders, and remote services
|
|
75
|
+
- Saved connections stored under `~/.nds/configs/`
|
|
76
|
+
- Default config at `~/.nds/config.yaml` — shared across NDS tools, auto-loaded when no args given
|
|
77
|
+
|
|
78
|
+
- **Authentication**
|
|
79
|
+
- Six methods: API key, query parameters, basic auth, bearer token, OAuth2 client credentials, and none
|
|
80
|
+
- Optional proxy support with authentication
|
|
81
|
+
|
|
82
|
+
- **Browser Integration**
|
|
83
|
+
- Multi-platform system browser detection (Chrome, Chromium, Edge, Brave)
|
|
84
|
+
- Optional bundled Chromium via Playwright (`[browser]` extra)
|
|
85
|
+
- Automatic browser launch on `run` and `connect`
|
|
86
|
+
|
|
87
|
+
- **Setup & Diagnostics**
|
|
88
|
+
- Interactive setup wizard with Docker daemon and registry checks
|
|
89
|
+
- Image pull with progress display
|
|
90
|
+
- `--dry` mode for walkthroughs without Docker access
|
|
91
|
+
- Edition selection (community / member)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nds-mapviewer
|
|
3
|
-
Version: 2026.4.2.
|
|
3
|
+
Version: 2026.4.2.dev205
|
|
4
4
|
Summary: CLI to run the NDS MapViewer Docker container for visualizing map data (NDS.Live, GeoJSON, and more)
|
|
5
5
|
Author-email: NDS Association <support@nds-association.org>
|
|
6
6
|
License: Proprietary
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/nds_mapviewer.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nds-mapviewer
|
|
3
|
-
Version: 2026.4.2.
|
|
3
|
+
Version: 2026.4.2.dev205
|
|
4
4
|
Summary: CLI to run the NDS MapViewer Docker container for visualizing map data (NDS.Live, GeoJSON, and more)
|
|
5
5
|
Author-email: NDS Association <support@nds-association.org>
|
|
6
6
|
License: Proprietary
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
.gitignore
|
|
2
|
+
CHANGELOG.md
|
|
1
3
|
README.md
|
|
2
4
|
pyproject.toml
|
|
3
5
|
setup.py
|
|
@@ -18,6 +20,7 @@ src/ndslive/mapviewer/exceptions.py
|
|
|
18
20
|
src/ndslive/mapviewer/tui.py
|
|
19
21
|
src/ndslive/mapviewer/ui.py
|
|
20
22
|
src/ndslive/mapviewer/viewer.py
|
|
23
|
+
tests/conftest.py
|
|
21
24
|
tests/test_cli.py
|
|
22
25
|
tests/test_clipboard.py
|
|
23
26
|
tests/test_config.py
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"""Shared pytest fixtures and container-runtime availability check."""
|
|
2
|
+
|
|
3
|
+
import shutil
|
|
4
|
+
import tempfile
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
import yaml
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Default edition for tests
|
|
12
|
+
DEFAULT_EDITION = "member"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture(scope="session")
|
|
16
|
+
def docker_client():
|
|
17
|
+
"""Verify the container runtime is available, skipping tests otherwise.
|
|
18
|
+
|
|
19
|
+
Returns ``None`` — the fixture is kept for backward compatibility with
|
|
20
|
+
tests that declare it as a dependency to gate on runtime availability.
|
|
21
|
+
"""
|
|
22
|
+
from ndslive.mapviewer import docker_client as dc
|
|
23
|
+
from ndslive.mapviewer.exceptions import RuntimeNotInstalled, RuntimeNotRunning
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
dc.get_docker_client()
|
|
27
|
+
return None # runtime OK
|
|
28
|
+
except RuntimeNotInstalled:
|
|
29
|
+
pytest.skip("No container runtime installed (Docker/Podman)")
|
|
30
|
+
except RuntimeNotRunning:
|
|
31
|
+
pytest.skip("Container runtime is not running")
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.fixture(scope="session")
|
|
35
|
+
def edition():
|
|
36
|
+
"""Default edition for tests."""
|
|
37
|
+
return DEFAULT_EDITION
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@pytest.fixture
|
|
41
|
+
def temp_dir():
|
|
42
|
+
"""Create a temporary directory for test files."""
|
|
43
|
+
path = Path(tempfile.mkdtemp(prefix="mapviewer-test-"))
|
|
44
|
+
yield path
|
|
45
|
+
shutil.rmtree(path, ignore_errors=True)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@pytest.fixture
|
|
49
|
+
def sample_config(temp_dir):
|
|
50
|
+
"""Create a sample config file with HTTP-only sources (no local paths)."""
|
|
51
|
+
config = {
|
|
52
|
+
"http-settings": [
|
|
53
|
+
{
|
|
54
|
+
"scope": "https://api.nds.live/*",
|
|
55
|
+
"api-key": "test-key",
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
"sources": [
|
|
59
|
+
{
|
|
60
|
+
"type": "SmartLayerTileService",
|
|
61
|
+
"uri": "https://api.nds.live/island6/openapi.json",
|
|
62
|
+
"mapId": "Test Island",
|
|
63
|
+
}
|
|
64
|
+
],
|
|
65
|
+
}
|
|
66
|
+
config_path = temp_dir / "config.yaml"
|
|
67
|
+
with open(config_path, "w") as f:
|
|
68
|
+
yaml.dump(config, f)
|
|
69
|
+
return config_path
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@pytest.fixture
|
|
73
|
+
def sample_config_with_local_path(temp_dir):
|
|
74
|
+
"""Create a sample config with a local path that needs volume mounting."""
|
|
75
|
+
data_dir = temp_dir / "data" / "maps"
|
|
76
|
+
data_dir.mkdir(parents=True)
|
|
77
|
+
(data_dir / "dummy.db").touch()
|
|
78
|
+
|
|
79
|
+
config = {
|
|
80
|
+
"sources": [
|
|
81
|
+
{
|
|
82
|
+
"type": "ClassicFolder",
|
|
83
|
+
"folder": str(data_dir),
|
|
84
|
+
"mapId": "Local Data",
|
|
85
|
+
}
|
|
86
|
+
],
|
|
87
|
+
}
|
|
88
|
+
config_path = temp_dir / "config.yaml"
|
|
89
|
+
with open(config_path, "w") as f:
|
|
90
|
+
yaml.dump(config, f)
|
|
91
|
+
return config_path, data_dir
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@pytest.fixture
|
|
95
|
+
def sample_config_filestore(temp_dir):
|
|
96
|
+
"""Create a sample config with filestore: URI."""
|
|
97
|
+
data_dir = temp_dir / "filestore"
|
|
98
|
+
data_dir.mkdir(parents=True)
|
|
99
|
+
(data_dir / "test.nds").touch()
|
|
100
|
+
|
|
101
|
+
config = {
|
|
102
|
+
"sources": [
|
|
103
|
+
{
|
|
104
|
+
"type": "SmartLayerTileService",
|
|
105
|
+
"uri": f"filestore:{data_dir}",
|
|
106
|
+
"mapId": "Filestore Test",
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
}
|
|
110
|
+
config_path = temp_dir / "config.yaml"
|
|
111
|
+
with open(config_path, "w") as f:
|
|
112
|
+
yaml.dump(config, f)
|
|
113
|
+
return config_path, data_dir
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@pytest.fixture
|
|
117
|
+
def container_name():
|
|
118
|
+
"""Generate a unique container name for test isolation."""
|
|
119
|
+
import uuid
|
|
120
|
+
return f"mapviewer-test-{uuid.uuid4().hex[:8]}"
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@pytest.fixture
|
|
124
|
+
def cleanup_container(docker_client, container_name):
|
|
125
|
+
"""Ensure test container is cleaned up after test."""
|
|
126
|
+
from ndslive.mapviewer import container_runtime as rt
|
|
127
|
+
yield container_name
|
|
128
|
+
try:
|
|
129
|
+
rt.run("stop", container_name, check=False, timeout=10)
|
|
130
|
+
rt.run("rm", container_name, check=False, timeout=10)
|
|
131
|
+
except Exception:
|
|
132
|
+
pass
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def pytest_configure(config):
|
|
136
|
+
"""Register custom markers."""
|
|
137
|
+
config.addinivalue_line(
|
|
138
|
+
"markers", "docker: mark test as requiring Docker"
|
|
139
|
+
)
|
|
140
|
+
config.addinivalue_line(
|
|
141
|
+
"markers", "slow: mark test as slow-running"
|
|
142
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/__init__.py
RENAMED
|
File without changes
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/browser.py
RENAMED
|
File without changes
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/cli.py
RENAMED
|
File without changes
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/clipboard.py
RENAMED
|
File without changes
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/exceptions.py
RENAMED
|
File without changes
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/tui.py
RENAMED
|
File without changes
|
|
File without changes
|
{nds_mapviewer-2026.4.2.dev203 → nds_mapviewer-2026.4.2.dev205}/src/ndslive/mapviewer/viewer.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|