Commit Graph

142 Commits

Author SHA1 Message Date
Nick Sweeting
9ee0dcf165
fix: address orchestration review findings 2026-09-02 12:56:23 -07:00
Nick Sweeting
2bba758314
refactor: simplify snapshot maintenance orchestration 2026-09-02 12:05:09 -07:00
Nick Sweeting
fbff88fb0e
Merge remote-tracking branch 'origin/dev' into audit-pr1846
# Conflicts:
#	archivebox/cli/archivebox_extract.py
#	archivebox/core/recovery_util.py
#	archivebox/services/archive_result_service.py
#	archivebox/services/runner.py
2026-09-01 15:43:48 -07:00
Nick Sweeting
032c20bdf5
cleanup: delete obsolete model lifecycle helpers 2026-09-01 15:06:48 -07:00
Nick Sweeting
3fc67705a5
Unify plugin runtime and queue lifecycle boundaries 2026-09-01 01:07:04 -07:00
Nick Sweeting
c062a3c54f
Eliminate request-side SQLite write transactions 2026-08-28 21:56:18 -07:00
Nick Sweeting
f0abdd2bc3 Preserve real 0.8 crawl seed data during upgrade 2026-08-01 22:54:35 -07:00
Nick Sweeting
6c87629b39
Make API pause win over runner leases 2026-07-31 23:50:40 -07:00
Nick Sweeting
05350846ab
Sync ArchiveBox UI and setup updates 2026-07-25 14:50:15 -07:00
Claude
6a8062090b
Slim DB helpers and address PR review feedback
Helper reduction:
- Move the Django DATABASES/SQLITE_CONNECTION_OPTIONS assembly into
  core/settings.py, dropping get_database_settings() and
  get_sqlite_connection_options() from misc/db.py.
- Inline the single-use migration_table_columns() into its one migration.

Review fixes:
- search: match only scalar JSON *values* on postgres (jsonb_path_query
  over '$.**' scalar leaves), mirroring SQLite json_tree.atom so config
  keys no longer match.
- CharField clamp now also runs in SnapshotQuerySet.bulk_create (bulk paths
  bypass the pre_save signal); truncate_overlong_charfields is dual-use.
- Restore reverse-migration parity on postgres: crawls/machine/api initial
  migrations drop their rebuilt tables on reverse via drop_models_on_postgres.
- docs: give DATABASE_NAME its own section so the anchor resolves correctly.
- CI: only install postgres binaries on the shard that runs the postgres test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YHSjZM6TstSAMN2PhgfUg
2026-07-24 07:57:09 +00:00
Claude
c2191f9e74
Fix lint: settings import placement and benchmark script exec bit
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YHSjZM6TstSAMN2PhgfUg
2026-07-23 17:18:54 +00:00
Claude
7167c5dd8a
Add native PostgreSQL support alongside SQLite
Add DATABASE_ENGINE=postgres (plus DATABASE_HOST/PORT/USER/PASSWORD/NAME)
config and centralize all sqlite-vs-postgres branching in
archivebox.misc.db:

- get_database_settings() builds DATABASES for either backend; the sqlite
  path is unchanged (custom lock-retry backend, same PRAGMAs).
- database_exists()/ensure_database_ready() replace index.sqlite3 file
  checks; init auto-creates the postgres database when missing.
- approximate_row_counts() serves admin index counts from sqlite_stat1 or
  pg_class.reltuples; missing-table detection covers both vendors.
- rebuild_models_from_migration_state() lets historical sqlite-only raw
  SQL migrations resync postgres schema from Django migration state at
  every divergence point (postgres can never hold legacy data, so
  affected tables are empty when these run). All raw-DDL and PRAGMA
  migrations are now vendor-gated with sqlite behavior byte-for-byte
  unchanged.
- A pre_save clamp truncates CharField values to max_length: sqlite
  never enforced varchar(n) but postgres does (e.g. long crawl labels).
- Collation-sensitive URL range scans branch to escaped LIKE on postgres
  (with a text_pattern_ops index) since linguistic collations break
  bytewise range tricks; the crawl-config JSON search wave gets a
  jsonb-text implementation.

