Skip to content

Localise every hotlinked image, and re-encode to stay under the artifact limit - #59

Merged
FDelporte merged 2 commits into
mainfrom
localise-external-images
Sep 8, 2026
Merged

Localise every hotlinked image, and re-encode to stay under the artifact limit#59
FDelporte merged 2 commits into
mainfrom
localise-external-images

Conversation

@FDelporte

Copy link
Copy Markdown
Contributor

393 posts referenced 1710 images on 115 hosts we do not control, and 129 of them across 46 posts were already dead -- a broken glyph mid-article on the live site. Hotlinking also spends a stranger's bandwidth on every page view, leaks each reader's IP to whoever owns the host, and puts 455 MB of pictures outside anything this repo can measure or shrink.

External references are now 212, and those are the unrecoverable remainder rather than a backlog: 44 dead, 9 behind a bot wall (a 403 is about the client, so they are kept), 4 mermaid.ink 503s, 3 connection failures, 5 live CI badges.

Two halves, agreeing on the filename by construction:

  • shared/HtmlToMarkdown.localizeImages localises ANY host, so a re-scrape produces local files and no post needs freezing. An external image is stored as -<8 hex of its URL>.: 58 bundles reference a URL whose basename is already a file in that bundle, where Files.exists would short-circuit and silently display a picture from another source. Lookup is by stem, ignoring the extension, which covers the 221 URLs that carry no extension at all and finds a file images.py later re-encoded. Content-Type is checked, because a dead URL usually answers 200 with HTML. WordPress emoji s are restored to the character; a GitHub Actions badge.svg stays hotlinked.

  • cleanup/external_images.py is the one-off sweep, shrinking in a temp dir so an oversized original never enters the repo -- and therefore never enters git history, which nothing here rewrites.

The import cost all the headroom (0.99 GB against a 1 GB limit whose warning lands on a green run). Bought back by de-duplicating 48 images stored twice (13.2 MB), lowering images.py --png-min from 300 KB to 100 KB site-wide (983 of 1263 PNGs converted, checked against before/after crops at reading size), and giving two newly-local animated heroes a still poster. Build: 864 MB, 136 MB of headroom.

Also fixes a latent bug in images.py: rewrite_in_bundle did a plain str.replace, so converting dummies.png rewrote the suffix of image-764x1024-dummies.png and pointed its hero at a file nothing ever wrote (add-mnemonic-bookmark.png too). It matches whole filenames now. BuiltSite.java caught it eight times over, because a hero is the card thumbnail on every listing page.

What's in this PR

…act limit

393 posts referenced 1710 images on 115 hosts we do not control, and 129 of
them across 46 posts were already dead -- a broken glyph mid-article on the
live site. Hotlinking also spends a stranger's bandwidth on every page view,
leaks each reader's IP to whoever owns the host, and puts 455 MB of pictures
outside anything this repo can measure or shrink.

External references are now 212, and those are the unrecoverable remainder
rather than a backlog: 44 dead, 9 behind a bot wall (a 403 is about the client,
so they are kept), 4 mermaid.ink 503s, 3 connection failures, 5 live CI badges.

Two halves, agreeing on the filename by construction:

- shared/HtmlToMarkdown.localizeImages localises ANY host, so a re-scrape
  produces local files and no post needs freezing. An external image is stored
  as <stem>-<8 hex of its URL>.<ext>: 58 bundles reference a URL whose basename
  is already a file in that bundle, where Files.exists would short-circuit and
  silently display a picture from another source. Lookup is by stem, ignoring
  the extension, which covers the 221 URLs that carry no extension at all and
  finds a file images.py later re-encoded. Content-Type is checked, because a
  dead URL usually answers 200 with HTML. WordPress emoji <img>s are restored
  to the character; a GitHub Actions badge.svg stays hotlinked.

- cleanup/external_images.py is the one-off sweep, shrinking in a temp dir so an
  oversized original never enters the repo -- and therefore never enters git
  history, which nothing here rewrites.

The import cost all the headroom (0.99 GB against a 1 GB limit whose warning
lands on a green run). Bought back by de-duplicating 48 images stored twice
(13.2 MB), lowering images.py --png-min from 300 KB to 100 KB site-wide (983 of
1263 PNGs converted, checked against before/after crops at reading size), and
giving two newly-local animated heroes a still poster. Build: 864 MB, 136 MB of
headroom.

Also fixes a latent bug in images.py: rewrite_in_bundle did a plain str.replace,
so converting dummies.png rewrote the suffix of image-764x1024-dummies.png and
pointed its hero at a file nothing ever wrote (add-mnemonic-bookmark.png too).
It matches whole filenames now. BuiltSite.java caught it eight times over,
because a hero is the card thumbnail on every listing page.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 8, 2026 08:43
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: d0a299ea-b326-49fc-a418-8d28c886494e


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The updated image references were verified to exist in their respective bundles and align with the PR’s goal of replacing hotlinks and reducing artifact size.

