Skip to content

Fix broken DiscoLike sponsor logo on the website - #6253

Merged
falkoschindler merged 2 commits into
zauberzeug:mainfrom
evnchn:fix-discolike-logo-case
Aug 7, 2026
Merged

Fix broken DiscoLike sponsor logo on the website#6253
falkoschindler merged 2 commits into
zauberzeug:mainfrom
evnchn:fix-discolike-logo-case

Conversation

@evnchn

@evnchn evnchn commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Posted by Claude Code on evnchn's behalf.

The DiscoLike logo is currently broken on nicegui.io — its two .webp files are still named Discolike.* while the sponsor key was lowercased to discolike, so the URL the website builds 404s on the Linux server.

It renders fine on macOS, which is why it slipped through: the filesystem there is case-insensitive.

Motivation

website/components/sponsors_section.py derives the logo URL from the sponsor key in github_stats.json:

themed_image(f'/static/sponsors/{sponsor}.THEME.webp', classes='h-12')

Commit 24a10a1 lowercased that key from Discolike to discolike (matching the real GitHub login), but the two image files kept their original capitalization. The site therefore requests a path that does not exist:

URL requested by the live homepage Status on nicegui.io
/static/sponsors/discolike.light.webp 404
/static/sponsors/discolike.dark.webp 404
/static/sponsors/Discolike.light.webp 200
/static/sponsors/lechler-gmbh.light.webp 200
Confirmed against the live site (commands + output)

The deployed homepage really does request the lowercase paths:

$ curl -s https://nicegui.io/ | grep -o 'sponsors/[A-Za-z0-9_.-]*webp' | sort -u
sponsors/discolike.dark.webp
sponsors/discolike.light.webp
sponsors/lechler-gmbh.dark.webp
sponsors/lechler-gmbh.light.webp

$ for f in discolike.light.webp Discolike.light.webp lechler-gmbh.light.webp; do
    printf "%-26s " "$f"
    curl -s -o /dev/null -w "%{http_code}\n" "https://nicegui.io/static/sponsors/$f"
  done
discolike.light.webp       404
Discolike.light.webp       200
lechler-gmbh.light.webp    200

Only DiscoLike is affected; lechler-gmbh matches its key and is fine.

Implementation

Rename the files to match the keyDiscolike.{dark,light}.webpdiscolike.{dark,light}.webp.

The rename goes in this direction rather than restoring the capitalized key because fetch_github_stats.py uses these keys for a case-sensitive exclusion, so that a special sponsor is not also rendered as a top sponsor:

if s['tier_amount'] >= 100 and not s['tier_is_one_time'] and s['login'] not in special_sponsors

The real GitHub login is lowercase (api.github.com/users/discolike returns "login": "discolike"), so the lowercased key is correct and the filenames should follow it.

Plus a guard, since this class of bug is invisible on macOS. fetch_github_stats.py now asserts that every special sponsor key has a matching logo file, comparing against a directory listing of website/static/sponsors rather than using Path.exists() — the latter is case-insensitive on macOS and would have happily reported the old files as present. (iterdir() returns the names as stored on disk and macOS is case-preserving, so the exact string comparison catches a mismatch even on the machine the script runs on.) It mirrors both branches in sponsors_section.py (single {sponsor}.webp, or the themed light/dark pair), so the script fails loudly before writing github_stats.json if a key and its files drift apart again. The check lives in the fetch script rather than a pytest so the library test suite stays free of website concerns.

Verified on a case-sensitive filesystem and through the real static route

macOS cannot tell the two states apart, so the before/after was also run on Linux (files copied onto a container's own overlayfs, so the host's case-insensitivity could not leak in):

container FS is case-SENSITIVE (test valid)

--- PRE-FIX tree (capital-D files), URLs the code requests ---
  discolike.light.webp       404
  discolike.dark.webp        404

--- POST-FIX tree (renamed), URLs the code requests ---
  discolike.light.webp       200
  discolike.dark.webp        200
  lechler-gmbh.light.webp    200
  lechler-gmbh.dark.webp     200