Verified on real PostgreSQL 16: fresh init applies the entire migration
graph, schema matches models exactly (column-level parity check +
makemigrations --check), and add/run/list/search/status/remove all work
end-to-end. New test_postgres_backend.py suite boots a real throwaway
postgres cluster (initdb + pg_ctl); CI workflows install postgres server
binaries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YHSjZM6TstSAMN2PhgfUg
2026-07-23 17:08:47 +00:00
Nick Sweeting
6592af0d19
Exercise ArchiveBox through unified runtime lifecycles 2026-07-21 19:26:42 -07:00
Nick Sweeting
01f5666dbc
Route runtime binaries through abxpkg 2026-07-20 12:50:14 -07:00
Nick Sweeting
1dbde4776f
release: archivebox 0.9.35rc27 2026-06-13 23:12:36 -07:00
Nick Sweeting
c9e63ccffd
Centralize synthetic root snapshot creation in CrawlRunner
Direct URL inputs from CLI/UI/API now seed Crawl.urls as explicit
{type:CrawlSeed,url,depth} JSONL rows; raw stdin/UI/API import text
stays verbatim. The runner's create_initial_snapshots() is now the
single place that either expands seed rows or creates the synthetic
archivebox://internal root + staticfile/stdin.txt, so add paths no
longer perform DB/FS side effects and the parser hooks run through
the same Snapshot lifecycle as every other extractor.
2026-06-13 17:10:06 -07:00
Nick Sweeting
6e0f2a41a3
Fix add input routing and plugin dependencies 2026-06-11 07:06:41 -07:00
Nick Sweeting
2bda2abbf0
Fix tagged internal add crawl sealing 2026-06-10 21:04:48 -07:00
Nick Sweeting
2127d07697
Inherit crawl tags on snapshot creation 2026-06-10 00:24:21 -07:00
Nick Sweeting
2bfb3ad4eb
release: archivebox 0.9.35rc5 2026-06-09 22:09:28 -07:00
Nick Sweeting
4fa90e484a
release: archivebox 0.9.34rc71 2026-06-07 20:51:28 -07:00
Nick Sweeting
87b518314a
release: archivebox 0.9.34rc67 2026-06-07 04:06:45 -07:00
Nick Sweeting
96437e1ffd
Publish local ArchiveBox changes 2026-06-02 02:25:52 -07:00
Nick Sweeting
7dd738b5b7
release: archivebox 0.9.34rc37
Some checks are pending
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run
Build Debian package / build (amd64) (push) Waiting to run
Build Debian package / build (arm64) (push) Waiting to run
Build Debian package / test (amd64, ubuntu-24.04) (push) Blocked by required conditions
Build Debian package / test (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
Build Debian package / release (push) Blocked by required conditions
Build Docker image / build ${{ matrix.platform }} (digest-linux-amd64, docker-amd64, linux/amd64, ubuntu-24.04) (push) Waiting to run
Build Docker image / build ${{ matrix.platform }} (digest-linux-arm64, docker-arm64, linux/arm64, ubuntu-24.04-arm) (push) Waiting to run
Build Docker image / publish multiarch tags (push) Blocked by required conditions
Run linters / lint (push) Waiting to run
Build Pip package / build (push) Waiting to run
Release State / release-state (push) Waiting to run
Parallel Tests / Discover test files (push) Waiting to run
Parallel Tests / ${{ matrix.test.name }} (push) Blocked by required conditions
Parallel Tests / ${{ matrix.plugin.name }} (push) Blocked by required conditions
Run tests / python_tests (ubuntu-22.04, 3.13) (push) Waiting to run
Run tests / docker_tests (push) Waiting to run
2026-06-01 21:44:23 -07:00
Nick Sweeting
051d16697e
Tighten state machine model typing 2026-06-01 15:14:41 -07:00
Nick Sweeting
c075d654d8
Consolidate runtime config handling 2026-06-01 15:03:40 -07:00
Nick Sweeting
3871a4ac7e
release: archivebox 0.9.33rc68 2026-06-01 03:12:47 -07:00
Nick Sweeting
cab05eb1c6
Refactor plugins search progress and config flows 2026-06-01 00:08:27 -07:00
Nick Sweeting
9bcba41b58
release: archivebox 0.9.33rc58 2026-05-31 04:38:45 -07:00
Nick Sweeting
3521f21c36
fix: self-heal legacy crawls_crawl NOT NULL columns + Puppeteer timeout
Pre-0.9.0 crawl tables had ``max_urls``, ``crawl_max_size``, and
``snapshot_max_size`` as NOT NULL ``IntegerField`` columns. The 0011
migration RemoveField'd them, but on long-lived DBs where a historical
0011 ran with different semantics the columns stayed on disk while
being absent from the model. Every Crawl.objects.create() through the
ORM (e.g. the /add/ form view) skips them, and SQLite refuses the
insert with "NOT NULL constraint failed: crawls_crawl.max_urls" —
an HTTP 500 on /add/. Cabbage hit this on the rc51 UI test.

The new 0017 migration introspects the live table, copies any
pre-existing values into ``config`` under the canonical
CRAWL_MAX_URLS / CRAWL_MAX_SIZE / SNAPSHOT_MAX_SIZE keys so nothing
gets silently dropped, then ALTER TABLE DROP COLUMNs each legacy
field. Fresh installs already have these columns removed and the
migration is a no-op there. Requires SQLite 3.35+ for DROP COLUMN.

Plus: bin/take_screenshot.js bumps Puppeteer's CDP protocolTimeout
from the 30s default to 5 minutes — admin pages with many DB-backed
partials (snapshot grid w/ 23K rows, progress monitor, etc.) blow
past 30s on the screenshot capture under load.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-30 23:14:35 -07:00
Nick Sweeting
b08f70e510
release: archivebox 0.9.33rc51 2026-05-30 22:37:06 -07:00
Nick Sweeting
5a38193f56
release: archivebox 0.9.33rc50 2026-05-30 22:27:28 -07:00
Nick Sweeting
66259c9177
fix: self-heal missing permissions columns on long-lived dev DBs
Beta-tester / cabbage-style DBs upgraded incrementally through the
0.8.x → 0.9.x rc chain have crawls/0013_crawl_permissions,
personas/0003_persona_permissions, and core/0041_snapshot_permissions
all marked applied in django_migrations — but the historical migrations
with those names predate the current GeneratedField design. The columns
they were supposed to add never actually landed on the tables. When the
downstream hydration migrations (crawls/0016_hydrate_crawl_permissions,
personas/0004_hydrate_persona_permissions) run and try to filter on
.permissions, the query fails with no such column: permissions and
bricks startup.

Add a defensive _ensure_permissions_column pass at the top of each
hydration migration that ALTER TABLEs the column in if absent. For the
snapshot side (no hydration migration to attach to) introduce a new
core/0046_repair_snapshot_permissions migration that runs the same
guard. Fresh installs already have the column from the initial 0013 /
0003 / 0041 migrations, so the guard no-ops there.

SQLite ALTER TABLE ADD COLUMN only accepts VIRTUAL generated columns
("cannot add a STORED column"), so the repaired columns evaluate the
JSON extract on read rather than write — runtime queries behave
identically.

Verified end-to-end against actual cabbage data (23517 snapshots,
229 crawls, 103122 archive_results): container now boots healthy on
rc48 with the legacy schema in place.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-30 16:42:46 -07:00
Nick Sweeting
6ce2555dfd
fix: rename utils.py → util.py across modules, fix add --index-only, misc cleanups
Renames (no functional change, just consistency with the rest of the codebase):
- cli/cli_utils.py → cli/cli_util.py
- core/host_utils.py → core/host_util.py
- core/tag_utils.py → core/tag_util.py
- crawls/schedule_utils.py → crawls/schedule_util.py
- machine/env_utils.py → machine/env_util.py

Functional fixes:
- archivebox add --index-only now materializes Snapshot rows synchronously
  via crawl.create_snapshots_from_urls() instead of just queueing the Crawl
  and leaving the index empty. The previous behavior broke every test that
  expected --index-only to populate the index, since the runner is never
  started in index-only mode.
- config/collection.py: add _coerce_from_str_dict as the inverse of
  _coerce_to_str_dict so JSON-encoded INI values are decoded back to native
  dict/list types when mirrored into Machine.config (a JSONField). Without
  this, downstream consumers like MachineEvent / abx-dl get raw JSON
  strings where they expect dicts.

Plus matching admin / middleware / model touch-ups, the registration
password_change_form template, and assorted small cleanups the user
worked through while validating the deploy path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-30 14:30:33 -07:00
Nick Sweeting
383e4b5c6e
release: archivebox 0.9.33rc45 2026-05-30 05:42:53 -07:00
Nick Sweeting
b0a47e8bf5
wip: snapshot live progress, universal --init, runner perms, supervisord SIGINT
- Snapshot detail page: embed scoped live-progress monitor (same-origin
  /progress.json on whichever host the page is served from); hide admin
  action buttons when scoped; per-snapshot perms via can_view_snapshot.
- crawl_file API: respect crawl-level permissions; PUBLIC/UNLISTED served
  to guests, PRIVATE returns 404 for non-admin/non-owner.
- CrawlRunner: replace allow_paused_snapshot_maintenance with
  allow_maintenance_on_inactive_crawl so SEALED crawls don't short-circuit
  the cancellation guard for legitimate maintenance hooks (search backend
  backfill, fs migration, etc.). Fixes infinite STARTED loop on snapshots
  with queued search_backend results.
- Universal `--init` flag: works on any subcommand (server, update, add,
  shell, install, ...). Detected at module load, stripped from argv, and
  consumed in the dispatcher so subprocesses inherit a clean env.
- supervisord_util.run_runner_worker: route Ctrl+C through
  supervisor.signalProcess(name, "SIGINT") instead of raw os.kill on a
  cached pid, gated on statename=RUNNING. Prevents killing unrelated
  processes when the worker's pid has been reused by the OS.
- Login page: remove non-functional password-reset links; add
  has_real_admin_users template tag to gate the bootstrap hint.
- Add page: hide underline on the "Get the extension" link.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-30 04:45:15 -07:00
Nick Sweeting
c750084c3c
release: archivebox 0.9.33rc37 2026-05-29 02:50:04 -07:00
Nick Sweeting
04f20447f8
Fix snapshot finalization race 2026-05-28 20:32:51 -07:00
Nick Sweeting
881a858383
release: archivebox 0.9.33rc35 2026-05-28 20:23:01 -07:00
Nick Sweeting
031e956080
release: archivebox 0.9.33rc29
Some checks are pending
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run
Build Debian package / build (amd64) (push) Waiting to run
Build Debian package / build (arm64) (push) Waiting to run
Build Debian package / test (amd64, ubuntu-24.04) (push) Blocked by required conditions
Build Debian package / test (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
Build Debian package / release (push) Blocked by required conditions
Build Docker image / build ${{ matrix.platform }} (digest-linux-amd64, docker-amd64, linux/amd64, ubuntu-24.04) (push) Waiting to run
Build Docker image / build ${{ matrix.platform }} (digest-linux-arm64, docker-arm64, linux/arm64, ubuntu-24.04-arm) (push) Waiting to run
Build Docker image / publish multiarch tags (push) Blocked by required conditions
Run linters / lint (push) Waiting to run
Build Pip package / build (push) Waiting to run
Release State / release-state (push) Waiting to run
Parallel Tests / Discover test files (push) Waiting to run
Parallel Tests / ${{ matrix.test.name }} (push) Blocked by required conditions
Parallel Tests / ${{ matrix.plugin.name }} (push) Blocked by required conditions
Run tests / python_tests (ubuntu-22.04, 3.13) (push) Waiting to run
Run tests / docker_tests (push) Waiting to run
2026-05-28 15:35:33 -07:00
Nick Sweeting
f60b190182
fix: centralize ctrl-c rich logging 2026-05-28 08:49:17 -07:00
Nick Sweeting
b1fa3de5a5
release: archivebox 0.9.33rc13 2026-05-28 06:27:57 -07:00
Nick Sweeting
f09c3a8e0d
release: archivebox 0.9.33rc9 2026-05-28 05:50:28 -07:00
Nick Sweeting
fbcc972441
backup: save in-progress dev changes 2026-05-28 05:20:52 -07:00
Nick Sweeting
09f7c8bba0
release: archivebox 0.9.32rc32 2026-05-27 14:50:49 -07:00
Nick Sweeting
89a3119f2a
release: v0.9.32rc24 2026-05-27 12:40:49 -07:00
Nick Sweeting
066f79a029
release: v0.9.32rc23 2026-05-27 12:07:58 -07:00
Nick Sweeting
aa3f67ae7b
release: v0.9.32rc22 2026-05-27 12:05:57 -07:00
Nick Sweeting
1126c469d0
release: archivebox 0.9.32rc7 2026-05-27 03:24:04 -07:00
Nick Sweeting
a34abb5c52
release: archivebox 0.9.32rc4 2026-05-27 03:03:04 -07:00