mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 11:00:55 +02:00
Package the Frame Control web UI as an installable Electron Mac app and bring in the tooling built alongside it. - app/: Electron wrapper that starts ui/server.py on a free loopback port, hardened window (sandbox, no navigation, runAsNode fuse off), login-shell PATH so Homebrew tools work from Finder, first-run offer to run connect.sh, ad-hoc signed DMG/zip via electron-builder. - ui/: headset view (OpenVR screenshots), device status, library, Steam "Get games" (owned games, install, store search), Android apps as persistent Lepton instances with a rated F-Droid catalogue and a private compatibility database, Android display controls over ADB, file and clipboard transfer, Flatpaks, remote and power actions. - apk-catalog/, compat-db/, frame/: catalogue build pipeline, Lakebed capsule for compatibility reports, Frame-side launchers. - tests/ and CI: server guard and validation tests plus Steam helper tests, run on Python 3.9 with script and app syntax checks. - Docs: README leads with the Mac app; new Android, panels, Steam games and field-notes docs; security notes on LAN-exposed ADB ports. Screenshot values for the headset's IP and Wi-Fi name are placeholders. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
34 lines
1.4 KiB
Python
34 lines
1.4 KiB
Python
"""How compatibility reports turn into a verdict. The reports themselves live
|
||
in Frame Control's private database (ui/frame_compat_db.py, a Lakebed capsule
|
||
in compat-db/); this module is the pure logic shared by the build and the app.
|
||
|
||
A report: package, version, result (runs | crashes | install_failed |
|
||
instance_failed, from an automated test), rating (works | issues | broken, from
|
||
a person), notes, via (harness | probe | user), date, steamos, lepton, runtime.
|
||
Newest wins, and a person's rating beats an automated result.
|
||
"""
|
||
|
||
|
||
def verdict(reports):
|
||
"""(verdict, summary lines) for one package's reports, or None."""
|
||
if not reports:
|
||
return None
|
||
rs = sorted(reports, key=lambda r: r.get('date') or '')
|
||
people = [r for r in rs if r.get('rating')]
|
||
best = people[-1] if people else rs[-1]
|
||
kind = best.get('rating') or best.get('result')
|
||
v = {'works': 'works', 'runs': 'works', 'issues': 'maybe'}.get(kind, 'no')
|
||
n_ok = sum((r.get('rating') or r.get('result')) in ('works', 'runs') for r in rs)
|
||
lines = [f"Reported on a Frame {(best.get('date') or '')[:10]} (v{best.get('version')}): "
|
||
f"{kind}{' – ' + best['notes'] if best.get('notes') else ''}"]
|
||
if len(rs) > 1:
|
||
lines.append(f'{len(rs)} reports, {n_ok} working')
|
||
return v, lines
|
||
|
||
|
||
def by_package(reports):
|
||
out = {}
|
||
for r in reports:
|
||
out.setdefault(r['package'], []).append(r)
|
||
return out
|