0.6.9: azione sulla copertina (P8) — il boost senza aprire l'app

Sulla copertina compare l'icona del boost (CoverAction). Una sola azione: la
documentazione Silica ammette piu' di una azione ma dice che lo stile delle app
di sistema ne mostra una. CoverBackground eredita da Cover, quindi l'elenco
dichiarato li' si attacca; l'icona e' iconSource (non icon.source del Button:
sbagliarlo non da' errore, l'icona semplicemente non compare). La riga in fondo
si ancora a Cover.coverActionArea, cosi' l'icona non la copre.

Nuovo controllo statico tests/cover_action_check.py: elenco figlio diretto del
Cover, una sola azione, icona che esiste, id del comando presente nella tabella
del bridge. Il componente e' nominato nella guida Silica dell'SDK di Carlo.
This commit is contained in:
Carlo
2026-10-11 11:35:49 +02:00
parent 1ac1617c2c
commit 2136122398
11 changed files with 164 additions and 14 deletions
+97
View File
@@ -0,0 +1,97 @@
#!/usr/bin/env python3
"""Controllo statico dell'azione sulla copertina (P8 del piano).
Verifica le regole che la documentazione Silica pone sulle azioni di copertina,
e che il componente sia usato come va usato:
- il `CoverActionList` sta come figlio diretto della copertina (qui la radice
e' `CoverBackground`, che eredita da `Cover`: e' li' che va dichiarato).
Un elenco annidato dentro un altro elemento non si attaccherebbe;
- al massimo una azione: la documentazione dice che due si possono avere, ma
che lo stile delle app di sistema ne mostra una;
- l'icona si dichiara con `iconSource` (non `icon.source`, che e' del
pulsante Button: sbagliarlo qui non da' errore, l'icona semplicemente non
compare);
- l'icona esiste davvero, risolta rispetto al file QML che definisce la
copertina;
- il comando che l'azione invia esiste nella tabella dei comandi del bridge
(un id sbagliato lo scoprirebbe solo il telefono, con un 400).
Non serve il kit Silica: legge i file. Uscita 0 = tutto a posto.
"""
import pathlib
import re
import sys
RADICE = pathlib.Path(__file__).resolve().parent.parent
COPERTINA = RADICE / "qml" / "cover" / "CoverPage.qml"
BRIDGE = RADICE / "bridge" / "aira_bridge.py"
def main():
if not COPERTINA.exists():
print("ESITO: manca %s" % COPERTINA)
return 1
testo = COPERTINA.read_text(encoding="utf-8")
righe = testo.splitlines()
problemi = []
radice = next((r.strip() for r in righe
if re.match(r"^[A-Z][A-Za-z]*\s*\{", r)), "")
if not re.match(r"CoverBackground|Cover\s*\{", radice):
problemi.append("la radice della copertina e' %r: le azioni vanno dentro "
"un Cover (CoverBackground eredita da Cover)" % radice[:40])
# il CoverActionList deve stare al primo livello dentro la radice
elenchi = [(i, r) for i, r in enumerate(righe) if re.match(r"^\s*CoverActionList\s*\{", r)]
if not elenchi:
print("nessuna azione sulla copertina: niente da controllare (0.6.8 e prima)")
return 0
for i, r in elenchi:
rientro = len(r) - len(r.lstrip())
if rientro != 4:
problemi.append("riga %d: il CoverActionList e' rientrato di %d spazi, "
"deve essere figlio diretto della copertina" % (i + 1, rientro))
azioni = [r for r in righe if re.match(r"^\s*CoverAction\s*\{", r)]
if len(azioni) > 1:
problemi.append("%d azioni: la documentazione Silica ne ammette piu' di una "
"ma lo stile delle app di sistema ne mostra una" % len(azioni))
if re.search(r"^\s*icon\.source\s*:", testo, re.M):
problemi.append("usa `iconSource`, non `icon.source`: `icon.source` e' del "
"pulsante Button e qui non darebbe errore, solo nessuna icona")
for m in re.finditer(r'iconSource\s*:\s*"([^"]+)"', testo):
icona = (COPERTINA.parent / m.group(1)).resolve()
if not icona.exists():
problemi.append("l'icona %s non esiste (risolta da %s)"
% (m.group(1), COPERTINA.name))
else:
print("icona: %s -> %s" % (m.group(1), icona.relative_to(RADICE)))
comandi = re.findall(r'sendCommand\("([^"]+)"', testo)
if not comandi:
problemi.append("l'azione non invia nessun comando: a che serve?")
for c in comandi:
if not BRIDGE.exists():
print("salto il controllo del comando %r: manca %s" % (c, BRIDGE))
continue
ponte = BRIDGE.read_text(encoding="utf-8")
if not re.search(r'"%s"\s*:' % re.escape(c), ponte):
problemi.append("il comando %r non e' nella tabella del bridge: "
"il telefono riceverebbe un 400" % c)
else:
print("comando: %s -> presente nel bridge" % c)
if problemi:
for p in problemi:
print("PROBLEMA: %s" % p)
print("ESITO: %d problemi sull'azione di copertina" % len(problemi))
return 1
print("ESITO: azione di copertina a posto")
return 0
if __name__ == "__main__":
sys.exit(main())