68 lines
No EOL
2.7 KiB
Markdown
68 lines
No EOL
2.7 KiB
Markdown
# [WIP] minna-pima
|
||
|
||
> Picture manager intended for usage with Minna.
|
||
|
||
**minna-pima** integrates with [minna-caos](https://git.moritzruth.de/minna/minna-caos) to provide picture management features.
|
||
|
||
Similarly to the latter, it is intended as a companion to a single application (“the app”) that has full authority.
|
||
|
||
|
||
## Features
|
||
|
||
- automatic conversion of unwanted file formats
|
||
|
||
- [ThumbHash](https://evanw.github.io/thumbhash/) generation
|
||
|
||
- on-demand resizing and format conversion (without caching, see below)
|
||
|
||
- similarity search for finding duplicates
|
||
|
||
- CLI for administrative tasks
|
||
|
||
|
||
## Notes
|
||
|
||
### Pictures are not cached
|
||
|
||
minna-pima does not cache the pictures it generates on-demand.
|
||
This is by design: Caching is hard and better left to tools designated for this purpose.
|
||
It is therefore recommended to use a caching reverse-proxy in front of minna-pima.
|
||
|
||
<!-- TODO: example configuration for Caddy with https://github.com/darkweak/souin#caddy-module -->
|
||
|
||
|
||
### Example picture upload flow
|
||
|
||
1. The client uploads a PNG file to minna-caos in cooperation with the app.
|
||
2. Because minna-caos detected that the file is a PNG image, the app decides to use minna-pima.
|
||
3. The app sends a `GET /objects/ORIGINAL_UPLOAD_HASH/similar` request to minna-pima:
|
||
1. minna-pima fetches the object’s content and media type from minna-caos.
|
||
2. minna-pima computes a perceptual hash of the picture and uses it to search its database for similar pictures.
|
||
3. It finds two matching pictures and returns the following result:
|
||
```json
|
||
{
|
||
"similar_picture_ids": ["abc123", "def456"]
|
||
}
|
||
```
|
||
|
||
4. The app notifies the client that there are similar pictures.
|
||
5. The user decides that…
|
||
1. the first picture is unrelated, and
|
||
2. the second picture is a lower-quality version of the uploaded picture and should be replaced by the higher-quality version.
|
||
6. The client notifies the app of the user’s decision.
|
||
7. The app creates a new upload through minna-caos. Its ID is `CONVERTED_UPLOAD_ID`.
|
||
8. The app sends a `POST /pictures/` request to _`minna_pima`_ with the following payload:
|
||
```json
|
||
{
|
||
"hash": "ORIGINAL_UPLOAD_HASH",
|
||
"upload_id": "CONVERTED_UPLOAD_ID",
|
||
"replaces": ["def456"]
|
||
}
|
||
```
|
||
1. minna-pima fetches the content and the media type of the object from minna-caos.
|
||
2. minna-pima generates a ThumbHash and converts the picture to AVIF because PNG is not in the list of allowed source formats.
|
||
3. minna-pima uploads the picture to minna-caos using `PATCH /uploads/CONVERTED_UPLOAD_ID`.
|
||
|
||
9. The app waits for the `CONVERTED_UPLOAD_ID` upload to finish. The new picture’s ID is also `CONVERTED_UPLOAD_ID`.
|
||
|
||
A 100×100 WebP version could then, for example, be fetched from `/pictures/CONVERTED_UPLOAD_ID/100x100.webp`. |