mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-21 18:01:54 +02:00
PostHog (0.4.0): Grayjay installs failed twice with apk_wrong_abi, once with an armeabi-v7a file and once with an x86_64 file. Grayjay's own site offers one APK per ABI; the FUTO F-Droid repo's Grayjay 391 is universal and does contain arm64-v8a, and the catalogue and repo search already drop builds without arm64-v8a, so the wrong files did not come from those paths. - The wrong-ABI error now tells the user to download the arm64-v8a (or arm64, or universal) APK instead, so they don't guess again. - An install_failed report caused by a wrong-ABI (or too-new-Android) file no longer rates the whole app as broken in the catalogue. - Search results and details carry the compatibility reports the catalogue uses: "Reported not working on the Frame" (a warning, not a block) or "Works on the Frame". A report never overrides a hard blocker. - Tests: per-ABI split builds (offer and download the arm64 one), the new error text and its telemetry category, wrong-file reports, and search verdicts from reports, with the database hook off by default in tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
48 lines
2.0 KiB
Python
48 lines
2.0 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.
|
||
|
||
An install_failed report saying the file had no arm64-v8a build (or needed a
|
||
newer Android) is about that one APK file, often the wrong per-ABI download of
|
||
an app that has an arm64 build, so it says nothing about the app and is left out.
|
||
"""
|
||
import re
|
||
|
||
FILE_FAULT = re.compile(r'no arm64-v8a build|needs Android API')
|
||
|
||
|
||
def about_app(r):
|
||
"""False for reports about one wrong APK file rather than the app itself."""
|
||
return not (r.get('result') == 'install_failed' and not r.get('rating')
|
||
and FILE_FAULT.search(r.get('notes') or ''))
|
||
|
||
|
||
def verdict(reports):
|
||
"""(verdict, summary lines) for one package's reports, or None."""
|
||
reports = [r for r in reports or () if about_app(r)]
|
||
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
|