Documentation
¶
Overview ¶
Package media stores application media in a private bucket. A registry declares media kinds, uploads, renditions and access. Each item has an ordered manifest that is authoritative for retained source and derived files. A database journal records conditional manifest writes, pending allocations and exact retirement effects, including interrupted uploads and caches.
Scoped roots are tenant/<tenant>/app/<app>/<kind>/<item>/; versioned content uses the version as the physical item ID. Account media uses tenant/<tenant>/account/. Legacy roots remain documented in media/layout.
Index ¶
- Constants
- Variables
- func PageIncluded(f File) bool
- func ValidNamed(name string) bool
- type Animation
- type ArchiveStatus
- type Aspect
- type Avatars
- type Capabilities
- type Codec
- type CommitBody
- type CommitReceipt
- type CommitReply
- type CompleteReply
- type Config
- type CopyBody
- type CopyFrom
- type CopyOptions
- type CopyReply
- type CopyRequest
- type Crop
- type Deletion
- type Delivery
- type DeliveryMode
- type Dims
- type DownloadState
- type Edit
- type EditorImage
- type EncodeProgress
- type EncodeStatus
- type ErrorDetails
- type ErrorReply
- type Failure
- type File
- type FileInfo
- type FitMode
- type FolderNotEmptyError
- type Frame
- type GatewayRules
- type GetOptions
- type HLS
- type Image
- type ImageError
- type ImageFormat
- type ImageQuery
- type Kind
- type LimitError
- type MP4
- type MediaStatus
- type Multipart
- type MultipartReply
- type Object
- type ObjectVersion
- type Op
- type PageAnalysis
- type PageAnalysisMetrics
- type Part
- type PartBody
- type PartReply
- type PartRequest
- type PartsBody
- type PartsReply
- type PresetRule
- type PresetStatus
- type PresignBody
- type PresignPut
- type PresignReply
- type PresignRequest
- type Presigned
- type PresignedPart
- type PresignedRequest
- type Private
- type ProcessingCount
- type ProcessingEvent
- type ProcessingFailure
- type Public
- type PublicImage
- type PublicRendition
- type Publication
- type PublicationState
- type Publish
- type PutOptions
- type ReadOptions
- type ReadResult
- type Readiness
- type RefBody
- type RequestReply
- type Segment
- type Shape
- type SourceAdmission
- type Sprite
- type StagedCopy
- type Store
- type Subtitles
- type TicketBody
- type Track
- type TrackIndex
- type Upload
- type UploadAuthorizer
- type UploadError
- type UploadGrant
- type UploadRule
- type UploadTarget
- type VideoJobClass
- type VideoLimits
Constants ¶
const (
AccessFull = "full" // whole-item private access
)
const (
AccessNone = "none" // public files only (previews)
)
const (
AccessPartial = "partial" // exact authorized private files only
)
const AvatarPreset = "avatar"
AvatarPreset is the public preset a user-owned group's avatar shows.
const (
CodeAnimationNotAllowed = "animation_not_allowed" // 422: an animated image where the policy is AnimationReject
)
const (
CodeAnimationTooLong = "animation_too_long" // 422: more frames or seconds than the processor allows
)
const (
CodeAnimationUnsupported = "animation_unsupported" // 415: an AVIF/HEIF image sequence (decoded as one frame)
)
const (
CodeChecksum = "checksum_mismatch" // 422: stored bytes differ from the declared hash
)
const (
CodeConflict = "conflict" // 409: a path taken, or a new item's folder not empty
)
const (
CodeForbidden = "forbidden" // 403
)
const (
CodeImageTooLarge = "image_too_large" // 413: more pixels than the processor decodes
)
const ( // Image refusals (ImageError): the rules refuse the image; never a server fault. CodeImageTooSmall = "image_too_small" // 422: edited narrower than the public preset's MinWidth )
const (
CodeImageUnreadable = "image_unreadable" // 422: not a decodable image of its declared type
)
const (
CodeIncomplete = "incomplete" // 409: multipart parts missing
)
const (
CodeInvalid = "invalid_request" // 400
)
const (
CodeNotFound = "not_found" // 404: unknown kind, file or upload
)
const (
CodeNotUploaded = "not_uploaded" // 409: commit before the object landed
)
const (
CodeQuota = "quota_exceeded" // 413: owner quota
)
const (
CodeRate = "rate_limited" // 429
)
const (
CodeTooLarge = "too_large" // 413: over the Upload's MaxBytes
)
const (
CodeTooManyFiles = "too_many_files" // 409: the commit would exceed an Upload's Max
)
const (
CodeType = "type_not_allowed" // 415
)
const (
)
const (
CodeUpgrade = "upgrade_required" // 503: the item's publication is being restored
)
const ( // CodeVideoAspectUnsupported: the display aspect is outside its HLS // presets' MinAspect and MaxAspect. CodeVideoAspectUnsupported = "video_aspect_unsupported" // 422 )
const (
CodeVideoOverBudget = "video_over_budget" // 422: the planned encode is over MaxWork, or the source averages under a frame a second
)
const (
CodeVideoTooLarge = "video_too_large" // 422: frames larger than MaxPixels
)
const ( // Video refusals (ImageError, recorded as the upload's Failure): its // Upload.Video limits refuse what the real stream would cost. CodeVideoTooLong = "video_too_long" // 422: runs longer than MaxSeconds (audio too) )
const CookieName = token.CookieName
CookieName is the media gateway's cookie.
const CoverPreset = "cover"
CoverPreset is the public preset a content's or a group's cover shows.
const (
DefaultMaxAspect = 2.4
)
const (
DefaultMinAspect = 1 / 2.4
)
const (
EventProcessingCompleted = "media.processing_completed"
)
const (
EventProcessingProgressed = "media.processing_progressed"
)
const (
HLSContentType = "application/vnd.apple.mpegurl"
)
const ItemProgressKey = ""
ItemProgressKey carries Item in a job's reported map.
const ManifestVersion = 3
ManifestVersion is the manifest format.
const (
MaxAudioTracks = 8
)
const (
MaxItemMetaBytes = 16 << 10 // the item's meta, as JSON
)
const (
MaxManifestBytes = 8 << 20
)
const (
MaxMetaBytes = 4 << 10 // an upload's meta, as JSON
)
const (
MaxPartSize = 16 << 20
)
const (
MaxSinglePut = 64 << 20
)
const (
MaxSubtitleTracks = 16
)
const (
MaxUploads = 10000
)
const (
MetaAutoCover = "auto_cover" // automatic cover ownership; explicit uploads clear it
)
const (
MetaCharset = "charset" // a subtitle's IANA charset, overriding detection
)
const (
MetaFor = "for" // a subtitle's video upload path; default every video of the item
)
const (
MetaForced = "forced" // bool: a forced-narrative subtitle track
)
const (
MetaLabel = "label" // a track's name
)
const (
MetaLang = "lang" // subtitles and audio: BCP 47
)
const (
MinPartSize = 8 << 20
)
const NamedPrefix = "i-"
NamedPrefix starts the names the server gives Named uploads.
const (
OpAttach = "attach" // make an unattached upload part of the item
)
const (
OpCopy = "copy" // copy an upload within the kind (CopyFrom), optionally with a new edit
)
const (
OpEdit = "edit" // crop and rotate an image upload; nil clears
)
const (
OpFrame = "frame" // fill an upload from a frame of its Upload.Frames video, or of another item's (From)
)
const (
OpMeta = "meta" // set the template values (download names)
)
const (
OpMove = "move" // reorder an upload among its Upload's; its outputs follow
)
const (
OpPut = "put" // add an upload, or replace the one with the same path stem
)
const (
OpRegenerate = "regenerate" // redo stale outputs and retry failed uploads (of Preset), or every output with Force
)
const (
OpRemove = "remove" // remove an upload and its outputs
)
const (
OpRename = "rename" // rename an upload and its outputs
)
const PageAnalysisRecipe = "page-analysis-v1"
PageAnalysisRecipe versions the evidence independently of image renditions.
const (
PhaseDownloading = "downloading" // fetching the original
)
const (
PhaseEncoding = "encoding" // the single ffmpeg pass: ladder, audio, subtitles, sprite
)
const (
PhaseImages = "images" // item-wide, after every file: poster frame from the renditions
)
const (
PhaseMuxing = "muxing" // per-quality MP4 downloads
)
const (
PhaseProbing = "probing"
)
const (
PhasePublishing = "publishing" // the manifest edit
)
const (
PhaseQueued = "queued"
)
const (
PhaseUploading = "uploading"
)
const PublicationLayoutVersion = 1
PublicationLayoutVersion marks explicit separation of retained sources, prepared files and served files in a version-owned item.
const StartRung = 1080
StartRung is the short side of the variant listed first in each codec: native HLS players (Safari, iOS) start there before measuring.
const (
StateFailed = "failed"
)
const (
StateFull = "full" // the manifest is Full: work is left, stopped until a commit shrinks it
)
const (
StateProcessing = "processing"
)
const (
StateReady = "ready"
)
const (
TrackAudio = "audio"
)
const (
TrackSprite = "sprite"
)
const (
TrackSubs = "subs"
)
const (
TrackVideo = "video"
)
const (
VTTContentType = "text/vtt; charset=utf-8"
)
const (
VideoAnimation = "animation"
)
const (
VideoLive = ""
)
const ZipRecipe = "zip-source-names-2"
ZipRecipe versions the Zip producer.
Variables ¶
var (
AspectNative = Aspect{}
)
var DefaultEditor = Image{Width: 2048, Height: 2048, Quality: 82}
DefaultEditor renders editor views.
var DefaultLadder = []int{2160, 1080, 480}
DefaultLadder is the HLS ladder by short side.
var DefaultVideoLimits = VideoLimits{MaxSeconds: 4 * 3600, MaxFPS: 60, MaxPixels: 8192 * 4320, MaxWork: 4e13}
DefaultVideoLimits are an upload's VideoLimits where it sets none: 4 h at up to 60 fps, frames up to DCI 8K (8192×4320; the ladder scales larger sources down to 4K), and the work of a 4 h 4K60 default ladder (2160, 1080, 480) in three codecs plus MP4 downloads, about 3e13 pixel-frames.
var EncodePhases = []string{PhaseQueued, PhaseDownloading, PhaseProbing, PhaseEncoding, PhaseMuxing, PhaseUploading, PhasePublishing, PhaseImages}
EncodePhases lists every phase in order.
var ErrFolderNotEmpty = errors.New("media: new item's folder is not empty")
ErrFolderNotEmpty: a new item's folder already holds objects. Item ids are never reused, so leftovers mean a host bug (a reset id, a restored database); they are never adopted. Purge them deliberately with Jobs.Purge.
var ErrRateLimited = errors.New("media: rate limited")
ErrRateLimited is a refusal that a later attempt will pass.
var ( // HTTP handlers answer 503. ErrUnavailable = errors.New("media: store unavailable") )
var ImageTypes = []string{"image/jpeg", "image/png", "image/webp", "image/gif", "image/avif", "image/heic", "image/heif", "image/tiff"}
ImageTypes are the image types the image presets decode (media/image); an upload feeding one accepts no other. SVG, BMP and JPEG XL are refused: their libvips loaders are blocked as untrusted.
var (
Square = Aspect{1, 1}
)
Functions ¶
func PageIncluded ¶ added in v0.99.0
PageIncluded is the planner's persisted effective selection. An ordinary upload or an older page without a decision remains included.
func ValidNamed ¶ added in v0.62.0
ValidNamed reports a server-given name ("i-{uuid}").
Types ¶
type Animation ¶ added in v0.39.0
type Animation string
Animation is a policy for animated images (GIF, WebP; AVIF/HEIF sequences are refused as animation_unsupported, never flattened).
const ( // AnimationAllow keeps every frame, delay and the loop count. AnimationAllow Animation = "" )
const ( // AnimationReject refuses an animated upload with animation_not_allowed. AnimationReject Animation = "reject" )
type ArchiveStatus ¶ added in v0.125.0
type ArchiveStatus struct {
ProcessingCount
Pages *ProcessingCount `json:"pages,omitempty"`
}
ArchiveStatus counts source ZIPs and, once validation has determined the expected entries, the pages actually committed by the ingest worker. Page counts are persisted progress, not a claim that a worker is running.
type Aspect ¶ added in v0.40.0
type Aspect struct{ W, H int }
Aspect is a width:height ratio in lowest terms, written "W:H" ("3:1", "9:16"). The zero value is AspectNative: the source's own shape.
func ParseAspect ¶ added in v0.40.0
ParseAspect parses "W:H" with positive integer terms up to 10000 and reduces it ("6:2" is "3:1"); "" and "native" are AspectNative.
func Ratio ¶ added in v0.40.0
Ratio parses "W:H" and panics on an invalid one (for constants in code).
func (Aspect) Height ¶ added in v0.40.0
Height is width's height at a, rounded half up, at least 1 (0 when native).
func (Aspect) MarshalText ¶ added in v0.40.0
MarshalText writes "W:H" (native: empty), so JSON and config carry the string.
func (*Aspect) UnmarshalText ¶ added in v0.40.0
type Avatars ¶ added in v0.71.0
Avatars is Config.Avatars: Kind's items are people's accounts, keyed by the host auth's subject (auth.Identity.Subject), such as the shared accounts kind "user", and Preset is the public image each is shown with.
type Capabilities ¶
type Capabilities struct {
ConditionalPut bool // If-Match / If-None-Match on PUT
ChecksumSHA256 bool // x-amz-checksum-sha256 enforced on PUT
}
Capabilities are backend features the library depends on, established by Probe.
type Codec ¶ added in v0.53.0
type Codec string
Codec is a video codec of an HLS ladder: each rung is encoded in each of the worker's codecs (Track.Codec).
const (
CodecAV1 Codec = "av1"
)
const (
CodecH264 Codec = "h264"
)
const (
CodecHEVC Codec = "hevc"
)
type CommitBody ¶
type CommitBody struct {
Ref RefBody `json:"ref"`
OperationID string `json:"operation_id"` // stable UUID for this complete ordered batch
Ops []Op `json:"ops"`
}
CommitBody applies ops to an item in one conditional write.
type CommitReceipt ¶ added in v0.68.0
CommitReceipt proves which prepared attempt reached S3. Every writer keeps the receipt until recovery has settled it; it is not an authorization token.
type CommitReply ¶
type CommitReply struct {
Files []FileInfo `json:"files"`
}
CommitReply is the item's uploads as an editor reads them.
type CompleteReply ¶
type CompleteReply struct {
Blob string `json:"blob"`
Type string `json:"type"`
Size int64 `json:"size"`
}
CompleteReply is a completed multipart upload; Blob is its staged name.
type Config ¶ added in v0.62.0
type Config struct {
// Namespace is the app's own namespace, e.g. "doujins": its kinds' items
// live under {Namespace}/{kind}/{id}/.
Namespace string `json:"namespace,omitempty"`
// Scope derives object roots and internal partitions; Namespace is legacy-only.
Scope layout.Scope `json:"scope,omitzero"`
// BaseURL is the site's media origin, e.g. "https://media.doujins.ai":
// every URL is {BaseURL}/v1/{namespace}/{kind}/{id}/{public|private}/{name}.
BaseURL string `json:"base_url,omitempty"`
// Kinds are the app's kinds plus the shared kinds it imports.
Kinds []Kind `json:"kinds"`
// Avatars names people's avatars: content shows them beside comment
// authors and in moderation lists. Zero: people have none.
Avatars Avatars `json:"avatars,omitzero"`
// Editor is how editor views render (the whole oriented source the
// cropper draws on); zero is DefaultEditor.
Editor Image `json:"editor,omitzero"`
}
Config is the app's media registry, as data (NewRegistry).
func ForContent ¶ added in v0.81.0
ForContent derives c from the site's one kinds list: a media kind named after a content kind is that kind's, of Versions, in the app's namespace; every entity kind without one declared gets GroupKind's. No other kind has versions.
func ParseConfig ¶ added in v0.62.0
ParseConfig reads a registry written by Registry.MarshalJSON; unknown keys are ignored.
type CopyBody ¶ added in v0.81.0
type CopyBody struct {
Ref RefBody `json:"ref"`
Files []CopyRequest `json:"files"`
}
CopyBody stages server-side copies of keys of the item's bucket outside ContentKit's namespaces (an importer's), for one commit's puts.
type CopyFrom ¶ added in v0.62.0
type CopyFrom struct {
Kind string `json:"kind,omitempty"` // frame only
ID string `json:"id"`
Version string `json:"version,omitempty"`
Path string `json:"path"`
}
CopyFrom names an upload of an item of the same kind, including this item: of a versioned kind, one version's. Into a published kind's item, it names a file of a version of the kind it publishes: an upload, or a finished output, which comes alone, as an upload. A frame op's names a video upload of any item in the namespace (Kind, default this item's) the editor may edit; the worker grabs it once.
type CopyOptions ¶ added in v0.40.0
type CopyOptions struct {
IfMatch string
ContentType string
// Metadata merges trusted operation receipts into the copied object's
// existing metadata as part of the server-side copy itself.
Metadata map[string]string
}
CopyOptions: IfMatch copies only while the source's ETag is this one (ErrPreconditionFailed otherwise); ContentType replaces the source's.
type CopyReply ¶ added in v0.81.0
type CopyReply struct {
Files []StagedCopy `json:"files"`
}
CopyReply is each copy's path to commit and staged blob, in order.
type CopyRequest ¶ added in v0.81.0
type CopyRequest struct {
Path string `json:"path"`
Type string `json:"type"`
From string `json:"from"`
Size int64 `json:"size,omitempty"` // checked when > 0
}
CopyRequest stages a server-side copy of From, a key of the item's bucket outside ContentKit's namespaces, as an upload at Path.
type Deletion ¶
type Deletion struct {
Ref contentref.ContentRef
Owner string
OperationID string // required by Purge with a quota owner; stable across retries
}
Deletion is one item to delete. Owner is its quota owner (UploadGrant.Owner), "" for none; with a Limiter configured the owner's usage is released. OperationID is required for Purge; queued deletion uses its River job id.
type Delivery ¶
type Delivery struct {
Mode DeliveryMode
// CookieDomain is the site's registrable domain, e.g. "doujins.ai";
// required in cookie mode, because a host-only cookie never reaches media.
CookieDomain string
// SigningKey is the current key of the ring the media gateway verifies.
SigningKey token.Key
// TTL is the minimum token lifetime (default 1h); expiries round up to
// Window (default token.DefaultWindow, whole seconds).
TTL, Window time.Duration
}
Delivery is the host's signing configuration; URLs are at the registry's BaseURL.
type DeliveryMode ¶
type DeliveryMode string
DeliveryMode is how viewers with access present their item token.
const ( // DeliverCookie (default) sets the item cookie; URLs are plain. DeliverCookie DeliveryMode = "cookie" )
const ( // DeliverURL appends ?t= to every URL: apps and clients without cookies. DeliverURL DeliveryMode = "url" )
type DownloadState ¶ added in v0.87.0
type DownloadState int
DownloadState is how far an item's Download file is.
const ( DownloadNone DownloadState = iota // nothing to serve: no source, a failed or dropped one DownloadPending // still being placed or produced DownloadReady )
type Edit ¶ added in v0.17.0
type Edit struct {
Crop *Crop `json:"crop,omitempty"`
Rotate int `json:"rotate,omitempty"` // clockwise degrees: 0, 90, 180 or 270
}
Edit is a non-destructive image edit: Crop, in the source's pixels (EXIF orientation applied), then a clockwise Rotate. Variants derive from the source through it; the source is never modified.
func (*Edit) Check ¶ added in v0.17.0
Check validates the edit's shape and, with a known size (w, h > 0), that the crop lies inside it.
type EditorImage ¶ added in v0.68.0
EditorImage records the rendered view's allocation and source/spec fingerprint.
type EncodeProgress ¶ added in v0.29.0
type EncodeProgress struct {
Phase string `json:"phase"`
QueuePosition int `json:"queue_position,omitempty"` // 1 = next; 0 = unknown or behind a file of the same job
SegmentsDone int `json:"segments_done,omitempty"`
SegmentsTotal int `json:"segments_total,omitempty"`
Percent float64 `json:"percent"`
Speed float64 `json:"speed,omitempty"`
ETA float64 `json:"eta,omitempty"`
At int64 `json:"at"` // unix milliseconds of the measurement
Stalled bool `json:"stalled,omitempty"`
// Stage of Stages: each rung is published before the next one starts.
Stage int `json:"stage,omitempty"`
Stages int `json:"stages,omitempty"`
}
EncodeProgress is a pending video file's live encode state. Segments count HLS segments of the source's duration; Speed is the encode's smoothed ×realtime; ETA is seconds from At to publish, including uploads. Percent never decreases within a run. Stalled marks a report older than a minute from a running job (a dead worker until River rescues the job).
type EncodeStatus ¶ added in v0.29.0
type EncodeStatus struct {
Files map[string]EncodeProgress
Queued *EncodeProgress
Item *EncodeProgress
}
EncodeStatus is an item's encode progress: Files from the running job, Queued for pending files it does not cover (a waiting job), Item for the job's item-wide step (PhaseImages).
func (EncodeStatus) Current ¶ added in v0.29.0
func (s EncodeStatus) Current() *EncodeProgress
Current is the item's most advanced step: the item-wide one, a running file, else the wait.
type ErrorDetails ¶ added in v0.38.0
type ErrorDetails struct {
Width int `json:"width,omitempty"` // image_too_small: the edited width; image_too_large, video_too_large, video_aspect_unsupported: the source's
Height int `json:"height,omitempty"` // image_too_large, video_too_large, video_aspect_unsupported: the source's
MinWidth int `json:"min_width,omitempty"` // image_too_small
MaxPixels int `json:"max_pixels,omitempty"` // image_too_large, video_too_large
Type string `json:"type,omitempty"` // the declared type (image_unreadable, type_not_allowed, too_large)
Allowed []string `json:"allowed,omitempty"` // type_not_allowed: the kind's types
Size int64 `json:"size,omitempty"` // too_large: bytes
MaxBytes int64 `json:"max_bytes,omitempty"` // too_large
Frames int `json:"frames,omitempty"` // animation_too_long, image_too_large: the animation's
MaxFrames int `json:"max_frames,omitempty"` // animation_too_long
Seconds float64 `json:"seconds,omitempty"` // animation_too_long, video_too_long: running time
MaxSeconds float64 `json:"max_seconds,omitempty"` // animation_too_long, video_too_long
MinAspect float64 `json:"min_aspect,omitempty"` // video_aspect_unsupported: the narrowest width/height accepted
MaxAspect float64 `json:"max_aspect,omitempty"` // video_aspect_unsupported: the widest width/height accepted
Max int `json:"max,omitempty"` // too_many_files: the files allowed; comment_too_long: the characters allowed
}
ErrorDetails qualifies an image refusal so clients can state the rule.
type ErrorReply ¶
type ErrorReply struct {
Error string `json:"error"`
Code string `json:"code"`
RetryAfter int `json:"retry_after,omitempty"` // seconds, with 429
Blobs []string `json:"blobs,omitempty"` // not_uploaded at commit: the blobs to upload again
Details *ErrorDetails `json:"details,omitempty"` // image refusals
}
ErrorReply is the error body; Code is one of the Code* constants, "unauthorized" or "internal_error".
type Failure ¶ added in v0.62.0
type Failure struct {
Of string `json:"of"` // File.Key it was recorded for
Message string `json:"message"`
Code string `json:"code,omitempty"` // an ImageError's code
Details *ErrorDetails `json:"details,omitempty"`
}
Failure is why an upload's blob through its edit cannot be processed.
type File ¶
type File struct {
Path string `json:"path"` // app path: "originals/001.png", "low-res/001.webp"
Blob string `json:"blob,omitempty"` // "sha256-{hex}-{uuid}" in private/; "" for a staged upload or a frame not grabbed yet
Type string `json:"type"`
Size int64 `json:"size,omitempty"`
W int `json:"w,omitempty"` // an upload's oriented size once measured; an output's size
H int `json:"h,omitempty"`
Dur float64 `json:"dur,omitempty"`
// Uploads:
Admission *SourceAdmission `json:"admission,omitempty"` // verified ZIP source quota policy, never client-supplied
Staged string `json:"staged,omitempty"` // "u-{uuid}" in temp/ until the worker hashes and places it at Blob
CreateID string `json:"create_id,omitempty"` // create-only put receipt; retained through placement and processing
Edit *Edit `json:"edit,omitempty"` // crop and rotate in source pixels
Frame *Frame `json:"frame,omitempty"` // grabbed from a video (the frame op)
Meta map[string]any `json:"meta,omitempty"` // lang, label, …
Unattached bool `json:"unattached,omitempty"` // processed on upload, not yet part of the item
Gone bool `json:"gone,omitempty"` // blob dropped (KeepOriginals false); the hash stays for provenance
Pending []string `json:"pending,omitempty"` // presets still producing from this upload
Failed *Failure `json:"failed,omitempty"` // this blob and edit cannot be processed
Public []Publication `json:"public,omitempty"` // reserved or published public generations
Editor *EditorImage `json:"editor,omitempty"` // selected immutable editor view, never listed to ordinary readers
// Derived files:
From string `json:"from,omitempty"` // the upload's path, or a zip's prefix
Preset string `json:"preset,omitempty"` // the Private preset
FP string `json:"fp,omitempty"` // Fingerprint of its inputs
Download string `json:"download,omitempty"` // the human download name
Track *Track `json:"track,omitempty"` // HLS
}
File is one file: an upload (no Preset) or a derived file.
func (File) Current ¶ added in v0.69.0
func (f File) Current(preset string) (Publication, bool)
Current returns the upload's ready generation of preset.
func (File) Fail ¶ added in v0.62.0
Fail is the upload's failure for its current blob and edit, or nil.
func (File) HasPageAnalysis ¶ added in v0.99.0
func (File) Key ¶ added in v0.62.0
Key identifies the source and edit an upload's Failure applies to.
func (File) Publication ¶ added in v0.68.0
func (f File) Publication(preset string) (Publication, bool)
Publication returns the upload's latest generation of preset: its reserved successor if any, else its current one.
type FileInfo ¶
type FileInfo struct {
Path string `json:"path"`
Type string `json:"type"`
Size int64 `json:"size,omitempty"`
W int `json:"w,omitempty"`
H int `json:"h,omitempty"`
Dur float64 `json:"dur,omitempty"`
Download string `json:"download,omitempty"` // the name a download read serves it under
URL string `json:"url,omitempty"`
// Editors (editor reads and commit replies):
PageID string `json:"page_id,omitempty"` // original page bytes' SHA-256, not filename, position or rendition hash
CreateID string `json:"create_id,omitempty"`
Upload bool `json:"upload,omitempty"`
Staged bool `json:"staged,omitempty"` // uploaded, not yet placed by the worker: no blob, views or frames yet
From string `json:"from,omitempty"`
Edit *Edit `json:"edit,omitempty"`
Frame *Frame `json:"frame,omitempty"`
Meta map[string]any `json:"meta,omitempty"`
Unattached bool `json:"unattached,omitempty"`
Pending []string `json:"pending,omitempty"`
Failed *Failure `json:"failed,omitempty"`
EditorURL string `json:"editor_url,omitempty"`
Progress *EncodeProgress `json:"progress,omitempty"`
}
FileInfo is one file of a read.
type FitMode ¶ added in v0.62.0
type FitMode string
FitMode is how an image fits its Width×Height box.
const (
FitCover FitMode = "cover"
)
const (
FitInside FitMode = "" // within the box, keeping the aspect
)
type FolderNotEmptyError ¶ added in v0.45.0
FolderNotEmptyError names the folder and a few of its keys.
func (*FolderNotEmptyError) Error ¶ added in v0.45.0
func (e *FolderNotEmptyError) Error() string
func (*FolderNotEmptyError) Unwrap ¶ added in v0.45.0
func (e *FolderNotEmptyError) Unwrap() error
type Frame ¶ added in v0.62.0
type Frame struct {
T float64 `json:"t,omitempty"`
Auto bool `json:"auto,omitempty"`
Of string `json:"of,omitempty"`
From *CopyFrom `json:"from,omitempty"`
}
Frame is an upload grabbed from a frame of its Upload.Frames video: the one a player shows T seconds in; Auto lets the worker choose T. Of is the video blob it was grabbed from: a new video grabs again. From names another item's video instead (Kind always set): grabbed once, it is a still that video's changes leave alone.
type GatewayRules ¶ added in v0.65.0
type GatewayRules struct {
Namespaces []string
// Scopes are the exact scoped roots; build gateway.Routes for these.
Scopes []layout.Scope
Defaults []layout.Default
}
GatewayRules are the media gateway's rules for an app's media host: the namespaces it serves there (MEDIA_GATEWAY_HOSTS, with layout.FormatHosts; each one's bucket in MEDIA_GATEWAY_BUCKETS) and the default public names of its kinds (MEDIA_GATEWAY_DEFAULTS, with layout.FormatDefaults).
type GetOptions ¶
GetOptions: IfNoneMatch returns ErrNotModified on a match; Range is an HTTP Range value.
type HLS ¶
type HLS struct {
// Ladder is the rendition short sides, largest first; empty is DefaultLadder.
Ladder []int `json:"ladder,omitempty"`
// MinAspect and MaxAspect bound the source's display width/height; zero
// is DefaultMinAspect and DefaultMaxAspect. A source outside fails.
MinAspect float64 `json:"min_aspect,omitempty"`
MaxAspect float64 `json:"max_aspect,omitempty"`
Profile string `json:"profile,omitempty"` // VideoLive or VideoAnimation
}
HLS is a byte-range fMP4 ladder, one blob per rendition, with the source's audio and subtitle tracks and a seek sprite. A rung above the source is not produced.
type Image ¶ added in v0.62.0
type Image struct {
Format ImageFormat `json:"format,omitempty"`
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Fit FitMode `json:"fit,omitempty"`
Quality int `json:"quality,omitempty"` // default 80
Blur float64 `json:"blur,omitempty"`
// Aspect and MinWidth bound an upload's edit when this is its public
// preset's image: the crop is fitted to Aspect, and an edit narrower
// than MinWidth fails.
Aspect Aspect `json:"aspect,omitzero"`
MinWidth int `json:"min_width,omitempty"`
Animation Animation `json:"animation,omitempty"`
}
Image is a rendering, WebP by default. Source-format private presets retain the upload's codec and copy unchanged bytes when no resize/edit is needed. Resizing and editing in source format support JPEG, PNG, WebP and GIF. Zero Width and Height keep the full size; nothing is upscaled.
func (Image) Resolve ¶ added in v0.62.0
Resolve is the edit im applies to a w×h source (EXIF-oriented): e with its crop height fitted to Aspect, or without a crop the largest centred one at Aspect (a native aspect: the whole source). It must lie inside the source and be at least MinWidth wide once edited.
type ImageError ¶ added in v0.38.0
type ImageError struct {
Code string
Message string
Details ErrorDetails
}
ImageError is an image the rules refuse, synchronously (an edit checked against known dims) or in the image job (recorded as the upload's Failure).
func (*ImageError) Error ¶ added in v0.38.0
func (e *ImageError) Error() string
type ImageFormat ¶ added in v0.102.0
type ImageFormat string
ImageFormat selects WebP encoding or the upload's original codec.
const ( // ImageFormatSource preserves the upload's codec in a private preset. ImageFormatSource ImageFormat = "source" )
const ( // ImageFormatWebP is the default for all images and the only format for // public presets and editor previews. ImageFormatWebP ImageFormat = "" )
type ImageQuery ¶ added in v0.69.0
type ImageQuery struct {
Ref contentref.ContentRef
Preset string
Name string
}
ImageQuery selects an item's current public images: all of them, or only those of a Preset, of an upload Name (its path's {name}, e.g. an inline image's "i-{uuid}"), or both.
type Kind ¶
type Kind struct {
Name string `json:"name"`
// Namespace is "" for Config.Namespace, or a shared one such as
// "accounts" whose items every app importing the kind serves.
Namespace string `json:"namespace,omitempty"`
// Account places this kind in the tenant account root of a scoped registry.
Account bool `json:"account,omitempty"`
// Versions marks a content kind (ForContent). Each version owns its
// folder; its parent content exists in the catalog, not in storage.
Versions bool `json:"versions,omitempty"`
// Publish describes the existing files a version's reader can use.
// Published snapshots contain metadata, not separate media folders.
Publish *Publish `json:"publish,omitempty"`
Uploads []Upload `json:"uploads"`
// KeepOriginals keeps an upload's blob once its private outputs exist;
// version-owned content always retains its originals independently of this flag.
// otherwise it is dropped (File.Gone). Public presets' sources are
// always kept, so unhiding can render them again, as are body images,
// which new versions copy.
KeepOriginals bool `json:"keep_originals,omitempty"`
// ServeOriginals lists and serves uploads to viewers with access, like
// any private file. Otherwise viewer URLs are scoped to served files,
// not the whole private folder, and reads omit upload paths and blobs.
ServeOriginals bool `json:"serve_originals,omitempty"`
// Downloads are the upload paths and private presets (Image, MP4 or Zip)
// whose files live in download/: only a download token opens them and
// reads never list them. ForContent adds a content kind's originals, its
// zip and what the zip packs.
Downloads []string `json:"downloads,omitempty"`
// Download is what a version's download serves, one of Downloads: a
// literal upload (the original) or an MP4 or Zip preset. ForContent sets
// it from the content kind's download; "" serves none.
Download string `json:"download,omitempty"`
Private []Private `json:"private,omitempty"`
Public []Public `json:"public,omitempty"`
// Defaults holds the images the kind's public presets name in
// Public.Default, so a shared kind ships its own (go:embed). A registry
// read from JSON (the stock worker) has none; PublishDefaults needs them.
Defaults fs.FS `json:"-"`
}
Kind declares one kind of item: what may be uploaded, what is derived from the uploads in private/, and which public images it has. NewRegistry validates it into a RegisteredKind.
func EntityKind ¶ added in v0.117.0
func EntityKind(name string, gk kinds.EntityKind) Kind
GroupKind is a entity kind's media: named cover images ("cover/i-{uuid}"), and for kinds with avatars (kinds.GroupKind.HasAvatar) named avatars, each the group's selection (entities.Cover.Image) among them.
type LimitError ¶ added in v0.62.0
LimitError is ErrRateLimited with how long to wait.
func (*LimitError) Error ¶ added in v0.62.0
func (e *LimitError) Error() string
func (*LimitError) Is ¶ added in v0.62.0
func (e *LimitError) Is(target error) bool
type MP4 ¶ added in v0.62.0
MP4 is a muxed H.264 MP4 at one rung (short side), with the default audio.
type MediaStatus ¶ added in v0.125.0
type MediaStatus struct {
State string `json:"state"`
Uploads ProcessingCount `json:"uploads"`
Archives ArchiveStatus `json:"archives"`
Presets []PresetStatus `json:"presets"`
Encoding *EncodeProgress `json:"encoding,omitempty"`
FailureCount int `json:"failure_count"`
Failures []ProcessingFailure `json:"failures"`
}
MediaStatus is a read-only editor snapshot of all uploads, including staging. Unattached sources count placement and private processing; their public presets wait until attachment. This state is separate from publication readiness. Public presets count after attachment. An archive may have finished placement while still waiting for extraction. Encoding is the existing worker checkpoint, when available, never a new job or operation.
type Multipart ¶
Multipart carries the opaque ticket for PresignParts, ListParts, Complete and Abort, and the part-size bounds the client adapts within.
type MultipartReply ¶
type Object ¶
type Object struct {
Key string
Size int64
ETag string
ContentType string
CacheControl string
ContentRange string
LastModified time.Time
ChecksumSHA256 []byte // set when the backend stored a full-object SHA-256
Metadata map[string]string // user metadata (x-amz-meta-*), lower-case keys; Head and Get
}
Object is object metadata. For a ranged Get, Size is the body length and ContentRange is set.
type ObjectVersion ¶ added in v0.68.0
type ObjectVersion struct {
Key, VersionID string
}
ObjectVersion identifies immutable bytes in a versioned bucket.
type Op ¶
type Op struct {
Op string `json:"op"`
SourceName string `json:"source_name,omitempty"`
Path string `json:"path,omitempty"`
Blob string `json:"blob,omitempty"` // put: the staged upload (u-{uuid}) or a blob in the folder
CreateID string `json:"create_id,omitempty"` // put: create-only UUID; repeat the same ID to retry
Replace bool `json:"replace,omitempty"` // put: explicitly replace the target, including another source alias
Index *int `json:"index,omitempty"` // put, move, attach: among the attached uploads of its Upload
Meta map[string]any `json:"meta,omitempty"` // put, copy: upload meta; attach: merged; meta: item meta; remove: auto_cover guards ownership
Edit *Edit `json:"edit,omitempty"` // put, edit, copy, frame
Unattached bool `json:"unattached,omitempty"`
To string `json:"to,omitempty"` // rename, copy (default the source's path)
From *CopyFrom `json:"from,omitempty"` // copy; frame: the video
T *float64 `json:"t,omitempty"` // frame: the one a player shows t seconds in
Auto bool `json:"auto,omitempty"` // frame: the worker chooses
Preset string `json:"preset,omitempty"`
Force bool `json:"force,omitempty"`
// Takedown (remove) also removes the frames grabbed from the upload and
// the zips that bundled it, then deletes at once, not a grace period
// later, the blobs the commit dropped, the removed uploads' editor views
// and the public files no upload renders. With an exempt grant it deletes
// every private blob the item no longer references (earlier versions and
// every editor view too), and repeating it, the path already gone, runs
// that sweep again: how staff complete a takedown that failed part way.
Takedown bool `json:"takedown,omitempty"`
}
Op is one commit op.
type PageAnalysis ¶ added in v0.99.0
type PageAnalysis struct {
Recipe string `json:"recipe"`
SourceSHA256 string `json:"source_sha256"`
Status string `json:"status"` // complete | unsupported | failed
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Frames int `json:"frames,omitempty"`
PixelSHA256 string `json:"pixel_sha256,omitempty"`
PixelFormat string `json:"pixel_format,omitempty"`
ProfileSHA256 string `json:"profile_sha256,omitempty"`
Blank string `json:"blank"` // none | blank | suspected | unknown
BlankReason string `json:"blank_reason,omitempty"`
Confidence string `json:"confidence"` // exact | high | possible | unknown
Metrics PageAnalysisMetrics `json:"metrics,omitzero"`
Flags []string `json:"flags,omitempty"`
}
PageAnalysis is immutable evidence, not the reader's include/exclude decision. The planner owns duplicate keepers, ordering and manual overrides.
func ReadPageAnalysis ¶ added in v0.99.0
func ReadPageAnalysis(meta map[string]any) (PageAnalysis, bool)
ReadPageAnalysis accepts both newly typed values and JSON-decoded metadata.
type PageAnalysisMetrics ¶ added in v0.99.0
type PartReply ¶
type PartReply struct {
Number int32 `json:"number"`
Size int64 `json:"size,omitempty"`
SHA256 string `json:"sha256,omitempty"`
Request *RequestReply `json:"request,omitempty"`
}
PartReply is a presigned part (parts) or a landed part (parts/list).
type PartRequest ¶
PartRequest is one part to presign: its exact length and SHA-256.
type PartsReply ¶
type PartsReply struct {
Parts []PartReply `json:"parts"`
}
type PresetRule ¶ added in v0.68.0
type PresetRule struct {
Kind string `json:"kind"`
Name string `json:"name"`
From string `json:"from"`
Base string `json:"base"`
Namespace string `json:"namespace"`
// Root is the server-selected path before Kind, including its trailing slash.
Root string `json:"root,omitempty"`
To string `json:"to"`
Widths []int `json:"widths"`
// Aspect is the rendition's shape ("W:H"); absent keeps the edit's.
Aspect Aspect `json:"aspect,omitzero"`
// MinWidth is the narrowest edit the preset accepts.
MinWidth int `json:"min_width,omitempty"`
// First makes it a preview: the first First uploads, {n} in To.
First int `json:"first,omitempty"`
// Default: the gateway serves the kind's default image at the template's
// names while an item has no publication (Registry.DefaultImage).
Default bool `json:"default"`
// Stable: the template's names are also the current image's
// (Public.Stable), so clients build its URLs from an item's id.
Stable bool `json:"stable,omitempty"`
}
PresetRule is a kind's public preset: its upload, name template, widths and crop bounds. Published files carry a generation suffix, so {base}/v1/{namespace}/{kind}/{id}/public/{to} ({w} each of Widths) names the kind's default image (only when Default), never an item's current one: a read's Public lists those.
type PresetStatus ¶ added in v0.125.0
type PresetStatus struct {
Name string `json:"name"`
ProcessingCount
}
PresetStatus is progress for one configured rendition preset.
type PresignBody ¶
type PresignBody struct {
Ref RefBody `json:"ref"`
Path string `json:"path"`
Type string `json:"type"`
Size int64 `json:"size"`
SHA256 string `json:"sha256"`
}
PresignBody declares one upload: its path, type, size and whole-file SHA-256, which finds an identical blob already in the folder and binds a single PUT's body.
type PresignPut ¶
PresignPut binds a direct upload to its exact type, length and SHA-256.
type PresignReply ¶
type PresignReply struct {
Path string `json:"path"`
SourceName string `json:"source_name,omitempty"`
Blob string `json:"blob"`
Exists bool `json:"exists,omitempty"`
Put *RequestReply `json:"put,omitempty"`
Multipart *MultipartReply `json:"multipart,omitempty"`
ProcessOnUpload bool `json:"process_on_upload,omitempty"`
}
PresignReply is the upload plan: Exists (commit directly), one Put, or a Multipart upload. Path is the path to commit: cleaned, with an extension, and named by the server for a Named upload. Blob is the name to commit: the folder's blob (sha256-{hex}-{uuid}) with Exists, else the staged upload (u-{uuid}) the PUT or parts write, which the worker places.
type PresignRequest ¶
type PresignRequest struct {
Ref contentref.ContentRef
Path string
Type string
Size int64
SHA256 []byte
}
PresignRequest declares one upload; SHA256 is the whole file's: it finds an identical blob already in the folder and binds a single PUT's body.
type Presigned ¶
type Presigned struct {
Path string
SourceName string
Blob string
Exists bool
Put *PresignedRequest
Multipart *Multipart
ProcessOnUpload bool
}
Presigned is the upload plan: Exists (commit it), a single Put, or a Multipart upload. Path is the path to commit; Blob is the name to commit: the folder's blob when Exists, else the staged upload (u-{uuid}) that the PUT or the parts write.
type PresignedPart ¶
type PresignedPart struct {
Number int32
PresignedRequest
}
PresignedPart is a part URL.
type PresignedRequest ¶
PresignedRequest is a request a browser sends as is, with exactly Header.
type Private ¶ added in v0.62.0
type Private struct {
Name string `json:"name"`
// From is an upload path or pattern; "" for Zip.
From string `json:"from,omitempty"`
// To is the output path template: a file ("low-res/{name}.webp",
// "video/source-1080p.mp4") or, for producers with several outputs, a
// directory ending in "/" ("hls/"). Source-format
// images end in {ext}, the upload's extension: "download/{name}{ext}".
To string `json:"to"`
// Download is the human name template a download read signs into the
// URL, filled from the manifest's meta and {name}: "{title}.zip".
Download string `json:"download,omitempty"`
// HostOnly leaves this preset out of generic reads and playlists. Version
// outputs stay in internal and can be served only by the authorized host
// download transfer. They never share an allocation with ordinary served
// outputs, because an item token opens every private file in its folder.
HostOnly bool `json:"host_only,omitempty"`
Image *Image `json:"image,omitempty"`
HLS *HLS `json:"hls,omitempty"`
MP4 *MP4 `json:"mp4,omitempty"`
Zip string `json:"zip,omitempty"` // the files under this prefix, in manifest order: "high/"
Subtitles *Subtitles `json:"subtitles,omitempty"`
// Shapes render an Image preset's uploads of another shape: an upload
// whose oriented size is in one renders its Image, any other (or one not
// yet measured) renders Image. Shapes never overlap.
Shapes []Shape `json:"shapes,omitempty"`
}
Private derives files in private/, recorded in the manifest with their provenance (File.From, Preset, FP). Exactly one producer is set.
type ProcessingCount ¶ added in v0.125.0
type ProcessingCount struct {
Completed int `json:"completed"`
Total int `json:"total"`
Failed int `json:"failed"`
}
ProcessingCount counts source files, not individual encoded widths or chunks. Completed and Failed are disjoint; the remaining files are still pending.
type ProcessingEvent ¶ added in v0.126.1
type ProcessingEvent struct {
Kind string `json:"kind"`
ContentID string `json:"content_id"`
VersionID string `json:"version_id,omitempty"`
State string `json:"state"`
Uploads ProcessingCount `json:"uploads"`
Archives ArchiveStatus `json:"archives"`
Presets []PresetStatus `json:"presets"`
FailureCount int `json:"failure_count"`
}
ProcessingEvent is a durable observation of media, without delivery URLs or credentials. Completion includes settled failures; State distinguishes them.
type ProcessingFailure ¶ added in v0.125.0
type ProcessingFailure struct {
Path string `json:"path"`
Code string `json:"code"`
Message string `json:"message"`
}
ProcessingFailure is an editor-visible failure without internal paths, source URLs or the worker's unfiltered error chain.
type Public ¶ added in v0.62.0
type Public struct {
Name string `json:"name"`
From string `json:"from"`
To string `json:"to"` // "cover-{w}.webp", "{name}.webp", "preview-{n}.webp"
First int `json:"first,omitempty"`
Widths []int `json:"widths,omitempty"`
Image Image `json:"image"`
// Default is a path in Kind.Defaults, rendered to the kind's _default
// item at every width (PublishDefaults).
Default string `json:"default,omitempty"`
// Stable also keeps the current image at the logical names (To without
// a generation), overwritten in place: a URL built from the item's id,
// which the gateway answers with Default while none is current. One
// image per item: no {name}, no First.
Stable bool `json:"stable,omitempty"`
}
Public is a fixed public image: {To} with {w} at each of Widths (or one file without Widths), rendered from an upload through its edit, at public/{name}. With Widths, each width is Image at that width: in the shape of its Width×Height box (both or neither), fitted per Fit, else of the edit. It is never in the manifest; the object carries its from and fp as metadata. A missing one is served Default by the media gateway.
First makes it a preview: the first First attached uploads of From (a {name} pattern) in manifest order, {n} in To their position from 1 ("preview-{n}.webp"). Anyone who can see the item sees them; a position is rendered again when another upload takes it, and names past the last upload are deleted. Everything else of the item stays private.
type PublicImage ¶ added in v0.68.0
type PublicImage struct {
From string `json:"from"`
Preset string `json:"preset"`
Renditions []PublicRendition `json:"renditions"`
}
PublicImage is a published public preset for one upload. From is empty for a preset's default image (Registry.DefaultImage).
func (PublicImage) SrcSet ¶ added in v0.68.0
func (p PublicImage) SrcSet() string
SrcSet uses published URLs and actual encoded widths, without deriving a filename from the item ID. Duplicate widths (a small source) occur once.
func (PublicImage) URL ¶ added in v0.68.0
func (p PublicImage) URL(width int) string
URL picks the narrowest published rendition at least width pixels wide, or the widest when the source is smaller. An unpublished image has no URL.
type PublicRendition ¶ added in v0.68.0
PublicRendition carries its physical URL and actual encoded dimensions.
type Publication ¶ added in v0.68.0
type Publication struct {
Preset string `json:"preset"`
Source string `json:"source"` // the upload's Key
FP string `json:"fp"`
// Stable records whether this generation also owns its logical names.
// Nil marks historical manifests whose alias policy was not recorded.
Stable *bool `json:"stable,omitempty"`
// Generation suffixes every physical name; "" is a legacy publication,
// files a pre-v0.68 worker wrote at the logical names (always ready).
Generation string `json:"generation"`
Blobs []string `json:"blobs,omitempty"` // version preset outputs prepared in internal/, aligned with Names
Names []string `json:"names"` // logical preset names at this position
State PublicationState `json:"state"`
Dims []Dims `json:"dims"`
}
Publication owns one public preset's physical files. Reservation precedes every PUT; State becomes ready only after all renditions have landed. Retired generations are never reused, even when their source bytes are identical. An upload holds at most one ready publication per preset, the current one, and one reserved successor, which replaces it once ready: cleanup never retires the current files while their successor is written.
func (Publication) NamesOnDisk ¶ added in v0.68.0
func (p Publication) NamesOnDisk() []string
NamesOnDisk lists the immutable physical names reserved by the publication.
func (Publication) Ready ¶ added in v0.68.0
func (p Publication) Ready() bool
type PublicationState ¶ added in v0.68.0
type PublicationState uint8
PublicationState has a fixed-width JSON representation: reserving and publishing a replacement must not consume Full manifests' flag headroom.
const ( PublicationReserved PublicationState = iota PublicationReady )
type Publish ¶ added in v0.81.0
type Publish struct {
// Pages is the {name} upload of the version's ordered pages:
// "originals/{name}".
Pages string `json:"pages"`
// Renditions are the private image presets from Pages a reader reads,
// the first at reading size: "low", "thumb".
Renditions []string `json:"renditions"`
// Previews names a declared public preview preset (First caps the reader
// preview count). Its uploads render normally; reader plans may also sign
// existing private renditions under the live access policy.
Previews string `json:"previews,omitempty"`
// Playback is the declared {name} audio upload the reader plays unchanged.
Playback string `json:"playback,omitempty"`
// Import is the {name} upload of page archives (application/zip),
// expanded into Pages in name order.
Import string `json:"import,omitempty"`
// Download is the HostOnly Zip preset of the version's pages, which a
// download serves when its content kind serves pages.
Download string `json:"download,omitempty"`
}
Publish declares which existing version files a reader may consume. Its immutable metadata snapshot contains no chapter folders or duplicated files; chapter boundaries and release dates are evaluated when the reader asks.
type PutOptions ¶
type PutOptions struct {
ContentType string
CacheControl string
ChecksumSHA256 []byte
IfMatch string
IfNoneMatch string
Metadata map[string]string
}
PutOptions are conditions and headers for Put. IfNoneMatch "*" creates only.
type ReadOptions ¶
type ReadOptions struct {
Prefix string // only files under this path prefix ("low-res/")
Offset, Limit int // the range that gets URLs
// Paths selects at most 64 exact file paths to receive URLs, independent
// of ordinal position. All allowed metadata remains in manifest order.
// It cannot be combined with a nonzero Offset or Limit.
Paths []string
Download bool // URLs serve each file as a download under its name
// Editor adds an editor's uploads with their edit, frame, meta,
// pending, failure, editor view and retained source URL, unattached ones
// included. Source URLs are independent of the viewer's ServeOriginals.
Editor bool
// Status returns only whole-manifest processing counts, for editors.
// It issues no URLs or editor-view work and ignores pagination/prefix.
Status bool
}
ReadOptions select what a read returns.
type ReadResult ¶
type ReadResult struct {
Access string `json:"access"`
Inspection bool `json:"inspection,omitempty"` // explicit administrative view; playlists must repeat the management-read request
// Expires is when the item token (the URLs, the cookie) stops working,
// in unix seconds. A read before then answers the same token, so a
// client keeps what it has and reads again shortly before.
Expires int64 `json:"expires"`
Meta map[string]any `json:"meta,omitempty"`
// Previews are the item's public preview images in order (a Public
// preset with First): every viewer who can see the item gets them.
Previews []string `json:"previews,omitempty"`
// Public lists the exact published renditions. Clients must not infer a
// current cover or avatar's physical filename from the preset template.
Public []PublicImage `json:"public,omitempty"`
// Locked: the item holds files this viewer does not open. A viewer is
// listed only the files it opens, so Total counts those alone.
Locked bool `json:"locked,omitempty"`
Total int `json:"total"`
Offset int `json:"offset"`
Limit int `json:"limit"`
// HLS lists the item's playable ladders by output directory ("hls/"):
// play {read API}/{kind}/{id}/hls/{dir}master.m3u8.
HLS []string `json:"hls,omitempty"`
// State is the item's readiness (editors).
State string `json:"state,omitempty"`
// Status is a whole-manifest processing snapshot for editors only.
Status *MediaStatus `json:"status,omitempty"`
// Full (editors): the item's manifest cannot hold more outputs, so
// processing stopped; remove uploads (any commit that shrinks it) to
// resume. Uploads left unprocessed stay pending.
Full bool `json:"full,omitempty"`
// Uploads (editors) are the kind's upload paths and their rules.
Uploads []UploadRule `json:"uploads,omitempty"`
Files []FileInfo `json:"files"`
// Cookie must be set on the response (cookie delivery, with access).
Cookie *http.Cookie `json:"-"`
}
ReadResult is the read API's answer: the files under the requested prefix in manifest order (Total of them), each with a URL within [offset, offset+limit). Without access it lists none.
type Readiness ¶ added in v0.50.0
type Readiness struct {
State string `json:"state"`
Processing []string `json:"processing,omitempty"`
Failed []string `json:"failed,omitempty"`
}
Readiness is whether an item's media is processed: ready when no attached upload is pending (its public presets count only while the item is visible) and every zip packs its inputs; processing while any is; failed once nothing is processing and an upload failed for its current blob and edit; full while work is left on a Full manifest. Processing and Failed name upload paths (and zip outputs).
type RefBody ¶
type RefBody struct {
Kind string `json:"kind"`
ID string `json:"id"`
Version string `json:"version,omitempty"`
}
RefBody names an item of the handler's registry: of a content kind, one version's; of any other kind, Version "".
type RequestReply ¶
type RequestReply struct {
Method string `json:"method"`
URL string `json:"url"`
Headers map[string]string `json:"headers"`
Expires time.Time `json:"expires"`
}
RequestReply is a presigned request: send exactly these headers (the browser adds Content-Length, which is signed too).
type Segment ¶
Segment is one EXT-X-BYTERANGE segment, encoded as [offset, length, seconds].
func (Segment) MarshalJSON ¶
func (*Segment) UnmarshalJSON ¶
type Shape ¶ added in v0.133.0
type Shape struct {
WiderThan Aspect `json:"wider_than,omitzero"`
NoWiderThan Aspect `json:"no_wider_than,omitzero"`
Image Image `json:"image"`
}
Shape is a range of upload aspects (width:height), wider than WiderThan and no wider than NoWiderThan; an unset bound is open. Tall pages (height at least twice the width) are NoWiderThan 1:2; wide ones WiderThan 1:1. Image keeps its preset's Format and Animation.
type SourceAdmission ¶ added in v0.126.0
type SourceAdmission struct {
// Generation is the accepting commit ID. Removing and re-adding a retained
// ZIP creates fresh work; metadata edits keep the existing generation.
Generation string `json:"generation"`
Target string `json:"target"`
Accounting bool `json:"accounting,omitempty"`
Owner string `json:"owner,omitempty"`
Enforce bool `json:"enforce,omitempty"`
Quota int64 `json:"quota,omitempty"`
}
SourceAdmission records the verified upload policy accepted for a ZIP source. Only server commit code writes it; HTTP operations cannot supply these fields. A background importer uses the same owner and ceiling when attaching decoded originals. Quota <= 0 is unlimited, as in PGLimits.Quota.
type Sprite ¶
type Sprite struct {
Cols int `json:"cols"`
Rows int `json:"rows"`
W int `json:"w"`
H int `json:"h"`
Interval float64 `json:"interval"`
}
Sprite is a seek-preview grid of Cols×Rows tiles of W×H, one per Interval seconds.
type StagedCopy ¶ added in v0.81.0
type StagedCopy struct {
Path string `json:"path"`
Blob string `json:"blob"`
Size int64 `json:"size"`
}
StagedCopy is a staged copy for a commit's put: its path and blob.
type Store ¶
type Store interface {
Put(ctx context.Context, key string, body io.Reader, size int64, opts PutOptions) (Object, error)
Get(ctx context.Context, key string, opts GetOptions) (io.ReadCloser, Object, error)
Head(ctx context.Context, key string) (Object, error)
Delete(ctx context.Context, key string) error
List(ctx context.Context, prefix string) iter.Seq2[Object, error]
// Copy copies src to dst server-side, keeping its content type (unless
// o.ContentType), cache control and metadata; objects past the backend's single-copy limit
// (5 GiB on S3) copy in parts. The returned Object has dst's size.
Copy(ctx context.Context, src, dst string, o CopyOptions) (Object, error)
PresignPut(ctx context.Context, key string, p PresignPut) (PresignedRequest, error)
// PresignGet is for a worker reading an original over HTTP ranges. Its URL
// uses the store's internal endpoint and must not be returned to browsers.
PresignGet(ctx context.Context, key string, ttl time.Duration) (PresignedRequest, error)
CreateMultipart(ctx context.Context, key, contentType string) (uploadID string, err error)
PresignPart(ctx context.Context, key, uploadID string, number int32, size int64, sha256 []byte, ttl time.Duration) (PresignedRequest, error)
// PutPart uploads one part from the server, bound to its length and SHA-256.
PutPart(ctx context.Context, key, uploadID string, number int32, body io.Reader, size int64, sha256 []byte) (Part, error)
ListParts(ctx context.Context, key, uploadID string) ([]Part, error)
CompleteMultipart(ctx context.Context, key, uploadID string, parts []Part) (Object, error)
AbortMultipart(ctx context.Context, key, uploadID string) error
// Capabilities are the backend's, probed on first use when not given; an
// error (ErrUnavailable) means they are not known yet.
Capabilities(ctx context.Context) (Capabilities, error)
// Check reports whether the backend answers, establishing Capabilities
// while they are unknown.
Check(ctx context.Context) error
}
Store is the bucket. Item builds keys and enforces ownership. A backend may recognize canonical temporary keys solely to apply storage expiry policy.
type Subtitles ¶ added in v0.62.0
type Subtitles struct{}
Subtitles converts SRT, SSA/ASS and WebVTT to clean UTF-8 WebVTT. A video lists the item's converted subtitles as tracks after its own.
type TicketBody ¶
type TicketBody struct {
Ticket string `json:"ticket"`
}
type Track ¶ added in v0.62.0
type Track struct {
Kind string `json:"kind"` // TrackVideo, TrackAudio, TrackSubs, TrackSprite
Codec string `json:"codec,omitempty"` // video: h264, hevc, av1
Codecs string `json:"codecs,omitempty"` // RFC 6381
Bandwidth int `json:"bw,omitempty"`
Average int `json:"avg,omitempty"`
ID string `json:"id,omitempty"`
Lang string `json:"lang,omitempty"`
Label string `json:"label,omitempty"`
Default bool `json:"default,omitempty"`
Forced bool `json:"forced,omitempty"`
Index string `json:"index,omitempty"` // "sha256-{hex}-{uuid}": the TrackIndex
}
Track is an HLS track file. It is small: the segment table or sprite grid is its own private blob, Index (a TrackIndex), cached by hash.
type TrackIndex ¶ added in v0.62.0
type TrackIndex struct {
Segments []Segment `json:"segments,omitempty"`
Sprite *Sprite `json:"sprite,omitempty"`
}
TrackIndex is a Track's index blob: a byte-range track's segments (its init segment is bytes [0, Segments[0].Offset)), or a sprite's grid.
type Upload ¶ added in v0.62.0
type Upload struct {
Path string `json:"path"`
// ArchiveTo expands a ZIP into this image upload pattern during ingestion.
// It is media-level policy and may target gallery pages or body images.
ArchiveTo string `json:"archive_to,omitempty" yaml:"archive_to"`
// Body marks a content kind's body images (Named, with a private image
// preset and no public one): each version keeps its copy in private/,
// which only the version's openers read.
Body bool `json:"body,omitempty"`
Types []string `json:"types"` // accepted content types
MaxBytes int64 `json:"max_bytes"` // per file
Max int `json:"max,omitempty"` // uploads matching Path; 0 is unlimited
Frames string `json:"frames,omitempty"` // may be grabbed from a frame of this video upload (the frame op)
Named bool `json:"named,omitempty"` // the server names it ({name} is "i-{uuid}"): inline images
// Video bounds a video upload as probed from its real stream;
// nil or zero fields take the defaults (DefaultVideoLimits).
Video *VideoLimits `json:"video,omitempty"`
}
Upload is an app path that may be uploaded: a literal ("cover") or a pattern ending in {name} ("originals/{name}"). A file's path is the path plus its extension ("cover.png", "originals/001.png"); a put to the same stem replaces it.
type UploadAuthorizer ¶
type UploadAuthorizer interface {
CanUpload(ctx context.Context, actor access.Actor, t UploadTarget) (UploadGrant, error)
}
UploadAuthorizer is the app's upload permission check, run at presign and commit against what is written.
type UploadError ¶
type UploadError struct {
Code string
Message string
RetryAfter time.Duration // CodeRate: when the window frees
Blobs []string // CodeNotUploaded at commit: the blobs to upload again
Details *ErrorDetails // image refusals
}
UploadError is a refused upload request. UploadLimiter implementations refuse with CodeRate or CodeQuota.
func (*UploadError) Error ¶
func (e *UploadError) Error() string
type UploadGrant ¶
type UploadGrant struct {
Allowed bool
Exempt bool
Owner string
// ArchiveTo explicitly approves every generated filename in this configured
// destination pattern. Empty does not authorize expansion.
ArchiveTo string
}
UploadGrant is the app's verdict. Exempt (trusted roles) skips the UploadLimiter; Owner is the quota owner, "" for none.
type UploadRule ¶ added in v0.68.0
type UploadRule struct {
Path string `json:"path"`
Types []string `json:"types"`
MaxBytes int64 `json:"max_bytes"`
// Max caps the files at Path; 0 is unlimited.
Max int `json:"max,omitempty"`
Named bool `json:"named,omitempty"`
Page bool `json:"page,omitempty"` // original pages of a versioned reader
// Body: the upload holds the body's images (Upload.Body).
Body bool `json:"body,omitempty"`
Frames string `json:"frames,omitempty"`
// Aspect and MinWidth bound an image's edit: its first public preset's.
Aspect Aspect `json:"aspect,omitzero"`
MinWidth int `json:"min_width,omitempty"`
// Video is a video upload's limits in effect; MinAspect and
// MaxAspect the display aspects (width/height) its HLS presets accept.
Video *VideoLimits `json:"video,omitempty"`
MinAspect float64 `json:"min_aspect,omitempty"`
MaxAspect float64 `json:"max_aspect,omitempty"`
}
UploadRule is one upload path's rules, as editor reads carry them so a client turns away a file the server would refuse. The server stays the authority.
type UploadTarget ¶ added in v0.60.0
type UploadTarget struct {
Ref contentref.ContentRef
Path string
}
UploadTarget is what an upload writes: an item and an upload path stem ("cover", "originals/001"); "" for ops that change no one upload (move, meta, regenerate).
type VideoJobClass ¶ added in v0.58.0
type VideoJobClass string
VideoJobClass selects the priority of a new video run. An empty class is an upload; re-encodes and backfills yield to new playable videos.
const (
VideoBackfill VideoJobClass = "backfill"
)
const (
VideoReencode VideoJobClass = "reencode"
)
type VideoLimits ¶ added in v0.62.0
type VideoLimits struct {
MaxSeconds float64 `json:"max_seconds,omitempty"` // real running time
MaxFPS float64 `json:"max_fps,omitempty"` // output frame rate (at most 60); a faster source is encoded at it
MaxPixels int `json:"max_pixels,omitempty"` // displayed frame area
// MaxWork bounds the planned encode: the sum over the HLS and MP4
// presets' rungs and codecs of output pixels × output frames.
MaxWork float64 `json:"max_work,omitempty"`
}
VideoLimits bound what one video upload may cost the worker; an upload past them fails (video_too_long, video_too_large, video_over_budget) before any encode runs.
func (*VideoLimits) Limits ¶ added in v0.62.0
func (l *VideoLimits) Limits() VideoLimits
Limits are the limits in effect: l's, and the defaults for nil or zero fields.
Source Files
¶
- aspect.go
- config.go
- content.go
- edit.go
- folders.go
- hls.go
- ingest.go
- issuance.go
- jobs.go
- kind.go
- manifest.go
- ops.go
- page_analysis.go
- page_names.go
- paths.go
- process.go
- processing_events.go
- progress.go
- provenance.go
- public.go
- publications.go
- read.go
- registry.go
- restore.go
- source_admission.go
- status.go
- store.go
- upload.go
- upload_errors.go
- video_support.go
- wire.go
Directories
¶
| Path | Synopsis |
|---|---|
|
Package avatar provides a user-avatar kind for ContentKit media registries.
|
Package avatar provides a user-avatar kind for ContentKit media registries. |
|
Package gateway serves the exact app/account roots declared for a media host.
|
Package gateway serves the exact app/account roots declared for a media host. |
|
Package layout defines media object keys, dependency-free so the media gateway can classify paths without importing the media runtime.
|
Package layout defines media object keys, dependency-free so the media gateway can classify paths without importing the media runtime. |
|
Package s3 implements media.Store over aws-sdk-go-v2 for Ceph RGW (production) and MinIO (tests).
|
Package s3 implements media.Store over aws-sdk-go-v2 for Ceph RGW (production) and MinIO (tests). |
|
Package token signs and verifies media access tokens, shared by the host signer and the media gateway so the format cannot drift:
|
Package token signs and verifies media access tokens, shared by the host signer and the media gateway so the format cannot drift: |
|
Package versions publishes content versions and binds their optional media.
|
Package versions publishes content versions and binds their optional media. |