aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 36e7b534c3b86984c52743f8f8f4b3a086e0ba15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# pathways

A photo viewer that walks your library as a maze. You start on one random
picture; every photo secretly holds up to four paths — its biggest memberships
across labels, keywords, camera, and lens — one per direction. Press a
direction (arrow keys, or the buttons that appear when you hover) and the next
photo of that path locks into the grid beside you, in the direction you moved.
The visited pictures accumulate into a mosaic you can pan around and step back
through.

The live instance lives at <https://pathways.dax.ist> and reads the PhotoPrism
database directly (read-only) on the same machine. PhotoPrism's admin UI
stays behind basic auth at <https://prism.dax.ist>; pathways is public.

## How the paths work

- Every photo's paths are its member groups: label(s), keyword(s), camera,
  lens. They're ranked by member count; the top four (one per direction) become
  its exits.
- Paths with a single member are skipped; a photo with fewer than four usable
  paths is topped up with a "library" path (all photos), so every direction
  always leads somewhere.
- Each path is an ordered cycle (by taken date, then id): walking "grey" goes
  grey → grey → … and wraps around. Assignment is deterministic, so revisiting
  a photo always offers the same four exits.
- If a step lands on a photo already placed in the mosaic, focus just jumps to
  its existing tile — the mosaic never holds two copies.

## Run it

```bash
npm install
DB_HOST=127.0.0.1 DB_USER=photoprism DB_PASSWORD=… DB_NAME=photoprism \
  PORT=3100 THUMBS_ROOT=/srv/photoprism/storage/cache/thumbnails \
  node server.mjs
```

On NixOS the box runs it as a systemd unit (`systemd.services.pathways`),
started after `mysql.service`, as user `dax`.

## API

- `GET /api/paths` — every photo (id, thumb, title, date) plus the facets
  (groups with ≥3 members)
- `GET /api/random` — one random photo
- `GET /api/exits/:id` — a photo plus its four exits; each exit has the path
  it follows (`type`, `name`, `count`) and the `next` photo in that path's cycle
- `GET /api/health` — liveness probe

Thumbnails are served as static files by Caddy from
`/srv/photoprism/storage/cache/thumbnails/{a}/{b}/{c}/{hash}_{size}.jpg`
(`720x720_fit` for tiles).

## Layout

```
server.mjs        API + static file serving
public/index.html splash + the walkable stage
public/app.css    tiles, hover exits, lock-in animation
public/app.js     grid state, exits, pan/click/keyboard, cycling walk
```

The thumbnail path sharding matches PhotoPrism: directory = first three
characters of the file hash. Note `file_hash` comes back from MariaDB as a
binary Buffer, so it is decoded to a string before building URLs.