Les gestes d'une seconde — volume, musique, presse-papiers, capture, vitaux.
Atlas, panier « Ensuite », 24 août 2026. « Monte le son » n'avait aucun
outil : l'assistant passait par shell_exec — donc par la cloche, un clic et
jusqu'à quarante-cinq secondes d'attente pour un geste qu'une main fait en
une seconde. La jurisprudence est celle d'open_anything (desktop_tools.py) :
un geste VISIBLE et RÉVERSIBLE ne se gate pas derrière une approbation.
Chaque outil constate au lieu de proclamer : après une commande de lecture,
on redemande au lecteur son état réel ; la capture rend le chemin du fichier
qui existe ; les vitaux disent « illisible » plutôt que d'inventer. Les
fonctions de décision sont pures et testables sans matériel ; subprocess ne
s'appelle que via _run, que les tests remplacent.
Bases: BaseTool
Le volume de sortie du Mac — lire, régler, couper.
Bases: BaseTool
Pause, reprise, piste suivante/précédente — sur le lecteur en marche.
Bases: BaseTool
Ce que contient le presse-papiers, en texte.
Bases: BaseTool
Une capture d'écran, déposée sur le Bureau.
Bases: BaseTool
Batterie, Wi-Fi et disque en une phrase.
interpreter_volume(
sortie: str,
) -> tuple[Optional[int], bool]
(volume, coupé) depuis « 62, false » — (None, False) si illisible.
Source code in src/diapason/tools/gestes.py
| def interpreter_volume(sortie: str) -> tuple[Optional[int], bool]:
"""(volume, coupé) depuis « 62, false » — (None, False) si illisible."""
morceaux = [m.strip() for m in (sortie or "").strip().split(",")]
try:
volume = int(morceaux[0])
except (ValueError, IndexError):
return None, False
coupe = len(morceaux) > 1 and morceaux[1].lower() == "true"
return volume, coupe
|
lecteur_en_marche(runner=None) -> Optional[str]
Le premier lecteur dont le processus tourne — None sinon.
Source code in src/diapason/tools/gestes.py
| def lecteur_en_marche(runner=None) -> Optional[str]:
"""Le premier lecteur dont le processus tourne — None sinon."""
for lecteur in _LECTEURS:
if (runner or _run)(["pgrep", "-x", lecteur]).returncode == 0:
return lecteur
return None
|
interpreter_etat_lecteur(sortie: str) -> tuple[str, str]
(état, « Titre — Artiste ») — champs vides si le lecteur s'est tu.
Source code in src/diapason/tools/gestes.py
| def interpreter_etat_lecteur(sortie: str) -> tuple[str, str]:
"""(état, « Titre — Artiste ») — champs vides si le lecteur s'est tu."""
lignes = (sortie or "").strip().split("\n")
etat = lignes[0].strip().lower() if lignes else ""
piste = lignes[1].strip() if len(lignes) > 1 else ""
return etat, piste
|
interpreter_wifi(
sortie_getsummary: str, sortie_getifaddr: str
) -> str
La phrase réseau : nom du Wi-Fi, « connecté », ou « pas de réseau ».
Source code in src/diapason/tools/gestes.py
| def interpreter_wifi(sortie_getsummary: str, sortie_getifaddr: str) -> str:
"""La phrase réseau : nom du Wi-Fi, « connecté », ou « pas de réseau »."""
m = _SSID_RE.search(sortie_getsummary or "")
ssid = m.group(1).strip() if m else ""
if ssid and ssid != "<redacted>":
return f"Wi-Fi : {ssid}"
if (sortie_getifaddr or "").strip():
return "Réseau : connecté"
return "pas de réseau"
|
formater_disque(libre: int, total: int) -> str
« 210 Go libres sur 494 » — en Go décimaux, comme le Finder.
Source code in src/diapason/tools/gestes.py
| def formater_disque(libre: int, total: int) -> str:
"""« 210 Go libres sur 494 » — en Go décimaux, comme le Finder."""
return f"{libre / 1e9:.0f} Go libres sur {total / 1e9:.0f}"
|