rename applephotos to photoscli, update module path to gitea.k3s.k0.nu/tools/photocli

This commit is contained in:
Ein Anderssono
2026-06-11 20:29:06 +02:00
parent e48e20ad18
commit ca3a3e4a2a
6 changed files with 43 additions and 40 deletions
+28 -25
View File
@@ -1,26 +1,26 @@
# applephotos
# photoscli
`applephotos` is a small macOS-only CLI written in Go that reads data from Apple Photos through a PhotoKit bridge.
`photoscli` is a small macOS-only CLI written in Go that reads data from Apple Photos through a PhotoKit bridge.
It supports five tasks:
- listing albums
- listing asset IDs and filenames in an album
- listing asset IDs, filenames, and cloud status in an album
- showing the folder and album tree
- backing up all albums into the Photos folder tree
- exporting resized JPEG previews or original files from an album
## What The Code Does
The executable lives in `cmd/applephotos` and calls into `internal/photos`, which wraps an Objective-C bridge in `bridge/`.
The executable lives in `cmd/photoscli` and calls into `internal/photos`, which wraps an Objective-C bridge in `bridge/`.
Current behavior:
- `albums` prints one line per album as `<album-id>\t<title>`
- `photos --album-id <id-or-title>` prints one asset local identifier and filename per line; accepts either a PhotoKit local identifier or an album title
- `photos --album-id <id-or-title>` prints one asset per line as `<id>\t<filename>\t<cloud>`; accepts either a PhotoKit local identifier or an album title
- `tree` prints the human-readable folder and album hierarchy from Apple Photos
- `backup-all --out <dir> [--size <px>] [--originals]` exports every album into a matching folder tree under the output directory
- `export --album-id <id-or-title> --out <dir> [--size <px>] [--originals]` exports either JPEG previews or original files and reports the number exported on stderr; `--album-id` accepts either a PhotoKit local identifier or an album title
- `backup-all --out <dir> [--size <px>] [--originals]` exports every album into a matching folder tree, showing per-asset progress with filename, size, and cloud status
- `export --album-id <id-or-title> --out <dir> [--size <px>] [--originals]` exports either JPEG previews or original files with a progress bar showing filename, size, and cloud status; `--album-id` accepts either a PhotoKit local identifier or an album title
The bridge uses PhotoKit to:
@@ -48,7 +48,7 @@ make build
Output binary:
```bash
./bin/applephotos
./bin/photoscli
```
## Test
@@ -62,16 +62,16 @@ Tests run against a stub bridge, so they do not require real Photos access.
## Usage
```bash
./bin/applephotos albums
./bin/applephotos photos --album-id "<album-local-identifier>"
./bin/applephotos photos --album-id "Vacation"
./bin/applephotos tree
./bin/applephotos backup-all --out ./backup
./bin/applephotos backup-all --out ./backup --originals
./bin/applephotos export --album-id "<album-local-identifier>" --out ./export
./bin/applephotos export --album-id "Vacation" --out ./export
./bin/applephotos export --album-id "<album-local-identifier>" --out ./export --size 2048
./bin/applephotos export --album-id "<album-local-identifier>" --out ./export --originals
./bin/photoscli albums
./bin/photoscli photos --album-id "<album-local-identifier>"
./bin/photoscli photos --album-id "Vacation"
./bin/photoscli tree
./bin/photoscli backup-all --out ./backup
./bin/photoscli backup-all --out ./backup --originals
./bin/photoscli export --album-id "<album-local-identifier>" --out ./export
./bin/photoscli export --album-id "Vacation" --out ./export
./bin/photoscli export --album-id "<album-local-identifier>" --out ./export --size 2048
./bin/photoscli export --album-id "<album-local-identifier>" --out ./export --originals
```
### Commands
@@ -93,13 +93,13 @@ Example output:
- Requests Photos access
- If the value looks like a PhotoKit local identifier, uses it directly
- Otherwise searches album titles for a match and resolves the identifier
- Lists asset local identifiers for the given album
- Lists asset local identifiers and cloud status for the given album
Example output:
```text
1F2A.../L0/001 IMG_0001.JPG
9C4D.../L0/001 IMG_0002.JPG
1F2A.../L0/001 IMG_0001.JPG local
9C4D.../L0/001 IMG_0002.JPG cloud
```
`backup-all --out <dir> [--size <px>] [--originals]`
@@ -107,8 +107,8 @@ Example output:
- Requests Photos access
- Walks the Photos folder and album hierarchy
- Creates directories as `out/folder/album/files`
- Exports previews by default
- Exports original files when `--originals` is present
- Exports previews by default, originals when `--originals` is present
- Shows per-asset progress bar with filename, file size, and cloud/local status
- Uses `--size` only for preview export
Example layout:
@@ -128,6 +128,8 @@ backup/
- Requests Photos access
- Resolves `--album-id` by local identifier first, then by album title if not found
- Creates the output directory if needed
- Exports assets one at a time with a progress bar: `[=======---] 50% filename.jpg 1.2 MB cloud`
- Shows file size and cloud/local status for each exported asset
- Exports resized JPEG previews by default
- Exports original files when `--originals` is present
- Writes a summary like `exported 10 photos to ./export` or `exported 10 original files to ./export` to stderr
@@ -187,7 +189,9 @@ Sending `SIGINT` (Ctrl+C) or `SIGTERM` during export or backup triggers a gracef
A second signal forces an immediate exit.
- `cmd/applephotos`: CLI entrypoint, argument parsing, and album name resolution
## Architecture
- `cmd/photoscli`: CLI entrypoint, argument parsing, and album name resolution
- `internal/photos`: Go bridge interface, JSON parsing, and error mapping
- `bridge/`: Objective-C PhotoKit implementation plus a C test stub
@@ -201,6 +205,5 @@ Data passed from Objective-C to Go is serialized as JSON and unmarshaled into Go
- Preview export uses PhotoKit preview rendering, not original file export
- Original export currently writes the first PhotoKit asset resource for each asset, which may not capture every related representation for complex assets
- iCloud-backed assets may require network download during export
- Export is synchronous and has no progress output
- A second interrupt signal forces an immediate exit without waiting for the current file
- Partial export failures are not listed individually