Help us shape the future of Go! Take the 2026 Go Developer Survey

artwork

package
v0.3.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 3, 2026 License: GPL-3.0 Imports: 43 Imported by: 0

Documentation

Overview

Package artwork serves and makes Ether's artwork: a caching proxy for TMDB images (memory LRU over a disk cache) and a pure-Go poster generator for collections (collage and backdrop treatments with the title set in the Go fonts).

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidPath rejects anything that is not a TMDB image path.
	ErrInvalidPath = errors.New("artwork: not a TMDB image path")
	// ErrNotFound means the image does not exist upstream.
	ErrNotFound = errors.New("artwork: image not found")
)
View Source
var ErrSVG = errors.New("artwork: SVG cannot be safely rasterized")

Functions

func BlurHash added in v0.3.0

func BlurHash(img image.Image, componentsX, componentsY int) (string, error)

BlurHash returns a standard BlurHash for img. The input is sampled on a bounded grid so computation remains cheap even for a large source image.

func Compose

func Compose(req PosterRequest, posters, backdrops []image.Image) *image.RGBA

Compose draws a poster from already-decoded images. It is pure, so tests can check its output without a network.

collage   2×2 (4+ posters) or 3×2 (6 posters) tiles under a gradient
backdrop  a member backdrop cropped to portrait with a title treatment
auto      collage with 4+ posters, else backdrop, else a single poster,
          else a typographic poster in the accent colour

func ResizePoster added in v0.2.34

func ResizePoster(data []byte, w int) ([]byte, error)

ResizePoster validates the decode budget before allocating pixels. Raster re-encoding also excludes SVG scripts, animation and upstream metadata.

func Size

func Size(w int) string

Size picks the smallest TMDB size at least w wide ("original" for 0, capped at w1280 otherwise).

func ThumbHash added in v0.3.0

func ThumbHash(img image.Image) ([]byte, error)

ThumbHash encodes a bounded sample of img in the standard ThumbHash format. It returns the raw encoded bytes.

func ValidPath

func ValidPath(p string) bool

ValidPath reports whether p is a TMDB image path such as "/abc123.jpg": a single file name, so it can never traverse or address another host.

Types

type ImageSource

type ImageSource interface {
	Get(ctx context.Context, path string, w int) ([]byte, string, error)
}

ImageSource loads TMDB images; *Images satisfies it.

type Images

type Images struct {
	// contains filtered or unexported fields
}

Images is a caching TMDB image store. Concurrent requests for the same image share one fetch. Safe for concurrent use.

func NewImages

func NewImages(o ImagesOptions) *Images

NewImages creates an image store.

func (*Images) Get

func (im *Images) Get(ctx context.Context, path string, w int) ([]byte, string, error)

Get returns a TMDB image at the smallest size covering width w.

func (*Images) GetPoster added in v0.2.34

func (im *Images) GetPoster(ctx context.Context, t *core.Title, fallback string, w int) ([]byte, string, error)

GetPoster never sends provider URLs to a client. Missing IDs, unsupported title kinds and every provider failure use the original TMDB artwork.

func (*Images) GetURL

func (im *Images) GetURL(ctx context.Context, rawURL string) ([]byte, string, error)

GetURL fetches an owner-supplied image URL (custom collection art). Only http(s) URLs to images are accepted.

func (*Images) GetUntrustedURL added in v0.3.0

func (im *Images) GetUntrustedURL(ctx context.Context, rawURL string) ([]byte, string, error)

GetUntrustedURL fetches a URL supplied by a remote feed, preventing it from reaching private addresses or rebinding across redirects. Owner-configured collection URLs continue to use GetURL and retain their existing behavior.

func (*Images) PosterVersion added in v0.2.34

func (im *Images) PosterVersion() string

type ImagesOptions

type ImagesOptions struct {
	// Posters returns the current owner settings; nil preserves TMDB.
	Posters func() config.Posters

	// Dir is the disk cache directory ("" = memory only).
	Dir string
	// MemoryBytes bounds the in-memory LRU (default 64 MiB).
	MemoryBytes int64
	// DiskBytes bounds the disk cache (default 512 MiB).
	DiskBytes int64
	// HTTPClient fetches images (default: 20 s timeout).
	HTTPClient *http.Client
	// ImageURL builds TMDB URLs (default image.tmdb.org).
	ImageURL core.ImageURLFunc
	Logger   *slog.Logger
}

ImagesOptions configure an image store.

type PosterRequest

type PosterRequest struct {
	Title    string   `json:"title"`
	Subtitle string   `json:"subtitle,omitempty"` // small caps line above the title, e.g. "24 FILMS"
	Mode     string   `json:"mode"`               // auto | collage | backdrop
	Accent   string   `json:"accent,omitempty"`   // "#rrggbb"; derived from the artwork when empty
	Posters  []string `json:"posters,omitempty"`  // member poster paths (up to 6 used)
	// Backdrops are member backdrop paths (the first that loads is used).
	Backdrops []string `json:"backdrops,omitempty"`
	Width     int      `json:"width"` // output width; height is 1.5×
}

PosterRequest describes a collection poster.

func (PosterRequest) String

func (r PosterRequest) String() string

String describes a request (logs).

type RasterOptions added in v0.3.0

type RasterOptions struct {
	Width, Height int
	Format        string
	Blur          bool
}

type Renderer

type Renderer struct {
	// contains filtered or unexported fields
}

Renderer makes collection posters and caches them on disk, keyed by everything that affects the pixels (title, mode, accent, members, size).

func NewRenderer

func NewRenderer(src ImageSource, dir string, log *slog.Logger) *Renderer

NewRenderer creates a renderer. dir "" disables the disk cache.

func (*Renderer) Poster

func (r *Renderer) Poster(ctx context.Context, req PosterRequest) ([]byte, string, error)

Poster returns a JPEG poster for req.

type SVGRasterizer added in v0.3.0

type SVGRasterizer struct {
	// contains filtered or unexported fields
}

SVGRasterizer bounds work on untrusted SVG and caches raster variants. It is shared by a runtime, not global. References are never authorization tokens.

func NewSVGRasterizer added in v0.3.0

func NewSVGRasterizer() *SVGRasterizer
func (r *SVGRasterizer) ChannelLogo(ctx context.Context, reference, number, name string, opts RasterOptions) ([]byte, string, error)

ChannelLogo renders the same channel number, name and colours as Ether's SVG fallback; oksvg cannot render SVG text, so that generated logo is drawn from its source fields instead of rasterizing the SVG.

func (*SVGRasterizer) Rasterize added in v0.3.0

func (r *SVGRasterizer) Rasterize(ctx context.Context, reference string, data []byte, opts RasterOptions) ([]byte, string, error)

Rasterize validates and renders an SVG without resolving external resources.

Directories

Path Synopsis
Package service owns shared artwork authorization, selection and rendering.
Package service owns shared artwork authorization, selection and rendering.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL