|
|
|
@@ -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
|
|
|
|
|