aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 31c6e94001fb2ed88e5569316fdeac36930e36f0 (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
66
67
68
# 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.
- Movement is spatial: pressing a direction lands you on whatever photo already
  occupies that cell — you walk through photos you've placed before rather than
  over them. New photos are only added when you step into a genuinely empty
  cell. If the path's next photo is already placed elsewhere, focus jumps to
  it, so the mosaic never holds two copies of a photo.

## 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.