Skip to content

Commit 05a8f1f

Browse files
DyNooobHrbeiknandylizf
authored
feat(cli): add batch URL input support (#64)
* feat(cli): add batch URL input support * fix(cli): preserve batched URL rendering --------- Co-authored-by: DyNooob <i@nooob.top> Co-authored-by: Andy Lee <andylizf@outlook.com>
1 parent 03369a7 commit 05a8f1f

2 files changed

Lines changed: 67 additions & 7 deletions

File tree

render/src/pixelrag_render/render.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,17 @@ def main() -> None:
198198
# Single URL, default CDP backend
199199
pixelshot https://example.com --output ./tiles
200200
201-
# Multiple inputs with 4 workers
202-
pixelshot https://a.com https://b.com --output ./tiles --workers 4
201+
# Multiple inputs
202+
pixelshot https://a.com https://b.com --output ./tiles
203203
204204
# PDF
205205
pixelshot report.pdf --output ./tiles
206206
207207
# Local HTML
208208
pixelshot index.html --output ./tiles --backend playwright
209209
210-
# Pipe URLs from a file
211-
cat urls.txt | xargs pixelshot --output ./tiles --workers 8
210+
# URL file
211+
pixelshot urls.txt --output ./tiles
212212
213213
# Chrome management (folded from the former `pixelrag-chrome`)
214214
pixelshot install-chrome # download the patched headless Chrome
@@ -311,18 +311,25 @@ def main() -> None:
311311
args = parser.parse_args()
312312
output_dir = Path(args.output)
313313

314-
# Partition inputs into URLs and files for batch processing
315314
urls = []
316315
files = []
317316
for inp in args.inputs:
318-
if inp.startswith("http://") or inp.startswith("https://"):
317+
if inp.lower().endswith(".txt"):
318+
try:
319+
with open(inp, encoding="utf-8") as f:
320+
for line in f:
321+
url = line.strip()
322+
if url:
323+
urls.append(url)
324+
except FileNotFoundError:
325+
parser.error(f"URL file not found: {inp}")
326+
elif inp.startswith("http://") or inp.startswith("https://"):
319327
urls.append(inp)
320328
else:
321329
files.append(Path(inp))
322330

323331
results: list[Path] = []
324332

325-
# Batch-render URLs together for efficiency
326333
if urls:
327334
logger.info(
328335
"Rendering %d URL(s) with backend=%s workers=%d",

tests/test_cli.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import sys
99
from pathlib import Path
1010

11+
import pytest
12+
1113
# Console scripts live next to the interpreter running the tests (works whether
1214
# invoked via `uv run pytest` or `.venv/bin/python -m pytest`).
1315
_BIN = Path(sys.executable).parent
@@ -23,6 +25,57 @@ def test_pixelshot_help():
2325
assert "pixelshot" in r.stdout
2426

2527

28+
def test_pixelshot_txt_input_uses_batch_render(monkeypatch, tmp_path, capsys):
29+
from pixelrag_render import render as render_mod
30+
31+
urls_file = tmp_path / "urls.txt"
32+
urls_file.write_text(
33+
"\n https://example.com/a \n\nhttps://example.com/b\nhttps://example.com/c\n"
34+
)
35+
calls = []
36+
37+
def fake_render_urls(urls, output_dir, **kwargs):
38+
calls.append((list(urls), kwargs["workers"]))
39+
return [Path(output_dir) / "a.png.tiles", Path(output_dir) / "c.png.tiles"]
40+
41+
monkeypatch.setattr(render_mod, "render_urls", fake_render_urls)
42+
monkeypatch.setattr(
43+
sys,
44+
"argv",
45+
["pixelshot", str(urls_file), "-o", str(tmp_path / "out"), "-w", "8"],
46+
)
47+
48+
render_mod.main()
49+
50+
assert calls == [
51+
(
52+
[
53+
"https://example.com/a",
54+
"https://example.com/b",
55+
"https://example.com/c",
56+
],
57+
8,
58+
)
59+
]
60+
stdout = capsys.readouterr().out
61+
assert "a.png.tiles" in stdout
62+
assert "b.png.tiles" not in stdout
63+
assert "c.png.tiles" in stdout
64+
65+
66+
def test_pixelshot_missing_txt_input(monkeypatch, tmp_path, capsys):
67+
from pixelrag_render import render as render_mod
68+
69+
missing = tmp_path / "missing.txt"
70+
monkeypatch.setattr(sys, "argv", ["pixelshot", str(missing)])
71+
72+
with pytest.raises(SystemExit) as exc:
73+
render_mod.main()
74+
75+
assert exc.value.code == 2
76+
assert "URL file not found" in capsys.readouterr().err
77+
78+
2679
def test_pixelrag_umbrella_help():
2780
r = _run("pixelrag", "--help")
2881
assert r.returncode == 0

0 commit comments

Comments
 (0)