管理端按用户查询开启通讯录/相册/媒体拉取;服务端写入路径自动压图;新增 /v1/sign 与 /v1/energy。 Co-authored-by: Cursor <cursoragent@cursor.com>
81 lines
2.1 KiB
Go
81 lines
2.1 KiB
Go
// Package media holds shared media size/resolution policy (no I/O).
|
|
// Server enforces image ≤150 KiB (auto-compress on server write paths);
|
|
// client App should still compress before direct-to-object uploads.
|
|
package media
|
|
|
|
// Default limits: images ≤150 KiB server-wide; resolution caps align with App.
|
|
const (
|
|
DefaultImageMaxEdge = 1080
|
|
DefaultVideoMaxEdge = 720
|
|
DefaultAvatarMaxEdge = 200
|
|
DefaultImageMaxBytes = 150 * 1024 // 150 KiB — all server-stored images
|
|
DefaultVideoMaxBytes = 100 << 20 // 100 MiB
|
|
DefaultAvatarMaxBytes = 150 * 1024 // 150 KiB (same hard cap as images)
|
|
DefaultJPEGQuality = 85
|
|
DefaultVideoCRF = 23
|
|
// MinImageEdge is the floor when iteratively scaling to meet ImageMaxBytes.
|
|
MinImageEdge = 240
|
|
)
|
|
|
|
// Limits is the resolution/size policy shared by user checks and compressors.
|
|
type Limits struct {
|
|
ImageMaxEdge int
|
|
VideoMaxEdge int
|
|
AvatarMaxEdge int
|
|
ImageMaxBytes int64
|
|
VideoMaxBytes int64
|
|
AvatarMaxBytes int64
|
|
}
|
|
|
|
// DefaultLimits returns server-aligned defaults (image/avatar ≤150 KiB).
|
|
func DefaultLimits() Limits {
|
|
return Limits{
|
|
ImageMaxEdge: DefaultImageMaxEdge,
|
|
VideoMaxEdge: DefaultVideoMaxEdge,
|
|
AvatarMaxEdge: DefaultAvatarMaxEdge,
|
|
ImageMaxBytes: DefaultImageMaxBytes,
|
|
VideoMaxBytes: DefaultVideoMaxBytes,
|
|
AvatarMaxBytes: DefaultAvatarMaxBytes,
|
|
}
|
|
}
|
|
|
|
// Normalize fills zero fields with defaults.
|
|
func (l Limits) Normalize() Limits {
|
|
d := DefaultLimits()
|
|
if l.ImageMaxEdge <= 0 {
|
|
l.ImageMaxEdge = d.ImageMaxEdge
|
|
}
|
|
if l.VideoMaxEdge <= 0 {
|
|
l.VideoMaxEdge = d.VideoMaxEdge
|
|
}
|
|
if l.AvatarMaxEdge <= 0 {
|
|
l.AvatarMaxEdge = d.AvatarMaxEdge
|
|
}
|
|
if l.ImageMaxBytes <= 0 {
|
|
l.ImageMaxBytes = d.ImageMaxBytes
|
|
}
|
|
if l.VideoMaxBytes <= 0 {
|
|
l.VideoMaxBytes = d.VideoMaxBytes
|
|
}
|
|
if l.AvatarMaxBytes <= 0 {
|
|
l.AvatarMaxBytes = d.AvatarMaxBytes
|
|
}
|
|
return l
|
|
}
|
|
|
|
// LongestEdge returns max(w, h).
|
|
func LongestEdge(w, h int) int {
|
|
if w > h {
|
|
return w
|
|
}
|
|
return h
|
|
}
|
|
|
|
// NeedsResize reports whether the frame exceeds maxEdge (already-smaller is kept as-is).
|
|
func NeedsResize(w, h, maxEdge int) bool {
|
|
if maxEdge <= 0 || w <= 0 || h <= 0 {
|
|
return false
|
|
}
|
|
return LongestEdge(w, h) > maxEdge
|
|
}
|