64 lines
1.8 KiB
Python
Executable file
64 lines
1.8 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
import subprocess
|
|
import re
|
|
|
|
def parse_wpctl_status():
|
|
devices = []
|
|
current_section = None
|
|
|
|
output = subprocess.run(["wpctl", "status"], capture_output=True, text=True).stdout.splitlines()
|
|
|
|
for line in output:
|
|
line = line.rstrip()
|
|
|
|
if "Sinks:" in line:
|
|
current_section = "sink"
|
|
continue
|
|
elif "Sources:" in line:
|
|
current_section = "source"
|
|
continue
|
|
elif re.match(r"^[^\s]", line):
|
|
current_section = None
|
|
|
|
if current_section:
|
|
m = re.search(r"\*\s*|\s*(\d+)\.\s+(.*?)\s+\[vol:", line)
|
|
if m:
|
|
id_match = re.search(r"(\d+)\.", line)
|
|
dev_id = id_match.group(1) if id_match else None
|
|
name_match = re.search(r"\d+\.\s+(.*?)\s+\[vol:", line)
|
|
name = name_match.group(1) if name_match else None
|
|
|
|
if dev_id and name:
|
|
devices.append((current_section, dev_id, name))
|
|
|
|
return devices
|
|
|
|
def main():
|
|
devices = parse_wpctl_status()
|
|
if not devices:
|
|
print("No devices found.")
|
|
return
|
|
|
|
# Prepare choices and a mapping from display line to device ID
|
|
choices = []
|
|
id_map = {}
|
|
|
|
for dev_type, dev_id, name in devices:
|
|
label = "O" if dev_type == "sink" else "I"
|
|
line = f"{label} {name}"
|
|
choices.append(line)
|
|
id_map[line] = dev_id
|
|
|
|
result = subprocess.run(["tofi"], input="\n".join(choices), capture_output=True, text=True)
|
|
choice = result.stdout.strip()
|
|
if not choice:
|
|
return
|
|
|
|
selected_id = id_map.get(choice)
|
|
if selected_id:
|
|
subprocess.run(["wpctl", "set-default", selected_id])
|
|
subprocess.run(["notify-send", f"Set default device to {choice}"])
|
|
|
|
if __name__ == "__main__":
|
|
main()
|