All checks were successful
Deploy / deploy (push) Successful in 30s
- Full FastAPI sync engine: master→replica document sync via paperless REST API - Web UI: dashboard, replicas, logs, settings (Jinja2 + HTMX + Pico CSS) - APScheduler background sync, SSE live log stream, Prometheus metrics - Fernet encryption for API tokens at rest - pngx.env credential file: written on save, pre-fills forms on load - Dockerfile with layer-cached uv build, Python healthcheck - docker-compose with host networking for Tailscale access - Gitea Actions workflow: version bump, secret injection, docker compose deploy Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
53 lines
1.6 KiB
Python
53 lines
1.6 KiB
Python
"""Read and write a plain-text pngx.env credential file alongside the database."""
|
|
from pathlib import Path
|
|
|
|
|
|
def _path() -> Path:
|
|
from .config import get_config
|
|
return Path(get_config().db_path).parent / "pngx.env"
|
|
|
|
|
|
def read() -> dict[str, str]:
|
|
"""Return all key=value pairs from pngx.env, ignoring comments/blanks."""
|
|
p = _path()
|
|
if not p.exists():
|
|
return {}
|
|
result: dict[str, str] = {}
|
|
for line in p.read_text().splitlines():
|
|
line = line.strip()
|
|
if not line or line.startswith("#"):
|
|
continue
|
|
if "=" in line:
|
|
key, _, value = line.partition("=")
|
|
result[key.strip()] = value.strip()
|
|
return result
|
|
|
|
|
|
def write(updates: dict[str, str]) -> None:
|
|
"""Merge updates into pngx.env, preserving unrelated existing lines."""
|
|
p = _path()
|
|
lines: list[str] = []
|
|
key_to_line: dict[str, int] = {}
|
|
|
|
if p.exists():
|
|
for i, line in enumerate(p.read_text().splitlines()):
|
|
stripped = line.strip()
|
|
if stripped and not stripped.startswith("#") and "=" in stripped:
|
|
k, _, _ = stripped.partition("=")
|
|
key_to_line[k.strip()] = i
|
|
lines.append(line)
|
|
|
|
for key, value in updates.items():
|
|
if key in key_to_line:
|
|
lines[key_to_line[key]] = f"{key}={value}"
|
|
else:
|
|
lines.append(f"{key}={value}")
|
|
|
|
p.write_text("\n".join(lines) + "\n")
|
|
|
|
|
|
def replica_keys(name: str) -> tuple[str, str]:
|
|
"""Return the env var names for a replica (URL key, token key)."""
|
|
safe = name.upper().replace(" ", "_").replace("-", "_")
|
|
return f"REPLICA_{safe}_URL", f"REPLICA_{safe}_TOKEN"
|