mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-12 19:50:57 +05:00
Resolve install binary names through plugins
This commit is contained in:
parent
3d680b5379
commit
a3ca0f68c0
2
.github/workflows/deploy-publicsite.yml
vendored
2
.github/workflows/deploy-publicsite.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
||||
- name: Setup Python and uv
|
||||
uses: astral-sh/setup-uv@v6
|
||||
with:
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
|
||||
- name: Install ArchiveBox and screenshot dependencies
|
||||
run: uv sync --no-cache --frozen
|
||||
|
||||
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
@ -49,7 +49,7 @@ jobs:
|
||||
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
||||
with:
|
||||
version: "0.11.3"
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
|
||||
- name: Resolve Docker through abxpkg
|
||||
|
||||
4
.github/workflows/docs.yml
vendored
4
.github/workflows/docs.yml
vendored
@ -26,7 +26,7 @@ jobs:
|
||||
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
||||
with:
|
||||
version: "0.11.3"
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
- name: Install ArchiveBox development dependencies
|
||||
run: uv sync --no-cache --locked --dev
|
||||
@ -81,7 +81,7 @@ jobs:
|
||||
if: ${{ !contains(fromJSON('["freebsd", "openbsd"]'), matrix.environment) }}
|
||||
with:
|
||||
version: "0.11.3"
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
- name: Install ArchiveBox
|
||||
if: ${{ !contains(fromJSON('["freebsd", "openbsd"]'), matrix.environment) }}
|
||||
|
||||
4
.github/workflows/lint.yml
vendored
4
.github/workflows/lint.yml
vendored
@ -25,11 +25,11 @@ jobs:
|
||||
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
||||
with:
|
||||
version: "0.11.3"
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
|
||||
- name: Verify checked dependency lock
|
||||
run: uv lock --check
|
||||
run: uv lock --no-cache --check
|
||||
|
||||
- name: Install dependencies with uv
|
||||
run: uv sync --no-cache --locked --dev --extra sonic --extra debug
|
||||
|
||||
6
.github/workflows/pip.yml
vendored
6
.github/workflows/pip.yml
vendored
@ -23,13 +23,13 @@ jobs:
|
||||
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
||||
with:
|
||||
version: ${{ env.UV_VERSION }}
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
|
||||
- name: Build every distribution
|
||||
run: |
|
||||
set -Eeuo pipefail
|
||||
uv build --all-packages --no-sources --out-dir dist --clear
|
||||
uv build --no-cache --all-packages --no-sources --out-dir dist --clear
|
||||
|
||||
shopt -s nullglob
|
||||
artifacts=(dist/*)
|
||||
@ -92,7 +92,7 @@ jobs:
|
||||
uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
||||
with:
|
||||
version: ${{ env.UV_VERSION }}
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
|
||||
- name: Download distributions
|
||||
|
||||
4
.github/workflows/test-parallel.yml
vendored
4
.github/workflows/test-parallel.yml
vendored
@ -30,7 +30,7 @@ jobs:
|
||||
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
||||
with:
|
||||
version: "0.11.3"
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
|
||||
- name: Resolve discovery tools through abxpkg
|
||||
@ -96,7 +96,7 @@ jobs:
|
||||
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
|
||||
with:
|
||||
version: "0.11.3"
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
|
||||
- name: Resolve optional build dependencies through abxpkg
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -46,7 +46,7 @@ jobs:
|
||||
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
||||
with:
|
||||
version: "0.11.3"
|
||||
enable-cache: true
|
||||
enable-cache: false
|
||||
cache-dependency-glob: uv.lock
|
||||
|
||||
- name: Prepare abxpkg environment
|
||||
|
||||
@ -12,6 +12,63 @@ from rich import print
|
||||
from archivebox.misc.util import docstring, enforce_types
|
||||
|
||||
|
||||
def _resolve_install_plugin_names(
|
||||
requested_names: tuple[str, ...],
|
||||
) -> list[str]:
|
||||
"""Resolve `archivebox install <name>` tokens to installable plugin names."""
|
||||
from archivebox.config import CONSTANTS
|
||||
from archivebox.config.common import get_config, normalize_runtime_config
|
||||
from archivebox.machine.models import Machine
|
||||
from abx_dl.config import get_required_binary_requests
|
||||
from abx_dl.models import discover_plugins, filter_plugins
|
||||
|
||||
plugins = discover_plugins(runtime="archivebox")
|
||||
config = get_config(include_machine=False)
|
||||
runtime_config = normalize_runtime_config(config.for_crawl(), json_safe=False)
|
||||
derived_config = normalize_runtime_config(Machine.current().config, json_safe=False)
|
||||
selected_plugins = dict(filter_plugins(plugins, list(requested_names), include_providers=True))
|
||||
unmatched_names: list[str] = []
|
||||
|
||||
for requested_name in requested_names:
|
||||
if requested_name in selected_plugins:
|
||||
continue
|
||||
|
||||
matched_plugin_names: list[str] = []
|
||||
for plugin_name, plugin in plugins.items():
|
||||
logical_records = get_required_binary_requests(
|
||||
plugin,
|
||||
plugin.config.required_binaries,
|
||||
overrides=runtime_config,
|
||||
derived_overrides=derived_config,
|
||||
run_output_dir=CONSTANTS.DATA_DIR,
|
||||
)
|
||||
actual_records = get_required_binary_requests(
|
||||
plugin,
|
||||
plugin.config.required_binaries,
|
||||
overrides=runtime_config,
|
||||
derived_overrides=derived_config,
|
||||
run_output_dir=CONSTANTS.DATA_DIR,
|
||||
logical_names=False,
|
||||
)
|
||||
for logical_record, actual_record in zip(logical_records, actual_records, strict=False):
|
||||
logical_name = str(logical_record["name"])
|
||||
actual_name = str(actual_record["name"])
|
||||
display_name = Path(actual_name).expanduser().name if ("/" in actual_name or actual_name.startswith("~")) else actual_name
|
||||
if requested_name in {logical_name, actual_name, display_name}:
|
||||
matched_plugin_names.append(plugin_name)
|
||||
break
|
||||
|
||||
if matched_plugin_names:
|
||||
selected_plugins.update(filter_plugins(plugins, matched_plugin_names, include_providers=True))
|
||||
else:
|
||||
unmatched_names.append(requested_name)
|
||||
|
||||
if unmatched_names:
|
||||
raise click.UsageError(f"No plugins or required binaries found matching: {', '.join(unmatched_names)}")
|
||||
|
||||
return sorted(selected_plugins)
|
||||
|
||||
|
||||
def ensure_data_dir_lib_symlink(data_dir: Path, abxpkg_lib_dir: Path) -> Path | None:
|
||||
"""Expose the shared abxpkg lib dir at DATA_DIR/lib after install."""
|
||||
link_path = data_dir / "lib"
|
||||
@ -90,7 +147,7 @@ def install(binaries: tuple[str, ...] = (), binproviders: str = "*", dry_run: bo
|
||||
|
||||
setup_django()
|
||||
|
||||
plugin_names = list(binaries)
|
||||
plugin_names = _resolve_install_plugin_names(binaries) if binaries else []
|
||||
if binproviders != "*":
|
||||
plugin_names.extend(provider.strip() for provider in binproviders.split(",") if provider.strip())
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ CAPTURE_PROFILES=$'desktop|1600|1000\ntablet|1024|1366\nmobile|390|844'
|
||||
stop_background_runner() {
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'from archivebox.workers.supervisord_util import get_existing_supervisord_process, stop_worker; supervisor=get_existing_supervisord_process(quiet=True); supervisor is not None and stop_worker(supervisor, "worker_runner")'
|
||||
) >/dev/null
|
||||
}
|
||||
@ -79,7 +79,7 @@ cleanup() {
|
||||
if [[ "$CREATED_TEMP_USER" == "1" && -f "$DATA_DIR/index.sqlite3" ]]; then
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
UI_SCREENSHOT_USERNAME="$USERNAME" uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
UI_SCREENSHOT_USERNAME="$USERNAME" uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'import os; from django.contrib.auth import get_user_model; get_user_model().objects.filter(username=os.environ["UI_SCREENSHOT_USERNAME"]).delete()'
|
||||
) >/dev/null 2>&1 || true
|
||||
fi
|
||||
@ -91,12 +91,12 @@ mkdir -p "$DATA_DIR" "$OUTPUT_DIR" "$PUBLIC_OUTPUT_DIR"
|
||||
echo "[*] Initializing the ArchiveBox collection at $DATA_DIR"
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox init --quick
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox init --quick
|
||||
)
|
||||
|
||||
SEED_STATE="$( (
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'from django.db.models import Count; from archivebox.core.models import Snapshot, ArchiveResult; from archivebox.crawls.models import CrawlSchedule; from archivebox.personas.models import Persona; from archivebox.api.models import APIToken; from signal_webhooks.utils import get_webhook_model; recent=list(Snapshot.objects.filter(status=Snapshot.StatusChoices.SEALED).order_by("-bookmarked_at").values_list("id", "status")[:100]); counts=dict(ArchiveResult.objects.filter(snapshot_id__in=[row[0] for row in recent], status="succeeded").values_list("snapshot_id").annotate(Count("id"))); screenshots=set(ArchiveResult.objects.filter(snapshot_id__in=[row[0] for row in recent], plugin="screenshot", status="succeeded").values_list("snapshot_id", flat=True)); useful=sum(counts.get(snapshot_id,0)>=8 and snapshot_id in screenshots for snapshot_id,status in recent)>=2; print(int(useful)); print(CrawlSchedule.objects.count()); print(Persona.objects.exclude(name="Default").count()); print(APIToken.objects.count()); print(get_webhook_model().objects.count())'
|
||||
) | tail -5)"
|
||||
HAS_USEFUL_SNAPSHOT="$(printf '%s\n' "$SEED_STATE" | sed -n '1p')"
|
||||
@ -109,7 +109,7 @@ if [[ "$HAS_USEFUL_SNAPSHOT" == "0" ]]; then
|
||||
echo "[*] Archiving real reference sites so snapshot views have meaningful outputs"
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox add \
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox add \
|
||||
--depth=0 \
|
||||
--overwrite \
|
||||
--tag=documentation,reference \
|
||||
@ -122,7 +122,7 @@ if [[ "$HAS_SCHEDULE" == "0" ]]; then
|
||||
echo "[*] Creating a real weekly documentation crawl schedule"
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox schedule --every=weekly --depth=0 --tag=documentation https://archivebox.io/feed.xml
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox schedule --every=weekly --depth=0 --tag=documentation https://archivebox.io/feed.xml
|
||||
)
|
||||
fi
|
||||
|
||||
@ -130,7 +130,7 @@ if [[ "$HAS_PERSONA" == "0" ]]; then
|
||||
echo "[*] Creating a real browser persona for the populated Persona views"
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox persona create "Research Browser"
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox persona create "Research Browser"
|
||||
)
|
||||
fi
|
||||
|
||||
@ -139,7 +139,7 @@ fi
|
||||
|
||||
ROUTE_CONFIG="$( (
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'from urllib.parse import urlparse; from archivebox.config.common import get_config; from archivebox.core.routes_util import get_admin_base_url, get_web_base_url; config = get_config(); admin = get_admin_base_url(config=config); web = get_web_base_url(config=config); parsed = urlparse(admin); print(admin); print(web); print(parsed.port or (443 if parsed.scheme == "https" else 80))'
|
||||
) | tail -3)"
|
||||
ADMIN_BASE_URL="$(printf '%s\n' "$ROUTE_CONFIG" | sed -n '1p')"
|
||||
@ -155,10 +155,10 @@ fi
|
||||
echo "[*] Creating a temporary screenshot admin"
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'from django.contrib.auth import get_user_model; get_user_model().objects.filter(username__startswith="archivebox-screenshots-").delete()'
|
||||
UI_SCREENSHOT_USERNAME="$USERNAME" UI_SCREENSHOT_PASSWORD="$PASSWORD" \
|
||||
uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'import os; from django.contrib.auth import get_user_model; get_user_model().objects.create_superuser(username=os.environ["UI_SCREENSHOT_USERNAME"], password=os.environ["UI_SCREENSHOT_PASSWORD"])'
|
||||
)
|
||||
CREATED_TEMP_USER=1
|
||||
@ -169,7 +169,7 @@ echo "[*] Starting ArchiveBox on port $PORT"
|
||||
# Use the real server command so the runner, worker, and log views describe
|
||||
# the same persistent runtime that an operator sees.
|
||||
UI_SCREENSHOT_HIDE_HIGH_LOAD_WARNING=1 \
|
||||
exec uv run --project "$REPO_DIR" archivebox server "127.0.0.1:$PORT"
|
||||
exec uv run --no-cache --project "$REPO_DIR" archivebox server "127.0.0.1:$PORT"
|
||||
) >"$DATA_DIR/ui-screenshot-server.log" 2>&1 &
|
||||
SERVER_PID=$!
|
||||
|
||||
@ -265,7 +265,7 @@ while [[ "$capture_index" -lt "${#VIEWS[@]}" ]]; do
|
||||
fi
|
||||
elif [[ "$profile" == "desktop" || "$capture_mode" == wait-replay:* || -z "${ABXPKG_LIB_DIR:-}" ]]; then
|
||||
capture_log="$CAPTURE_ROOT/$(printf '%02d' "$capture_index")-$profile-abx-dl.log"
|
||||
if ! env "${capture_env[@]}" uv run --project "$REPO_DIR" abx-dl dl \
|
||||
if ! env "${capture_env[@]}" uv run --no-cache --project "$REPO_DIR" abx-dl dl \
|
||||
--plugins=screenshot \
|
||||
--timeout=120 \
|
||||
--dir "$capture_dir" \
|
||||
@ -281,7 +281,7 @@ while [[ "$capture_index" -lt "${#VIEWS[@]}" ]]; do
|
||||
echo "[!] Screenshot navigation metadata is missing for $profile $url" >&2
|
||||
exit 1
|
||||
fi
|
||||
uv run --project "$REPO_DIR" "$REPO_DIR/bin/generate_ui_screenshot_gallery.py" validate \
|
||||
uv run --no-cache --project "$REPO_DIR" "$REPO_DIR/bin/generate_ui_screenshot_gallery.py" validate \
|
||||
"$screenshot_metadata_path" "$expected_path"
|
||||
else
|
||||
screenshot_path="$capture_dir/screenshot.png"
|
||||
@ -300,7 +300,7 @@ while [[ "$capture_index" -lt "${#VIEWS[@]}" ]]; do
|
||||
SCREENSHOT_VARIANTS_JSON="$responsive_variants" \
|
||||
SCREENSHOT_COLLAPSE_FILTERS=1 \
|
||||
node "$REPO_DIR/bin/take_screenshot.js" "$url" "$screenshot_path" >"$capture_dir/report.json"
|
||||
uv run --project "$REPO_DIR" "$REPO_DIR/bin/generate_ui_screenshot_gallery.py" validate \
|
||||
uv run --no-cache --project "$REPO_DIR" "$REPO_DIR/bin/generate_ui_screenshot_gallery.py" validate \
|
||||
"$capture_dir/report.json" "$expected_path"
|
||||
fi
|
||||
fi
|
||||
@ -312,14 +312,14 @@ while [[ "$capture_index" -lt "${#VIEWS[@]}" ]]; do
|
||||
cp "$screenshot_path" "$PUBLIC_OUTPUT_DIR/$filename"
|
||||
UI_SCREENSHOT_NAME="$name" UI_SCREENSHOT_URL="$url" UI_SCREENSHOT_SOURCE="$source" \
|
||||
UI_SCREENSHOT_FILENAME="$filename" UI_SCREENSHOT_PROFILE="$profile" \
|
||||
uv run --project "$REPO_DIR" "$REPO_DIR/bin/generate_ui_screenshot_gallery.py" append \
|
||||
uv run --no-cache --project "$REPO_DIR" "$REPO_DIR/bin/generate_ui_screenshot_gallery.py" append \
|
||||
"$MANIFEST_FILE" "$OUTPUT_DIR/$filename"
|
||||
done <<<"$CAPTURE_PROFILES"
|
||||
|
||||
# Capture the public views before login because the real admin-login hint
|
||||
# intentionally redirects authenticated personas away from /public/.
|
||||
if [[ "$capture_index" == "2" ]]; then
|
||||
ABXPKG_LIB_DIR="$(uv run --project "$REPO_DIR" abx-dl config --get ABXPKG_LIB_DIR | sed 's/^[^=]*=//; s/^"//; s/"$//')"
|
||||
ABXPKG_LIB_DIR="$(uv run --no-cache --project "$REPO_DIR" abx-dl config --get ABXPKG_LIB_DIR | sed 's/^[^=]*=//; s/^"//; s/"$//')"
|
||||
SCREENSHOT_CHROME_BINARY="$ABXPKG_LIB_DIR/env/bin/chromium"
|
||||
if [[ ! -x "$SCREENSHOT_CHROME_BINARY" ]]; then
|
||||
echo "[!] abx-dl projected Chromium was not found at $SCREENSHOT_CHROME_BINARY" >&2
|
||||
@ -344,7 +344,7 @@ while [[ "$capture_index" -lt "${#VIEWS[@]}" ]]; do
|
||||
CREATE_WEBHOOK="$CREATE_WEBHOOK" \
|
||||
node "$REPO_DIR/bin/setup_ui_screenshot_data.js" "$ADMIN_BASE_URL" "$USERNAME"
|
||||
|
||||
OPENCODE_PORT="$(uv run --project "$REPO_DIR" python - <<'PY'
|
||||
OPENCODE_PORT="$(uv run --no-cache --project "$REPO_DIR" python - <<'PY'
|
||||
import socket
|
||||
|
||||
with socket.socket() as sock:
|
||||
@ -354,20 +354,20 @@ PY
|
||||
)"
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
OPENCODE_PORT="$OPENCODE_PORT" uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
OPENCODE_PORT="$OPENCODE_PORT" uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'import os; from archivebox.machine.models import Machine; Machine.from_json({"config": {"OPENCODE_ENABLED": True, "OPENCODE_PORT": int(os.environ["OPENCODE_PORT"])}})'
|
||||
uv run --project "$REPO_DIR" archivebox install opencode --binproviders=env,pnpm
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox install opencode --binproviders=env,pnpm
|
||||
)
|
||||
|
||||
SWEETING_CAPTURE_STARTED_AT="$( (
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'from django.utils import timezone; print(timezone.now().isoformat())'
|
||||
) | tail -1)"
|
||||
echo "[*] Starting a real Sweeting.me capture for the live progress view"
|
||||
(
|
||||
cd "$DATA_DIR"
|
||||
exec uv run --project "$REPO_DIR" archivebox add \
|
||||
exec uv run --no-cache --project "$REPO_DIR" archivebox add \
|
||||
--depth=0 \
|
||||
--overwrite \
|
||||
--tag=screenshot-gallery \
|
||||
@ -379,7 +379,7 @@ PY
|
||||
for _attempt in $(seq 1 120); do
|
||||
LIVE_SNAPSHOT_RECORD="$( (
|
||||
cd "$DATA_DIR"
|
||||
UI_SCREENSHOT_CAPTURE_STARTED_AT="$SWEETING_CAPTURE_STARTED_AT" uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
UI_SCREENSHOT_CAPTURE_STARTED_AT="$SWEETING_CAPTURE_STARTED_AT" uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'import os; from django.utils.dateparse import parse_datetime; from archivebox.core.models import Snapshot; from archivebox.core.routes_util import build_snapshot_url; started_at=parse_datetime(os.environ["UI_SCREENSHOT_CAPTURE_STARTED_AT"]); snapshot=Snapshot.objects.filter(url__startswith="https://sweeting.me",bookmarked_at__gte=started_at).order_by("-bookmarked_at").first(); print(build_snapshot_url(str(snapshot.id), "") if snapshot else "")'
|
||||
) | tail -1)"
|
||||
if [[ -n "$LIVE_SNAPSHOT_RECORD" ]]; then
|
||||
@ -403,7 +403,7 @@ PY
|
||||
|
||||
RECORD_CONFIG="$( (
|
||||
cd "$DATA_DIR"
|
||||
uv run --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
uv run --no-cache --project "$REPO_DIR" archivebox manage shell --no-imports -c \
|
||||
'from django.db.models import Count; from archivebox.core.models import Snapshot, ArchiveResult, Tag; from archivebox.crawls.models import Crawl, CrawlSchedule; from archivebox.personas.models import Persona; from archivebox.machine.models import Machine, NetworkInterface, Binary, Process; from archivebox.api.models import APIToken; from django.contrib.auth import get_user_model; from signal_webhooks.utils import get_webhook_model; from archivebox.core.routes_util import build_snapshot_url; recent=list(Snapshot.objects.filter(status=Snapshot.StatusChoices.SEALED).order_by("-bookmarked_at").values_list("id", flat=True)[:1000]); counts=dict(ArchiveResult.objects.filter(snapshot_id__in=recent,status="succeeded").values_list("snapshot_id").annotate(Count("id"))); snapshot_id=str(max(recent,key=lambda item: counts.get(item,0))); snapshot=Snapshot.objects.get(id=snapshot_id); result=ArchiveResult.objects.filter(snapshot_id=snapshot_id,status="succeeded").order_by("-output_size").first() or ArchiveResult.objects.filter(snapshot_id=snapshot_id).first(); tag=snapshot.tags.first() or Tag.objects.first(); crawl=snapshot.crawl or Crawl.objects.order_by("-created_at").first(); schedule=CrawlSchedule.objects.order_by("-created_at").first(); persona=Persona.objects.exclude(name="Default").order_by("-created_at").first() or Persona.objects.first(); machine=Machine.objects.order_by("-modified_at").first(); interface=NetworkInterface.objects.order_by("-modified_at").first(); binary=Binary.objects.order_by("-modified_at").first(); process=Process.objects.order_by("-created_at").first(); token=APIToken.objects.order_by("-created_at").first(); webhook=get_webhook_model().objects.order_by("-created_at").first(); user=get_user_model().objects.get(username="'"$USERNAME"'"); values={"SNAPSHOT_ID":snapshot_id,"SNAPSHOT_VIEW_URL":build_snapshot_url(snapshot_id,""),"SNAPSHOT_FILES_URL":build_snapshot_url(snapshot_id,"/?files=1"),"ARCHIVERESULT_ID":str(result.id),"TAG_ID":str(tag.id),"USER_ID":str(user.id),"CRAWL_ID":str(crawl.id),"SCHEDULE_ID":str(schedule.id),"PERSONA_ID":str(persona.id),"MACHINE_ID":str(machine.id),"INTERFACE_ID":str(interface.id),"BINARY_ID":str(binary.id),"PROCESS_ID":str(process.id),"TOKEN_ID":str(token.id),"WEBHOOK_ID":str(webhook.id)}; [print(f"{key}={value}") for key,value in values.items()]'
|
||||
) | tail -15)"
|
||||
eval "$RECORD_CONFIG"
|
||||
@ -474,7 +474,7 @@ PY
|
||||
SCREENSHOT_WIDTH=1600 \
|
||||
SCREENSHOT_HEIGHT=1000 \
|
||||
node "$REPO_DIR/bin/take_screenshot.js" "$LIVE_SNAPSHOT_VIEW_URL" "$CAPTURE_ROOT/snapshot-output-discovery.png" >"$SNAPSHOT_DISCOVERY_REPORT"
|
||||
SNAPSHOT_OUTPUT_PLUGINS="$(UI_SCREENSHOT_DISCOVERY_REPORT="$SNAPSHOT_DISCOVERY_REPORT" uv run --project "$REPO_DIR" python -c \
|
||||
SNAPSHOT_OUTPUT_PLUGINS="$(UI_SCREENSHOT_DISCOVERY_REPORT="$SNAPSHOT_DISCOVERY_REPORT" uv run --no-cache --project "$REPO_DIR" python -c \
|
||||
'import json, os; from urllib.parse import urlsplit; report=json.load(open(os.environ["UI_SCREENSHOT_DISCOVERY_REPORT"])); print("\n".join("{}\t{}".format(output["plugin"], "wait-replay:Nick Sweeting" if urlsplit(output["previewUrl"]).path.endswith(".wacz") else "") for output in report["checks"]["snapshotOutputs"]))')"
|
||||
if [[ -z "$SNAPSHOT_OUTPUT_PLUGINS" ]]; then
|
||||
echo "[!] The Sweeting.me snapshot detail page exposed no selectable outputs" >&2
|
||||
@ -492,7 +492,7 @@ PY
|
||||
done
|
||||
|
||||
[[ "$MAX_VIEWS" != "0" ]] && export UI_SCREENSHOT_ALLOW_PARTIAL=1
|
||||
uv run --project "$REPO_DIR" "$REPO_DIR/bin/generate_ui_screenshot_gallery.py" build \
|
||||
uv run --no-cache --project "$REPO_DIR" "$REPO_DIR/bin/generate_ui_screenshot_gallery.py" build \
|
||||
"$MANIFEST_FILE" "$REPO_DIR/docs/Screenshots.md" "$PUBLIC_OUTPUT_DIR/index.html"
|
||||
|
||||
echo "[+] Captured $capture_index views at desktop, tablet, and mobile sizes"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "archivebox",
|
||||
"version": "0.9.35rc163",
|
||||
"version": "0.9.35rc164",
|
||||
"repository": "github:ArchiveBox/ArchiveBox",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "archivebox"
|
||||
version = "0.9.35rc163"
|
||||
version = "0.9.35rc164"
|
||||
requires-python = ">=3.13"
|
||||
description = "Self-hosted internet archiving solution."
|
||||
authors = [{name = "Nick Sweeting", email = "pyproject.toml@archivebox.io"}]
|
||||
@ -83,7 +83,7 @@ dependencies = [
|
||||
"abxbus==2.5.40", # EventBus API
|
||||
"abxpkg", # direct imports only; version constrained by abx-dl -> abx-plugins
|
||||
"abx-plugins", # direct imports only; version constrained by abx-dl
|
||||
"abx-dl==1.12.29", # shared ArchiveBox downloader package
|
||||
"abx-dl==1.12.31", # shared ArchiveBox downloader package
|
||||
### UUID7 backport for Python <3.14
|
||||
"uuid7>=0.1.0; python_version < '3.14'", # provides the uuid_extensions module on Python 3.13
|
||||
]
|
||||
@ -348,7 +348,7 @@ Donate = "https://github.com/ArchiveBox/ArchiveBox/wiki/Donations"
|
||||
|
||||
|
||||
[tool.bumpver]
|
||||
current_version = "v0.9.35rc163"
|
||||
current_version = "v0.9.35rc164"
|
||||
version_pattern = "vMAJOR.MINOR.PATCH[PYTAGNUM]"
|
||||
commit_message = "bump version {old_version} -> {new_version}"
|
||||
tag_message = "{new_version}"
|
||||
|
||||
22
uv.lock
22
uv.lock
@ -24,7 +24,7 @@ abxpkg = "2100-01-01T00:00:00Z"
|
||||
|
||||
[[package]]
|
||||
name = "abx-dl"
|
||||
version = "1.12.29"
|
||||
version = "1.12.31"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "abx-plugins" },
|
||||
@ -39,14 +39,14 @@ dependencies = [
|
||||
{ name = "rich" },
|
||||
{ name = "rich-click" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/27/1c/ef4512b5209a94f3e3945907ae3fbefc47ff2b630aff9f7d957cfb8917da/abx_dl-1.12.29.tar.gz", hash = "sha256:d072755cb069ae8f412316810ab38a7c754e03555d02e0d9a8eb5ae04a8b0d60", size = 86814, upload-time = "2026-07-28T17:52:24.237Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/83/12/a17dbf6ff8cd8a17ecbbd8b2c1b5ea47d2562299d9efd7bc7ba00b38d623/abx_dl-1.12.31.tar.gz", hash = "sha256:544a8ac11a08b390c021a92bfb7d648f85a3b110ed728864c6c6f798333b39d0", size = 86789, upload-time = "2026-07-29T03:20:31.08Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/08/ea/9c15aeacf2492004bca3874008dad34557e06c56ae6c6caf037c068b93a9/abx_dl-1.12.29-py3-none-any.whl", hash = "sha256:429da9b175680ead21cae69ebf3e22204ad16a48c0e656d65d82b9153014caf7", size = 90704, upload-time = "2026-07-28T17:52:23.154Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/9d/2c02fbea7239f0aac9857c0670328b40ee16e5491ebd3fe802e2cb56a7a8/abx_dl-1.12.31-py3-none-any.whl", hash = "sha256:41c389573c05c6db47bb93ae0d45876cdbc22468dbf075204546d6da8eb23579", size = 90708, upload-time = "2026-07-29T03:20:29.935Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "abx-plugins"
|
||||
version = "1.12.32"
|
||||
version = "1.12.39"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "abxbus" },
|
||||
@ -56,9 +56,9 @@ dependencies = [
|
||||
{ name = "rich-click" },
|
||||
{ name = "uv" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ac/08/0f0150ce87f2ed6d7bf946f0f5bb075d8dd7dc5ff2e42c92691ce62231b6/abx_plugins-1.12.32.tar.gz", hash = "sha256:24d18831da390fe88a81c239ebaf22b500cc36e6ebfd6f375a57824b6cc8c334", size = 260578, upload-time = "2026-07-28T15:20:39.477Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1f/2c/63433217fd2ae742cc81d00acd3585a714b1439b9916ea0dec3d25831f1a/abx_plugins-1.12.39.tar.gz", hash = "sha256:596bf68fd994364dd37bb4f2830dfe11ef0e676f9880ac44e278ea4f5fb0b964", size = 260565, upload-time = "2026-07-29T02:47:16.992Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/06/0d/3cca76c0f94a883e3b619180b80232319932474448c0b38c633dd90b255d/abx_plugins-1.12.32-py3-none-any.whl", hash = "sha256:721d921554d4cacc6c756b737735b315ff7e74921ee1ce303d37f4ea727f05ba", size = 411230, upload-time = "2026-07-28T15:20:38.194Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/5f/a7f3b33db738b52e96d16768cc6bbccaa230497b7f446cf3aa94201c66c9/abx_plugins-1.12.39-py3-none-any.whl", hash = "sha256:15d54449c7a0e534152ddb71bdb7fa83b0fa01f5883c52f5c52ead8a8dea5c74", size = 411239, upload-time = "2026-07-29T02:47:15.565Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -77,7 +77,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "abxpkg"
|
||||
version = "1.12.25"
|
||||
version = "1.12.26"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pip" },
|
||||
@ -86,9 +86,9 @@ dependencies = [
|
||||
{ name = "rich-click" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/e1ccdb0cee3bc18e33d00a6484273887836db54e96c75e5a2244287de97f/abxpkg-1.12.25.tar.gz", hash = "sha256:2cac56e9d624565c8b175d5f5469147ab7a756c0092b9bd13ee52ba94ae89287", size = 220914, upload-time = "2026-07-28T09:35:55.827Z" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8e/aa/ba5ad1fea91287a05eb6d563bd4bc8904104824e5429865671a4610d200d/abxpkg-1.12.26.tar.gz", hash = "sha256:fde0d3eaf854af21acc296a1aceeb51cae439fbd16d162183c774121f84e0a9a", size = 221167, upload-time = "2026-07-29T01:52:10.984Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/20/e1/80657dc861e6f73444579915f54994a4df86f940ab9f7fa447eb2756d569/abxpkg-1.12.25-py3-none-any.whl", hash = "sha256:d1580766c63ff7cd67209ce6bb3c61c6efcb5ae65fa332d482fca44f5f1dfbd4", size = 234632, upload-time = "2026-07-28T09:35:54.448Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/2f/c3befcb4446a24f8ad22c51feae972cadf67cb5be4e169b809580a7c73c7/abxpkg-1.12.26-py3-none-any.whl", hash = "sha256:b3f11b4ceefebf8651311b59b5b34048eb9dfcfa090b735ec81da4264de13d54", size = 234868, upload-time = "2026-07-29T01:52:11.977Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -123,7 +123,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "archivebox"
|
||||
version = "0.9.35rc163"
|
||||
version = "0.9.35rc164"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "abx-dl" },
|
||||
@ -223,7 +223,7 @@ dev = [
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "abx-dl", specifier = "==1.12.29" },
|
||||
{ name = "abx-dl", specifier = "==1.12.31" },
|
||||
{ name = "abx-plugins" },
|
||||
{ name = "abxbus", specifier = "==2.5.40" },
|
||||
{ name = "abxpkg" },
|
||||
|
||||
Loading…
Reference in New Issue
Block a user