59 lines
1.4 KiB
Python
59 lines
1.4 KiB
Python
from datetime import datetime, timezone
|
|
from typing import Optional
|
|
import json
|
|
import subprocess
|
|
from services.runner import run_cmd
|
|
|
|
|
|
def backup_badge(last_time: datetime) -> str:
|
|
age = datetime.now(timezone.utc) - last_time
|
|
hours = age.total_seconds() / 3600
|
|
|
|
if hours < 24:
|
|
return "🟢 Backup: OK"
|
|
if hours < 72:
|
|
return "🟡 Backup: stale"
|
|
return "🔴 Backup: OLD"
|
|
|
|
|
|
async def get_last_snapshot() -> Optional[dict]:
|
|
rc, raw = await run_cmd(
|
|
["restic", "snapshots", "--json"],
|
|
use_restic_env=True,
|
|
timeout=20
|
|
)
|
|
if rc != 0:
|
|
return None
|
|
|
|
snaps = json.loads(raw)
|
|
if not snaps:
|
|
return None
|
|
|
|
snaps.sort(key=lambda s: s["time"], reverse=True)
|
|
return snaps[0]
|
|
|
|
|
|
def last_backup() -> str:
|
|
out = subprocess.check_output(
|
|
["restic", "snapshots", "--json"],
|
|
env=None
|
|
).decode()
|
|
snaps = json.loads(out)
|
|
snaps.sort(key=lambda s: s["time"], reverse=True)
|
|
s = snaps[0]
|
|
t = datetime.fromisoformat(s["time"].replace("Z", ""))
|
|
return (
|
|
"📦 Last backup\n\n"
|
|
f"🕒 {t:%Y-%m-%d %H:%M}\n"
|
|
f"🧉 ID: {s['short_id']}\n"
|
|
f"📁 Paths: {len(s['paths'])}"
|
|
)
|
|
|
|
|
|
def restore_help() -> str:
|
|
return (
|
|
"🧯 Restore help\n\n"
|
|
"Example:\n"
|
|
"restic restore <snapshot_id> --target /restore"
|
|
)
|