尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A self-updating anime wallpaper archive. A scheduled job pulls from curated
sources daily, filters and re-encodes what it finds, extracts a colour
palette from each image, and commits the result. Cloudflare Pages serves the
repo as a static site — there is no server, no database, and no build step.
Images live in Cloudflare R2, not in git. The repository therefore holds
only code and a JSON manifest and stays a few megabytes no matter how long
the sync runs — which matters because deleting a file from git does not
reclaim its history, so an image-in-repo archive grows forever.查看完整 README ↗A self-updating anime wallpaper archive. A scheduled job pulls from curated sources daily, filters and re-encodes what it finds, extracts a colour palette from each image, and commits the result. Cloudflare Pages serves the repo as a static site — there is no server, no database, and no build step.
GitHub Actions (daily cron)
└─ sync_danbooru.py fetch → filter → dedupe → WebP → palette
└─ prune.py drop oldest entries once a free-tier ceiling is hit
└─ build_site.py manifest + JSON-LD + sitemap + robots + llms.txt + OG card
└─ git push
└─ Cloudflare Pages redeploys automatically
| Path | What it is |
|---|---|
index.html | The whole site. Static gallery is injected at build time. |
assets/ | Stylesheet, runtime, favicon, generated OG card |
data/wallpapers.json | The index the frontend reads |
wallpapers/ | Processed WebP images — only in local mode; empty once storage is on R2 |
incoming/ | Local drop zone for your own uploads (git-ignored) |
scripts/ | The pipeline |
_headers, robots.txt, sitemap.xml, llms.txt | Generated — edit build_site.py, not these |
Images live in Cloudflare R2, not in git. The repository therefore holds only code and a JSON manifest and stays a few megabytes no matter how long the sync runs — which matters because deleting a file from git does not reclaim its history, so an image-in-repo archive grows forever.
Set these and the pipeline uses R2. Locally, leaving them unset falls back to
writing into wallpapers/ so the project still runs with no cloud account —
but the GitHub Actions workflow requires all five and fails its preflight
check without them, rather than silently publishing a manifest that points
at storage nothing was actually uploaded to:
R2_ACCOUNT_ID R2_ACCESS_KEY_ID R2_SECRET_ACCESS_KEY R2_BUCKET
R2_PUBLIC_BASE # public bucket URL, e.g. https://cdn.okeyamy.xyz
R2_PUBLIC_BASE also drives the img-src in the generated CSP, so the
image host can never fall out of sync with the security policy.
prune.py runs before every build and drops the oldest entries once either
ceiling is reached:
R2 bills nothing for egress, so traffic alone can never generate a charge.
Set in scripts/pipeline.py:
scripts/cropmatch.py: ORB feature matching with a geometric check). The
fingerprint index is one file in R2 (index/features.npz), not in git;
scripts/crop_index.py fills it from thumbnails before every synccull.py or prune.py is recorded in
data/removed.json and never re-fetched, from any sourcerating:general onlyDrop image files into incoming/ and run scripts/ingest_local.py. To credit
wherever an image actually came from, add a same-named .source sidecar:
incoming/nice.png
incoming/nice.png.source
https://twitter.com/artist/status/12345
artist_handle
Ganyu standing in the snow
Line 1 is the source link, line 2 is the artist/handle (optional), line 3 is a
title (optional). Both files are consumed on ingest — the sidecar is deleted
along with the source image once its contents are written into the item's
permalink/author/title fields.
The title is worth writing. It becomes the image's alt text and the name it is
indexed under, and an image with no title is deliberately left untitled rather
than named after its file — IMG-20260810-WA0002 describes nothing. Naming the
subject puts it on that character's page:
python scripts/ingest_local.py --title "Ganyu in the snow" --character Ganyu
Both flags apply to every image in the batch; a .source sidecar wins over
--title for the image it belongs to. scripts/build_site.py prints a count of
items it could not describe, so a missing title shows up at build time rather
than in a search result months later.
build_site.py writes one page per character into w/, served at
/w/<character>, for every character with at least MIN_HUB_ITEMS wallpapers
(2). Characters below the line still appear on the homepage and in the image
sitemap — they just don't get a page whose only content is a single image.
scripts/backfill_metadata.py is a one-off that repaired the titles and
character tags of items ingested before any of this existed. It has already
been run; it is kept because it is idempotent and documents what was wrong.
Static egress on Cloudflare Pages is unmetered, which matters because a wallpaper site's entire cost is bandwidth.
R2_* values as repository secrets.r2.dev domain or attach a
custom one such as cdn.okeyamy.xyz. That value is R2_PUBLIC_BASE./.wallpapers.okeyamy.xyz.robots.txt welcomes search and AI crawlers (that is the point — discovery)
while keeping generic bots out of the image directories. That is advisory
only, so the actual defence is at the edge — in the Cloudflare dashboard:
http.request.uri.path contains "/wallpapers/", e.g. 60 requests per minute
per IP, action BlockThat breaks the sequential crawl pattern used to clone a whole gallery without affecting anyone browsing normally.
Site code: MIT. The wallpapers are not covered — copyright remains with the original artists, and each item links back to its source post. Open an issue to request removal.