Uploads skip per-gallery duplicates, checksums can be backfilled, and STORAGE_BACKEND plus sync tooling make switching storage backends safe.
32 lines
1022 B
Go
32 lines
1022 B
Go
// Package checksum defines the content hash used to spot duplicate photos and
|
|
// the backfill that fills it in for photos uploaded before it existed.
|
|
//
|
|
// The hash is sha256 over the untouched original bytes, hex encoded, stored in
|
|
// photos_photos.checksum. Duplicate scope is one gallery — the unique index is
|
|
// on (gallery_id, checksum) — so the same image may still live in several
|
|
// galleries, each with its own row and its own stored object.
|
|
package checksum
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"hash"
|
|
"io"
|
|
)
|
|
|
|
// New returns a fresh hasher. Upload hashes as it spools the body, so it needs
|
|
// the writer rather than a finished reader.
|
|
func New() hash.Hash { return sha256.New() }
|
|
|
|
// Format renders a hasher's digest the way it is stored.
|
|
func Format(h hash.Hash) string { return hex.EncodeToString(h.Sum(nil)) }
|
|
|
|
// Sum reads r to EOF and returns its digest.
|
|
func Sum(r io.Reader) (string, error) {
|
|
h := New()
|
|
if _, err := io.Copy(h, r); err != nil {
|
|
return "", err
|
|
}
|
|
return Format(h), nil
|
|
}
|