viewinline 0.5.0__tar.gz → 0.5.1__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.
- viewinline-0.5.1/.gitignore +5 -0
- {viewinline-0.5.0 → viewinline-0.5.1}/CITATION.cff +2 -2
- {viewinline-0.5.0 → viewinline-0.5.1}/PKG-INFO +10 -1
- {viewinline-0.5.0 → viewinline-0.5.1}/README.md +9 -0
- {viewinline-0.5.0 → viewinline-0.5.1}/context7.json +2 -3
- {viewinline-0.5.0 → viewinline-0.5.1}/llms.txt +13 -1
- {viewinline-0.5.0 → viewinline-0.5.1}/pyproject.toml +1 -1
- {viewinline-0.5.0 → viewinline-0.5.1/skills}/viewinline/SKILL.md +11 -2
- {viewinline-0.5.0 → viewinline-0.5.1}/src/viewinline/viewinline.py +12 -3
- viewinline-0.5.1/tests/test_missing_image.py +39 -0
- viewinline-0.5.0/.gitignore +0 -4
- {viewinline-0.5.0 → viewinline-0.5.1}/.github/FUNDING.yml +0 -0
- {viewinline-0.5.0 → viewinline-0.5.1}/LICENSE +0 -0
- {viewinline-0.5.0 → viewinline-0.5.1}/src/viewinline/__init__.py +0 -0
- {viewinline-0.5.0 → viewinline-0.5.1}/viewinline_gif1.gif +0 -0
- {viewinline-0.5.0 → viewinline-0.5.1}/viewinline_gif2.gif +0 -0
- {viewinline-0.5.0 → viewinline-0.5.1}/viewinline_gif2.jpg +0 -0
|
@@ -19,8 +19,8 @@ authors:
|
|
|
19
19
|
repository-code: "https://github.com/nkeikon/inlineviewer"
|
|
20
20
|
url: "https://github.com/nkeikon/inlineviewer"
|
|
21
21
|
license: Apache-2.0
|
|
22
|
-
version: 0.5.
|
|
23
|
-
date-released: 2026-10
|
|
22
|
+
version: 0.5.1
|
|
23
|
+
date-released: 2026-11-10
|
|
24
24
|
# ---------------------------------------------------------------------------
|
|
25
25
|
# The DOI below is the VERSION DOI for v0.3.2 (a specific archived snapshot).
|
|
26
26
|
# To make citations always resolve to your LATEST release, replace it with the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: viewinline
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: Quick look geospatial viewer for the terminal, with inline image previews
|
|
5
5
|
Project-URL: Homepage, https://github.com/nkeikon/viewinline
|
|
6
6
|
Project-URL: Repository, https://github.com/nkeikon/viewinline
|
|
@@ -109,6 +109,15 @@ viewinline counties.shp --table --unique STATE_NAME
|
|
|
109
109
|
viewinline data.geoparquet --table --where "POP > 100000" --sort POP --desc
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
## Use with Claude Code
|
|
113
|
+
|
|
114
|
+
viewinline includes a skill that lets Claude Code inspect files with `--info` and offer quick-look previews with `--export`. To install:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
mkdir -p ~/.claude/skills/viewinline
|
|
118
|
+
curl -o ~/.claude/skills/viewinline/SKILL.md https://raw.githubusercontent.com/nkeikon/inlineviewer/main/skills/viewinline/SKILL.md
|
|
119
|
+
```
|
|
120
|
+
|
|
112
121
|
## Compatible terminals
|
|
113
122
|
|
|
114
123
|
Native (no extra install required): images render via the iTerm2 inline image protocol on:
|
|
@@ -76,6 +76,15 @@ viewinline counties.shp --table --unique STATE_NAME
|
|
|
76
76
|
viewinline data.geoparquet --table --where "POP > 100000" --sort POP --desc
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
+
## Use with Claude Code
|
|
80
|
+
|
|
81
|
+
viewinline includes a skill that lets Claude Code inspect files with `--info` and offer quick-look previews with `--export`. To install:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
mkdir -p ~/.claude/skills/viewinline
|
|
85
|
+
curl -o ~/.claude/skills/viewinline/SKILL.md https://raw.githubusercontent.com/nkeikon/inlineviewer/main/skills/viewinline/SKILL.md
|
|
86
|
+
```
|
|
87
|
+
|
|
79
88
|
## Compatible terminals
|
|
80
89
|
|
|
81
90
|
Native (no extra install required): images render via the iTerm2 inline image protocol on:
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
```json
|
|
2
1
|
{
|
|
3
2
|
"$schema": "https://context7.com/schema/context7.json",
|
|
4
3
|
"projectTitle": "viewinline",
|
|
@@ -14,7 +13,7 @@
|
|
|
14
13
|
"Use inline terminal image rendering instead of GUI workflows.",
|
|
15
14
|
"Highlight support for GeoTIFF, NetCDF, GeoJSON, and GeoParquet.",
|
|
16
15
|
"Emphasize compatibility limitations for terminal graphics protocols.",
|
|
17
|
-
"For programmatic or AI-agent use, note --info (JSON metadata) and --export (save rendered image)."
|
|
16
|
+
"For programmatic or AI-agent use, note --info (JSON metadata) and --export (save rendered image).",
|
|
17
|
+
"For Claude Code users, mention the viewinline skill at skills/viewinline/SKILL.md and how to install it."
|
|
18
18
|
]
|
|
19
19
|
}
|
|
20
|
-
```
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- Command name: `viewinline`
|
|
8
8
|
- Requires: Python 3.9+
|
|
9
9
|
- License: Apache-2.0 © 2026 Keiko Nomura
|
|
10
|
-
- Latest release: v0.5.
|
|
10
|
+
- Latest release: v0.5.1 (2026-11-10)
|
|
11
11
|
- Combines the core display logic of `viewtif` and `viewgeom`, but is **non-interactive**: no zoom/pan/colormap-switching on the fly. Everything is controlled via CLI options (e.g. `--display`, `--color-by`, `--colormap`).
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
@@ -24,6 +24,17 @@ Optional extras (install only if needed):
|
|
|
24
24
|
- `h5py` — fallback for HDF5 if GDAL lacks HDF5 support (usually unnecessary). `pip install h5py`
|
|
25
25
|
- `chafa` — system binary (not a Python package); strongly recommended for terminal coverage beyond the native list. See "Terminals".
|
|
26
26
|
|
|
27
|
+
## Use with Claude Code
|
|
28
|
+
|
|
29
|
+
viewinline has a Claude Code skill. It is a separate install from the pip package:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
mkdir -p ~/.claude/skills/viewinline
|
|
33
|
+
curl -o ~/.claude/skills/viewinline/SKILL.md https://raw.githubusercontent.com/nkeikon/inlineviewer/main/skills/viewinline/SKILL.md
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Start a new Claude Code session after installing. The skill is at skills/viewinline/SKILL.md in the GitHub repository.
|
|
37
|
+
|
|
27
38
|
## How display works (rendering engines)
|
|
28
39
|
|
|
29
40
|
- Uses the **iTerm2 inline image protocol (OSC 1337)** natively in supported terminals.
|
|
@@ -239,6 +250,7 @@ Optional: `chafa` (terminal coverage; system binary), `duckdb` (filter/sort/SQL)
|
|
|
239
250
|
- **v0.1.5 (2026-02-13):** Fixed duplicate band-display prints; optimized uint8 normalization; minor perf.
|
|
240
251
|
- **v0.4.0 (2026-08-23):** New agent-facing inspection commands: `--info` (file metadata + statistics as JSON, for rasters and vectors; lists variables for NetCDF/HDF with `--subset`; always returns JSON including structured errors) and `--export` (save the rendered image to PNG/JPEG, works with any display flag). Existing viewer behavior unchanged.
|
|
241
252
|
- **v0.5.0 (2026-10-21):** New `--grid [N]` flag: axis ticks and a light grid overlay. Georeferenced rasters and vectors are labelled in real CRS coordinates; photos, NetCDF, and non-georeferenced files in pixel positions. Grid contributed by @luismanriqueruiz.
|
|
253
|
+
- **v0.5.1 (2026-11-10):** Bug fix: viewinline now exits with code 1 (instead of 0) when an input file is missing or unreadable — PNG/JPG, GeoTIFF, vectors (.shp, .geojson, .gpkg), and NetCDF — so scripts and agents can detect the failure. Missing PNG/JPG fix contributed by @Qrytics (#8).
|
|
242
254
|
|
|
243
255
|
## Support & links
|
|
244
256
|
|
|
@@ -10,6 +10,15 @@ Quick-look terminal viewer for geospatial and tabular data. Think of it as `ls`
|
|
|
10
10
|
|
|
11
11
|
Renders natively in iTerm2, WezTerm, Konsole, Rio, and Contour. Falls back to `chafa` (ASCII art with 24-bit color) in other terminals like kitty, Ghostty, Terminal.app, VS Code, and Linux terminals. Works over SSH without X11 forwarding or VNC.
|
|
12
12
|
|
|
13
|
+
## Inside Claude Code
|
|
14
|
+
|
|
15
|
+
To show the user an image, use `--export`. It saves a PNG and opens it in the user's default image viewer, and you can read the same PNG. Ask before running it, e.g. "Want to see a quick-look of `ndvi.tif`?" If the user asks to see a file, run it directly. If they say to always or never show images, follow that for the rest of the session.
|
|
16
|
+
|
|
17
|
+
- Use `--info` freely for your own checks. It prints JSON and opens nothing.
|
|
18
|
+
- A plain `viewinline file.tif` run from the shell does not reach the user, because the output is captured as text. Don't claim you showed them an image that way.
|
|
19
|
+
- CSV and Parquet previews with more than 10 rows ask `[first/all]`. Pipe the answer in: `echo first | viewinline data.csv`.
|
|
20
|
+
- Delete exported PNGs once they're no longer needed, unless the user wants to keep them.
|
|
21
|
+
|
|
13
22
|
## When to Use
|
|
14
23
|
|
|
15
24
|
- **File browsing**: `find . -name "*.jpg" | xargs -n1 viewinline` to visually scan results
|
|
@@ -59,9 +68,9 @@ Note: `--info` and `--export` report what a file *is* and what it *looks like*
|
|
|
59
68
|
|
|
60
69
|
## Core Flags
|
|
61
70
|
|
|
62
|
-
**Inspection
|
|
71
|
+
**Inspection:**
|
|
63
72
|
- `--info` — print metadata + statistics as JSON, then exit (rasters and vectors; lists variables for NetCDF/HDF with `--subset N`)
|
|
64
|
-
- `--export PATH` — save the rendered image to PATH (`.png`/`.jpg`)
|
|
73
|
+
- `--export PATH` — save the rendered image to PATH (`.png`/`.jpg`), open it in the default image viewer, and print `{"path": "..."}`
|
|
65
74
|
- `--grid [N]` — overlay axis ticks and a light grid (N divisions, default 5). Labels are in the file's CRS units for georeferenced rasters and vectors, pixel positions otherwise. Combine with `--export` to save a quick-look with readable coordinates, e.g. to check a file covers the expected area.
|
|
66
75
|
|
|
67
76
|
**Raster Display:**
|
|
@@ -35,7 +35,7 @@ warnings.filterwarnings("ignore", message="invalid scale_factor or add_offset at
|
|
|
35
35
|
_EXPORT_PATH = None
|
|
36
36
|
_EXPORT_RESULT = None
|
|
37
37
|
|
|
38
|
-
__version__ = "0.5.
|
|
38
|
+
__version__ = "0.5.1"
|
|
39
39
|
|
|
40
40
|
AVAILABLE_COLORMAPS = [
|
|
41
41
|
"viridis", "inferno", "magma", "plasma",
|
|
@@ -1068,6 +1068,11 @@ def render_simple_image(filepath: str, args) -> None:
|
|
|
1068
1068
|
|
|
1069
1069
|
show_image_auto(img_array, getattr(args, "display", None), is_vector=False)
|
|
1070
1070
|
|
|
1071
|
+
except FileNotFoundError:
|
|
1072
|
+
# A missing file is not a damaged-but-readable image: let the
|
|
1073
|
+
# caller report it with a nonzero exit instead of falling back
|
|
1074
|
+
# to the rasterio path.
|
|
1075
|
+
raise
|
|
1071
1076
|
except Exception as e:
|
|
1072
1077
|
print(f"[ERROR] Failed to load image: {e}")
|
|
1073
1078
|
|
|
@@ -1087,7 +1092,7 @@ def render_netcdf_via_netcdf4(path, args):
|
|
|
1087
1092
|
nc = netCDF4.Dataset(path)
|
|
1088
1093
|
except Exception as e:
|
|
1089
1094
|
print(f"[ERROR] Could not open NetCDF file: {e}")
|
|
1090
|
-
|
|
1095
|
+
sys.exit(1)
|
|
1091
1096
|
|
|
1092
1097
|
# Recursively collect (path, variable) pairs across all groups
|
|
1093
1098
|
def collect_vars(group, prefix=""):
|
|
@@ -1536,6 +1541,7 @@ def render_raster(paths: list[str], args) -> None:
|
|
|
1536
1541
|
print("[INFO] viewinline only supports 2D or 3D NetCDF variables")
|
|
1537
1542
|
else:
|
|
1538
1543
|
print(f"[ERROR] Inline render failed: {e}")
|
|
1544
|
+
sys.exit(1)
|
|
1539
1545
|
|
|
1540
1546
|
|
|
1541
1547
|
def render_gallery(folder: str, grid: str = "4x4", display_scale=None, is_vector=False) -> None:
|
|
@@ -1750,7 +1756,7 @@ def render_vector(path, args):
|
|
|
1750
1756
|
return
|
|
1751
1757
|
except Exception as e:
|
|
1752
1758
|
print(f"[ERROR] Failed to read vector: {e}")
|
|
1753
|
-
|
|
1759
|
+
sys.exit(1)
|
|
1754
1760
|
|
|
1755
1761
|
# Detect non-geometry columns
|
|
1756
1762
|
all_cols = [c for c in gdf.columns if c != gdf.geometry.name]
|
|
@@ -2292,6 +2298,9 @@ def main() -> None:
|
|
|
2292
2298
|
try:
|
|
2293
2299
|
render_simple_image(paths[0], args)
|
|
2294
2300
|
return
|
|
2301
|
+
except FileNotFoundError as e:
|
|
2302
|
+
print(f"[ERROR] Failed to read file: {e}")
|
|
2303
|
+
sys.exit(1)
|
|
2295
2304
|
except Exception:
|
|
2296
2305
|
pass
|
|
2297
2306
|
render_raster(paths, args)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""A missing PNG/JPG must exit nonzero, not report an error with exit 0."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from viewinline.viewinline import main
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _run(argv, capsys):
|
|
11
|
+
sys.argv = argv
|
|
12
|
+
with pytest.raises(SystemExit) as exc:
|
|
13
|
+
main()
|
|
14
|
+
out = capsys.readouterr().out
|
|
15
|
+
return exc.value.code, out
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_missing_png_exits_nonzero(capsys):
|
|
19
|
+
code, out = _run(["viewinline", "/nonexistent-xyz-440.png"], capsys)
|
|
20
|
+
assert code == 1
|
|
21
|
+
assert "[ERROR]" in out
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_missing_jpg_exits_nonzero(capsys):
|
|
25
|
+
code, out = _run(["viewinline", "/nonexistent-xyz-440.jpg"], capsys)
|
|
26
|
+
assert code == 1
|
|
27
|
+
assert "[ERROR]" in out
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@pytest.mark.parametrize("path", [
|
|
31
|
+
"/nonexistent-xyz-440.tif",
|
|
32
|
+
"/nonexistent-xyz-440.shp",
|
|
33
|
+
"/nonexistent-xyz-440.geojson",
|
|
34
|
+
"/nonexistent-xyz-440.nc",
|
|
35
|
+
])
|
|
36
|
+
def test_missing_raster_or_vector_exits_nonzero(path, capsys):
|
|
37
|
+
code, out = _run(["viewinline", path], capsys)
|
|
38
|
+
assert code == 1
|
|
39
|
+
assert "[ERROR]" in out
|
viewinline-0.5.0/.gitignore
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|