72 lines
1.9 KiB
Python
Executable File
72 lines
1.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import re
|
|
import subprocess
|
|
from functools import partial
|
|
from itertools import chain
|
|
from pathlib import Path
|
|
|
|
PASSWORD_STORE = Path(
|
|
os.environ.get("PASSWORD_STORE_DIR", Path("~/.password-store").expanduser())
|
|
)
|
|
|
|
cmd = partial(subprocess.run, capture_output=True, encoding="ascii")
|
|
|
|
|
|
def alias(server_name):
|
|
match server_name.rpartition("@"):
|
|
case [_, _, "salt"]:
|
|
return "cms/*cms-net-svcs"
|
|
case [_, _, ("iPad1" | "iPad2" | "iPad3")]:
|
|
return "cms/*ipads"
|
|
case [_, _, ("octopi-taz-6" | "octopi-lulzbot-mini")]:
|
|
return "cms/*octopi"
|
|
case _:
|
|
return server_name
|
|
|
|
|
|
def notify(summary: str, body: str) -> None:
|
|
subprocess.run(["notify-send", summary, body])
|
|
|
|
|
|
def rofi_select(options: list[str]) -> str:
|
|
options_str = "\n".join(options)
|
|
rofi = cmd(["rofi", "-dmenu"], input=options_str)
|
|
return rofi.stdout.strip()
|
|
|
|
|
|
def get_password(password_name: str) -> None:
|
|
pass_result = cmd(["pass", password_name])
|
|
password, _, _ = pass_result.stdout.partition("\n")
|
|
return password
|
|
|
|
|
|
def select_and_type(server_name: str) -> None:
|
|
files = chain(
|
|
PASSWORD_STORE.glob(f"servers/**/{server_name}.gpg"),
|
|
PASSWORD_STORE.glob(f"servers/**/*@{server_name}.gpg"),
|
|
)
|
|
file_list = list(
|
|
dict.fromkeys(str(f.relative_to(PASSWORD_STORE).with_suffix("")) for f in files)
|
|
)
|
|
|
|
selected = rofi_select(file_list)
|
|
password = get_password(selected)
|
|
|
|
subprocess.run(["xdotool", "type", password + "\n"])
|
|
|
|
|
|
window_name = cmd(["xdotool", "getactivewindow", "getwindowname"]).stdout.strip()
|
|
|
|
ssh_match = re.search(":(mosh|ssh) (?P<server>.*)", window_name)
|
|
if ssh_match:
|
|
server_name = alias(ssh_match.group("server"))
|
|
|
|
notify(f"Matched server '{server_name}'", f"Window name: {window_name}")
|
|
|
|
select_and_type(server_name)
|
|
|
|
else:
|
|
notify("Window name did not match any rules", f"Window name: {window_name}")
|