144 lines
6.8 KiB
Markdown
144 lines
6.8 KiB
Markdown
# mangabaka-seeder
|
||
|
||
A tool for seeding edits to the [MangaBaka](https://mangabaka.org) manga/comics
|
||
database, in the spirit of [yambs](https://codeberg.org/derat/yambs) for
|
||
MusicBrainz.
|
||
|
||
> **Status:** v0.1 works end to end locally (Tower of God: current and archived
|
||
> covers found, checked and rehosted); not deployed yet. Design:
|
||
> [the spec](docs/specs/001-webtoons-covers.md).
|
||
|
||
Today's goal is one thing done well: **given a MangaBaka series link and a
|
||
WEBTOON or Tapas series link, find every cover that series has used, current
|
||
and historical, and request them added to the MangaBaka series**. The current
|
||
poster becomes the main (default) cover for the edition's language.
|
||
|
||
## Two ways to use it
|
||
|
||
- **Web page** (primary). Open the page, paste the two links, review the
|
||
covers. A small server behind the page reads Webtoons and the Wayback
|
||
Machine for you, because browsers can't. It runs on your own machine with
|
||
Bun.
|
||
- **Userscript.** Install `mbseed.user.js` in Tampermonkey or Violentmonkey.
|
||
On a MangaBaka series page it adds a **Seed covers** panel; paste the
|
||
Webtoons link. It reads Webtoons directly from your browser, and with
|
||
litterbox or catbox it needs no server at all.
|
||
|
||
A command-line version (Bun) may follow.
|
||
|
||
## How it works
|
||
|
||
1. **Read both links.** The MangaBaka link gives the series id; the Webtoons
|
||
link gives the title, `title_no`, language, and official or canvas. If the
|
||
MangaBaka series has no link to that `title_no`, you're warned.
|
||
2. **Collect covers.**
|
||
- **Current:** the portrait poster, the square thumbnail, and the banner and
|
||
hero art.
|
||
- **Historical** (tick "Old covers from the Wayback Machine"; off by default,
|
||
it takes minutes): cover images in archived copies of the series page on the
|
||
[Wayback Machine](https://web.archive.org), up to one snapshot per month.
|
||
3. **Check each image.** It downloads each image to get its size and hash,
|
||
classifies it by shape (portrait → `volume`, square → `other`, wide →
|
||
`banner`), and drops duplicates and images MangaBaka already has.
|
||
4. **Build the submission.** Existing covers are kept and new ones added. The
|
||
current poster is the default (the square for canvas series, which have no
|
||
poster). Every new cover gets a note recording where and when it was seen.
|
||
5. **Rehost the images** when you click **Rehost selected**, to the host you
|
||
pick:
|
||
|
||
| Host | Links last |
|
||
|---|---|
|
||
| the server's own storage (default, if configured) | 30 days |
|
||
| [litterbox](https://litterbox.catbox.moe) | 1 hour – 72 hours |
|
||
| [catbox.moe](https://catbox.moe) | permanently |
|
||
| none (`direct`): submit the Webtoons URL itself | as long as Webtoons keeps it |
|
||
|
||
A link must still work when a MangaBaka moderator looks at the request. If
|
||
it has expired by then, run the tool again.
|
||
6. **Hand it to you.**
|
||
- **Without API access (most users):** press **Download selected (ZIP)** for
|
||
the cover files plus a `covers.txt` with each one's type, rating and note,
|
||
and upload them in MangaBaka's cover form for the series (the page links to
|
||
it). No rehosting needed. Or rehost them and paste the hosted URLs instead.
|
||
- **With a personal access token:** the tool shows MangaBaka's preview diff
|
||
and, after you confirm, submits the request for review.
|
||
|
||
The page keeps a **history** of the series you searched, in your browser: the
|
||
covers, your ticks, notes and ratings, and what you did with them (downloaded,
|
||
rehosted, filed). Pick one from **History** or the start screen to reopen it
|
||
instantly; **Search again** refreshes it and keeps your edits. It holds the 30
|
||
latest series (up to 300 MB) and stays in this browser only.
|
||
|
||
Nothing is uploaded or sent to MangaBaka without your action, and submissions
|
||
always go to review. You choose the content rating (default `safe`); titles
|
||
Webtoons marks as mature show a warning. Your token is sent only to
|
||
MangaBaka's API, never to our server.
|
||
|
||
MangaBaka's submissions API is only open to contributors, or to users with at
|
||
least 25 approved submissions.
|
||
|
||
## Supported sources
|
||
|
||
| Source | Links | Current covers | Historical covers |
|
||
|---|---|---|---|
|
||
| WEBTOON (official & canvas) | `https://www.webtoons.com/<lang>/…/list?title_no=N`, `m.webtoons.com` | poster, square, banner, foreground | Wayback Machine |
|
||
| Tapas (comics & novels) | `https://tapas.io/series/<name>` (or `…/info`, the series number, or an `/episode/N` link) | portrait cover (full size), banner | Wayback Machine |
|
||
|
||
Tapas is English only. Mature Tapas series are shown only to signed-in adults:
|
||
the page can't read their current covers (it says so and still searches the
|
||
archive), but the userscript can, when you are signed in to Tapas in that browser.
|
||
|
||
Each Webtoons language edition has its own `title_no`. Run the tool once per
|
||
edition; the covers are tagged with that edition's language.
|
||
|
||
## Notes and limitations
|
||
|
||
- **Some covers may only exist in the archive.** If an old cover is no longer
|
||
on Webtoons' server, its archive.org copy is used instead.
|
||
- **Not everything is a cover.** Some historical images are promotional or
|
||
landing-page art. Review the list before submitting.
|
||
- **Requests are rate-limited** to stay polite to Webtoons, the Wayback Machine
|
||
and MangaBaka.
|
||
|
||
## Running it
|
||
|
||
Needs [Bun](https://bun.sh) 1.3 or newer.
|
||
|
||
```sh
|
||
bun install --frozen-lockfile
|
||
bun run build # the page and the userscript into dist/web/
|
||
MBSEED_STORAGE_DIR=/srv/mbseed/covers MBSEED_PUBLIC_URL=https://mbseed.example.org bun run start
|
||
```
|
||
|
||
Open the address it prints. Without `MBSEED_STORAGE_DIR` the server runs without
|
||
its own storage and the page offers litterbox, catbox and no rehosting. All
|
||
settings, and how to put it behind a reverse proxy, are in
|
||
[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md#running-the-server).
|
||
|
||
### With Docker
|
||
|
||
Every push to `main` builds an image and publishes it to
|
||
`gitea.lucaswinther.info/lucasw89/mangabaka-seeder` (`latest`, the branch name,
|
||
`sha-<commit>`, and the version for `v*` tags). Copy
|
||
[`docker-compose.example.yml`](docker-compose.example.yml) to `docker-compose.yml`,
|
||
set `MBSEED_PUBLIC_URL`, and run `docker compose up -d`. To build it yourself:
|
||
`docker build -t mangabaka-seeder .`
|
||
|
||
The CI workflow (`.gitea/workflows/ci.yml`) publishes with a repository or user
|
||
secret `REGISTRY_TOKEN`: a Gitea access token with package write permission
|
||
(Gitea's job token cannot publish packages).
|
||
|
||
### The userscript
|
||
|
||
Install `/mbseed.user.js` from the running server (or `dist/web/mbseed.user.js`)
|
||
in Tampermonkey or Violentmonkey. A **Seed covers** button appears on MangaBaka
|
||
series pages. To rehost on your server from the userscript, enter its address
|
||
under *Settings* in the panel; build with `MBSEED_PUBLIC_URL` set so the script
|
||
is allowed to reach it.
|
||
|
||
## Development
|
||
|
||
Working on this repo, by hand or with an AI agent: start at
|
||
[`AGENTS.md`](AGENTS.md). Design: [`docs/specs/`](docs/specs/); current
|
||
architecture: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md).
|