Skip to content

Feed check: take a feed's website and find its icon there - #69

Merged
ronibhakta1 merged 2 commits into
edrlab:mainfrom
ronibhakta1:feat/feed-check-website-icon
Nov 11, 2026
Merged

ronibhakta1 merged 2 commits into
edrlab:mainfrom
ronibhakta1:feat/feed-check-website-icon

Conversation

@ronibhakta1

@ronibhakta1 ronibhakta1 commented Nov 11, 2026 •

Copy link
Copy Markdown
Member

Fixes #68

Feedback on the Add catalog flow asked for a website step for OPDS feeds and for Apple touch icons and well-known icon locations. This does both in the feed check. Nothing is stored and there is no schema change.

What changes

  • POST /admin/feed-checks accepts an optional website (same limits as url). For an OPDS feed, feed.links gains {rel: "alternate", href: website, type: "text/html"} unless the feed already has it, and it is checked like any other link. A web page ignores it. A refused website blocks with url-invalid / url-unsafe and rel: "alternate".
  • When the feed has no icon of its own, the icon is looked for on its website: the website given, else the feed's first alternate link of type text/html. A web page is its own website.
  • Icon candidates, best first: apple-touch-icon / apple-touch-icon-precomposed, then icon by largest sizes (any counts as largest), then /apple-touch-icon.png, then /favicon.ico. At most 4 are tried. The first that answers with an image/* type is kept, with the type the server served. If none answers, no icon is suggested and nothing is reported.
  • rel is read as tokens, so icon shortcut counts and mask-icon does not. Tags after </head> are no longer read.
  • Link probes and the icon search share one concurrency limit per check and per host. The icon search also has its own 6 s limit and gives up quietly (no icon, no finding), so a slow website never runs the check to its 18 s limit. The 18 s total is unchanged.
  • A website given with or without a trailing slash is not added again when the feed already links it.

Tests

  • tests/unit/test_feed_check.py: candidate ranking, well-known fallbacks without repeats, sizes="any", nothing read after the head.
  • tests/unit/test_feed_check_service.py: the website's best working icon, a well-known fallback after a soft 404, a feed's own icon never reads the website, a given website becomes the alternate (not repeated), a dead website only warns, a refused website blocks before any request, a web page ignores website, a slow icon search gives up without a finding, a website differing only by a trailing slash is not repeated.
  • tests/e2e/test_admin_feed_checks.py: website through the app gives the alternate and the icon; an empty website is 422.
  • Full suite: 2190 passed. ruff check, ruff format --check, mypy clean.
  • Run against the real network: https://test.opds.io/2.0/home.json with website=https://opds.io/ gives the alternate link and https://opds.io/apple-touch-icon.png (image/png) in 1.2 s.

Website

edrlab/catalog-registry-website#65 (issue edrlab/catalog-registry-website#64) sends website. Merge and deploy this first: today the endpoint refuses unknown fields with a 422.

POST /admin/feed-checks accepts an optional `website`. For an OPDS feed it
becomes the `alternate` text/html link (unless the feed already has it) and is
checked like any other link; it is ignored for a web page. A refused website
blocks with url-invalid/url-unsafe, rel "alternate".

When a feed has no icon of its own, the icon is looked for on its website (the
one given, else its first alternate text/html link); a web page is its own
website. Candidates, best first: Apple touch icons, then icons by largest
`sizes`, then /apple-touch-icon.png and /favicon.ico; at most 4 tried, the
first answering with an image is kept with its served type. A page with no
working icon suggests none and says nothing.

`rel` is read as tokens, so "icon shortcut" and apple-touch-icon-precomposed
count, and tags after </head> are no longer read. Link probes and the icon
search share one limit per check and per host, inside the links stage's
existing deadline.
…ut a slash is one link

A library CMS that renders each missing icon slowly could keep the icon search
running to the check's limit and end it with check-timed-out. The search now
has its own 6 s limit and stops quietly: no icon, no finding.

"https://x.org" given as the website no longer adds a second alternate link
when the feed already links "https://x.org/".
@ronibhakta1
ronibhakta1 merged commit 29e5155 into edrlab:main Nov 11, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feed check: take a feed's website, and find its icon there (Apple touch icons, well-known locations)

1 participant