81 lines
2.0 KiB
Python
81 lines
2.0 KiB
Python
import hashlib
|
|
import os
|
|
import pathlib
|
|
import re
|
|
import socket
|
|
from typing import Optional
|
|
|
|
from .constants import HTTPS_PORTS
|
|
|
|
|
|
def ensure_dir(path: pathlib.Path) -> None:
|
|
path.mkdir(parents=True, exist_ok=True)
|
|
|
|
|
|
def sha256_file(path: pathlib.Path) -> str:
|
|
h = hashlib.sha256()
|
|
with path.open("rb") as f:
|
|
for chunk in iter(lambda: f.read(1024 * 1024), b""):
|
|
h.update(chunk)
|
|
return h.hexdigest()
|
|
|
|
|
|
def normalize_path(path: Optional[str]) -> str:
|
|
"""Normalize optional service path. Empty -> ''. Ensure leading slash."""
|
|
if not path:
|
|
return ""
|
|
p = str(path).strip()
|
|
if not p:
|
|
return ""
|
|
if not p.startswith("/"):
|
|
p = "/" + p
|
|
return p
|
|
|
|
|
|
def default_host() -> str:
|
|
"""Return preferred hostname (append .local if bare)."""
|
|
host = socket.gethostname()
|
|
if "." not in host:
|
|
host = f"{host}.local"
|
|
return host
|
|
|
|
|
|
def detect_https(host: str, port: int) -> bool:
|
|
"""Heuristic: known HTTPS ports or .local certs."""
|
|
return int(port) in HTTPS_PORTS or host.lower().endswith(".local") or host.lower() == "pikit"
|
|
|
|
|
|
def port_online(host: str, port: int) -> bool:
|
|
try:
|
|
with socket.create_connection((host, int(port)), timeout=1.5):
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
def reboot_required() -> bool:
|
|
return pathlib.Path("/run/reboot-required").exists()
|
|
|
|
|
|
def strip_comments(text: str) -> str:
|
|
"""Remove // and # line comments for safer parsing."""
|
|
lines = []
|
|
for ln in text.splitlines():
|
|
l = ln.strip()
|
|
if l.startswith("//") or l.startswith("#"):
|
|
continue
|
|
lines.append(ln)
|
|
return "\n".join(lines)
|
|
|
|
|
|
def validate_time(val: str, default: str) -> str:
|
|
if not val:
|
|
return default
|
|
m = re.match(r"^(\d{1,2}):(\d{2})$", val.strip())
|
|
if not m:
|
|
return default
|
|
h, mi = int(m.group(1)), int(m.group(2))
|
|
if 0 <= h < 24 and 0 <= mi < 60:
|
|
return f"{h:02d}:{mi:02d}"
|
|
return default
|