Example script: download every album's photos and metadata (closes #144)

`examples/download-albums.ts` logs in with `QUAK_EMAIL` and `QUAK_PASSWORD`,
opens the library, and for every album downloads each photo to its save path,
writes `{savePath}.json` with the photo's record (cache paths left out) and its
EXIF fields, and writes `albums/{collectionID}.json` with the album's save
paths. A JSON file is written only when its content changed, so a second run
downloads and rewrites nothing. `tsconfig.json` includes `examples/`, so the
build type-checks it. A test runs it twice against a stand-in account.

Model: opus-5-5
This commit is contained in:
2026-10-01 22:10:19 +00:00
committed by sneak
parent d40f339c0b
commit 56641c6785
5 changed files with 456 additions and 5 deletions
+36 -4
View File
@@ -80,6 +80,34 @@ await lib.close();
The lower-level `Client` (login, session serialization, and the raw
enumeration/download calls) is exported too and documented under Design below.
## Examples
`examples/download-albums.ts` downloads every album's photos and their metadata
into a directory, `photos` in the working directory unless you name another. The
build compiles it; run it after `yarn install`:
```bash
yarn build
QUAK_EMAIL=… QUAK_PASSWORD=… node dist/examples/download-albums.js [dir]
```
It asks on the terminal for a two-factor or email code when the account requires
one, and writes:
- each photo's original at its save path under `dir`, as `photo.download()`
writes it: `YYYY/YYYY-MM/YYYY-MM-DD/YYYY-MM-DD.<fileID>.<ext>`, and for a live
photo its image, its video and the `.livephoto.json` file naming them
- beside each original, a JSON file named after it with `.json` added, for
example `2026-03-01.12345.jpg.json`: the photo's record (`photo.record()`)
without its cache paths, and its EXIF fields (`photo.exif()`) under `exif`
- `albums/<collectionID>.json` for each album: its `collectionID`, its `name`,
and under `savePaths` the save paths of its photos relative to `dir`, newest
first
A photo in several albums is downloaded once. A second run downloads nothing and
rewrites only the JSON files whose content changed. A failed download stops the
run; running it again carries on, since every photo already saved is skipped.
## Entrypoints
This repository adheres to the
@@ -239,6 +267,9 @@ quak/
index.ts public library exports
bin/
quak.ts CLI entrypoint (commander.js)
examples/
download-albums.ts
download every album's photos and metadata
test/ unit + integration tests (vitest)
Makefile
Dockerfile lint phase, test phase, compile
@@ -247,10 +278,11 @@ quak/
```
`make build` compiles that tree into `dist/`, preserving its shape: the library
lands in `dist/src/` and the CLI in `dist/bin/quak.js`, which is what
`package.json` points `main`, `types` and `bin` at. The compiler's `rootDir` is
the repository root rather than `src/`, because `bin/` is compiled too and
`rootDir` has to contain everything that is compiled.
lands in `dist/src/`, the examples in `dist/examples/`, and the CLI in
`dist/bin/quak.js`, which is what `package.json` points `main`, `types` and
`bin` at. The compiler's `rootDir` is the repository root rather than `src/`,
because `bin/` is compiled too and `rootDir` has to contain everything that is
compiled.
### Cryptography