Add publisher artwork to GitHub APK source entries

Include curated app images and summaries, owner avatars and social banners for topic discovery, and fixture coverage for artwork preservation.

Co-Authored-By: GPT-6 Astra <noreply@openai.com>
This commit is contained in:
saphidandGPT-6 Astra committed 2026-09-28 21:24:55 +10:00
1 parent 113216cc0e
commit 41684e2d90
9 files changed
+225 -17

No files matched your search

+8
View File
@@ -13,3 +13,11 @@ values are unchanged. No token, cookies or signed download URL is included.
The synthetic ZIP in tests is only a transport/integrity fixture, not an
installable APK. Actual APK parsing was verified separately on the downloaded
Khronos Vulkan sample; see docs/apk-sources.md.
Artwork follow-up: `topic.json` now retains `owner.avatar_url` from authenticated
repository API reads. `artwork-check.json` records HTTPS response status,
Content-Type and image magic checks for all curated URLs and three topic
results. All curated URLs returned real images; LWJGL's social preview returned
HTTP 429. This fixture is evidence of a point-in-time check, not an uptime test.
Open Brush screenshots came from the Steam appdetails response for app 1634870,
linked by its README. SuperTux's README links the recorded upstream screenshot.
+90
View File
@@ -0,0 +1,90 @@
[
{
"url": "https://avatars.githubusercontent.com/u/2757344?v=4",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://avatars.githubusercontent.com/u/784805?v=4",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://avatars.githubusercontent.com/u/94376830?v=4",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://opengraph.githubassets.com/1/KhronosGroup/OpenXR-SDK-Source",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://opengraph.githubassets.com/1/LWJGL/lwjgl3",
"error": "HTTP Error 429: Too Many Requests"
},
{
"url": "https://opengraph.githubassets.com/1/bjornbytes/lovr",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://opengraph.githubassets.com/1/sahibzada-allahyar/YC-Killer",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://raw.githubusercontent.com/KhronosGroup/OpenXR-SDK-Source/3ed64d0f9bb680f24b80a085091e5c8fab38f7b7/src/tests/hello_xr/android_resources/vulkan/mipmap-xxxhdpi/ic_helloxr_launcher.png",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://raw.githubusercontent.com/SgtBilko76/SuperTux-3D/1955493ee6f1000e048c58db40d4904df827210e/data/images/engine/icons/supertux-256x256.png",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://raw.githubusercontent.com/icosa-foundation/open-brush/56acbce831c7e9f257bfee9e21853da99773787b/Assets/Resources/DefaultImages/OpenBrushLogo.png",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://raw.githubusercontent.com/icosa-foundation/open-brush/56acbce831c7e9f257bfee9e21853da99773787b/open-brush.png",
"status": 200,
"content_type": "image/png",
"image": true
},
{
"url": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1634870/ss_0a9c208e26a43cf34879c2ca361d4c8f18af8cba.1920x1080.jpg",
"status": 200,
"content_type": "image/jpeg",
"image": true
},
{
"url": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1634870/ss_19b25b86ef55c0d8769a65135d60eaae8fa40553.1920x1080.jpg",
"status": 200,
"content_type": "image/jpeg",
"image": true
},
{
"url": "https://shared.akamai.steamstatic.com/store_item_assets/steam/apps/1634870/ss_785ea37d63378146dfe0f0ffa3f1d5c155ca978f.1920x1080.jpg",
"status": 200,
"content_type": "image/jpeg",
"image": true
},
{
"url": "https://www.supertux.org/images/0_7_0/github_preview.png",
"status": 200,
"content_type": "image/png",
"image": true
}
]
+12 -3
View File
@@ -3,17 +3,26 @@
{
"full_name": "LWJGL/lwjgl3",
"name": "lwjgl3",
"description": "LWJGL is a Java library that enables cross-platform access to popular native APIs useful in the development of graphics (OpenGL, Vulkan, bgfx), audio (OpenAL, Opus), parallel computing (OpenCL, CUDA) and XR (OpenVR, LibOVR, OpenXR) applications."
"description": "LWJGL is a Java library that enables cross-platform access to popular native APIs useful in the development of graphics (OpenGL, Vulkan, bgfx), audio (OpenAL, Opus), parallel computing (OpenCL, CUDA) and XR (OpenVR, LibOVR, OpenXR) applications.",
"owner": {
"avatar_url": "https://avatars.githubusercontent.com/u/2757344?v=4"
}
},
{
"full_name": "sahibzada-allahyar/YC-Killer",
"name": "YC-Killer",
"description": "A library of enterprise-grade AI agents designed to democratize artificial intelligence and provide free, open-source alternatives to overvalued Y Combinator startups."
"description": "A library of enterprise-grade AI agents designed to democratize artificial intelligence and provide free, open-source alternatives to overvalued Y Combinator startups.",
"owner": {
"avatar_url": "https://avatars.githubusercontent.com/u/94376830?v=4"
}
},
{
"full_name": "bjornbytes/lovr",
"name": "lovr",
"description": "Lua Virtual Reality Framework"
"description": "Lua Virtual Reality Framework",
"owner": {
"avatar_url": "https://avatars.githubusercontent.com/u/784805?v=4"
}
}
]
}
+40
View File
@@ -23,6 +23,33 @@ class PublisherSources(unittest.TestCase):
self.assertEqual(github.search(github.sources()[0], 'hello')[0]['id'], 'KhronosGroup/OpenXR-SDK-Source')
self.assertEqual(github.search(github.sources()[0], '', 0), [])
def test_curated_artwork_has_recorded_image_evidence(self):
evidence = {r['url']: r for r in json.loads((FIX / 'artwork-check.json').read_text())}
entries = github.search(github.sources()[0], '')
self.assertEqual(len(entries), 3)
for entry in entries:
self.assertTrue(entry['summary'])
images = entry['images']
self.assertEqual(entry['icon'], images['icon'])
for url in [images['icon'], images['banner']] + images['screenshots']:
self.assertTrue(url.startswith('https://'))
self.assertEqual(evidence[url]['status'], 200)
self.assertTrue(evidence[url]['image'])
self.assertTrue(entries[1]['images']['screenshots'])
self.assertTrue(entries[2]['images']['screenshots'])
def test_topic_keeps_curated_artwork(self):
curated = github._curated()[1]
repo = {'full_name': curated['repo'], 'name': 'open-brush',
'owner': {'avatar_url': 'https://avatars.githubusercontent.com/u/1'}}
with patch.object(github, '_api', return_value={'items': [repo]}):
entry = github.search(github.sources()[0], 'topic:openxr')[0]
self.assertEqual(entry['images'], curated['images'])
unknown = github.details(github.sources()[0], 'unknown/project')
self.assertEqual(unknown['icon'], 'https://github.com/unknown.png')
self.assertEqual(unknown['images']['banner'],
'https://opengraph.githubassets.com/1/unknown/project')
def test_real_releases(self):
for key, repo in [('khronos', 'KhronosGroup/OpenXR-SDK-Source'),
('brush', 'icosa-foundation/open-brush'), ('tux', 'SgtBilko76/SuperTux-3D')]:
@@ -31,6 +58,9 @@ class PublisherSources(unittest.TestCase):
self.assertTrue(e['downloadable'])
self.assertTrue(e['versions'][0]['name'].endswith('.apk'))
self.assertIsNone(e['version_code'])
search_entry = github.search(github.sources()[0], repo)[0]
self.assertEqual(e['images'], search_entry['images'])
self.assertEqual(e['icon'], e['images']['icon'])
with self.assertRaises(SourceError):
github.download(github.sources()[0], repo, 123)
@@ -40,6 +70,12 @@ class PublisherSources(unittest.TestCase):
entries = github.search(github.sources()[0], 'topic:openxr')
self.assertTrue(entries)
self.assertTrue(any(not e['downloadable'] for e in entries))
for entry, repo in zip(entries, data['items']):
self.assertEqual(entry['icon'], repo['owner']['avatar_url'])
self.assertEqual(entry['images']['icon'], entry['icon'])
self.assertEqual(entry['images']['banner'],
'https://opengraph.githubassets.com/1/' + repo['full_name'])
self.assertEqual(entry['images']['screenshots'], [])
self.assertFalse(github.details(github.sources()[0], 'unknown/project')['downloadable'])
with self.assertRaises(SourceError):
github.search(github.sources()[0], 'topic:piracy')
@@ -51,6 +87,10 @@ class PublisherSources(unittest.TestCase):
e = itch.details(itch.sources()[0], entries[0]['id'])
self.assertTrue(e['vr'])
self.assertTrue(e['images']['banner'])
for item in entries:
self.assertEqual(item['icon'], item['images']['icon'])
self.assertEqual(item['icon'], item['images']['banner'])
self.assertEqual(item['images']['screenshots'], [])
self.assertFalse(e['downloadable'])
self.assertEqual(itch.search(itch.sources()[0], 'off nominal')[0]['name'], 'Off Nominal')
with self.assertRaises(SourceError):