And booting main.py from this branch, through NiceGUI's actual /static mount:

  discolike.light.webp       200  7264B  image/webp
  discolike.dark.webp        200  5418B  image/webp
  Discolike.light.webp       200  7264B  image/webp   <-- macOS case-insensitivity, illustrating the trap
  lechler-gmbh.light.webp    200  4160B  image/webp
Checked and ruled out
  • Other references to the capitalized name — only README.md mentions DiscoLike, and it uses the GitHub avatar URL (https://github.com/discolike.png), not this directory. Unaffected.
  • The other sponsorslechler-gmbh matches its key. testmu-ai.{dark,light}.webp are orphaned (that sponsor left the list in 44cc19e, back when it lived in sponsors.json); left untouched here as it is out of scope, happy to remove them in a follow-up if you would like.
  • Case-only rename on a case-insensitive filesystem — done with git mv, and the diff shows both files as pure renames (Bin / no content change).

Progress

  • The PR title is a short phrase starting with a verb like "Add ...", "Fix ...", "Update ...", "Remove ...", etc.
  • The implementation is complete.
  • This PR does not address a security issue.
  • Pytests are not applicable — the test suite covers the library, not the website.
  • Documentation is not necessary.
  • No breaking changes to the public API.

The logo URLs are derived from the sponsor keys in github_stats.json,
but the files were still named "Discolike.*.webp" while the key had
been lowercased to "discolike". The mismatch 404s on the Linux server
and is invisible on macOS, where the filesystem is case-insensitive.

Rename the files to match the key, and add a test that compares the
sponsor keys against a directory listing so a future mismatch fails
on any platform.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@falkoschindler falkoschindler added the documentation Type/scope: Documentation, examples and website label Aug 6, 2026
@falkoschindler falkoschindler added this to the 3.16 milestone Aug 6, 2026
@falkoschindler falkoschindler self-assigned this Aug 6, 2026
@falkoschindler
falkoschindler self-requested a review August 6, 2026 15:41
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@falkoschindler falkoschindler left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracking this down so thoroughly — the case-sensitivity analysis and the verification on a case-sensitive filesystem made this easy to trust.

One restructuring before merging: I moved the logo check from tests/test_sponsors_section.py into fetch_github_stats.py (dd4446e). We like to keep the pytest suite focused on the library itself, so website concerns don't really belong there. The fetch script is also the more natural checkpoint: it runs exactly when the sponsor list changes, and it now fails loudly before writing github_stats.json if a special key has no matching logo. Your directory-listing trick survives the move — since iterdir() returns the names as stored on disk, the check catches a case mismatch even on the case-insensitive macOS machine the script runs on.

@falkoschindler falkoschindler added the review Status: PR is open and needs review label Aug 6, 2026
@evnchn

evnchn commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Agreed — better placement, and I confirmed it still catches the bug.

Verified your version both ways, plus one residual worth knowing

Ran the assert block from fetch_github_stats.py against this branch with the rename in place and with it undone:

=== with the fix (current branch) ===
guard PASSED

=== with the fix reverted ===
AssertionError: Logo for special sponsor "discolike" is missing in website/static/sponsors

=== restored ===
guard PASSED

Moving it out of tests/ also resolves the reservation I had when writing it — it was going to be the first website-touching test in the library suite, which did not sit right.

Residual, entirely your call: the check now runs only when the script is run with a token, so it never runs in CI. The original mismatch was introduced by a hand-edit of the sponsor key (the script preserves special verbatim, so it cannot have lowercased it) — a hand-edit not followed by a script run would still slip through. In practice the sponsor list and the script move together, so this may well be theoretical; noting it rather than arguing for the test back.

@falkoschindler
falkoschindler added this pull request to the merge queue Aug 7, 2026
Merged via the queue into zauberzeug:main with commit 581576d Aug 7, 2026
12 of 16 checks passed
@evnchn
evnchn deleted the fix-discolike-logo-case branch August 7, 2026 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Type/scope: Documentation, examples and website review Status: PR is open and needs review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants