Skip to content
LukeEvansTechPublic

About

Japanese anime cel catalogue: watches Yahoo Auctions, Mercari and Mandarake, groups relists into one cel, and sends one daily digest of new cels.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

sakuga

A personal catalogue of Japanese anime production cels for sale. It watches Yahoo Auctions (through Buyee), Mercari, Mandarake and eBay for cels of a few franchises, recognises a relisted cel by its photo, and sends one Pushover digest a day of the cels it has never seen before. Everything still for sale is on the Catalogue page, however long it has been listed.

How it works

sweep (every 30 min) ─▶ Buyee / Mercari / Mandarake shop + auctions (headless Chromium)
                     ─▶ eBay through the Browse API (UK marketplace, prices in pounds), when keys are set
                     ─▶ regular expression first pass (franchise from the title, prints and goods dropped)
                     ─▶ photo saved + perceptual hash
                     ─▶ LLM reads title + up to 3 photos: cel / genga / print / Cel Club, English title
                        (asked again if further photos arrive later)
                     ─▶ same cel as one already catalogued? (pHash; LLM compares borderline photos)
                     ─▶ listings not seen any more retire; a cel stays available while any listing is
digest (08:00)       ─▶ one alert for the cels first seen since the last digest
                     ─▶ the daily email, every day: new cels with photos, and sweep health
  • Cel and listing. A listing is one sighting on one site; a cel is the artwork. A relist, or the same cel on another site, joins the existing cel, so it is announced once.
  • Instant alerts only for GAINAX's numbered limited reproduction cels; everything else waits for the digest. The first sweep is a baseline and is never announced, and so is a franchise's first full read after it is added.
  • Franchises (Broly, Vegeta and Goku from Dragon Ball, Fullmetal Alchemist, Evangelion, Pokémon, Kiki's Delivery Service, Princess Mononoke, Cowboy Bebop) and their searches live in sakuga/filters.py. On Yahoo each is a keyword search inside セル画, and where Yahoo has the franchise's own セル画 sub-category (Evangelion, Kiki, Mononoke, Bebop) that is read whole too, which finds titles the keywords miss (a typo, no name). Such a listing is catalogued only when the LLM names the same franchise from the photo, as the categories hold misfiled listings.

Run it

uv venv -p 3.13 .venv && uv pip install -p .venv -r requirements.txt -r requirements-dev.txt
.venv/bin/python -m playwright install chromium
.venv/bin/python -m pytest -q
SAKUGA_DATA=data .venv/bin/python -m sakuga sweep --no-notify
SAKUGA_DATA=data .venv/bin/python -m sakuga digest   # send the digest now; stop the server first
SAKUGA_DATA=data .venv/bin/python -m sakuga serve   # :8080, sweeps every 30 min, digest 08:00

Docker: docker build -t sakuga . then docker run --read-only --tmpfs /tmp -v sakuga:/data -p 8080:8080 sakuga. The image runs as uid 65532 with a read-only root filesystem as long as /tmp is writable.

Configuration

Variable Default Description
SAKUGA_DATA data Directory for sakuga.db and the stored photos (img/).
SAKUGA_PUBLIC_URL none Base URL of the web UI; alert links are absolute when set.
SAKUGA_SCHEDULE */30 * * * * Cron for sweeps.
SAKUGA_DIGEST 0 8 * * * Cron for the daily digest.
SAKUGA_TZ Europe/London Timezone both crons are read in.
APPRISE_URLS none Comma-separated Apprise URLs. Empty sends nothing.
SAKUGA_SMTP_HOST none SMTP relay for the daily email (STARTTLS when offered). Empty: no email.
SAKUGA_SMTP_PORT 25 Port on that relay.
SAKUGA_MAIL_FROM none Sender address of the daily email.
SAKUGA_DIGEST_TO none Recipient of the daily email; it also needs SAKUGA_PUBLIC_URL.
SAKUGA_LLM_URL none OpenAI-compatible endpoint. Empty: regular expression filter only, no LLM.
SAKUGA_LLM_KEY none Bearer key for that endpoint.
SAKUGA_LLM_MODEL claude Model name; it must accept images.
SAKUGA_TRIES 3 Page loads per search before it counts as failed.
EBAY_CLIENT_ID none eBay app ID (Browse API, client credentials). Empty: eBay not searched.
EBAY_CLIENT_SECRET none eBay cert ID for that app.
SAKUGA_EBAY_MARKETPLACE EBAY_GB eBay marketplace searched; its currency must be pounds.

Pages

/today (new since the last digest, and the last digest), /catalogue (filters and sorts), /cel/<id> (photos, every sighting, price history), /log (each sweep and its sources), /digest/last (the last daily email, with linked photos), /health, /metrics. The UI has no login: run it behind an internal-only route.

About

Japanese anime cel catalogue: watches Yahoo Auctions, Mercari and Mandarake, groups relists into one cel, and sends one daily digest of new cels.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages