mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-14 11:06:13 +05:00
release: archivebox 0.9.31rc27
This commit is contained in:
parent
02a6cb91cd
commit
035132ded5
17
Dockerfile
17
Dockerfile
@ -205,7 +205,7 @@ RUN --mount=type=cache,target=/root/.npm,sharing=locked,id=npm-$TARGETARCH$TARGE
|
||||
|
||||
# Set up uv and main app /venv
|
||||
RUN curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/bin sh
|
||||
ENV UV_COMPILE_BYTECODE=1 \
|
||||
ENV UV_COMPILE_BYTECODE=0 \
|
||||
UV_PYTHON_PREFERENCE=managed \
|
||||
UV_PYTHON_INSTALL_DIR=/opt/uv/python \
|
||||
UV_LINK_MODE=copy \
|
||||
@ -268,6 +268,7 @@ RUN --mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml \
|
||||
&& apt-get install -qq -y --no-install-recommends build-essential gcc python3-dev \
|
||||
&& uv sync \
|
||||
--no-cache \
|
||||
--no-dev \
|
||||
--inexact \
|
||||
--all-extras \
|
||||
--no-install-project \
|
||||
@ -275,6 +276,8 @@ RUN --mount=type=bind,source=pyproject.toml,target=/app/pyproject.toml \
|
||||
--no-sources \
|
||||
&& apt-get purge -y python3-dev build-essential gcc \
|
||||
&& apt-get autoremove -y \
|
||||
&& find /venv -type d -name __pycache__ -prune -exec rm -rf {} + \
|
||||
&& find /venv -type f \( -name '*.pyc' -o -name '*.pyo' \) -delete \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
# installs the pip packages that archivebox depends on, defined in pyproject.toml dependencies
|
||||
|
||||
@ -289,7 +292,9 @@ RUN --mount=type=cache,target=/root/.cache/uv,sharing=locked,id=uv-$TARGETARCH$T
|
||||
pip show archivebox \
|
||||
&& which archivebox \
|
||||
&& echo -e '\n\n' \
|
||||
) | tee -a /VERSION.txt
|
||||
) | tee -a /VERSION.txt \
|
||||
&& find /venv "$CODE_DIR" -type d -name __pycache__ -prune -exec rm -rf {} + \
|
||||
&& find /venv "$CODE_DIR" -type f \( -name '*.pyc' -o -name '*.pyo' \) -delete
|
||||
# installs archivebox itself, and any other vendored packages in pkgs/*, defined in pyproject.toml workspaces
|
||||
|
||||
####################################################
|
||||
@ -319,6 +324,9 @@ RUN openssl rand -hex 16 > /etc/machine-id \
|
||||
# returned to the runtime archivebox user.
|
||||
RUN echo "[+] Initializing image collection and installing plugin runtime dependencies into $LIB_DIR..." \
|
||||
&& PUID=0 PGID=0 archivebox init --install \
|
||||
&& find /venv "$CODE_DIR" "$LIB_DIR" "$DATA_DIR" -type d -name __pycache__ -prune -exec rm -rf {} + \
|
||||
&& find /venv "$CODE_DIR" "$LIB_DIR" "$DATA_DIR" -type f \( -name '*.pyc' -o -name '*.pyo' \) -delete \
|
||||
&& rm -rf /root/.cache /var/cache/apt/* /var/lib/apt/lists/* \
|
||||
&& (chown "$DEFAULT_PUID:$DEFAULT_PGID" "$DATA_DIR" "$DATA_DIR"/logs "$DATA_DIR"/sources "$DATA_DIR"/archive "$DATA_DIR"/archive/users "$DATA_DIR"/personas "$DATA_DIR"/index.sqlite3 "$DATA_DIR"/ArchiveBox.conf 2>/dev/null || true) \
|
||||
&& chown -R "$DEFAULT_PUID:$DEFAULT_PGID" "$LIB_DIR"
|
||||
|
||||
@ -330,7 +338,10 @@ RUN (echo -e "\n\n[√] Finished Docker build successfully. Saving build summary
|
||||
|
||||
# Verify ArchiveBox is installed and write full version/dependency info.
|
||||
RUN chmod +x "$CODE_DIR"/bin/*.sh \
|
||||
&& gosu "$ARCHIVEBOX_USER" archivebox version 2>&1 | tee -a /VERSION.txt
|
||||
&& gosu "$ARCHIVEBOX_USER" archivebox version 2>&1 | tee -a /VERSION.txt \
|
||||
&& find /venv "$CODE_DIR" "$LIB_DIR" "$DATA_DIR" -type d -name __pycache__ -prune -exec rm -rf {} + \
|
||||
&& find /venv "$CODE_DIR" "$LIB_DIR" "$DATA_DIR" -type f \( -name '*.pyc' -o -name '*.pyo' \) -delete \
|
||||
&& rm -rf /root/.cache /var/cache/apt/* /var/lib/apt/lists/*
|
||||
|
||||
####################################################
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ __package__ = "archivebox.core"
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from django.contrib import admin
|
||||
from django.db import DatabaseError, connection
|
||||
from admin_data_views.admin import (
|
||||
admin_data_index_view as adv_admin_data_index_view,
|
||||
get_admin_data_urls as adv_get_admin_data_urls,
|
||||
@ -31,6 +32,51 @@ class ArchiveBoxAdmin(admin.AdminSite):
|
||||
def admin_data_index_view(self, request: "HttpRequest", **kwargs: Any) -> "TemplateResponse":
|
||||
return adv_admin_data_index_view(self, request, **kwargs)
|
||||
|
||||
def index(self, request: "HttpRequest", extra_context: dict[str, Any] | None = None) -> "TemplateResponse":
|
||||
response = super().index(request, extra_context)
|
||||
if connection.vendor != "sqlite":
|
||||
return response
|
||||
|
||||
models_by_table: dict[str, list[dict[str, Any]]] = {}
|
||||
for app in response.context_data.get("app_list", []):
|
||||
for model in app.get("models", []):
|
||||
model_class = model.get("model")
|
||||
if not model_class or not model.get("perms", {}).get("view"):
|
||||
continue
|
||||
models_by_table.setdefault(model_class._meta.db_table, []).append(model)
|
||||
|
||||
if not models_by_table:
|
||||
return response
|
||||
|
||||
try:
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute("SELECT tbl, stat FROM sqlite_stat1")
|
||||
for table, stat in cursor.fetchall():
|
||||
models = models_by_table.get(table)
|
||||
if not models:
|
||||
continue
|
||||
try:
|
||||
count = int(str(stat).split()[0])
|
||||
except (IndexError, TypeError, ValueError):
|
||||
continue
|
||||
if count >= 1_000_000_000:
|
||||
count_label = f"~{count / 1_000_000_000:.1f}B"
|
||||
elif count >= 1_000_000:
|
||||
count_label = f"~{count / 1_000_000:.1f}M"
|
||||
elif count >= 1_000:
|
||||
count_label = f"~{count / 1_000:.1f}K"
|
||||
else:
|
||||
count_label = f"~{count:,}"
|
||||
count_label = count_label.replace(".0", "")
|
||||
for model in models:
|
||||
model["object_count"] = count
|
||||
model["object_count_label"] = count_label
|
||||
model["object_count_title"] = f"Approximate count from SQLite stats: {count:,}"
|
||||
models_by_table.pop(table, None)
|
||||
except DatabaseError:
|
||||
pass
|
||||
return response
|
||||
|
||||
def get_admin_data_urls(self) -> list["URLResolver | URLPattern"]:
|
||||
return adv_get_admin_data_urls(self)
|
||||
|
||||
|
||||
@ -271,6 +271,13 @@
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.abx-admin-card__title-row {
|
||||
display: flex;
|
||||
gap: 7px;
|
||||
align-items: baseline;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
#content .abx-admin-card__title {
|
||||
color: var(--abx-ink) !important;
|
||||
font-size: 15px;
|
||||
@ -279,6 +286,22 @@
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.abx-admin-card__count {
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
align-items: center;
|
||||
min-height: 16px;
|
||||
padding: 0 5px;
|
||||
color: var(--abx-ink-4);
|
||||
background: rgba(28, 24, 20, .035);
|
||||
border: 1px solid rgba(28, 24, 20, .08);
|
||||
border-radius: 999px;
|
||||
font-family: var(--abx-font-mono);
|
||||
font-size: 10px;
|
||||
font-weight: 650;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.abx-admin-card__text {
|
||||
color: var(--abx-ink-3);
|
||||
font-size: 12px;
|
||||
|
||||
@ -50,7 +50,12 @@
|
||||
</svg>
|
||||
</span>
|
||||
<span class="abx-admin-card__copy">
|
||||
<strong class="abx-admin-card__title">{{ model.name }}</strong>
|
||||
<span class="abx-admin-card__title-row">
|
||||
<strong class="abx-admin-card__title">{{ model.name }}</strong>
|
||||
{% if model.object_count_label %}
|
||||
<span class="abx-admin-card__count" title="{{ model.object_count_title }}">{{ model.object_count_label }}</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
<span class="abx-admin-card__text">
|
||||
{% if model.object_name == "Crawl" %}
|
||||
Create and monitor URL collection jobs.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "archivebox"
|
||||
version = "0.9.31rc26"
|
||||
version = "0.9.31rc27"
|
||||
requires-python = ">=3.13"
|
||||
description = "Self-hosted internet archiving solution."
|
||||
authors = [{name = "Nick Sweeting", email = "pyproject.toml@archivebox.io"}]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user