#!/usr/bin/env python3 """ opp-dm.py: Operator Direct Messages (fixed) Works from container OR from bl directly. Detects environment and acts accordingly. Verifies writes. For operator-to-operator: 646, operator-main. """ import argparse import subprocess import sys import os import datetime from pathlib import Path # Detect if we're on bl (has /home/super/Projects/NetVM) ON_BL = Path("/home/super/Projects/NetVM").exists() BL_MSG_DIR = Path("/home/super/Projects/NetVM/opp-dms") def bl_run_container(cmd): """Run on bl via SSH chain (from container).""" full = f"ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes super@100.123.153.75 '{cmd}'" vm_cmd = f"ssh -i ~/.ssh/vm_to_gcp -o ProxyCommand=\"$HOME/workspace/bin/ssh-via-proxy %h %p\" -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes super@34.139.37.135 \"{full}\"" result = subprocess.run(vm_cmd, shell=True, capture_output=True, text=True, timeout=30) return result.stdout.strip(), result.returncode def opp_send(to, message, from_who="operator-main"): """Send operator DM. Works from container or bl.""" if to not in ["646", "operator-main"]: print(f"ERROR: Unknown operator {to}", file=sys.stderr) sys.exit(1) ts = datetime.datetime.now().isoformat() safe = message.replace("'", "'\"'\"'")[:1000] line = f"{ts} [{from_who}]: {safe}" if ON_BL: # Direct write (we're on bl) BL_MSG_DIR.mkdir(parents=True, exist_ok=True) logfile = BL_MSG_DIR / f"{to}.log" with open(logfile, "a") as f: f.write(line + "\n") # Verify if logfile.exists(): print(f"OPP-DM sent to {to} (verified)") return True else: print(f"ERROR: Write failed", file=sys.stderr) sys.exit(1) else: # Via SSH (from container) cmd = f"mkdir -p {BL_MSG_DIR} && echo '{line}' >> {BL_MSG_DIR}/{to}.log && test -f {BL_MSG_DIR}/{to}.log && echo OK" out, rc = bl_run_container(cmd) if rc == 0 and "OK" in out: print(f"OPP-DM sent to {to} (verified)") return True else: print(f"ERROR: Send failed: {out}", file=sys.stderr) sys.exit(1) def opp_read(who="operator-main", n=5): """Read operator DMs. Works from container or bl.""" if who not in ["646", "operator-main"]: print(f"ERROR: Unknown operator {who}", file=sys.stderr) sys.exit(1) if ON_BL: logfile = BL_MSG_DIR / f"{who}.log" if not logfile.exists(): print("no messages") return with open(logfile) as f: lines = f.readlines() for l in lines[-n:]: print(l.strip()) else: cmd = f"tail -n {n} {BL_MSG_DIR}/{who}.log 2>/dev/null || echo 'no messages'" out, rc = bl_run_container(cmd) print(out) def main(): p = argparse.ArgumentParser(description="OPP-DM: Operator DMs (fixed)") sub = p.add_subparsers(dest='cmd', required=True) ps = sub.add_parser('send', help='Send operator DM') ps.add_argument('--to', required=True, choices=['646', 'operator-main']) ps.add_argument('--from', dest='from_who', default='operator-main') ps.add_argument('message', help='Message') ps.set_defaults(func=lambda a: opp_send(a.to, a.message, a.from_who)) pr = sub.add_parser('read', help='Read operator DMs') pr.add_argument('--who', default='operator-main', choices=['646', 'operator-main']) pr.add_argument('--n', type=int, default=5) pr.set_defaults(func=lambda a: opp_read(a.who, a.n)) args = p.parse_args() args.func(args) if __name__ == '__main__': main()