83 lines
2.3 KiB
Python
83 lines
2.3 KiB
Python
import asyncio
|
|
import shutil
|
|
from pathlib import Path
|
|
|
|
import yaml
|
|
|
|
from app.models.proxy import ProxyDocument
|
|
|
|
|
|
def script_path_for(work_dir: Path, proxy: ProxyDocument) -> Path:
|
|
return work_dir / "addons" / f"{proxy.proxy_port}.py"
|
|
|
|
|
|
def conf_dir_for(work_dir: Path, proxy: ProxyDocument) -> Path:
|
|
return work_dir / "conf" / str(proxy.proxy_port)
|
|
|
|
|
|
def config_path_for(work_dir: Path, proxy: ProxyDocument) -> Path:
|
|
return conf_dir_for(work_dir, proxy) / "config.yaml"
|
|
|
|
|
|
def log_path_for(work_dir: Path, proxy: ProxyDocument) -> Path:
|
|
return work_dir / "logs" / f"{proxy.proxy_port}.log"
|
|
|
|
|
|
async def write_script(work_dir: Path, proxy: ProxyDocument) -> Path:
|
|
path = script_path_for(work_dir, proxy)
|
|
await asyncio.to_thread(path.parent.mkdir, parents=True, exist_ok=True)
|
|
await asyncio.to_thread(path.write_text, proxy.code, encoding="utf-8")
|
|
return path
|
|
|
|
|
|
async def write_config(work_dir: Path, proxy: ProxyDocument) -> Path:
|
|
path = config_path_for(work_dir, proxy)
|
|
await asyncio.to_thread(path.parent.mkdir, parents=True, exist_ok=True)
|
|
options = {"block_global": False, **proxy.mitm_options}
|
|
config_text = yaml.safe_dump(options, sort_keys=True)
|
|
await asyncio.to_thread(path.write_text, config_text, encoding="utf-8")
|
|
return path
|
|
|
|
|
|
async def ensure_log_path(work_dir: Path, proxy: ProxyDocument) -> Path:
|
|
path = log_path_for(work_dir, proxy)
|
|
await asyncio.to_thread(path.parent.mkdir, parents=True, exist_ok=True)
|
|
return path
|
|
|
|
|
|
async def read_log_tail(path: Path, limit: int = 4000) -> str:
|
|
if not await asyncio.to_thread(path.exists):
|
|
return ""
|
|
content = await asyncio.to_thread(
|
|
path.read_text,
|
|
encoding="utf-8",
|
|
errors="replace",
|
|
)
|
|
return content[-limit:].strip()
|
|
|
|
|
|
def remove_file(path: Path) -> None:
|
|
try:
|
|
path.unlink(missing_ok=True)
|
|
except OSError:
|
|
return
|
|
|
|
|
|
def remove_dir(path: Path) -> None:
|
|
try:
|
|
shutil.rmtree(path)
|
|
except FileNotFoundError:
|
|
return
|
|
except OSError:
|
|
return
|
|
|
|
|
|
def read_cmdline(pid: int) -> list[str]:
|
|
path = Path(f"/proc/{pid}/cmdline")
|
|
try:
|
|
raw = path.read_bytes()
|
|
except OSError:
|
|
return []
|
|
decoded = raw.decode("utf-8", errors="replace")
|
|
return [part for part in decoded.split("\x00") if part]
|