Merge pull request #246 from saphid/fix/framey-store-catalog-edges

Handle root tags and ambiguous Decky store IDs
This commit is contained in:
Alex Southwell authored and GitHub committed 2026-10-25 21:27:24 +00:00
commit e89ff39cff
3 files changed
+20 -3

No files matched your search

+4 -1
View File
@@ -82,7 +82,10 @@ The in-headset **Open official store** view loads the full official catalogue.
Search matches names, authors, and descriptions. Filters show non-root plugins
or installed plugins, and Previous/Next buttons browse 20 results per page.
The root label is a compatibility warning; other APIs are checked only when a
plugin is opened. The store still needs the managed Decky user service running
plugin is opened. Both `root` and `_root`
store tags mark a plugin as needing root, and duplicate store IDs are omitted
because an ID alone could select a different archive than the visible row.
The store still needs the managed Decky user service running
before its Install or Update buttons are enabled. If a plugin prevents Decky
from starting, Remove remains available for Frame Control-owned plugins while
the managed service is stopped; it does not restart the service.
+9
View File
@@ -41,6 +41,15 @@ class ArchiveTests(unittest.TestCase):
with patch.object(frame_decky_store.urllib.request, 'urlopen', return_value=io.BytesIO(json.dumps(records).encode())):
self.assertEqual([(p['id'], p['author']) for p in frame_decky_store.catalog()], [(42, 'Panel Author')])
def test_catalog_marks_underscore_root_and_omits_ambiguous_store_ids(self):
records = [{'id': 42, 'name': 'Needs root', 'tags': ['_root'],
'versions': [{'name': '1.0', 'hash': 'a' * 64}]},
{'id': 43, 'name': 'First', 'versions': [{'name': '1.0', 'hash': 'b' * 64}]},
{'id': 43, 'name': 'Second', 'versions': [{'name': '2.0', 'hash': 'c' * 64}]}]
with patch.object(frame_decky_store.urllib.request, 'urlopen',
return_value=io.BytesIO(json.dumps(records).encode())):
self.assertEqual([(p['id'], p['root']) for p in frame_decky_store.catalog()], [(42, True)])
def test_accepts_hashed_non_root_archive(self):
data, digest = archive()
self.assertEqual(frame_decky_store.archive_info(data, digest, 'Example'), 'Example')
+7 -2
View File
@@ -59,8 +59,13 @@ def catalog():
'description': str(item.get('description') or '')[:300],
'author': author[:100],
'version': latest['name'][:40], 'sha256': latest['hash'],
'root': 'root' in tags})
return result
'root': 'root' in tags or '_root' in tags})
# A repeated store ID makes a clicked row ambiguous: change() resolves by ID
# and could install a different archive than the one the user reviewed.
counts = {}
for item in result:
counts[item['id']] = counts.get(item['id'], 0) + 1
return [item for item in result if counts[item['id']] == 1]
def archive_info(data, expected_hash, expected_name):