75 lines
1.9 KiB
Python
Executable File
75 lines
1.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import configparser
|
|
import json
|
|
import os
|
|
import pathlib
|
|
import shlex
|
|
|
|
SEARCH_DIRS = [
|
|
"/usr/share/wayland-sessions",
|
|
"/usr/local/share/wayland-sessions",
|
|
os.path.expanduser("~/.local/share/wayland-sessions"),
|
|
"/usr/share/xsessions",
|
|
"/usr/local/share/xsessions",
|
|
os.path.expanduser("~/.local/share/xsessions"),
|
|
]
|
|
|
|
def clean_exec(exec_string: str):
|
|
parts = shlex.split(exec_string)
|
|
out = []
|
|
|
|
for part in parts:
|
|
if part == "%%":
|
|
out.append("%")
|
|
elif part.startswith("%"):
|
|
# ignore desktop-entry field codes for login sessions
|
|
continue
|
|
else:
|
|
out.append(part)
|
|
|
|
return out
|
|
|
|
def truthy(value: str) -> bool:
|
|
return value.strip().lower() in {"1", "true", "yes"}
|
|
|
|
sessions = []
|
|
|
|
for directory in SEARCH_DIRS:
|
|
kind = "wayland" if "wayland-sessions" in directory else "x11"
|
|
base = pathlib.Path(directory)
|
|
|
|
if not base.is_dir():
|
|
continue
|
|
|
|
for file in sorted(base.glob("*.desktop")):
|
|
parser = configparser.ConfigParser(interpolation=None, strict=False)
|
|
parser.read(file, encoding="utf-8")
|
|
|
|
if "Desktop Entry" not in parser:
|
|
continue
|
|
|
|
entry = parser["Desktop Entry"]
|
|
|
|
if entry.get("Type", "Application") != "Application":
|
|
continue
|
|
if truthy(entry.get("Hidden", "false")):
|
|
continue
|
|
if truthy(entry.get("NoDisplay", "false")):
|
|
continue
|
|
|
|
exec_string = entry.get("Exec", "").strip()
|
|
if not exec_string:
|
|
continue
|
|
|
|
sessions.append({
|
|
"id": file.stem,
|
|
"name": entry.get("Name", file.stem),
|
|
"comment": entry.get("Comment", ""),
|
|
"icon": entry.get("Icon", ""),
|
|
"kind": kind,
|
|
"desktopFile": str(file),
|
|
"command": clean_exec(exec_string),
|
|
})
|
|
|
|
print(json.dumps(sessions))
|