# AGENTS.md Guidance for AI coding agents working in this repository. ## What this is `bunkr_dl`: single-file Python script that downloads Bunkr albums and search results. Runtime dependencies: `requests`, `beautifulsoup4`, `lxml`. Keep it a single file and do not add dependencies. On the maintainer's machine the script is installed as a symlink into the repo, so edits are live immediately: ~/bin/bunkr_dl -> bunkr_dl ## Download chain Bunkr breaks this regularly (domain rotation, layout changes). When the script finds nothing, re-inspect the live pages with `curl` before changing code. 1. Album page `https:///a/`: relative `/f/` anchors. Large albums are paginated as `?page=N` (100 files each). An out-of-range page returns the last page again, so pagination stops when a page adds no new links, not when a page is empty. The page also contains a JS template with `href="/f/' + file.slug + '"`, which the parser correctly ignores. 2. File page `/f/`: anchor to `https://dl./file/`. 3. `POST https://dl./api/_001_v2` with JSON `{"id": ""}` returns `{"mediafiles", "path", "original"}`. 4. `GET https://glb-apisign.cdn.cr/sign?path=` returns `{"token", "ex"}`. Download `?token=..&ex=..`. ## Conventions - New options go in the `argparse` setup in `main()` and in the README usage table. - `download_file` resumes with a per-request `Range` header. Never mutate the global `headers` dict. 206 appends, 200 overwrites, 416 means already complete. - Use placeholder URLs (`https://bunkr.cr/a/XXXXXXXX`) in docs, comments and commit messages, never real album URLs or titles. ## Testing No test suite. Verify against a real album without writing to the default output folder, by loading the script as a module and stubbing the download step: python - <<'EOF' import importlib.util, importlib.machinery l = importlib.machinery.SourceFileLoader('b', 'bunkr_dl') b = importlib.util.module_from_spec(importlib.util.spec_from_loader('b', l)); l.exec_module(b) u = 'https://bunkr.cr/a/XXXXXXXX' soup = b.get_soup(u); links = b.find_media_links(u, soup); print(len(links)) fm = b.get_final_media_link(b.find_download_link(links[0])); print(fm[1]) EOF Compare the link count with the "N files" shown on the album page. For a full run use `-o` pointing at a temp dir. ## Repo facts - License: GPLv2 only (`LICENSE`, header in `bunkr_dl`). - `origin` is the personal git server (cgit section "Linux").