mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-14 11:06:13 +05:00
- 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>
88 lines
3.2 KiB
Python
88 lines
3.2 KiB
Python
__package__ = "archivebox"
|
|
|
|
|
|
import datetime
|
|
import re
|
|
import warnings
|
|
|
|
from daphne import access
|
|
import django_stubs_ext
|
|
from django.utils import timezone
|
|
|
|
django_stubs_ext.monkeypatch()
|
|
|
|
|
|
# monkey patch django timezone to add back utc (it was removed in Django 5.0)
|
|
setattr(timezone, "utc", datetime.UTC)
|
|
|
|
# monkey patch django-signals-webhooks to change how it shows up in Admin UI
|
|
# from signal_webhooks.apps import DjangoSignalWebhooksConfig
|
|
# DjangoSignalWebhooksConfig.verbose_name = 'API'
|
|
|
|
|
|
# Rich traceback handler disabled - it adds frames/boxes that wrap weirdly in log files
|
|
# Standard Python tracebacks are used instead (full width, no frames)
|
|
# from rich.traceback import install
|
|
# install(show_locals=True, word_wrap=False, ...)
|
|
|
|
|
|
# Hide site-packages/sonic/client.py:115: SyntaxWarning
|
|
# https://github.com/xmonader/python-sonic-client/pull/18
|
|
warnings.filterwarnings("ignore", category=SyntaxWarning, module="sonic")
|
|
|
|
|
|
SENSITIVE_QUERY_PARAM_RE = re.compile(r"(?i)([?&](?:api_key|token|access_token|password|secret)=)([^&#\s]+)")
|
|
|
|
|
|
# Make daphne log requests quieter and easier to read
|
|
class ModifiedAccessLogGenerator(access.AccessLogGenerator):
|
|
"""Clutge workaround until daphne uses the Python logging framework. https://github.com/django/daphne/pull/473/files"""
|
|
|
|
def __call__(self, protocol, action, details):
|
|
if protocol == "http" and action == "complete":
|
|
self.write_entry(
|
|
host=details["client"],
|
|
date=datetime.datetime.now(),
|
|
request="%(method)s %(path)s" % details,
|
|
status=details["status"],
|
|
length=details["size"],
|
|
time_taken=details.get("time_taken"),
|
|
)
|
|
return
|
|
return super().__call__(protocol, action, details)
|
|
|
|
def write_entry(self, host, date, request, status=None, length=None, ident=None, user=None, time_taken=None):
|
|
request = SENSITIVE_QUERY_PARAM_RE.sub(r"\1[REDACTED]", request)
|
|
|
|
# Ignore noisy requests to staticfiles / favicons / etc.
|
|
if "GET /static/" in request:
|
|
return
|
|
if "GET /health/" in request:
|
|
return
|
|
if "GET /progress.json" in request and (time_taken is None or time_taken < 1.0):
|
|
return
|
|
if "GET /api/v1/crawls/crawl/" in request and "/files/chrome_screencast/latest.jpg" in request:
|
|
return
|
|
if "GET /admin/jsi18n/" in request:
|
|
return
|
|
if request.endswith("/favicon.ico") or request.endswith("/robots.txt") or request.endswith("/screenshot.png"):
|
|
return
|
|
if request.endswith(".css") or request.endswith(".js") or request.endswith(".woff") or request.endswith(".ttf"):
|
|
return
|
|
if str(status) in ("404", "304"):
|
|
return
|
|
|
|
# clean up the log format to mostly match the same format as django.conf.settings.LOGGING rich formats
|
|
self.stream.write(
|
|
"%s HTTP %s %s %s\n"
|
|
% (
|
|
date.strftime("%Y-%m-%d %H:%M:%S"),
|
|
request,
|
|
status or "-",
|
|
"localhost" if host.startswith("127.") else host.split(":")[0],
|
|
),
|
|
)
|
|
|
|
|
|
access.AccessLogGenerator.write_entry = ModifiedAccessLogGenerator.write_entry # type: ignore
|