Pull request overview

This PR reduces reliance on hotlinked (third-party) images by updating content to reference localized and re-encoded assets (e.g., .png.jpg, external URLs → bundled hashed filenames), supporting the repo goal of preventing broken images and keeping the GitHub Pages artifact under size limits.

Changes:

  • Updated many posts’ image: frontmatter values to point at re-encoded local .jpg hero images.
  • Replaced numerous inline hotlinked image URLs with localized bundle files (including hashed names) and updated image extensions where assets were re-encoded.
  • Updated author profile avatarFull and an ad banner image to reference the new local .jpg assets.
File summaries
File Description
content/posts/2026/08/31/javafx-links-of-august-2026/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2026/07/31/javafx-links-of-july-2026/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2026/06/10/spring-ai-agents-no-second-runtime/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2026/05/31/javafx-links-of-may-2026/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2026/05/14/boxlang-ai-series-complete-guide-to-building-ai-agents/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2026/04/30/javafx-links-of-april-2026/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2026/04/20/spring-ai-amazon-bedrock-sdk-guide/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2026/03/31/javafx-links-of-march-2026/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2026/02/28/javafx-links-of-february-2026/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2026/01/31/javafx-links-of-january-2026/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/12/31/javafx-links-of-december-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/12/12/jakarta-data-makes-persistence-a-breeze/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/11/30/javafx-links-of-november-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/10/31/javafx-links-of-october-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/09/30/javafx-links-of-september-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/08/31/javafx-links-of-august-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/08/11/new-features-in-jakarta-ee-11-with-examples/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2025/07/31/javafx-links-of-july-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/07/16/getting-started-with-scala/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/07/08/prime-time-the-high-performance-java-event/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/06/29/javafx-links-of-june-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/06/16/foojay-podcast-73/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/06/01/javafx-links-of-may-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/04/30/javafx-links-of-april-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/04/09/webinar-java-ai/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2025/03/28/javafx-links-of-march-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/03/25/webassembly-on-kubernetes/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/03/01/javafx-links-of-february-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/02/01/javafx-links-of-january-2025/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/01/30/my-first-steps-with-playwright/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2025/01/30/a-solution-to-the-problem-of-cluster-wide-crds/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/01/29/project-loom-structured-concurrency-java/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2025/01/28/token-bucket-rate-limiter-redis-java/index.md Localize an external hotlinked image to a bundled .webp.
content/posts/2025/01/24/receiving-mails-in-java-with-imap-or-pop3/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/12/30/javafx-links-of-december-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/11/30/javafx-links-of-november-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/10/28/javafx-links-of-october-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/09/30/javafx-links-of-september-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/09/02/javafx-links-of-august-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/08/26/debugging-kubernetes-troubleshooting-guide/index.md Localize an external hotlinked image to a bundled file.
content/posts/2024/07/31/javafx-links-of-july-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/06/30/javafx-links-of-june-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/06/01/javafx-links-of-may-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/04/29/javafx-links-of-april-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/04/03/improving-upon-my-opentelemetry-tracing-demo/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2024/03/31/javafx-links-of-march-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/03/28/aspect-oriented-programming-aop/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/02/29/javafx-links-of-february-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/01/31/javafx-links-of-january-2024/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2024/01/26/book-review-tidy-first/index.md Localize a previously hotlinked image to a bundled .jpg.
content/posts/2024/01/17/payara-platform-roadmap-2024/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2024/01/03/semantic-versioning-your-java-libraries/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/11/24/java-for-desktop-applications-part-1/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/11/22/feedback-from-calling-rust-from-python/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/10/31/javafx-links-of-october-2023/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/10/21/domain-deadline-dog-driven-development/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/09/30/javafx-links-of-september-2023/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/09/15/system-architecture-move-authentication-to-the-api-gateway/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2023/08/22/introduction-tower/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2023/08/04/book-review-openjdk-migration-for-dummies/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/07/14/how-to-share-your-work-with-a-video-or-podcast/index.md Update gallery image reference to re-encoded local .jpg.
content/posts/2023/06/26/foojay-podcast-26/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2023/06/19/foojay-podcast-25/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/05/22/foojay-podcast-23/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/05/16/managing-data-residency-concepts-theory/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2023/05/02/optaplanner-continues-as-timefold/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/05/01/foojay-podcast-21/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2023/04/14/boldness-in-refactoring/index.md Update linked thumbnail image reference to re-encoded local .jpg.
content/posts/2023/04/11/hidden-beauties-of-java-enums/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/03/23/event-driven-order-processing-program/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2023/03/20/foojay-podcast-16/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/02/28/javafx-links-of-february-2023/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/02/24/porting-an-existing-javafx-app-to-ios/index.md Localize an external hotlinked image to a bundled file.
content/posts/2023/02/20/foojay-podcast-14/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/02/08/jfr-timestamps-and-system-nanotime/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/01/23/foojay-podcast-12/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2023/01/16/foojay-podcast-11/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/12/27/javafx-links-of-december/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/12/19/foojay-podcast-9/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/12/09/springone-tlv-world-tour-trip-report/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/09/12/kubernetes-gateway-api/index.md Localize an external image and/or update to bundled .jpg.
content/posts/2022/09/01/can-java-jakarta-ee-do-microservices/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/07/22/the-cost-of-production-blindness/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/07/15/debugging-java-collections-framework-issues-in-production/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2022/06/21/master-detail-with-hilla/index.md Localize an external hotlinked image to a bundled file.
content/posts/2022/06/15/microstream-part-2-configure-the-storage-manager/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/06/10/remote-debugging-and-developer-observability/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2022/05/16/azure-toolkit-for-intellij-april-2022-update/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2022/05/03/how-to-submit-your-next-article-on-foojay-io/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/04/25/chopping-monolith/index.md Update image shortcode to re-encoded local .jpg.
content/posts/2022/03/09/vaadin-and-jooq-match-made-in-heaven/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2022/02/04/video-sdkman-explained/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/11/15/github-actions-with-java-part-2/index.md Update inline image reference to re-encoded local .jpg.
content/posts/2021/08/20/deep-learning-in-java-for-drug-discovery/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/08/09/new-book-practical-vaadin/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/07/26/neo-stream-search-java-challenge/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/07/21/jedi-lambda-join-java-challenge/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/07/05/soprano-ofnullable-stream-java-challenge/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/06/24/openjdk-and-the-future-of-production-profiling/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/06/24/jdb/index.md Localize an external hotlinked image to a bundled file.
content/posts/2021/06/02/book-review-java-by-comparison/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/05/25/type-erasure-generics-java-challenge/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/05/17/map-equals-hashcode-java-challenge/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2021/04/13/deep-dive-into-multi-threading-in-java/index.md Localize an external hotlinked image to a bundled file.
content/posts/2021/01/11/device-monitoring-with-javafx-and-fxgl/index.md Update gallery image reference to re-encoded local .jpg.
content/posts/2021/01/08/how-to-bring-your-java-microservices-to-the-cloud/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2020/11/18/7-ways-to-contribute-to-openjdk/index.md Update hero image reference to re-encoded local .jpg.
content/posts/2020/11/10/getting-started-with-payara-server/index.md Update hero image reference to re-encoded local .jpg.
content/authors/wei-lin/_index.md Update avatarFull reference to re-encoded local .jpg.
content/authors/scott-sellers/_index.md Update avatarFull reference to re-encoded local .jpg.
content/authors/nataliia/_index.md Update avatarFull reference to re-encoded local .jpg.
content/authors/mohibul-chowdhury/_index.md Update avatarFull reference to re-encoded local .jpg.
content/authors/hardiksinghbehl/_index.md Update avatarFull reference to re-encoded local .jpg.
content/authors/gilbert-kwan/_index.md Update avatarFull reference to re-encoded local .jpg.
content/authors/geertjan-wielenga/_index.md Update avatarFull reference to re-encoded local .jpg.
content/authors/aicha-laafia/_index.md Update avatarFull reference to re-encoded local .jpg.
content/ads/foojay-sustainability-ebook/index.md Update ad image reference to re-encoded local .jpg.
Review details
  • Files reviewed: 67/3629 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

TITLE_EMOJI uses \p{IsExtended_Pictographic}, and Java's Unicode emoji
properties only arrived in JDK 21. On 17 that pattern throws
PatternSyntaxException from the static initialiser, so the whole check dies
before running a single rule -- and jbang honours //JAVA, so declaring 17
provisioned exactly the JDK that cannot compile it.

Hidden because this script runs only on a pull request: pushes to main go
through build-deploy.yml, which runs BuiltSite.java and not this one. PR #59 is
the first thing to execute it in CI, while it passed locally on JDK 26
throughout. Verified both ways: `jbang --java 17` reproduces the crash,
`--java 21` passes. The other 19 //JAVA 17+ scripts were checked for the same
property; none uses it, and transfer/Posts.java, which shares the character
class deliberately, already declared 21+.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@FDelporte
FDelporte merged commit c32bec7 into main Sep 8, 2026
2 checks passed
@FDelporte
FDelporte deleted the localise-external-images branch September 8, 2026 08:59
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.

2 participants