Commit Graph
100 Commits
Author SHA1 Message Date
multipleof4andClaude Opus 5.5 865b9d951d Fix: Cache AI fallback images for 90 days like every other image
They were kept for 24h so a later search could replace them, but that
regenerated them daily for no real gain. Searches where the AI image also
fails are still remembered for 24h as bad.webp. With one TTL for all images
again, the per-image ttl stored in KV and R2 is no longer needed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 03:06:31 +00:00
multipleof4andClaude Opus 5.5 6fb64e9d7b Feat: AI images on ai.direct-img.link, and as the fallback when a search finds nothing
ai.direct-img.link serves images from the AuroraIMG-6M API on our Dokploy
server (github.com/direct-img/AuroraIMG-6M) instead of searching. It takes
?src= (auroraimg-6m, case-insensitive, the default and only source for now)
and ?i=, where each i gets its own seed derived from the query, so it's a
different image of the same prompt. It has its own daily limit
(AI_DAILY_LIMIT) and AI: cache keys / ai/ R2 prefix. Failed generations
aren't cached, since they're likely temporary.

On direct-img.link and free.direct-img.link, a search that finds nothing (or
fewer than i working images) now serves an AI image of the query instead of
bad.webp. It's kept for 24h like failures were, so a later search can still
find a real image; bad.webp is only served if the AI image fails too. Its ttl
is stored in KV and R2 metadata so cache hits and deduped waiters send a
matching max-age.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:56:39 +00:00
multipleof4andClaude Opus 5.5 07564bade2 Fix: Finish searches when the client disconnects, and download candidates in parallel
A reload during a slow first-time search (seen on mobile Chrome and Safari)
made the runtime cancel the search mid-way. Its result was never stored and
its lock never released, so the reload waited out the 45s lock and then
served bad.webp. Logs show this as clientDisconnected invocations followed by
a bad.webp. The search now runs under waitUntil, so it still stores its
result and releases the lock, and the waiting reload serves the image.

