mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-12 19:50:57 +05:00
release: archivebox 0.9.34rc47
This commit is contained in:
parent
5b74eb5238
commit
77ee827a58
@ -35,6 +35,9 @@
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
#progress-monitor.collapsed .header-bar {
|
||||
cursor: pointer;
|
||||
}
|
||||
#progress-monitor .header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -1884,9 +1887,14 @@
|
||||
}
|
||||
|
||||
// Collapse toggle
|
||||
collapseBtn.addEventListener('click', function() {
|
||||
collapseBtn.addEventListener('click', function(event) {
|
||||
event.stopPropagation();
|
||||
setCollapsedState(!isCollapsed);
|
||||
});
|
||||
monitor.querySelector('.header-bar').addEventListener('click', function(event) {
|
||||
if (event.target.closest('button, a, input, select, textarea, [role="button"]')) return;
|
||||
if (isCollapsed) setCollapsedState(false);
|
||||
});
|
||||
|
||||
crawlTree.addEventListener('click', function(event) {
|
||||
const actionBtn = event.target.closest('.crawl-action-btn');
|
||||
|
||||
@ -62,7 +62,7 @@ def get_search_mode_options(config: dict[str, Any] | None = None, **config_kwarg
|
||||
]
|
||||
options = [
|
||||
{"value": "meta", "label": "meta"},
|
||||
{"value": "contents", "label": "contents"},
|
||||
{"value": "contents", "label": "deep"},
|
||||
]
|
||||
if backend_names:
|
||||
options.extend(
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import os
|
||||
import sqlite3
|
||||
|
||||
import pytest
|
||||
import requests
|
||||
@ -149,6 +148,17 @@ def test_opencode_project_current_is_seeded_data_project(admin_client, tmp_path,
|
||||
monkeypatch.setattr(views, "_machine_config", lambda: {"OPENCODE_ENABLED": True, "OPENCODE_WORKDIR": str(workdir)})
|
||||
monkeypatch.setattr(views, "_ensure_opencode", lambda settings: (True, ""))
|
||||
|
||||
def fake_request(method, url, **kwargs):
|
||||
assert url == "http://127.0.0.1:4096/project/current"
|
||||
assert kwargs["params"] == (("directory", str(workdir)),)
|
||||
upstream = requests.Response()
|
||||
upstream.status_code = 200
|
||||
upstream._content = (f'{{"id":"global","worktree":"{workdir.resolve()}","name":"data"}}').encode()
|
||||
upstream.headers["Content-Type"] = "application/json"
|
||||
return upstream
|
||||
|
||||
monkeypatch.setattr(views.requests, "request", fake_request)
|
||||
|
||||
response = admin_client.get(
|
||||
f"/admin/agent/opencode/project/current?directory={workdir}",
|
||||
HTTP_HOST=ADMIN_TEST_HOST,
|
||||
@ -167,6 +177,17 @@ def test_opencode_path_reports_data_as_worktree(admin_client, tmp_path, db, monk
|
||||
monkeypatch.setattr(views, "_machine_config", lambda: {"OPENCODE_ENABLED": True, "OPENCODE_WORKDIR": str(workdir)})
|
||||
monkeypatch.setattr(views, "_ensure_opencode", lambda settings: (True, ""))
|
||||
|
||||
def fake_request(method, url, **kwargs):
|
||||
assert url == "http://127.0.0.1:4096/path"
|
||||
assert kwargs["params"] == (("directory", str(workdir)),)
|
||||
upstream = requests.Response()
|
||||
upstream.status_code = 200
|
||||
upstream._content = (f'{{"directory":"{workdir.resolve()}","worktree":"{workdir.resolve()}"}}').encode()
|
||||
upstream.headers["Content-Type"] = "application/json"
|
||||
return upstream
|
||||
|
||||
monkeypatch.setattr(views.requests, "request", fake_request)
|
||||
|
||||
response = admin_client.get(
|
||||
f"/admin/agent/opencode/path?directory={workdir}",
|
||||
HTTP_HOST=ADMIN_TEST_HOST,
|
||||
@ -284,10 +305,9 @@ def test_opencode_starts_without_opening_browser(tmp_path, monkeypatch):
|
||||
return FakeProcess()
|
||||
|
||||
monkeypatch.setattr(views, "_health", lambda settings: next(health_checks))
|
||||
monkeypatch.setattr(views.shutil, "which", lambda binary: "/usr/bin/false")
|
||||
monkeypatch.setattr(views.subprocess, "Popen", fake_popen)
|
||||
|
||||
settings = views._settings({"OPENCODE_WORKDIR": str(tmp_path)})
|
||||
settings = views._settings({"OPENCODE_WORKDIR": str(tmp_path), "OPENCODE_BINARY": "/usr/bin/false"})
|
||||
ok, error = views._ensure_opencode(settings)
|
||||
|
||||
assert ok, error
|
||||
@ -310,35 +330,47 @@ def test_opencode_state_dir_is_separate_from_workdir(tmp_path):
|
||||
assert settings["config_home"] == workdir / "opencode" / "config"
|
||||
assert settings["data_home"] == workdir / "opencode" / "data"
|
||||
assert settings["state_home"] == workdir / "opencode" / "state"
|
||||
skill = workdir / "opencode" / "config" / "opencode" / "skills" / "archivebox" / "SKILL.md"
|
||||
assert skill.exists()
|
||||
assert f"ArchiveBox collection directory: {workdir.resolve()}" in skill.read_text()
|
||||
editable_skill = workdir / "opencode" / "SKILL.md"
|
||||
loaded_skill = workdir / "opencode" / "config" / "opencode" / "skills" / "archivebox" / "SKILL.md"
|
||||
assert editable_skill.exists()
|
||||
assert loaded_skill.is_symlink()
|
||||
assert loaded_skill.resolve() == editable_skill.resolve()
|
||||
assert f"ArchiveBox collection directory: {workdir.resolve()}" in editable_skill.read_text()
|
||||
|
||||
|
||||
def test_opencode_seeds_global_project_under_embedded_data_dir(tmp_path):
|
||||
def test_opencode_ensures_default_session_with_public_api(tmp_path, monkeypatch):
|
||||
from abx_plugins.plugins.opencode import views
|
||||
|
||||
workdir = tmp_path / "data"
|
||||
settings = views._settings({"OPENCODE_WORKDIR": str(workdir)})
|
||||
db_path = settings["data_home"] / "opencode" / "opencode.db"
|
||||
db_path.parent.mkdir(parents=True)
|
||||
with sqlite3.connect(db_path) as db:
|
||||
db.execute(
|
||||
"""
|
||||
CREATE TABLE project (
|
||||
id text PRIMARY KEY,
|
||||
worktree text NOT NULL,
|
||||
name text,
|
||||
time_created integer NOT NULL,
|
||||
time_updated integer NOT NULL,
|
||||
sandboxes text NOT NULL
|
||||
)
|
||||
""",
|
||||
)
|
||||
calls = []
|
||||
|
||||
views._ensure_global_project(settings)
|
||||
def fake_get(url, **kwargs):
|
||||
calls.append(("GET", url, kwargs))
|
||||
response = requests.Response()
|
||||
response.status_code = 200
|
||||
response._content = b"[]" if url.endswith("/session") else b"{}"
|
||||
return response
|
||||
|
||||
with sqlite3.connect(db_path) as db:
|
||||
row = db.execute("SELECT id, worktree, name, sandboxes FROM project").fetchone()
|
||||
def fake_post(url, **kwargs):
|
||||
calls.append(("POST", url, kwargs))
|
||||
response = requests.Response()
|
||||
response.status_code = 200
|
||||
response._content = b'{"id":"session"}'
|
||||
return response
|
||||
|
||||
assert row == ("global", str(workdir.resolve()), "data", "[]")
|
||||
monkeypatch.setattr(views.requests, "get", fake_get)
|
||||
monkeypatch.setattr(views.requests, "post", fake_post)
|
||||
|
||||
views._ensure_default_session(settings)
|
||||
|
||||
assert calls[0] == (
|
||||
"GET",
|
||||
"http://127.0.0.1:4096/project/current",
|
||||
{"params": {"directory": str(workdir.resolve())}, "timeout": 30},
|
||||
)
|
||||
assert calls[1][0:2] == ("GET", "http://127.0.0.1:4096/session")
|
||||
assert calls[1][2]["params"] == {"directory": str(workdir.resolve()), "roots": "true", "limit": 55}
|
||||
assert calls[2][0:2] == ("POST", "http://127.0.0.1:4096/session")
|
||||
assert calls[2][2]["params"] == {"directory": str(workdir.resolve())}
|
||||
assert calls[2][2]["json"] == {}
|
||||
|
||||
@ -128,6 +128,7 @@ def test_search_mode_options_use_canonical_backend_names(monkeypatch):
|
||||
|
||||
options = get_search_mode_options()
|
||||
|
||||
assert {"value": "contents", "label": "deep"} in options
|
||||
assert {"value": "deep:ripgrep", "label": "deep:ripgrep"} in options
|
||||
assert all(not option["label"].startswith("deep: ") for option in options)
|
||||
|
||||
@ -176,7 +177,8 @@ class TestAdminSnapshotSearch:
|
||||
assert response.status_code == 200
|
||||
assert response.context["cl"].search_mode == "deep:ripgrep"
|
||||
assert b'name="search_mode"' in response.content
|
||||
assert b'value="contents"' in response.content
|
||||
assert b'<option value="contents">deep</option>' in response.content
|
||||
assert b">contents<" not in response.content
|
||||
assert b'value="deep:ripgrep"' in response.content
|
||||
assert b">deep:ripgrep<" in response.content
|
||||
|
||||
@ -388,6 +390,8 @@ class TestPublicIndexSearch:
|
||||
assert response.status_code == 200
|
||||
assert response.context["search_mode"] == "deep:ripgrep"
|
||||
assert b'name="search_mode"' in response.content
|
||||
assert b'<option value="contents">deep</option>' in response.content
|
||||
assert b">contents<" not in response.content
|
||||
assert b'value="deep:ripgrep"' in response.content
|
||||
assert b">deep:ripgrep<" in response.content
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "archivebox",
|
||||
"version": "0.9.34rc40",
|
||||
"version": "0.9.34rc47",
|
||||
"repository": "github:ArchiveBox/ArchiveBox",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "archivebox"
|
||||
version = "0.9.34rc46"
|
||||
version = "0.9.34rc47"
|
||||
requires-python = ">=3.13"
|
||||
description = "Self-hosted internet archiving solution."
|
||||
authors = [{name = "Nick Sweeting", email = "pyproject.toml@archivebox.io"}]
|
||||
@ -79,9 +79,9 @@ dependencies = [
|
||||
### Extractor dependencies (optional binaries detected at runtime via shutil.which)
|
||||
### Binary/Package Management
|
||||
"abxbus==2.5.10", # EventBus API
|
||||
"abxpkg>=1.11.162", # for: detecting, versioning, and installing binaries via apt/brew/pip/npm
|
||||
"abx-plugins>=1.11.165", # shared ArchiveBox plugin package with Chrome/Puppeteer dependency wiring
|
||||
"abx-dl>=1.11.165", # shared ArchiveBox downloader package with blocking install preflight
|
||||
"abxpkg>=1.11.163", # for: detecting, versioning, and installing binaries via apt/brew/pip/npm
|
||||
"abx-plugins>=1.11.166", # shared ArchiveBox plugin package with Chrome/Puppeteer dependency wiring
|
||||
"abx-dl>=1.11.166", # shared ArchiveBox downloader package with blocking install preflight
|
||||
### UUID7 backport for Python <3.14
|
||||
"uuid7>=0.1.0; python_version < '3.14'", # provides the uuid_extensions module on Python 3.13
|
||||
]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user