Image candidates were downloaded one at a time, so each dead or slow host
could stall the search for its full 5s timeout. Up to 4 now download at once
but are checked in result order, so ?i= picks the same image. Downloads still
in flight are aborted once the image is found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 02:14:20 +00:00
multipleof4andClaude Opus 5.5 c3d4694823 Docs: SurrealDB v2.6.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:26:12 -07:00
multipleof4andClaude Opus 5.5 fd5694669a Fix: Dedupe concurrent searches for the same query with a SurrealDB lock
Two misses for the same query at once each ran their own search (ntfy
showed Search #24 and #25 for one image). An in-memory fix wouldn't
hold: a test of concurrent same-query requests on this project found
they share an isolate only ~25% of the time.

The rate-limit query is now one transaction that also claims a
per-query lock, so it's still a single SurrealDB round trip. Requests
that find the lock held write nothing (so aren't counted), poll until
it's released, then serve the image from R2. Write conflicts roll the
whole transaction back and are retried.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 14:00:28 -07:00
multipleof4andClaude Opus 5.5 f91d6c6616 Docs: Point README to the website for current rate limits
Limits change (e.g. 35 -> 25/day) and the README kept going stale, so it
now links to the homepage, which reads them live from rate-limit.js.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:28:35 -07:00
multipleof4 8ee76d38dd Reduce daily limit from 35 to 25 requests 2026-10-08 11:53:59 -07:00
multipleof4andClaude Opus 5.5 1ebcfc777e Perf: Serve homepage and assets without invoking Functions
Add _routes.json so /, /robots.txt and /assets/* skip the worker and
don't count against the Functions request quota. rate-limit.js moves to
assets/ so the homepage reads it client-side instead of via HTMLRewriter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:43:25 -07:00
multipleof4andClaude Opus 5.5 c76b1ba5f7 Feat: Homepage reads daily limits from rate-limit.js
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:35:46 -07:00
multipleof4andClaude Opus 5.5 826e0cd2dd Refactor: Move daily search limits into rate-limit.js
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:29:49 -07:00
multipleof4andClaude Opus 5.5 0ab01d6e66 Feat: Give free.direct-img.link its own 100/day search limit
Free searches never spend Brave credits, so they no longer share the
main site's 35/day counter. Main-site rate ids are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 16:23:56 -07:00
multipleof4andClaude Opus 5.5 2941397180 Fix: Serve bad.webp for unknown query params
Scanner probes like /userfiles?path=../../.env were treated as real
searches since extra params were ignored, wasting searches and rate limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 11:37:51 -07:00
multipleof4andClaude Opus 5.5 8b49ebdf71 Feat: Raise daily search limit to 35
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:42:17 -07:00
multipleof4andClaude Opus 5.5 62d6bcda0b Docs: Use free image in README preview, trim homepage i= note
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:10:46 -07:00
multipleof4andClaude Opus 5.5 029b259f05 Feat: Add free.direct-img.link and ?i= result picker (#1)
- free.direct-img.link serves only unrestricted (public domain/CC0) images
  from Openverse (license=cc0,pdm) and Wikimedia Commons
  (haslicense:unrestricted), with optional ?src=openverse|wikimedia
- ?i=1..20 picks the i-th working image on both sites; broken links are
  skipped so every index is a different image
- Openverse OAuth token is cached in KV and refreshed automatically
- Skip Flickr "photo unavailable" placeholders (served with HTTP 200)
- Free/indexed cache keys use uppercase prefixes; plain main-site keys
  are unchanged so existing cache entries stay valid
- Update README, homepage, privacy policy and terms

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 12:00:54 -07:00
multipleof4andClaude Opus 5.5 023f4d132c Feat: Add GoatCounter analytics, Terms & Privacy pages, prompt copy button
- Update AI system prompt example (README + index)
- Add copy button for the prompt on the index page
- Add GoatCounter to homepage; report image hits server-side via
  waitUntil (optional GOATCOUNTER_URL/GOATCOUNTER_TOKEN)
- Add TERMS.md and PRIVACY.md, linked in the index footer
- Remove dead c.planetrenox.com tracker

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 08:51:48 -07:00
multipleof4andClaude Opus 5.5 2976236c00 Feat: Add logo, favicon and bad.webp; move images to /assets
- New logo (svg + jpg) and multi-size favicon.ico
- /favicon.ico still served at root so direct image views get the icon
- Generated missing bad.webp placeholder
- Moved limit.webp into /assets and routed error images via helper

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 17:49:18 -07:00
multipleof4andClaude Opus 5.5 21b85acff5 Refactor: Move SurrealDB init to /_setup endpoint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:46:31 -07:00
multipleof4andClaude Opus 5.5 f1e894d1bb Fix: Lower daily search limit to 20
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:10:02 -07:00
multipleof4andClaude Opus 5.5 d81cd26a1e Docs: Add GitHub Sponsors button and fix rate limit/cache info
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:00:45 -07:00
multipleof4andClaude Opus 5.5 a9e381ab6d Chore: Switch funding to GitHub Sponsors
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 13:53:45 -07:00
multipleof4 9fae3f0ec9 Fix: Expire image cache after 90 days 2026-09-10 18:20:48 -07:00
multipleof4 ee31ffc2ed Feat: Add PayPal funding link 2026-05-12 18:05:19 -07:00
multipleof4 44ed25b654 Fix: Change ntfy priority for new searches to 2 2026-04-15 19:17:12 -07:00
multipleof4 6ee698b868 Refactor: Import search functions from utils 2026-03-12 14:31:57 -07:00
multipleof4 1fe9935fca Refactor: Extract Bing image search logic 2026-03-12 14:31:53 -07:00
multipleof4 deb931b466 Refactor: Extract Brave image search logic 2026-03-12 14:31:50 -07:00
multipleof4 6a2f7baa01 Feat: Add Bing Image Search fallback for empty results 2026-03-11 17:12:59 -07:00
multipleof4 cd3a9a5446 Feat: Add detailed fetch failure logging to ntfy 2026-03-10 14:41:05 -07:00
multipleof4 47710f30dd Refactor: Increase cache TTL to 60 days 2026-03-10 14:26:16 -07:00
multipleof4 864605d022 Remove unnecessary whitespace in index.html
Removed unnecessary whitespace in the head section.
2026-03-06 18:53:12 -08:00
multipleof4 c0202fc713 Update index.html 2026-03-06 18:53:04 -08:00
multipleof4 15ac411ed3 Feat: Add analytics tracker script to head 2026-02-27 09:30:47 -08:00
multipleof4 c02a615c9e Feat: Increase daily search rate limit to 35 2026-02-25 12:24:29 -08:00
multipleof4 f6a1d61045 Feat: Specify SurrealDB version v2.3.10 2026-02-23 11:02:11 -08:00
multipleof4 a2040381b3 Fix: SurrealDB rate limiting - headers, upsert, logging 2026-02-23 10:51:47 -08:00
multipleof4 86f97ed406 Feat: Cache error state and serve bad.webp on fail 2026-02-23 10:39:47 -08:00
multipleof4 cf7f35e184 Refactor: Drop KV rate limits docs, add SurrealDB secrets 2026-02-23 10:20:52 -08:00
multipleof4 d763f06415 Feat: Add async garbage collection to SurrealDB rate limits 2026-02-23 10:20:45 -08:00
multipleof4 406dd41258 Feat: Increase search result count to 50 2026-02-23 08:57:53 -08:00
multipleof4 b17057c49d Refactor: Update BTC donation address 2026-02-19 12:23:07 -08:00
multipleof4 bd47a1e6fb Refactor: Update BTC donation address 2026-02-19 12:23:02 -08:00
multipleof4 429e0d8d27 Update README.md 2026-02-19 10:58:32 -08:00
multipleof4 29bdea7f96 Add XMR address to README 2026-02-19 10:44:15 -08:00
multipleof4 98fc0a3920 Update README.md 2026-02-19 10:43:34 -08:00
multipleof4 7b5667d45d Refactor: Update AI system prompt instructions 2026-02-19 08:12:05 -08:00
multipleof4 8b9d72c83e Refactor: Update index.html with new AI prompt & golf CSS 2026-02-19 08:11:56 -08:00
multipleof4 12265dcfff Feat: Update docs to mention dot encoding 2026-02-17 19:51:56 -08:00
multipleof4 f7232b61e6 Fix: Reject literal dots and slashes in pathname 2026-02-17 19:51:50 -08:00
multipleof4 a045461df4 Fix: Block literal dots and slashes to stop bots 2026-02-17 19:51:45 -08:00
multipleof4 4e50f7c3f4 Docs: Update rate-limit TTL to 25 hours 2026-02-15 11:04:05 -08:00
multipleof4 0cbcc73326 Refactor: Reduce rate-limit TTL to 25 hours 2026-02-15 11:00:07 -08:00
multipleof4 606feec0ff Feat: Document slash rejection, update normalization rules 2026-02-15 09:03:00 -08:00
multipleof4 e5b167d731 Feat: Reject queries with slashes, serve bad.webp 2026-02-15 09:02:54 -08:00
multipleof4 509a1d7269 Fix: Update daily search rate limit to 15 2026-02-14 19:03:52 -08:00
multipleof4 43ff666933 Refactor: Update rate limit to 15 in landing page 2026-02-14 19:02:22 -08:00
multipleof4 b32535db4b Refactor: Update rate limit to 15, update KV docs 2026-02-14 19:02:17 -08:00
multipleof4 c6a7ad6960 Fix: Atomic rate limiting via individual KV keys 2026-02-14 18:58:10 -08:00
multipleof4 b4d515a9c7 Feat: Serve limit.webp meme on rate limit instead of JSON 2026-02-14 11:55:28 -08:00
multipleof4 f6a84e8216 Add files via upload 2026-02-14 11:45:24 -08:00
multipleof4 de6fec20ca Feat: Include full URL in search notifications 2026-02-14 09:19:34 -08:00
multipleof4 17090b28f3 Feat: Increase daily search rate limit from 10 to 25 2026-02-14 08:48:49 -08:00
multipleof4 4c629ea330 Feat: Increase daily search rate limit from 10 to 25 2026-02-14 08:48:43 -08:00
multipleof4 ede0bfe459 Feat: Increase daily search rate limit from 10 to 25 2026-02-14 08:48:35 -08:00
multipleof4 3ebc05718b Update README.md 2026-02-14 06:58:45 -08:00
multipleof4 1d5191763f Feat: Document query normalization rules and limits 2026-02-13 21:49:59 -08:00
multipleof4 ac74ce6cbe Fix: Sanitize queries, limit length, normalize slashes 2026-02-13 21:49:53 -08:00
multipleof4 d9466a9c08 Feat: Allow indexing of root while blocking queries 2026-02-13 21:14:10 -08:00
multipleof4 54437d6dde Feat: Remove comments from robots.txt 2026-02-13 19:33:26 -08:00
multipleof4 964249582a Refactor: Replace URL format with AI prompt, remove privacy 2026-02-13 19:07:20 -08:00
multipleof4 79c91e482b Feat: Add AI system instruction section to README 2026-02-13 19:01:48 -08:00
multipleof4 2bb96a5789 Fix: Add global 20s deadline with dynamic per-attempt timeout 2026-02-13 18:36:30 -08:00
multipleof4 62e683ad9f Fix: Replace setTimeout with AbortSignal.timeout 2026-02-13 18:28:52 -08:00
multipleof4 86e55cc222 Fix: Move body consumption inside fetchImage timeout scope 2026-02-13 18:24:25 -08:00
multipleof4 718d2de3da Docs: Add NTFY_URL to secrets table 2026-02-13 17:54:48 -08:00
multipleof4 1d434afaf1 Feat: Add ntfy notifications and robust search loop 2026-02-13 17:53:19 -08:00
multipleof4 adaa335486 Refactor: Update rate limits and fix markdown escaping 2026-02-13 16:56:49 -08:00
multipleof4 39d9692095 Refactor: Update rate limit table for CF Free 2026-02-13 16:56:43 -08:00
multipleof4 288dda0ece Fix: Correct markdown escaping for code blocks 2026-02-13 16:45:11 -08:00
multipleof4 45d8e25783 Feat: Add live example image to README 2026-02-13 16:44:22 -08:00
multipleof4 333b29e0a5 Fix: Update safesearch parameter to valid value 2026-02-13 16:34:31 -08:00
multipleof4 f05c642e65 Refactor: Remove redundant TTL logic and simplify cache check 2026-02-13 16:26:15 -08:00
multipleof4 5dbab52bad Feat: Add donation-based limit increase notice 2026-02-13 16:16:20 -08:00
multipleof4 f2f380c0b8 Feat: Complete info migration from README to index 2026-02-13 16:12:11 -08:00
multipleof4 ef28db0310 Refactor: Add rate limits and remove infra mentions 2026-02-13 16:07:39 -08:00
multipleof4 984ce17165 Refactor: Remove demo and add donation warning 2026-02-13 16:05:43 -08:00
multipleof4 8db9a006b2 Feat: Add minimalist light-themed landing page 2026-02-13 16:02:26 -08:00
multipleof4 cd1e4576f4 Refactor: Update README to reflect store-as-is approach 2026-02-13 15:51:12 -08:00
multipleof4 709737fce7 Update README.md 2026-02-13 15:33:30 -08:00
multipleof4 2bf64d8c3d Fix: Correct Brave API pricing to $5/1k with $5 free 2026-02-13 15:18:31 -08:00
multipleof4 fc839658c7 Feat: Switch from Google CSE to Brave Image Search API 2026-02-13 15:01:32 -08:00
multipleof4 ed3924cc33 Delete assets/sites-to-search.xml 2026-02-13 13:58:50 -08:00
multipleof4 159c46b298 Delete: Move sites-to-search.xml to assets/ 2026-02-13 13:17:54 -08:00
multipleof4 fc52043b7e Feat: Move sites-to-search.xml to assets/ 2026-02-13 13:17:52 -08:00
multipleof4 ce36698b62 Refactor: Remove inline sites list, reference assets/ XML 2026-02-13 13:17:46 -08:00
multipleof4 a0b070e44e Create sites-to-search.xml 2026-02-13 12:58:31 -08:00
multipleof4 189953b719 Refactor: Trim README, switch Bing to Google CSE 2026-02-13 12:52:58 -08:00
multipleof4 38ff34a284 Feat: Add Pages bindings reference with R2_IMAGES 2026-02-13 11:30:28 -08:00
multipleof4 be18840701 Refactor: Rename KV namespaces to be project-scoped 2026-02-13 11:22:22 -08:00
multipleof4 1b0fb332da Feat: Add BTC donation address to Support section 2026-02-13 11:17:08 -08:00